diff --git a/compiler/sem/semfold.nim b/compiler/sem/semfold.nim index a2b6e2f0d21..a2bf81793f0 100644 --- a/compiler/sem/semfold.nim +++ b/compiler/sem/semfold.nim @@ -961,6 +961,9 @@ proc foldInAstAux(m: PSym, n: PNode, idgen: IdGenerator, g: ModuleGraph): Folded # don't process the symbol slots result = fromAst(n, n.len - 1) result.add foldInAstAux(m, n[^1], idgen, g) + of nkElifExpr, nkElseExpr: + # must not exist in statement AST + unreachable(n.kind) else: # XXX: type AST reaches here, but ideally this catch-all branch # wouldn't be needed diff --git a/compiler/sem/semstmts.nim b/compiler/sem/semstmts.nim index 58a720f0457..cbf453950d4 100644 --- a/compiler/sem/semstmts.nim +++ b/compiler/sem/semstmts.nim @@ -173,6 +173,12 @@ proc semIf(c: PContext, n: PNode; flags: TExprFlags): PNode = elif isEmptyType(typ) or typ.kind in {tyNil, tyUntyped} or (not hasElse and efInTypeof notin flags): for it in n: + # transition the branch to its statement variant: + case it.kind + of nkElifExpr: it.transitionSonsKind(nkElifBranch) + of nkElseExpr: it.transitionSonsKind(nkElse) + else: discard "already correct" + it[^1] = discardCheck(c, it[^1], flags) if it[^1].isError: return wrapError(c.config, result) @@ -181,6 +187,12 @@ proc semIf(c: PContext, n: PNode; flags: TExprFlags): PNode = if typ == c.enforceVoidContext: result.typ = c.enforceVoidContext else: for it in n: + # transition the branch to its expression variant: + case it.kind + of nkElifBranch: it.transitionSonsKind(nkElifExpr) + of nkElse: it.transitionSonsKind(nkElseExpr) + else: discard "already correct" + let j = it.len-1 if not endsInNoReturn(it[j]): it[j] = fitNode(c, typ, it[j], it[j].info) diff --git a/tests/lang_exprs/tif_stmt_regression.nim b/tests/lang_exprs/tif_stmt_regression.nim new file mode 100644 index 00000000000..c14689179b7 --- /dev/null +++ b/tests/lang_exprs/tif_stmt_regression.nim @@ -0,0 +1,19 @@ +discard """ + description: ''' + Regression test for ``if`` statements within statement-list expressions. + They were not being processed by constant folding + ''' +""" + +var x = ( + # unfolded 'true'/'false' symbols lead to an internal compiler error, + # which is used for detecting whether folding took place here + if true: + # branch content doesn't matter, as long as it's a statement + var y = false + elif true: # also test an elif branch + var y = false + else: + var y = false + 1 +) \ No newline at end of file