summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-09-17 07:22:45 +0300
committerGitHub <noreply@github.com>2024-09-17 06:22:45 +0200
commitb5f2eafed1438e612b7f269e95422a52893f7a5d (patch)
tree440d36babc696ce0cd78b2ec6a166ccef38329d7 /compiler
parentfe55dcb2be26e9b955ad949a65bf94e65478a1ab (diff)
downloadNim-b5f2eafed1438e612b7f269e95422a52893f7a5d.tar.gz
don't match arguments with typeclass type in generics (#24123)
fixes #24121

Proc arguments can have typeclass type like `Foo | Bar` that `sigmatch`
handles specially before matching them to the param type, because they
wouldn't match otherwise. Not exactly sure why this existed but matching
any typeclass or unresolved type in generic contexts now fails the match
so typing the call is delayed until instantiation.

Also it turns out default values with `tyFromExpr` type depending on
other parameters was never tested, this also needs a patch to make the
`tyFromExpr` type `tfNonConstExpr` so it doesn't try to evaluate the
other parameter at compile time.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/seminst.nim2
-rw-r--r--compiler/sigmatch.nim5
2 files changed, 7 insertions, 0 deletions
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index ff1592573..1bc6d31a2 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -254,6 +254,8 @@ proc instantiateProcType(c: PContext, pt: TypeMapping,
 
     let needsStaticSkipping = resulti.kind == tyFromExpr
     let needsTypeDescSkipping = resulti.kind == tyTypeDesc and tfUnresolved in resulti.flags
+    if resulti.kind == tyFromExpr:
+      resulti.flags.incl tfNonConstExpr
     result[i] = replaceTypeVarsT(cl, resulti)
     if needsStaticSkipping:
       result[i] = result[i].skipTypes({tyStatic})
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 17d2e7a4d..a48e79b7c 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -1279,6 +1279,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
     if prev == nil: body
     else: return typeRel(c, prev, a, flags)
 
+  if c.c.inGenericContext > 0 and not c.isNoCall and
+      (tfUnresolved in a.flags or a.kind in tyTypeClasses):
+    # cheap check for unresolved arg, not nested
+    return isNone
+
   case a.kind
   of tyOr:
     # XXX: deal with the current dual meaning of tyGenericParam