Skip to content

Commit bafd04d

Browse files
authored
Merge pull request #85113 from jamieQ/try-never-discard-diags
[Sema]: minor improvements to unused expression result diagnostics
2 parents 8feba8d + 9a0f165 commit bafd04d

File tree

2 files changed

+83
-6
lines changed

2 files changed

+83
-6
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,9 +1840,14 @@ static bool isDiscardableType(Type type) {
18401840
if (auto *expansion = type->getAs<PackExpansionType>())
18411841
return isDiscardableType(expansion->getPatternType());
18421842

1843-
return (type->hasError() ||
1844-
type->isUninhabited() ||
1845-
type->lookThroughAllOptionalTypes()->isVoid());
1843+
if (type->hasError())
1844+
return true;
1845+
1846+
// Look through optionality and check if the type is either `Void` or
1847+
// 'structurally uninhabited'. Treat either as discardable.
1848+
auto nonOptionalType = type->lookThroughAllOptionalTypes();
1849+
return (nonOptionalType->isStructurallyUninhabited() ||
1850+
nonOptionalType->isVoid());
18461851
}
18471852

18481853
static void diagnoseIgnoredLiteral(ASTContext &Ctx, LiteralExpr *LE) {
@@ -1989,9 +1994,8 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
19891994
}
19901995
}
19911996

1992-
// If the result of this expression is of type "Never" or "()"
1993-
// (the latter potentially wrapped in optionals) then it is
1994-
// safe to ignore.
1997+
// If the result of this expression is either "structurally uninhabited" or
1998+
// `Void`, (potentially wrapped in optionals) then it is safe to ignore.
19951999
if (isDiscardableType(valueE->getType()))
19962000
return;
19972001

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
struct MyError: Error {}
4+
enum MyNever {}
5+
6+
func never_throws() throws -> Never { throw MyError() }
7+
func uninhabited_throws() throws -> (Int, MyNever) { throw MyError () }
8+
func almost_uninhabited_throws() throws -> (Int, Never?) { throw MyError () }
9+
func int_throws() throws -> Int { throw MyError() }
10+
func void_throws() throws {}
11+
12+
func maybe_never() -> Never? { nil }
13+
func maybe_uninhabited() -> (Int, MyNever)? { nil }
14+
func maybe_maybe_uninhabited() -> (Int, Never)?? { nil }
15+
func maybe_void() -> Void? { nil }
16+
func maybe_maybe_void() -> Void?? { nil }
17+
func looks_uninhabited_if_you_squint() -> (Int, Never?)? { nil }
18+
19+
// MARK: - Tests
20+
21+
func test_try() throws {
22+
try never_throws()
23+
try uninhabited_throws()
24+
try almost_uninhabited_throws()
25+
// expected-warning @-1 {{result of call to 'almost_uninhabited_throws()' is unused}}
26+
try int_throws()
27+
// expected-warning @-1 {{result of call to 'int_throws()' is unused}}
28+
try void_throws()
29+
}
30+
31+
func test_force_try() throws {
32+
try! never_throws()
33+
try! uninhabited_throws()
34+
try! almost_uninhabited_throws()
35+
// expected-warning @-1 {{result of call to 'almost_uninhabited_throws()' is unused}}
36+
try! int_throws()
37+
// expected-warning @-1 {{result of call to 'int_throws()' is unused}}
38+
try! void_throws()
39+
}
40+
41+
func test_optional_try() throws {
42+
try? never_throws()
43+
try? uninhabited_throws()
44+
try? almost_uninhabited_throws()
45+
// expected-warning @-1 {{result of 'try?' is unused}}
46+
try? int_throws()
47+
// expected-warning @-1 {{result of 'try?' is unused}}
48+
try? void_throws()
49+
}
50+
51+
func test_implicitly_discardable() {
52+
maybe_never()
53+
maybe_uninhabited()
54+
maybe_maybe_uninhabited()
55+
maybe_void()
56+
maybe_maybe_void()
57+
looks_uninhabited_if_you_squint()
58+
// expected-warning @-1 {{result of call to 'looks_uninhabited_if_you_squint()' is unused}}
59+
}
60+
61+
// https://github.com/swiftlang/swift/issues/85092
62+
63+
func test_85092() {
64+
struct MyError: Error {}
65+
66+
func f() throws -> Never {
67+
throw MyError()
68+
}
69+
70+
func g() {
71+
try? f()
72+
}
73+
}

0 commit comments

Comments
 (0)