Skip to content

Commit 31ee75f

Browse files
authored
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.
1 parent 2f5cfd6 commit 31ee75f

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

compiler/sigmatch.nim

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,10 +1196,15 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
11961196
return isGeneric
11971197
of tyFromExpr:
11981198
if c.c.inGenericContext > 0:
1199-
# generic type bodies can sometimes compile call expressions
1200-
# prevent expressions with unresolved types from
1201-
# being passed as parameters
1202-
return isNone
1199+
if not c.isNoCall:
1200+
# generic type bodies can sometimes compile call expressions
1201+
# prevent expressions with unresolved types from
1202+
# being passed as parameters
1203+
return isNone
1204+
else:
1205+
# Foo[templateCall(T)] shouldn't fail early if Foo has a constraint
1206+
# and we can't evaluate `templateCall(T)` yet
1207+
return isGeneric
12031208
else: discard
12041209

12051210
case f.kind

tests/generics/tuninstantiatedgenericcalls.nim

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,21 @@ block: # issue #23730
145145
proc test(M: static[int]): array[1 shl M, int] = discard
146146
doAssert len(test(3)) == 8
147147
doAssert len(test(5)) == 32
148+
149+
block: # issue #19819
150+
type
151+
Example[N: static int] = distinct int
152+
What[E: Example] = Example[E.N + E.N]
153+
154+
block: # issue #23339
155+
type
156+
A = object
157+
B = object
158+
template aToB(t: typedesc[A]): typedesc = B
159+
type
160+
Inner[I] = object
161+
innerField: I
162+
Outer[O] = object
163+
outerField: Inner[O.aToB]
164+
var x: Outer[A]
165+
doAssert typeof(x.outerField.innerField) is B

0 commit comments

Comments
 (0)