Skip to content

Commit 79ddb7d

Browse files
authored
concept patch for tyGenericInvocation (#25288)
matching between some generic invocations and equivalent instantiations did not have a code path
1 parent 7cb8165 commit 79ddb7d

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

compiler/concepts.nim

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ proc bindParam(c: PContext, m: var MatchCon; key, v: PType): bool {. discardable
137137
# check previously bound value
138138
if not matchType(c, old, value, m):
139139
return false
140-
elif key.hasElementType and key.elementType.kind != tyNone:
140+
elif key.hasElementType and not key.elementType.isNil and key.elementType.kind != tyNone:
141141
# check constaint
142142
if matchType(c, unrollGenericParam(key), value, m) == false:
143143
return false
@@ -358,6 +358,14 @@ proc matchType(c: PContext; fo, ao: PType; m: var MatchCon): bool =
358358
if not matchType(c, f[i], ea[i], m):
359359
result = false
360360
break
361+
elif f.kind == tyGenericInvocation:
362+
# bind potential generic constraints into body
363+
let body = f.base
364+
for i in 1 ..< len(f):
365+
bindParam(c,m,body[i-1], f[i])
366+
result = matchType(c, body, a, m)
367+
else: # tyGenericInst
368+
result = matchType(c, f.last, a, m)
361369
of tyOrdinal:
362370
result = isOrdinalType(a, allowEnumWithHoles = false) or a.kind == tyGenericParam
363371
of tyStatic:

tests/concepts/tconceptsv2.nim

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,3 +546,42 @@ proc len[T](t: DummyIndexable[T]): int =
546546

547547
let dummyIndexable = DummyIndexable(@[1, 2])
548548
echoAll(dummyIndexable)
549+
550+
block:
551+
type
552+
C = concept
553+
proc a(x: Self, i: int)
554+
AObj[T] = object
555+
x: T
556+
ARef[T] = ref AObj[T]
557+
558+
proc a[T: int](x: ARef[T], i: int) =
559+
discard
560+
561+
assert (ref AObj[int]) is C
562+
563+
block:
564+
type
565+
C = concept
566+
proc a(x: Self, i: int)
567+
AObj[T; B] = object
568+
x: T
569+
ARef[T; B] = ref AObj[T,B]
570+
571+
proc a[T: int, C: float](x: ARef[T, C], i: int) =
572+
discard
573+
574+
assert (ref AObj[int, int]) isnot C
575+
assert (ref AObj[int, float]) is C
576+
577+
block:
578+
type
579+
C = concept
580+
proc a(x: Self, i: int)
581+
AObj[T] = object
582+
ARef[T] = ref AObj[T]
583+
584+
proc a(x: ARef, i: int) =
585+
discard
586+
587+
assert (ref AObj[int]) is C

0 commit comments

Comments
 (0)