Skip to content

Commit beb5018

Browse files
committed
Sema: Fix @discardableResult for Self-returning methods on classes and protocols
When we form calls to these methods, the ApplyExpr is wrapped in an additional conversion. Dig through these to produce the right diagnostic (or not, if the method is @discardableResult). Fixes <https://bugs.swift.org/browse/SR-1890>.
1 parent 004f145 commit beb5018

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,13 +1017,17 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
10171017
return;
10181018
}
10191019

1020-
// Drill through noop expressions we don't care about, like ParanExprs.
1020+
// Drill through noop expressions we don't care about.
10211021
auto valueE = E;
10221022
while (1) {
10231023
valueE = valueE->getValueProvidingExpr();
10241024

10251025
if (auto *OEE = dyn_cast<OpenExistentialExpr>(valueE))
10261026
valueE = OEE->getSubExpr();
1027+
else if (auto *CRCE = dyn_cast<CovariantReturnConversionExpr>(valueE))
1028+
valueE = CRCE->getSubExpr();
1029+
else if (auto *EE = dyn_cast<ErasureExpr>(valueE))
1030+
valueE = EE->getSubExpr();
10271031
else
10281032
break;
10291033
}

test/ClangModules/AppKit_test.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class MyDocument : NSDocument {
1616

1717
func test(_ url: URL, controller: NSDocumentController) {
1818
try! NSDocument(contentsOf: url, ofType: "") // expected-warning{{result of 'NSDocument' initializer is unused}}
19-
try! MyDocument(contentsOf: url, ofType: "") // expected-warning {{expression of type 'MyDocument' is unused}}
19+
try! MyDocument(contentsOf: url, ofType: "") // expected-warning{{result of 'NSDocument' initializer is unused}}
2020

2121
try! controller.makeDocument(withContentsOf: url, ofType: "")
2222
}

test/attr/attr_discardableResult.swift

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,16 @@ class C1 {
4141
func f1() -> Int { }
4242

4343
func f2() -> Int { }
44+
45+
@discardableResult
46+
func me() -> Self { return self }
47+
48+
func reallyMe() -> Self { return self }
4449
}
4550

46-
func testFunctionsInClass(c1 : C1) {
51+
class C2 : C1 {}
52+
53+
func testFunctionsInClass(c1 : C1, c2: C2) {
4754
C1.f1Static() // okay
4855
C1.f2Static() // expected-warning {{result of call to 'f2Static()' is unused}}
4956
_ = C1.f2Static() // okay
@@ -60,6 +67,15 @@ func testFunctionsInClass(c1 : C1) {
6067
c1.f1() // okay
6168
c1.f2() // expected-warning {{result of call to 'f2()' is unused}}
6269
_ = c1.f2() // okay
70+
71+
c1.me() // okay
72+
c2.me() // okay
73+
74+
c1.reallyMe() // expected-warning {{result of call to 'reallyMe()' is unused}}
75+
c2.reallyMe() // expected-warning {{result of call to 'reallyMe()' is unused}}
76+
77+
_ = c1.reallyMe() // okay
78+
_ = c2.reallyMe() // okay
6379
}
6480

6581
struct S1 {
@@ -92,6 +108,18 @@ func testFunctionsInStruct(s1 : S1) {
92108
_ = s1.f2() // okay
93109
}
94110

111+
protocol P1 {
112+
@discardableResult
113+
func me() -> Self
114+
115+
func reallyMe() -> Self
116+
}
117+
118+
func testFunctionsInExistential(p1 : P1) {
119+
p1.me() // okay
120+
p1.reallyMe() // expected-warning {{result of call to 'reallyMe()' is unused}}
121+
_ = p1.reallyMe() // okay
122+
}
95123

96124
let x = 4
97125
"Hello \(x+1) world" // expected-warning {{expression of type 'String' is unused}}

0 commit comments

Comments
 (0)