delay markUsed for converters until call is resolved (#24243)

fixes #24241

(cherry picked from commit 09043f409f)
This commit is contained in:
metagn
2024-10-06 09:10:37 +03:00
committed by narimiran
parent 599f1ad6b3
commit 75e50f804a
5 changed files with 33 additions and 1 deletions

View File

@@ -89,6 +89,11 @@ proc fitNodePostMatch(c: PContext, formal: PType, arg: PNode): PNode =
changeType(c, x, formal, check=true)
result = arg
result = skipHiddenSubConv(result, c.graph, c.idgen)
# mark inserted converter as used:
var a = result
if a.kind == nkHiddenDeref: a = a[0]
if a.kind == nkHiddenCallConv and a[0].kind == nkSym:
markUsed(c, a.info, a[0].sym)
proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode =

View File

@@ -645,6 +645,15 @@ proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
for i in 1..<n.len:
instGenericConvertersArg(c, n[i], x)
proc markConvertersUsed*(c: PContext, n: PNode) =
assert n.kind in nkCallKinds
for i in 1..<n.len:
var a = n[i]
if a == nil: continue
if a.kind == nkHiddenDeref: a = a[0]
if a.kind == nkHiddenCallConv and a[0].kind == nkSym:
markUsed(c, a.info, a[0].sym)
proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode =
var m = newCandidate(c, f)
result = paramTypesMatch(m, f, a, arg, nil)
@@ -809,6 +818,7 @@ proc semResolvedCall(c: PContext, x: var TCandidate,
result = x.call
instGenericConvertersSons(c, result, x)
markConvertersUsed(c, result)
result[0] = newSymNode(finalCallee, getCallLineInfo(result[0]))
if finalCallee.magic notin {mArrGet, mArrPut}:
result.typ = finalCallee.typ.returnType

View File

@@ -1236,6 +1236,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType
else:
result = m.call
instGenericConvertersSons(c, result, m)
markConvertersUsed(c, result)
else:
result = overloadedCallOpr(c, n) # this uses efNoUndeclared

View File

@@ -2299,7 +2299,9 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
dest = generateTypeInstance(c, m.bindings, arg, dest)
let fdest = typeRel(m, f, dest)
if fdest in {isEqual, isGeneric} and not (dest.kind == tyLent and f.kind in {tyVar}):
markUsed(c, arg.info, c.converters[i])
# can't fully mark used yet, may not be used in final call
incl(c.converters[i].flags, sfUsed)
markOwnerModuleAsUsed(c, c.converters[i])
var s = newSymNode(c.converters[i])
s.typ = c.converters[i].typ
s.info = arg.info

View File

@@ -0,0 +1,14 @@
# issue #24241
{.warningAsError[Deprecated]: on.}
type X = distinct int
converter toInt(x: X): int{.deprecated.} = int(x)
template `==`(a, b: X): bool = false # this gets called so we didn't convert
doAssert not (X(1) == X(2))
doAssert not compiles(X(1) + X(2))
doAssert not (compiles do:
let x: int = X(1))