diff options
-rw-r--r-- | compiler/sigmatch.nim | 11 | ||||
-rw-r--r-- | tests/statictypes/tgenericcomputedrange.nim | 20 |
2 files changed, 31 insertions, 0 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index f94b4ee60..b2f52ba12 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1140,6 +1140,13 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, let x = typeRel(c, a, f, flags + {trDontBind}) if x >= isGeneric: return isGeneric + + 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 else: discard case f.kind @@ -2215,6 +2222,10 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType, of isNone: # do not do this in ``typeRel`` as it then can't infer T in ``ref T``: if a.kind in {tyProxy, tyUnknown}: + if a.kind == tyUnknown and c.inGenericContext > 0: + # don't bother with fauxMatch mechanism in generic type, + # reject match, typechecking will be delayed to instantiation + return nil inc(m.genericMatches) m.fauxMatch = a.kind return arg diff --git a/tests/statictypes/tgenericcomputedrange.nim b/tests/statictypes/tgenericcomputedrange.nim index 01ec4767a..82abe2677 100644 --- a/tests/statictypes/tgenericcomputedrange.nim +++ b/tests/statictypes/tgenericcomputedrange.nim @@ -95,3 +95,23 @@ block: x[2] = 3 doAssert x == [0: 1, 1: 2, 2: 3] doAssert x is array[0 .. 2, int] + +block: + type Foo[T; U: static T] = array[T(0) .. (U * 2) + 1, int] + + block: + var x: Foo[int, 1] + x[0] = 1 + x[1] = 2 + x[2] = 3 + x[3] = 4 + doAssert x == [0: 1, 1: 2, 2: 3, 3: 4] + doAssert x is array[0 .. 3, int] + +block: # issue #22187 + template m(T: type, s: int64): int64 = s + func p(n: int64): int = int(n) + type F[T; s: static int64] = object + k: array[p(m(T, s)), int64] + var x: F[int, 3] + doAssert x.k is array[3, int64] |