Skip to content

Commit 16394c3

Browse files
authored
fixes #24361 (#25179)
1 parent 41ce86b commit 16394c3

File tree

4 files changed

+35
-21
lines changed

4 files changed

+35
-21
lines changed

compiler/sem.nim

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ proc hasCycle(n: PNode): bool =
321321
break
322322
excl n.flags, nfNone
323323

324-
proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode =
324+
proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode; producedClosure: var bool): PNode =
325325
# recompute the types as 'eval' isn't guaranteed to construct types nor
326326
# that the types are sound:
327327
when true:
@@ -333,7 +333,7 @@ proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode =
333333
if hasCycle(result):
334334
result = localErrorNode(c, eOrig, "the resulting AST is cyclic and cannot be processed further")
335335
else:
336-
semmacrosanity.annotateType(result, expectedType, c.config)
336+
semmacrosanity.annotateType(result, expectedType, c.config, producedClosure)
337337
else:
338338
result = semExprWithType(c, evaluated)
339339
#result = fitNode(c, e.typ, result) inlined with special case:
@@ -370,7 +370,10 @@ proc tryConstExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
370370
if result == nil or result.kind == nkEmpty:
371371
result = nil
372372
else:
373-
result = fixupTypeAfterEval(c, result, e)
373+
var producedClosure = false
374+
result = fixupTypeAfterEval(c, result, e, producedClosure)
375+
if producedClosure:
376+
result = nil
374377

375378
except ERecoverableError:
376379
result = nil
@@ -407,7 +410,10 @@ proc semConstExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
407410
# error correction:
408411
result = e
409412
else:
410-
result = fixupTypeAfterEval(c, result, e)
413+
var producedClosure = false
414+
result = fixupTypeAfterEval(c, result, e, producedClosure)
415+
if producedClosure:
416+
result = nil
411417

412418
proc semExprFlagDispatched(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
413419
if efNeedStatic in flags:

compiler/semexprs.nim

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -951,11 +951,15 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
951951
result = evalStaticExpr(c.module, c.idgen, c.graph, call, c.p.owner)
952952
if result.isNil:
953953
localError(c.config, n.info, errCannotInterpretNodeX % renderTree(call))
954-
else: result = fixupTypeAfterEval(c, result, n)
954+
else:
955+
var producedClosure = false
956+
result = fixupTypeAfterEval(c, result, n, producedClosure)
955957
else:
956958
result = evalConstExpr(c.module, c.idgen, c.graph, call)
957959
if result.isNil: result = n
958-
else: result = fixupTypeAfterEval(c, result, n)
960+
else:
961+
var producedClosure = false
962+
result = fixupTypeAfterEval(c, result, n, producedClosure)
959963
else:
960964
result = n
961965
#if result != n:
@@ -973,7 +977,8 @@ proc semStaticExpr(c: PContext, n: PNode; expectedType: PType = nil): PNode =
973977
localError(c.config, n.info, errCannotInterpretNodeX % renderTree(n))
974978
result = c.graph.emptyNode
975979
else:
976-
result = fixupTypeAfterEval(c, result, a)
980+
var producedClosure = false
981+
result = fixupTypeAfterEval(c, result, a, producedClosure)
977982

978983
proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
979984
flags: TExprFlags; expectedType: PType = nil): PNode =
@@ -3070,10 +3075,10 @@ proc semTupleConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp
30703075

30713076
proc isExplicitGenericCall(c: PContext, n: PNode): bool =
30723077
## checks if a call node `n` is a routine call with explicit generic params
3073-
##
3078+
##
30743079
## the callee node needs to be either an nkBracketExpr or a call to a
30753080
## symchoice of `[]` in which case it will be transformed into nkBracketExpr
3076-
##
3081+
##
30773082
## the LHS of the bracket expr has to either be a symchoice or resolve to
30783083
## a routine symbol
30793084
template checkCallee(n: PNode) =

compiler/semmacrosanity.nim

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ proc ithField(t: PType, field: var FieldTracker): FieldInfo =
8686
base = b.baseClass
8787
result = ithField(t.n, field)
8888

