fixes #25290; tempalte overload scope dupe (#25308)

#25290
drafted bc if this passes full CI I am going to try and remove that
weird stuff in `pickBestCandidate`

(cherry picked from commit 2501e23d81)
This commit is contained in:
Ryan McConnell
2026-04-09 14:44:35 -04:00
committed by narimiran
parent c733904716
commit 5f32378115
3 changed files with 43 additions and 3 deletions

View File

@@ -131,7 +131,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
var sym = syms[0].s
let name = sym.name
var scope = syms[0].scope
c.openShadowScope
if allowTypeBoundOps:
for a in 1 ..< n.len:
# for every already typed argument, add type bound ops
@@ -218,6 +218,10 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
scope = syms[nextSymIndex].scope
inc(nextSymIndex)
if best.state == csMatch and best.calleeSym != nil and best.calleeSym.kind in {skTemplate, skMacro}:
c.closeShadowScope
else:
c.mergeShadowScope
proc effectProblem(f, a: PType; result: var string; c: PContext) =
if f.kind == tyProc and a.kind == tyProc:

View File

@@ -2835,9 +2835,11 @@ proc findFirstArgBlock(m: var TCandidate, n: PNode): int =
else: break
proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var IntSet) =
template noMatch() =
c.mergeShadowScope #merge so that we don't have to resem for later overloads
if m.calleeSym != nil and m.calleeSym.kind notin {skTemplate, skMacro}:
c.mergeShadowScope
else:
c.closeShadowScope
m.state = csNoMatch
m.firstMismatch.arg = a
m.firstMismatch.formal = formal

34
tests/overload/t25290.nim Normal file
View File

@@ -0,0 +1,34 @@
proc temp(one: int, two: int, three: int) =
discard
template temp(body: untyped): untyped =
body
temp:
proc a(tp: int) =
discard
proc mixedTemp(x: int) =
discard
proc mixedTemp(x: bool) =
discard
template mixedTemp(body: untyped): untyped =
body
# The `bool` proc should win here so `xx` survives
mixedTemp (let xx = 1; true)
discard xx
proc sinkTemp(x: int) =
discard
template sinkTemp(body: untyped): untyped =
discard
# Here the template should win here so `let xy` is sunk into template as AST
sinkTemp (let xy = "template"; xy)
when declared(xy):
{.error: "xy leaked from failed proc candidate".}