From bde6665167a08408d7bc15cc74e1caa2248cf4ee Mon Sep 17 00:00:00 2001 From: metagn Date: Sun, 11 Aug 2024 17:12:57 +0300 Subject: [PATCH] don't treat template/macro/module as overloaded for opensym (#23939) actually fixes #23865 following up #23873 In the handling of `nkIdent` in `semExpr`, the compiler looks for the closest symbol with the name and [checks the symbol kind](https://github.com/nim-lang/Nim/blob/6126a0bf46f4e29a368b8baefea69a2bcae54e93/compiler/semexprs.nim#L3171) to also consider the overloads if the symbol kind is overloadable. But it treats the normally overloadable template/macro/module sym kinds the same as non-overloadable symbols, just calling `semSym` on it. We need to mirror this behavior in `semOpenSym`; we treat the captured symchoice as a fresh identifier, so if the symbol we find is a template/macro/module, we use that symbol immediately as opposed to waiting for overloads. (cherry picked from commit a64aa51fe9b7a9dac63806ff77a75573079bdcbd) --- compiler/semexprs.nim | 7 ++++++- compiler/semgnrc.nim | 2 +- tests/generics/tmacroinjectedsym.nim | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 8c778409a23d9..64e6585596ee3 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -164,8 +164,10 @@ proc semOpenSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags, expectedType: # enough to replace the original # for `nkOpenSymChoice`, the first found symbol must be non-overloadable, # since otherwise we have to use regular `nkOpenSymChoice` functionality + # but of the overloadable sym kinds, semExpr does not handle skModule, skMacro, skTemplate + # as overloaded in the case where `nkIdent` finds them first if s2 != nil and not c.isAmbiguous and - ((s == nil and s2.kind notin OverloadableSyms) or + ((s == nil and s2.kind notin OverloadableSyms-{skModule, skMacro, skTemplate}) or (s != nil and s2 != s)): # only consider symbols defined under current proc: var o = s2.owner @@ -192,6 +194,9 @@ proc semOpenSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags, expectedType: message(c.config, n.info, warnGenericsIgnoredInjection, msg) break o = o.owner + if s == nil: + # set symchoice node type back to None + n.typ = newTypeS(tyNone, c) proc inlineConst(c: PContext, n: PNode, s: PSym): PNode {.inline.} = result = copyTree(s.astdef) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index b1de4133c0e89..04204333887ef 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -73,7 +73,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, result = symChoice(c, n, s, scOpen) if canOpenSym(s): result.flags.incl nfOpenSym - if result.kind == nkSym: result.typ = nil + result.typ = nil case s.kind of skUnknown: # Introduced in this pass! Leave it as an identifier. diff --git a/tests/generics/tmacroinjectedsym.nim b/tests/generics/tmacroinjectedsym.nim index 5271a667f1fe0..a2771a9e8878a 100644 --- a/tests/generics/tmacroinjectedsym.nim +++ b/tests/generics/tmacroinjectedsym.nim @@ -171,4 +171,4 @@ block: # issue #23865 let x = f().valueOr: return $error "ok" - doAssert g(int) == "error" + doAssert g(int) == "f"