From 5cbc7a6d1b1d6e440f26041fd7b7d7b023c06ea3 Mon Sep 17 00:00:00 2001 From: metagn Date: Mon, 9 Sep 2024 11:12:10 +0300 Subject: [PATCH] fix regression with generic params in static type (#24075) Caught in https://github.com/metagn/applicates, I'm not sure which commit causes this but it's also in the 2.0 branch (but not 2.0.2), so it's not any recent PRs. If a proc has a static parameter with type `static Foo[T]`, then another parameter with type `static Bar[T, U]`, the generic instantiation for `Bar` doesn't match `U` which has type `tyGenericParam`, but matches `T` since it has type `tyTypeDesc`. The reason is that `concreteType` returns the type itself for `tyTypeDesc` if `c.isNoCall` (i.e. matching a generic invocation), but returns `nil` for `tyGenericParam`. I'm guessing `tyGenericParam` is received here because of #22618, but that doesn't explain why `T` is still `tyTypeDesc`. I'm not sure. Regardless, we can just copy the behavior for `tyTypeDesc` to `tyGenericParam` and also return the type itself when `c.isNoCall`. This feels like it defeats the purpose of `concreteType` but the way it's used doesn't make sense without it (generic param can't match another generic param?). Alternatively we could loosen the `if concrete == nil: return isNone` checks in some places for specific conditions, whether `c.isNoCall` or `c.inGenericContext == 0` (though this would need (cherry picked from commit 24e5b21c900811ae8d0a69e06fc35fdd884b3ddc) --- compiler/sigmatch.nim | 1 + tests/generics/tuninstantiatedgenericcalls.nim | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index a0cf4ae55e..fb21a3cc39 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -379,6 +379,7 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType = else: result = t of tyGenericParam, tyAnything, tyConcept: result = t + if c.isNoCall: return while true: result = PType(idTableGet(c.bindings, t)) if result == nil: diff --git a/tests/generics/tuninstantiatedgenericcalls.nim b/tests/generics/tuninstantiatedgenericcalls.nim index 2163789e7b..6857f53199 100644 --- a/tests/generics/tuninstantiatedgenericcalls.nim +++ b/tests/generics/tuninstantiatedgenericcalls.nim @@ -163,3 +163,15 @@ block: # issue #23339 outerField: Inner[O.aToB] var x: Outer[A] doAssert typeof(x.outerField.innerField) is B + +block: # weird regression + type + Foo[T] = distinct int + Bar[T, U] = distinct int + proc foo[T, U](x: static Foo[T], y: static Bar[T, U]): Foo[T] = + # signature gives: + # Error: cannot instantiate Bar + # got: + # but expected: + x + doAssert foo(Foo[int](1), Bar[int, int](2)).int == 1