Skip to content

Commit b206f34

Browse files
committed
ensure you cannot discard a local called self
previous checking for the expr being `self` was checking for the decl being named `self`. that meant you could do naughty things like: ``` let `self` = Self() discard `self` ``` rdar://109376381 (cherry picked from commit 1c9ed33)
1 parent 041d9f4 commit b206f34

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1314,13 +1314,14 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
13141314
if (!diagnosed) {
13151315
bool isSelf = false;
13161316
auto *checkE = DS->getSubExpr();
1317+
assert(fn->getImplicitSelfDecl() && "no self?");
13171318

13181319
// Look through a load. Only expected if we're in an init.
13191320
if (auto *load = dyn_cast<LoadExpr>(checkE))
13201321
checkE = load->getSubExpr();
13211322

13221323
if (auto DRE = dyn_cast<DeclRefExpr>(checkE))
1323-
isSelf = DRE->getDecl()->getName().isSimpleName("self");
1324+
isSelf = DRE->getDecl() == fn->getImplicitSelfDecl();
13241325

13251326
if (!isSelf) {
13261327
ctx.Diags

test/Sema/discard.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,20 @@ struct HasGenericNotStored<T>: ~Copyable { // expected-note 2{{arguments to gene
175175
let `self` = HasGenericNotStored<Int>()
176176
discard `self`
177177
// expected-error@-1 {{cannot convert value of type 'HasGenericNotStored<Int>' to expected discard type 'HasGenericNotStored<T>'}}
178+
// expected-error@-2 {{you can only discard 'self'}}{{13-19=self}}
178179
}
179180

180181
func identity(_ t: T) -> T { return t }
181182
deinit{}
182183
}
184+
185+
struct Court: ~Copyable {
186+
let x: Int
187+
188+
consuming func discard(_ other: consuming Court) {
189+
let `self` = other
190+
discard `self` // expected-error {{you can only discard 'self'}}{{13-19=self}}
191+
}
192+
193+
deinit { print("deinit of \(self.x)") }
194+
}

0 commit comments

Comments
 (0)