diff --git a/compiler/concepts.nim b/compiler/concepts.nim index b808c6608b33..7e547b19ce3c 100644 --- a/compiler/concepts.nim +++ b/compiler/concepts.nim @@ -137,7 +137,7 @@ proc bindParam(c: PContext, m: var MatchCon; key, v: PType): bool {. discardable # check previously bound value if not matchType(c, old, value, m): return false - elif key.hasElementType and key.elementType.kind != tyNone: + elif key.hasElementType and not key.elementType.isNil and key.elementType.kind != tyNone: # check constaint if matchType(c, unrollGenericParam(key), value, m) == false: return false @@ -358,6 +358,14 @@ proc matchType(c: PContext; fo, ao: PType; m: var MatchCon): bool = if not matchType(c, f[i], ea[i], m): result = false break + elif f.kind == tyGenericInvocation: + # bind potential generic constraints into body + let body = f.base + for i in 1 ..< len(f): + bindParam(c,m,body[i-1], f[i]) + result = matchType(c, body, a, m) + else: # tyGenericInst + result = matchType(c, f.last, a, m) of tyOrdinal: result = isOrdinalType(a, allowEnumWithHoles = false) or a.kind == tyGenericParam of tyStatic: diff --git a/tests/concepts/tconceptsv2.nim b/tests/concepts/tconceptsv2.nim index c735aeeaccd4..629ac1c876d7 100644 --- a/tests/concepts/tconceptsv2.nim +++ b/tests/concepts/tconceptsv2.nim @@ -546,3 +546,42 @@ proc len[T](t: DummyIndexable[T]): int = let dummyIndexable = DummyIndexable(@[1, 2]) echoAll(dummyIndexable) + +block: + type + C = concept + proc a(x: Self, i: int) + AObj[T] = object + x: T + ARef[T] = ref AObj[T] + + proc a[T: int](x: ARef[T], i: int) = + discard + + assert (ref AObj[int]) is C + +block: + type + C = concept + proc a(x: Self, i: int) + AObj[T; B] = object + x: T + ARef[T; B] = ref AObj[T,B] + + proc a[T: int, C: float](x: ARef[T, C], i: int) = + discard + + assert (ref AObj[int, int]) isnot C + assert (ref AObj[int, float]) is C + +block: + type + C = concept + proc a(x: Self, i: int) + AObj[T] = object + ARef[T] = ref AObj[T] + + proc a(x: ARef, i: int) = + discard + + assert (ref AObj[int]) is C