diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 34df83f460..836be6e4a9 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -187,13 +187,15 @@ proc semIf(c: PContext, n: PNode; flags: TExprFlags; expectedType: PType = nil): it[0] = forceBool(c, semExprWithType(c, it[0], expectedType = getSysType(c.graph, n.info, tyBool))) it[1] = semExprBranch(c, it[1], flags, expectedType) typ = commonType(c, typ, it[1]) - expectedType = typ + if not endsInNoReturn(it[1]): + expectedType = typ closeScope(c) elif it.len == 1: hasElse = true it[0] = semExprBranchScope(c, it[0], expectedType) typ = commonType(c, typ, it[0]) - expectedType = typ + if not endsInNoReturn(it[0]): + expectedType = typ else: illFormedAst(it, c.config) if isEmptyType(typ) or typ.kind in {tyNil, tyUntyped} or (not hasElse and efInTypeof notin flags): @@ -234,7 +236,8 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags; expectedType: PType = nil) var expectedType = expectedType n[0] = semExprBranchScope(c, n[0], expectedType) typ = commonType(c, typ, n[0].typ) - expectedType = typ + if not endsInNoReturn(n[0]): + expectedType = typ var last = n.len - 1 var catchAllExcepts = 0 @@ -295,7 +298,8 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags; expectedType: PType = nil) if a.kind != nkFinally: a[^1] = semExprBranchScope(c, a[^1], expectedType) typ = commonType(c, typ, a[^1]) - expectedType = typ + if not endsInNoReturn(a[^1]): + expectedType = typ else: a[^1] = semExprBranchScope(c, a[^1]) dec last @@ -1145,7 +1149,8 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags; expectedType: PType = nil var last = x.len-1 x[last] = semExprBranchScope(c, x[last], expectedType) typ = commonType(c, typ, x[last]) - expectedType = typ + if not endsInNoReturn(x[last]): + expectedType = typ of nkElifBranch: if hasElse: invalidOrderOfBranches(x) chckCovered = false @@ -1154,13 +1159,15 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags; expectedType: PType = nil x[0] = forceBool(c, semExprWithType(c, x[0], expectedType = getSysType(c.graph, n.info, tyBool))) x[1] = semExprBranch(c, x[1], expectedType = expectedType) typ = commonType(c, typ, x[1]) - expectedType = typ + if not endsInNoReturn(x[1]): + expectedType = typ closeScope(c) of nkElse: checkSonsLen(x, 1, c.config) x[0] = semExprBranchScope(c, x[0], expectedType) typ = commonType(c, typ, x[0]) - expectedType = typ + if not endsInNoReturn(x[0]): + expectedType = typ if (chckCovered and covered == toCover(c, n[0].typ)) or hasElse: message(c.config, x.info, warnUnreachableElse) hasElse = true diff --git a/tests/types/ttopdowninference.nim b/tests/types/ttopdowninference.nim index cabc798edf..2a26e0e34e 100644 --- a/tests/types/ttopdowninference.nim +++ b/tests/types/ttopdowninference.nim @@ -290,3 +290,38 @@ block: # bug #21377 {:} doAssert b(0) == {:} + +block: # bug #22180 + type A = object + proc j() = discard + + let x = + if false: + (ref A)(nil) + else: + if false: + quit 1 + else: + if true: + j() + nil # compiles with (ref A)(nil) here + else: + (ref A)(nil) + doAssert x.isNil + + let y = + case true + of false: + (ref A)(nil) + else: + case true + of false: + quit 1 + else: + case true + of true: + j() + nil # compiles with (ref A)(nil) here + else: + (ref A)(nil) + doAssert y.isNil