Skip to content

Commit

Permalink
don't treat template/macro/module as overloaded for opensym (#23939)
Browse files Browse the repository at this point in the history
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 a64aa51)
  • Loading branch information
metagn authored and narimiran committed Aug 14, 2024
1 parent a2ec0fe commit bde6665
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 3 deletions.
7 changes: 6 additions & 1 deletion compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion compiler/semgnrc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion tests/generics/tmacroinjectedsym.nim
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,4 @@ block: # issue #23865
let x = f().valueOr:
return $error
"ok"
doAssert g(int) == "error"
doAssert g(int) == "f"

0 comments on commit bde6665

Please sign in to comment.