mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-20 22:35:24 +00:00
bypass constraints for tyFromExpr in generic bodies (#23863)
fixes #19819, fixes #23339
Since #22029 `tyFromExpr` does not match anything in overloading, so
generic bodies can know which call expressions to delay until the type
can be evaluated. However generic type invocations also run overloading
to check for generic constraints even in generic bodies. To prevent them
from failing early from the overload not matching, pretend that
`tyFromExpr` matches. This mirrors the behavior of the compiler in more
basic cases like:
```nim
type
Foo[T: int] = object
x: T
Bar[T] = object
y: Foo[T]
```
Unfortunately this case doesn't respect the constraint (#21181, some
other bugs) but `tyFromExpr` should easily use the same principle when
it does.
(cherry picked from commit 31ee75f10e)
This commit is contained in:
@@ -1220,10 +1220,15 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
|
||||
of tyFromExpr:
|
||||
if c.c.inGenericContext > 0:
|
||||
# generic type bodies can sometimes compile call expressions
|
||||
# prevent expressions with unresolved types from
|
||||
# being passed as parameters
|
||||
return isNone
|
||||
if not c.isNoCall:
|
||||
# generic type bodies can sometimes compile call expressions
|
||||
# prevent expressions with unresolved types from
|
||||
# being passed as parameters
|
||||
return isNone
|
||||
else:
|
||||
# Foo[templateCall(T)] shouldn't fail early if Foo has a constraint
|
||||
# and we can't evaluate `templateCall(T)` yet
|
||||
return isGeneric
|
||||
else: discard
|
||||
case f.kind
|
||||
of tyEnum:
|
||||
|
||||
@@ -145,3 +145,21 @@ block: # issue #23730
|
||||
proc test(M: static[int]): array[1 shl M, int] = discard
|
||||
doAssert len(test(3)) == 8
|
||||
doAssert len(test(5)) == 32
|
||||
|
||||
block: # issue #19819
|
||||
type
|
||||
Example[N: static int] = distinct int
|
||||
What[E: Example] = Example[E.N + E.N]
|
||||
|
||||
block: # issue #23339
|
||||
type
|
||||
A = object
|
||||
B = object
|
||||
template aToB(t: typedesc[A]): typedesc = B
|
||||
type
|
||||
Inner[I] = object
|
||||
innerField: I
|
||||
Outer[O] = object
|
||||
outerField: Inner[O.aToB]
|
||||
var x: Outer[A]
|
||||
doAssert typeof(x.outerField.innerField) is B
|
||||
|
||||
Reference in New Issue
Block a user