Skip to content

Commit e5e5d13

Browse files
Suyash SrijanSuyash Srijan
authored andcommitted
[Typechecker] Fix an issue with discardableResult error not being emitted
1 parent cf53143 commit e5e5d13

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,8 +1261,8 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
12611261
}
12621262
return;
12631263
}
1264-
1265-
// Skip checking if there is no type, which presumably means there was a
1264+
1265+
// Skip checking if there is no type, which presumably means there was a
12661266
// type error.
12671267
if (!E->getType()) {
12681268
return;
@@ -1308,7 +1308,25 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
13081308
// dead?
13091309
if (E->getType()->is<AnyFunctionType>()) {
13101310
bool isDiscardable = false;
1311-
if (auto *Fn = dyn_cast<ApplyExpr>(E)) {
1311+
1312+
// The called function could be wrapped inside a `dot_syntax_call_expr`
1313+
// node, for example:
1314+
//
1315+
// class Bar {
1316+
// @discardableResult
1317+
// func foo() -> Int { return 0 }
1318+
//
1319+
// func baz() {
1320+
// self.foo
1321+
// foo
1322+
// }
1323+
// }
1324+
//
1325+
// So look through the DSCE and get the function being called.
1326+
auto expr =
1327+
isa<DotSyntaxCallExpr>(E) ? cast<DotSyntaxCallExpr>(E)->getFn() : E;
1328+
1329+
if (auto *Fn = dyn_cast<ApplyExpr>(expr)) {
13121330
if (auto *declRef = dyn_cast<DeclRefExpr>(Fn->getFn())) {
13131331
if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(declRef->getDecl())) {
13141332
if (funcDecl->getAttrs().hasAttribute<DiscardableResultAttr>()) {

test/attr/attr_discardableResult.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,14 @@ class Foo {
211211
myOptionalFooProtocol?.returnSomething() // okay
212212
}
213213
}
214+
215+
class Discard {
216+
@discardableResult func bar() -> Int {
217+
return 0
218+
}
219+
220+
func baz() {
221+
self.bar // expected-error {{expression resolves to an unused function}}
222+
bar // expected-error {{expression resolves to an unused function}}
223+
}
224+
}

0 commit comments

Comments
 (0)