Skip to content

Commit

Permalink
Make always-immutable pattern bindings a warning for now
Browse files Browse the repository at this point in the history
These will become errors after the next release branch.

rdar://problem/23172698
  • Loading branch information
bitjammer committed Nov 3, 2015
1 parent b951525 commit 6402411
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 17 deletions.
4 changes: 2 additions & 2 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -641,8 +641,8 @@ ERROR(untyped_pattern_ellipsis,pattern_parsing,none,
"'...' cannot be applied to a subpattern which is not explicitly typed", ())
ERROR(non_func_decl_pattern_init,pattern_parsing,none,
"default argument is only permitted for a non-curried function parameter",())
ERROR(var_not_allowed_in_pattern,pattern_parsing, none,
"'var' is not allowed in this pattern binding", ())
WARNING(var_not_allowed_in_pattern,pattern_parsing, none,
"Use of 'var' binding here is deprecated and will be removed in a future version of Swift", ())
ERROR(var_pattern_in_var,pattern_parsing,none,
"'%select{var|let}0' cannot appear nested inside another 'var' or "
"'let' pattern", (unsigned))
Expand Down
4 changes: 3 additions & 1 deletion lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1234,7 +1234,8 @@ ParserStatus Parser::parseStmtCondition(StmtCondition &Condition,
if (BindingKind == BK_Case) {
// In our recursive parse, remember that we're in a matching pattern.
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
T(InVarOrLetPattern, IVOLP_InMatchingPattern);
T(InVarOrLetPattern, IVOLP_AlwaysImmutable);

ThePattern = parseMatchingPattern(/*isExprBasic*/ true);
} else if (BindingKind == BK_LetCase || BindingKind == BK_VarCase) {
// Recover from the 'if let case' typo gracefully.
Expand Down Expand Up @@ -2268,6 +2269,7 @@ ParserResult<Stmt> Parser::parseStmtForEach(SourceLoc ForLoc,
// if desired by using a 'var' pattern.
assert(InVarOrLetPattern == IVOLP_NotInVarOrLet &&
"for-each loops cannot exist inside other patterns");

InVarOrLetPattern = IVOLP_AlwaysImmutable;
pattern = parseTypedPattern();
assert(InVarOrLetPattern == IVOLP_AlwaysImmutable);
Expand Down
7 changes: 5 additions & 2 deletions test/Constraints/patterns.swift
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,11 @@ case x ?? 42: break // match value
default: break
}

for (var x) in 0...100 {} // expected-error {{'var' is not allowed in this pattern binding}}
for var x in 0...100 {} // expected-error {{'var' is not allowed in this pattern binding}}
// FIXME: rdar://problem/23378003
// These will eventually become errors.
for (var x) in 0...100 {} // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{6-9=}}
for var x in 0...100 {} // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{5-9=}}

for (let x) in 0...100 {} // expected-error {{'let' pattern is already in an immutable context}}

var (let y) = 42 // expected-error {{'let' cannot appear nested inside another 'var' or 'let' pattern}}
Expand Down
5 changes: 4 additions & 1 deletion test/Parse/foreach.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func for_each(r: Range<Int>, iir: IntRange<Int>) {
for i r { // expected-error 2{{expected ';' in 'for' statement}} expected-error {{use of unresolved identifier 'i'}}
}
for i in r sum = sum + i; // expected-error{{expected '{' to start the body of for-each loop}}
for var x in 0..<10 {} // expected-error {{'var' is not allowed in this pattern binding}} {{7-11=}}
for let x in 0..<10 {} // expected-error {{'let' pattern is already in an immutable context}} {{7-11=}}

// FIXME: rdar://problem/23378003
// This will eventually become an error.
for var x in 0..<10 {} // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{7-11=}}
}
6 changes: 4 additions & 2 deletions test/Parse/matching_patterns.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ case let (let b): // expected-error {{'let' cannot appear nested inside another
print(b)

// 'var' patterns (not allowed)
case var a: // expected-error {{'var' is not allowed in this pattern binding}}
// FIXME: rdar://problem/23378003
// This will eventually be an error.
case var a: // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{6-9=let}}
a += 1
case var let a: // expected-error {{'var' is not allowed in this pattern binding}}
case var let a: // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{6-9=let}}
// expected-error@-1 {{'let' cannot appear nested inside another 'var' or 'let' pattern}}
print(a, terminator: "")

Expand Down
6 changes: 4 additions & 2 deletions test/Parse/switch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,11 @@ case (1, let b): // let bindings
()

// var bindings are not allowed in cases.
case (1, var b): // expected-error {{'var' is not allowed in this pattern binding}}
// FIXME: rdar://problem/23378003
// This will eventually be an error.
case (1, var b): // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{10-13=let}}
()
case (var a, 2): // expected-error {{'var' is not allowed in this pattern binding}}
case (var a, 2): // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{7-10=let}}
()

case (let a, 2), (1, let b): // expected-error {{'case' labels with multiple patterns cannot declare variables}}
Expand Down
26 changes: 19 additions & 7 deletions test/decl/var/usage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,27 +170,35 @@ func testOpenExistential(var x: Fooable,
func couldThrow() throws {}

func testFixitsInStatementsWithPatterns(a : Int?) {
if var b = a, // expected-error {{'var' is not allowed in this pattern binding}} {{6-9=let}}
var b2 = a { // expected-error {{'var' is not allowed in this pattern binding}} {{7-10=let}}
// FIXME: rdar://problem/23378003
// This will eventually be an error.
if var b = a, // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{6-9=let}}
var b2 = a { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{7-10=let}}
b = 1
b2 = 1
_ = b
_ = b2
}

var g = [1,2,3].generate()
while var x = g.next() { // expected-error {{'var' is not allowed in this pattern binding}} {{9-12=let}}
// FIXME: rdar://problem/23378003
// This will eventually be an error.
while var x = g.next() { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{9-12=let}}
x = 0
_ = x
}

guard var y = Optional.Some(1) else { // expected-error {{'var' is not allowed in this pattern binding}} {{9-12=let}}
// FIXME: rdar://problem/23378003
// This will eventually be an error.
guard var y = Optional.Some(1) else { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{9-12=let}}
return
}
y = 0
_ = y

for var b in [42] { // expected-error {{'var' is not allowed in this pattern binding}} {{7-11=}}
// FIXME: rdar://problem/23378003
// This will eventually be an error.
for var b in [42] { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{7-11=}}
b = 42
_ = b
}
Expand All @@ -201,13 +209,17 @@ func testFixitsInStatementsWithPatterns(a : Int?) {

do {
try couldThrow()
} catch var err { // expected-error {{'var' is not allowed in this pattern binding}} {{11-14=let}}
// FIXME: rdar://problem/23378003
// This will eventually be an error.
} catch var err { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{11-14=let}}
// expected-warning@-1 {{variable 'err' was never mutated; consider changing to 'let' constant}}
_ = err
}

switch a {
case var b: // expected-error {{'var' is not allowed in this pattern binding}} {{10-13=let}}
// FIXME: rdar://problem/23378003
// This will eventually be an error.
case var b: // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{10-13=let}}
// expected-warning@-1 {{variable 'b' was never mutated; consider changing to 'let' constant}}
_ = b
}
Expand Down

0 comments on commit 6402411

Please sign in to comment.