treat generic body type as atomic in iterOverType (#24096)

follows up #24095

In #24095 a check was added that used `iterOverType` to check if a type
contained unresolved types, with the aim of always treating
`tyGenericBody` as resolved. But the body of the `tyGenericBody` is also
iterated over in `iterOverType`, so if the body of the type actually
used generic parameters (which isn't the case in the test added in
#24095, but is now), the check would still count the type as unresolved.

This is handled by not iterating over the children of `tyGenericBody`,
the only users of `iterOverType` are `containsGenericType` and
`containsUnresolvedType`, the first one always returns true for
`tyGenericBody` and the second one aims to always return false.
Unfortunately this means `iterOverType` isn't as generic of an API
anymore but maybe it shouldn't be used anymore for these procs.
This commit is contained in:
metagn
2024-09-11 17:13:28 +03:00
committed by GitHub
parent 9dda7ff7bc
commit 793cee4de1
2 changed files with 15 additions and 1 deletions

View File

@@ -232,7 +232,11 @@ proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
if result: return
if not containsOrIncl(marker, t.id):
case t.kind
of tyGenericInst, tyGenericBody, tyAlias, tySink, tyInferred:
of tyGenericBody:
# treat as atomic, containsUnresolvedType wants always false,
# containsGenericType always gives true
discard
of tyGenericInst, tyAlias, tySink, tyInferred:
result = iterOverTypeAux(marker, skipModifier(t), iter, closure)
else:
for a in t.kids:

View File

@@ -438,6 +438,16 @@ block: # issue #24090
block: # above but encountered by sigmatch using replaceTypeVarsN
type Opt[T] = object
x: T
proc none[T](x: type Opt, y: typedesc[T]): Opt[T] = discard
proc foo[T](x: T, a = Opt.none(int)) = discard
foo(1, a = Opt.none(int))
foo(1)
block: # real version of above
type Opt[T] = object
x: T
template none(x: type Opt, T: type): Opt[T] = Opt[T]()
proc foo[T](x: T, a = Opt.none(int)) = discard
foo(1, a = Opt.none(int))
foo(1)