Skip to content

Commit c501812

Browse files
erikjvjrose-apple
authored andcommitted
An unused @ discardableResult should not throw an error (#6785)
A function marked with @discardableResult should not throw an error if its returning closure is unused. Fixes SR-2948.
1 parent 2466431 commit c501812

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,9 +1082,22 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
10821082
// TODO: What about tuples which contain functions by-value that are
10831083
// dead?
10841084
if (E->getType()->is<AnyFunctionType>()) {
1085-
diagnose(E->getLoc(), diag::expression_unused_function)
1086-
.highlight(E->getSourceRange());
1087-
return;
1085+
bool isDiscardable = false;
1086+
if (auto *Fn = dyn_cast<ApplyExpr>(E)) {
1087+
if (auto *declRef = dyn_cast<DeclRefExpr>(Fn->getFn())) {
1088+
if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(declRef->getDecl())) {
1089+
if (funcDecl->getAttrs().hasAttribute<DiscardableResultAttr>()) {
1090+
isDiscardable = true;
1091+
}
1092+
}
1093+
}
1094+
}
1095+
1096+
if (!isDiscardable) {
1097+
diagnose(E->getLoc(), diag::expression_unused_function)
1098+
.highlight(E->getSourceRange());
1099+
return;
1100+
}
10881101
}
10891102

10901103
// If the result of this expression is of type "Never" or "()"

test/attr/attr_discardableResult.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,9 @@ func testOptionalChaining(c1: C1?, s1: S1?) {
176176
s1?.f2Optional() // expected-warning {{result of call to 'f2Optional()' is unused}}
177177
s1!.f2Optional() // expected-warning {{result of call to 'f2Optional()' is unused}}
178178
}
179+
180+
@discardableResult func SR2948 (_ closure: @escaping ()->()) -> (()->()) {
181+
closure()
182+
return closure
183+
}
184+
SR2948({}) // okay

0 commit comments

Comments
 (0)