Skip to content

Commit

Permalink
don't evaluate "cannot eval" errors with nim check
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Oct 12, 2024
1 parent aaf6c40 commit 6ba72e4
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 5 deletions.
22 changes: 17 additions & 5 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2332,9 +2332,17 @@ proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
localError(c.config, sym.info,
"NimScript: attempt to call non-routine: " & sym.name.s)

proc errorNode(idgen: IdGenerator; owner: PSym, n: PNode): PNode =
result = newNodeI(nkEmpty, n.info)
result.typ = newType(tyError, idgen, owner)
result.typ.flags.incl tfCheckedForDestructor

proc evalStmt*(c: PCtx, n: PNode) =
let n = transformExpr(c.graph, c.idgen, c.module, n)
let start = genStmt(c, n)
if c.cannotEval:
c.cannotEval = false
return
# execute new instructions; this redundant opcEof check saves us lots
# of allocations in 'execute':
if c.code[start].opcode != opcEof:
Expand All @@ -2345,7 +2353,10 @@ proc evalExpr*(c: PCtx, n: PNode): PNode =
# `nim --eval:"expr"` might've used it at some point for idetools; could
# be revived for nimsuggest
let n = transformExpr(c.graph, c.idgen, c.module, n)
c.cannotEval = false
let start = genExpr(c, n)
if c.cannotEval:
return errorNode(c.idgen, c.module, n)
assert c.code[start].opcode != opcEof
result = execute(c, start)

Expand Down Expand Up @@ -2398,7 +2409,10 @@ proc evalConstExprAux(module: PSym; idgen: IdGenerator;
var c = PCtx g.vm
let oldMode = c.mode
c.mode = mode
c.cannotEval = false
let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
if c.cannotEval:
return errorNode(idgen, prc, n)
if c.code[start].opcode == opcEof: return newNodeI(nkEmpty, n.info)
assert c.code[start].opcode != opcEof
when debugEchoCode: c.echoCode start
Expand Down Expand Up @@ -2469,11 +2483,6 @@ iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) =
# to prevent endless recursion in macro instantiation
const evalMacroLimit = 1000

#proc errorNode(idgen: IdGenerator; owner: PSym, n: PNode): PNode =
# result = newNodeI(nkEmpty, n.info)
# result.typ = newType(tyError, idgen, owner)
# result.typ.flags.incl tfCheckedForDestructor

proc evalMacroCall*(module: PSym; idgen: IdGenerator; g: ModuleGraph; templInstCounter: ref int;
n, nOrig: PNode, sym: PSym): PNode =
#if g.config.errorCounter > 0: return errorNode(idgen, module, n)
Expand All @@ -2497,7 +2506,10 @@ proc evalMacroCall*(module: PSym; idgen: IdGenerator; g: ModuleGraph; templInstC
c.comesFromHeuristic.line = 0'u16
c.callsite = nOrig
c.templInstCounter = templInstCounter
c.cannotEval = false
let start = genProc(c, sym)
if c.cannotEval:
return errorNode(idgen, module, n)

var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
let maxSlots = sym.offset
Expand Down
1 change: 1 addition & 0 deletions compiler/vmdef.nim
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ type
templInstCounter*: ref int # gives every template instantiation a unique ID, needed here for getAst
vmstateDiff*: seq[(PSym, PNode)] # we remember the "diff" to global state here (feature for IC)
procToCodePos*: Table[int, int]
cannotEval*: bool

PStackFrame* = ref TStackFrame
TStackFrame* {.acyclic.} = object
Expand Down
1 change: 1 addition & 0 deletions compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,7 @@ template cannotEval(c: PCtx; n: PNode) =
if c.config.cmd == cmdCheck:
localError(c.config, n.info, "cannot evaluate at compile time: " &
n.renderTree)
c.cannotEval = true
return
globalError(c.config, n.info, "cannot evaluate at compile time: " &
n.renderTree)
Expand Down

0 comments on commit 6ba72e4

Please sign in to comment.