Skip to content

Commit 850f327

Browse files
authored
folding const expressions with branching logic (#24689)
motivating example: ```nim iterator p(a: openArray[char]): int = if a.len != 0: if a[0] != '/': discard for t in p(""): discard ``` The compiler wants to evaluate `a[0]` at compile time even though it is protected by the if statement above it. Similarly expressions like `a.len != 0 and a[0] == '/'` have problems. It seems like the logic in semfold needs to be more aware of branches to positively identify when it is okay to fail compilation in these scenarios. It's a bit tough though because it may be the case that non-constant expressions in branching logic can properly protect some constant expressions.
1 parent 38ad336 commit 850f327

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

compiler/semfold.nim

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,19 +471,20 @@ proc foldArrayAccess(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNo
471471
if result.kind == nkExprColonExpr: result = result[1]
472472
else:
473473
result = nil
474-
localError(g.config, n.info, formatErrorIndexBound(idx, x.len-1) & $n)
474+
#localError(g.config, n.info, formatErrorIndexBound(idx, x.len-1) & $n)
475475
of nkBracket:
476476
idx -= toInt64(firstOrd(g.config, x.typ))
477477
if idx >= 0 and idx < x.len: result = x[int(idx)]
478478
else:
479479
result = nil
480-
localError(g.config, n.info, formatErrorIndexBound(idx, x.len-1) & $n)
480+
#localError(g.config, n.info, formatErrorIndexBound(idx, x.len-1) & $n)
481481
of nkStrLit..nkTripleStrLit:
482482
result = newNodeIT(nkCharLit, x.info, n.typ)
483483
if idx >= 0 and idx < x.strVal.len:
484484
result.intVal = ord(x.strVal[int(idx)])
485485
else:
486-
localError(g.config, n.info, formatErrorIndexBound(idx, x.strVal.len-1) & $n)
486+
result = nil
487+
#localError(g.config, n.info, formatErrorIndexBound(idx, x.strVal.len-1) & $n)
487488
else: result = nil
488489

489490
proc foldFieldAccess(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =

tests/controlflow/tcontrolflow.nim

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,10 @@ block named: # works
114114
if true:
115115
break named
116116
doAssert false, "not reached"
117+
118+
block:
119+
iterator p(a: openArray[char]): int =
120+
if a.len != 0:
121+
if a[0] != '/':
122+
discard
123+
for t in p(""): discard

0 commit comments

Comments
 (0)