diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index bf5fcaae8a..7711bfce5b 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -181,13 +181,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): @@ -228,7 +230,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 @@ -289,7 +292,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 @@ -1059,7 +1063,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: chckCovered = false checkSonsLen(x, 2, c.config) @@ -1067,13 +1072,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