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.
This commit is contained in:
metagn
2025-02-28 17:23:19 +03:00
committed by GitHub
parent 7e8a650729
commit e39d152b89
2 changed files with 23 additions and 1 deletions

View File

@@ -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:

17
tests/vm/tsetrange.nim Normal file
View File

@@ -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)