summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-09-13 12:08:22 +0300
committerGitHub <noreply@github.com>2024-09-13 11:08:22 +0200
commit61e04ba0ed4b8c6567f4cfd5c48c2c2439c62371 (patch)
treebb7628b388a52c676f1b66bad611a2b72465c861 /compiler
parent793cee4de1934fd1f6271cf5fed46f01c5abb19b (diff)
downloadNim-61e04ba0ed4b8c6567f4cfd5c48c2c2439c62371.tar.gz
fix calls to untyped arbitrary expressions in generics (#24100)
fixes #24099

If an arbitrary expression without a proc type (in this case
`tyFromExpr`) is called, the compiler [passes it to overload
resolution](https://github.com/nim-lang/Nim/blob/793cee4de1934fd1f6271cf5fed46f01c5abb19b/compiler/semexprs.nim#L1223).
But overload resolution also can't handle arbitrary expressions and
treats them as not participating at all, matching with the state
`csEmpty`. The compiler checks for this and gives an "identifier
expected" error. Instead, now if we are in a generic context and an
arbitrary expression call matched with `csEmpty`, we now return
`csNoMatch` so that `semResolvedCall` can leave it untyped as
appropriate.

The expression flag `efNoDiagnostics` is replaced with this check. It's
not checked anywhere else and the only place that uses it is
`handleCaseStmtMacro`. Replacing it with `efNoUndeclared`, we just get
`csEmpty` instead of `csNoMatch`, which is handled the same way here. So
`efNoDiagnostics` is now removed and `efNoUndeclared` is used instead.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semcall.nim3
-rw-r--r--compiler/semdata.nim1
-rw-r--r--compiler/semstmts.nim4
3 files changed, 3 insertions, 5 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index b81bc2a63..9111e3807 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -558,7 +558,8 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
     if overloadsState == csEmpty and result.state == csEmpty:
       if efNoUndeclared notin flags: # for tests/pragmas/tcustom_pragma.nim
         result.state = csNoMatch
-        if efNoDiagnostics in flags:
+        if c.inGenericContext > 0 and nfExprCall in n.flags:
+          # untyped expression calls end up here, see #24099
           return
         # xxx adapt/use errorUndeclaredIdentifierHint(c, n, f.ident)
         localError(c.config, n.info, getMsgDiagnostic(c, flags, n, f))
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index ef4a84af4..8c8e2c2dc 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -73,7 +73,6 @@ type
     efNoUndeclared, efIsDotCall, efCannotBeDotCall,
       # Use this if undeclared identifiers should not raise an error during
       # overload resolution.
-    efNoDiagnostics,
     efTypeAllowed # typeAllowed will be called after
     efWantNoDefaults
     efAllowSymChoice # symchoice node should not be resolved
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 334d10be7..f5f8fea0c 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1231,7 +1231,7 @@ proc handleCaseStmtMacro(c: PContext; n: PNode; flags: TExprFlags): PNode =
   toResolve.add n[0]
 
   var errors: CandidateErrors = @[]
-  var r = resolveOverloads(c, toResolve, toResolve, {skTemplate, skMacro}, {efNoDiagnostics},
+  var r = resolveOverloads(c, toResolve, toResolve, {skTemplate, skMacro}, {efNoUndeclared},
                            errors, false)
   if r.state == csMatch:
     var match = r.calleeSym
@@ -1245,8 +1245,6 @@ proc handleCaseStmtMacro(c: PContext; n: PNode; flags: TExprFlags): PNode =
     of skMacro: result = semMacroExpr(c, toExpand, toExpand, match, flags)
     of skTemplate: result = semTemplateExpr(c, toExpand, match, flags)
     else: result = errorNode(c, n[0])
-  elif r.state == csNoMatch:
-    result = errorNode(c, n[0])
   else:
     result = errorNode(c, n[0])
   if result.kind == nkEmpty: