From e39d152b89c5635c27dd4d8fc71c48747c5fc20b Mon Sep 17 00:00:00 2001 From: metagn Date: Fri, 28 Feb 2025 17:23:19 +0300 Subject: [PATCH] handle ranges in `annotateType` for set constructors (#24737) fixes #24736 The VM can produce integer nodes with no types as set elements, which are later reannotated in `semmacrosanity.annotateType`. However the case of ranges was not handled properly. Not sure why this is a regression, probably unrelated but will have to see the bisect result to make sure. Note. Originally tried to fix this in `opcInclRange`, generated for and only for range expressions in set constructors, this seems to add the range node directly to the set node without checking if it has overlap with the existing elements by calling `nimsets` so an expression like `{cctNone, cctNone..cctHeader}` can produce `{0, 0..5}`. Doesn't seem to cause problems but `opcIncl` for single elements does check for overlap. Something else to note is that integer nodes produced by `nimsets` have proper types, so another option instead of relying on semmacrosanity to fix this would be to make `opcIncl` and `opcInclRange` call `nimsets` to add to the set node, but this might lose performance. --- compiler/semmacrosanity.nim | 7 ++++++- tests/vm/tsetrange.nim | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/vm/tsetrange.nim diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim index f246e38fb2..cba6b4a46a 100644 --- a/compiler/semmacrosanity.nim +++ b/compiler/semmacrosanity.nim @@ -146,7 +146,12 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) = of nkCurly: if x.kind in {tySet}: n.typ() = t - for m in n: annotateType(m, x.elemType, conf) + for m in n: + if m.kind == nkRange: + annotateType(m[0], x.elemType, conf) + annotateType(m[1], x.elemType, conf) + else: + annotateType(m, x.elemType, conf) else: globalError(conf, n.info, "{} must have the set type") of nkFloatLit..nkFloat128Lit: diff --git a/tests/vm/tsetrange.nim b/tests/vm/tsetrange.nim new file mode 100644 index 0000000000..a0b8ce9c4a --- /dev/null +++ b/tests/vm/tsetrange.nim @@ -0,0 +1,17 @@ +# issue #24736 + +import std/setutils + +type CcsCatType = enum cctNone, cctHeader, cctIndex, cctSetup, cctUnk1, cctStream + +block: # original issue + const CCS_CAT_TYPES = fullSet(CcsCatType) + proc test(t: int): bool = t.CcsCatType in CCS_CAT_TYPES + discard test(5) + +block: # minimized + func foo(): set[CcsCatType] = + {cctNone..cctHeader} + const CCS_CAT_TYPES = foo() + proc test(t: int): bool = t.CcsCatType in CCS_CAT_TYPES + discard test(5)