summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-09-09 11:12:10 +0300
committerGitHub <noreply@github.com>2024-09-09 10:12:10 +0200
commit24e5b21c900811ae8d0a69e06fc35fdd884b3ddc (patch)
tree0ced05bc3a803206b52fa7f2acc5296c08641c99 /compiler
parentf223f016f35af0e32252560ad650c04a81a102ee (diff)
downloadNim-24e5b21c900811ae8d0a69e06fc35fdd884b3ddc.tar.gz
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).
Diffstat (limited to 'compiler')
-rw-r--r--compiler/sigmatch.nim1
1 files changed, 1 insertions, 0 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index e519f17c8..e1f197679 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -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: