From 88da5e8ceed02ea5bb0ce4fb4979aad3870436f4 Mon Sep 17 00:00:00 2001 From: Ryan McConnell Date: Thu, 11 Sep 2025 08:50:11 -0400 Subject: [PATCH] two small concept patches (#25076) - slightly better typeclass logic (eg for bare `range`) - reverse matching now substitutes potential implementation for `Self` --------- Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com> --- compiler/concepts.nim | 12 +++++++++--- tests/concepts/tconceptsv2.nim | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/compiler/concepts.nim b/compiler/concepts.nim index 7c64b5eae9..a16b2fbfa2 100644 --- a/compiler/concepts.nim +++ b/compiler/concepts.nim @@ -271,7 +271,10 @@ proc matchType(c: PContext; fo, ao: PType; m: var MatchCon): bool = var a = ao f = fo - + if a.isSelf: + if m.magic in {mArrPut, mArrGet}: + return false + a = m.potentialImplementation if a.kind in bindableTypes: a = existingBinding(m, ao) if a == ao and a.kind == tyGenericParam and a.hasElementType and a.elementType.kind != tyNone: @@ -337,8 +340,11 @@ proc matchType(c: PContext; fo, ao: PType; m: var MatchCon): bool = result = true else: let ak = a.skipTypes(ignorableForArgType - {f.kind}) - if ak.kind == f.kind and f.kidsLen == ak.kidsLen: - result = matchKids(c, f, ak, m) + if ak.kind == f.kind: + if f.base.kind == tyNone: + result = true + elif f.kidsLen == ak.kidsLen: + result = matchKids(c, f, ak, m) of tyGenericInvocation, tyGenericInst: result = false let ea = a.skipTypes(ignorableForArgType) diff --git a/tests/concepts/tconceptsv2.nim b/tests/concepts/tconceptsv2.nim index 369fd3e854..c735aeeacc 100644 --- a/tests/concepts/tconceptsv2.nim +++ b/tests/concepts/tconceptsv2.nim @@ -497,6 +497,28 @@ block: spring({One,Two}) +block: # bare `range` + type + MyRange = 0..64 + MyConcept = concept + proc a(x: typedesc[Self]) + + proc a(x: typedesc[range]) = discard + proc spring(x: typedesc[MyConcept]) = discard + spring(MyRange) + +block: + type + A = object + TestConcept = + concept + proc x(x: Self) + + proc x(x: not object) = + discard + + assert A isnot TestConcept + # this code fails inside a block for some reason type Indexable[T] = concept proc `[]`(t: Self, i: int): T