Skip to content

Commit

Permalink
[Parse] Allow self rebinding
Browse files Browse the repository at this point in the history
Instead of parisng identifiers and fallthrough to self, treat `kw_self` the same
as identifiers. This enables binding to self.
  • Loading branch information
dduan committed Mar 26, 2018
1 parent ef4353f commit 7a682a4
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,7 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
}

case tok::identifier: // foo
case tok::kw_self: // self
// Attempt to parse for 'type(of: <expr>)'.
if (canParseTypeOf(*this)) {
return parseExprTypeOf();
Expand Down Expand Up @@ -1571,7 +1572,6 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
}

LLVM_FALLTHROUGH;
case tok::kw_self: // self
case tok::kw_Self: // Self
return makeParserResult(parseExprIdentifier());

Expand Down
60 changes: 60 additions & 0 deletions test/Parse/self_rebinding.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// RUN: %target-typecheck-verify-swift

class Writer {
private var articleWritten = 47

func stop() {
let rest: () -> Void = { [weak self] in
let articleWritten = self?.articleWritten ?? 0
guard let `self` = self else {
return
}

self.articleWritten = articleWritten
}

fatalError("I'm running out of time")
rest()
}

func nonStop() {
let write: () -> Void = { [weak self] in
self?.articleWritten += 1

if let self = self {
self.articleWritten += 1
}

if let `self` = self {
self.articleWritten += 1
}

guard let self = self else {
return
}

self.articleWritten += 1
}

write()
}
}

struct T {
var mutable: Int = 0
func f() {
// expected-error @+2 {{keyword 'self' cannot be used as an identifier here}}
// expected-note @+1 {{if this name is unavoidable, use backticks to escape it}}
let self = self
}
}

class MyCls {
func something() {}

func test() {
// expected-warning @+1 {{initialization of immutable value 'self' was never used}}
let `self` = Writer() // Even if `self` is shadowed,
something() // this should still refer `MyCls.something`.
}
}

0 comments on commit 7a682a4

Please sign in to comment.