Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sem): crash with erroneous is expression #1485

Merged
merged 4 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/sem/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,9 @@ proc semRealConstExpr(c: PContext, n: PNode): PNode =
addInNimDebugUtils(c.config, "semRealConstExpr", n, result)
assert not n.isError

pushExecCon(c, {})
result = semExprWithType(c, n)
popExecCon(c)
if result.kind != nkError:
result = evalConstExpr(c, result)

Expand Down
42 changes: 21 additions & 21 deletions compiler/sem/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -531,28 +531,28 @@ proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode =
addInNimDebugUtils(c.config, "semIs", n, result, flags)

if n.len != 3:
result = c.config.newError(n, PAstDiag(kind: adSemIsOperatorTakes2Args))
return
# the check is necessary because `is` can be analyzed pre-sigmatch
return c.config.newError(n, PAstDiag(kind: adSemIsOperatorTakes2Args))

let boolType = getSysType(c.graph, n.info, tyBool)
n.typ = boolType
var liftLhs = true

n[1] = semExprWithType(c, n[1], flags + {efWantIterator})
var
liftLhs = true
lhs = semExprWithType(c, n[1], flags + {efWantIterator})
rhs: PNode

case n[2].kind
of nkStrLiterals:
n[2] = semExpr(c, n[2])
rhs = semExpr(c, n[2])
of nkError:
discard # below we'll wrap the result in an error
else:
let t2 = semTypeNode(c, n[2], nil)
n[2] = newNodeIT(nkType, n[2].info, t2)
rhs = newNodeIT(nkType, n[2].info, t2)
if t2.kind == tyStatic:
let evaluated = tryConstExpr(c, n[1])
let evaluated = tryConstExpr(c, lhs)
if evaluated != nil:
c.fixupStaticType(evaluated)
n[1] = evaluated
lhs = evaluated
else:
result = newIntNode(nkIntLit, 0)
result.typ = boolType
Expand All @@ -564,17 +564,17 @@ proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode =
# not allow regular values to be matched against the type:
liftLhs = false

var lhsType = n[1].typ
if n[1].isError or n[2].isError:
result = wrapError(c.config, n)
elif lhsType.kind == tyTypeDesc and (lhsType.base.kind == tyNone or
(c.inGenericContext > 0 and lhsType.base.containsGenericType)):
# BUGFIX: don't evaluate this too early: ``T is void``
result = n
result = shallowCopy(n)
result.typ = boolType
result[0] = n[0]
result[1] = lhs
result[2] = rhs
if result[1].isError or result[2].isError:
result = wrapError(c.config, result)
else:
if lhsType.kind != tyTypeDesc and liftLhs:
n[1] = makeTypeSymNode(c, lhsType, n[1].info)
result = isOpImpl(c, n, flags)
if lhs.typ.kind != tyTypeDesc and liftLhs:
result[1] = makeTypeSymNode(c, lhs.typ, n[1].info)
result = isOpImpl(c, result, flags)

proc semOpAux(c: PContext, n: PNode): bool =
## Returns whether n contains errors
Expand Down Expand Up @@ -2945,7 +2945,7 @@ proc semWhen(c: PContext, n: PNode, flags: TExprFlags): PNode =
case it.kind
of nkElifBranch, nkElifExpr:
checkSonsLen(it, 2, c.config)
let e = forceBool(c, semConstExpr(c, it[0]))
let e = forceBool(c, semRealConstExpr(c, it[0]))
if e.kind == nkError:
# error in the condition expression; wrap and return
result = copyNodeWithKids(n)
Expand Down
7 changes: 7 additions & 0 deletions tests/error_propagation/tin_expression_in_when.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
discard """
errormsg: "undeclared identifier: 'missing'"
"""

var x = missing
when x is int:
discard
Loading