mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 06:18:51 +00:00
concept patch for tyGenericInvocation (#25288)
matching between some generic invocations and equivalent instantiations did not have a code path
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user