(cherry picked from commit 16394c3772)
This commit is contained in:
Andreas Rumpf
2025-09-18 19:44:39 +02:00
committed by narimiran
parent 2c4b889d0a
commit 79e9634369
4 changed files with 35 additions and 21 deletions

View File

@@ -321,7 +321,7 @@ proc hasCycle(n: PNode): bool =
break
excl n.flags, nfNone
proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode =
proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode; producedClosure: var bool): PNode =
# recompute the types as 'eval' isn't guaranteed to construct types nor
# that the types are sound:
when true:
@@ -333,7 +333,7 @@ proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode =
if hasCycle(result):
result = localErrorNode(c, eOrig, "the resulting AST is cyclic and cannot be processed further")
else:
semmacrosanity.annotateType(result, expectedType, c.config)
semmacrosanity.annotateType(result, expectedType, c.config, producedClosure)
else:
result = semExprWithType(c, evaluated)
#result = fitNode(c, e.typ, result) inlined with special case:
@@ -370,7 +370,10 @@ proc tryConstExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
if result == nil or result.kind == nkEmpty:
result = nil
else:
result = fixupTypeAfterEval(c, result, e)
var producedClosure = false
result = fixupTypeAfterEval(c, result, e, producedClosure)
if producedClosure:
result = nil
except ERecoverableError:
result = nil
@@ -407,7 +410,10 @@ proc semConstExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
# error correction:
result = e
else:
result = fixupTypeAfterEval(c, result, e)
var producedClosure = false
result = fixupTypeAfterEval(c, result, e, producedClosure)
if producedClosure:
result = nil
proc semExprFlagDispatched(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
if efNeedStatic in flags:

View File

@@ -951,11 +951,15 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
result = evalStaticExpr(c.module, c.idgen, c.graph, call, c.p.owner)
if result.isNil:
localError(c.config, n.info, errCannotInterpretNodeX % renderTree(call))
else: result = fixupTypeAfterEval(c, result, n)
else:
var producedClosure = false
result = fixupTypeAfterEval(c, result, n, producedClosure)
else:
result = evalConstExpr(c.module, c.idgen, c.graph, call)
if result.isNil: result = n
else: result = fixupTypeAfterEval(c, result, n)
else:
var producedClosure = false
result = fixupTypeAfterEval(c, result, n, producedClosure)
else:
result = n
#if result != n:
@@ -973,7 +977,8 @@ proc semStaticExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
localError(c.config, n.info, errCannotInterpretNodeX % renderTree(n))
result = c.graph.emptyNode
else:
result = fixupTypeAfterEval(c, result, a)
var producedClosure = false
result = fixupTypeAfterEval(c, result, a, producedClosure)
proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
flags: TExprFlags; expectedType: PType = nil): PNode =
@@ -3070,10 +3075,10 @@ proc semTupleConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp
proc isExplicitGenericCall(c: PContext, n: PNode): bool =
## checks if a call node `n` is a routine call with explicit generic params
##
##
## the callee node needs to be either an nkBracketExpr or a call to a
## symchoice of `[]` in which case it will be transformed into nkBracketExpr
##
##
## the LHS of the bracket expr has to either be a symchoice or resolve to
## a routine symbol
template checkCallee(n: PNode) =

View File

@@ -86,7 +86,7 @@ proc ithField(t: PType, field: var FieldTracker): FieldInfo =
base = b.baseClass
result = ithField(t.n, field)
proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
proc annotateType*(n: PNode, t: PType; conf: ConfigRef; producedClosure: var bool) =
let x = t.skipTypes(abstractInst+{tyRange})
# Note: x can be unequal to t and we need to be careful to use 't'
# to not to skip tyGenericInst
@@ -102,7 +102,7 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
globalError conf, n.info, "invalid field at index " & $i
else:
internalAssert(conf, n[i].kind == nkExprColonExpr)
annotateType(n[i][1], field.sym.typ, conf)
annotateType(n[i][1], field.sym.typ, conf, producedClosure)
if field.delete:
# only codegen fields from active case branches
incl(n[i].flags, nfPreventCg)
@@ -111,9 +111,11 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
n.typ() = t
for i in 0..<n.len:
if i >= x.kidsLen: globalError conf, n.info, "invalid field at index " & $i
else: annotateType(n[i], x[i], conf)
else: annotateType(n[i], x[i], conf, producedClosure)
elif x.kind == tyProc and x.callConv == ccClosure:
n.typ() = t
if n.len > 1 and n[1].kind notin {nkEmpty, nkNilLit}:
producedClosure = true
elif x.kind == tyOpenArray: # `opcSlice` transforms slices into tuples
if n.kind == nkTupleConstr:
let
@@ -125,11 +127,11 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
of nkStrKinds:
for i in left..right:
bracketExpr.add newIntNode(nkCharLit, BiggestInt n[0].strVal[i])
annotateType(bracketExpr[^1], x.elementType, conf)
annotateType(bracketExpr[^1], x.elementType, conf, producedClosure)
of nkBracket:
for i in left..right:
bracketExpr.add n[0][i]
annotateType(bracketExpr[^1], x.elementType, conf)
annotateType(bracketExpr[^1], x.elementType, conf, producedClosure)
else:
globalError(conf, n.info, "Incorrectly generated tuple constr")
n[] = bracketExpr[]
@@ -140,7 +142,7 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
of nkBracket:
if x.kind in {tyArray, tySequence, tyOpenArray}:
n.typ() = t
for m in n: annotateType(m, x.elemType, conf)
for m in n: annotateType(m, x.elemType, conf, producedClosure)
else:
globalError(conf, n.info, "[] must have some form of array type")
of nkCurly:
@@ -148,10 +150,10 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
n.typ() = t
for m in n:
if m.kind == nkRange:
annotateType(m[0], x.elemType, conf)
annotateType(m[1], x.elemType, conf)
annotateType(m[0], x.elemType, conf, producedClosure)
annotateType(m[1], x.elemType, conf, producedClosure)
else:
annotateType(m, x.elemType, conf)
annotateType(m, x.elemType, conf, producedClosure)
else:
globalError(conf, n.info, "{} must have the set type")
of nkFloatLit..nkFloat128Lit:

View File

@@ -859,9 +859,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcLdObj:
# a = b.c
decodeBC(rkNode)
if rb >= regs.len or regs[rb].kind == rkNone or
if rb >= regs.len or regs[rb].kind == rkNone or
(regs[rb].kind == rkNode and regs[rb].node == nil) or
(regs[rb].kind == rkNodeAddr and regs[rb].nodeAddr[] == nil):
(regs[rb].kind == rkNodeAddr and regs[rb].nodeAddr[] == nil):
stackTrace(c, tos, pc, errNilAccess)
else:
let src = if regs[rb].kind == rkNode: regs[rb].node else: regs[rb].nodeAddr[]
@@ -1472,7 +1472,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
let node = regs[rb+i].regToNode
node.info = c.debug[pc]
if prc.typ[i].kind notin {tyTyped, tyUntyped}:
node.annotateType(prc.typ[i], c.config)
var producedClosure = false
node.annotateType(prc.typ[i], c.config, producedClosure)
macroCall.add(node)
var a = evalTemplate(macroCall, prc, genSymOwner, c.config, c.cache, c.templInstCounter, c.idgen)