89-
proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
89+
proc annotateType*(n: PNode, t: PType; conf: ConfigRef; producedClosure: var bool) =
9090
let x = t.skipTypes(abstractInst+{tyRange})
9191
# Note: x can be unequal to t and we need to be careful to use 't'
9292
# to not to skip tyGenericInst
@@ -102,7 +102,7 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
102102
globalError conf, n.info, "invalid field at index " & $i
103103
else:
104104
internalAssert(conf, n[i].kind == nkExprColonExpr)
105-
annotateType(n[i][1], field.sym.typ, conf)
105+
annotateType(n[i][1], field.sym.typ, conf, producedClosure)
106106
if field.delete:
107107
# only codegen fields from active case branches
108108
incl(n[i].flags, nfPreventCg)
@@ -111,9 +111,11 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
111111
n.typ() = t
112112
for i in 0..<n.len:
113113
if i >= x.kidsLen: globalError conf, n.info, "invalid field at index " & $i
114-
else: annotateType(n[i], x[i], conf)
114+
else: annotateType(n[i], x[i], conf, producedClosure)
115115
elif x.kind == tyProc and x.callConv == ccClosure:
116116
n.typ() = t
117+
if n.len > 1 and n[1].kind notin {nkEmpty, nkNilLit}:
118+
producedClosure = true
117119
elif x.kind == tyOpenArray: # `opcSlice` transforms slices into tuples
118120
if n.kind == nkTupleConstr:
119121
let
@@ -125,11 +127,11 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
125127
of nkStrKinds:
126128
for i in left..right:
127129
bracketExpr.add newIntNode(nkCharLit, BiggestInt n[0].strVal[i])
128-
annotateType(bracketExpr[^1], x.elementType, conf)
130+
annotateType(bracketExpr[^1], x.elementType, conf, producedClosure)
129131
of nkBracket:
130132
for i in left..right:
131133
bracketExpr.add n[0][i]
132-
annotateType(bracketExpr[^1], x.elementType, conf)
134+
annotateType(bracketExpr[^1], x.elementType, conf, producedClosure)
133135
else:
134136
globalError(conf, n.info, "Incorrectly generated tuple constr")
135137
n[] = bracketExpr[]
@@ -140,18 +142,18 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
140142
of nkBracket:
141143
if x.kind in {tyArray, tySequence, tyOpenArray}:
142144
n.typ() = t
143-
for m in n: annotateType(m, x.elemType, conf)
145+
for m in n: annotateType(m, x.elemType, conf, producedClosure)
144146
else:
145147
globalError(conf, n.info, "[] must have some form of array type")
146148
of nkCurly:
147149
if x.kind in {tySet}:
148150
n.typ() = t
149151
for m in n:
150152
if m.kind == nkRange:
151-
annotateType(m[0], x.elemType, conf)
152-
annotateType(m[1], x.elemType, conf)
153+
annotateType(m[0], x.elemType, conf, producedClosure)
154+
annotateType(m[1], x.elemType, conf, producedClosure)
153155
else:
154-
annotateType(m, x.elemType, conf)
156+
annotateType(m, x.elemType, conf, producedClosure)
155157
else:
156158
globalError(conf, n.info, "{} must have the set type")
157159
of nkFloatLit..nkFloat128Lit:

compiler/vm.nim

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -859,9 +859,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
859859
of opcLdObj:
860860
# a = b.c
861861
decodeBC(rkNode)
862-
if rb >= regs.len or regs[rb].kind == rkNone or
862+
if rb >= regs.len or regs[rb].kind == rkNone or
863863
(regs[rb].kind == rkNode and regs[rb].node == nil) or
864-
(regs[rb].kind == rkNodeAddr and regs[rb].nodeAddr[] == nil):
864+
(regs[rb].kind == rkNodeAddr and regs[rb].nodeAddr[] == nil):
865865
stackTrace(c, tos, pc, errNilAccess)
866866
else:
867867
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 =
14721472
let node = regs[rb+i].regToNode
14731473
node.info = c.debug[pc]
14741474
if prc.typ[i].kind notin {tyTyped, tyUntyped}:
1475-
node.annotateType(prc.typ[i], c.config)
1475+
var producedClosure = false
1476+
node.annotateType(prc.typ[i], c.config, producedClosure)
14761477

14771478
macroCall.add(node)
14781479
var a = evalTemplate(macroCall, prc, genSymOwner, c.config, c.cache, c.templInstCounter, c.idgen)

0 commit comments

Comments
 (0)