concept patch for tyGenericInvocation (#25288)

matching between some generic invocations and equivalent instantiations
did not have a code path
This commit is contained in:
Ryan McConnell
2025-11-15 06:52:16 -05:00
committed by GitHub
parent 7cb8165e75
commit 79ddb7d89e
2 changed files with 48 additions and 1 deletions

View File

@@ -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:

View File

@@ -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