mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
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 #24005).
This commit is contained in:
@@ -485,6 +485,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 = idTableGet(c.bindings, t)
|
||||
if result == nil:
|
||||
|
||||
@@ -397,3 +397,15 @@ block: # `when`, test no constant semchecks
|
||||
{.error: "bad 2".}
|
||||
)
|
||||
var y: Bar[int]
|
||||
|
||||
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: <typedesc[T], U>
|
||||
# but expected: <T, U>
|
||||
x
|
||||
doAssert foo(Foo[int](1), Bar[int, int](2)).int == 1
|
||||
|
||||
Reference in New Issue
Block a user