Skip to content

Commit 28717ca

Browse files
committed
Restore the circular pattern binding validation hack
Overload resolution performs a lookup rooted at a pattern binding's initializer that scoops up the var decl bound by the pattern. This forces it to validate the variable while type checking said variable's initializer. The old answer to this problem was to skip validation which returns a temporary ErrorType. We should patch lookup so it doesn't consider these variables.
1 parent 742f6b2 commit 28717ca

File tree

5 files changed

+21
-5
lines changed

5 files changed

+21
-5
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4243,6 +4243,14 @@ void TypeChecker::validateDecl(ValueDecl *D) {
42434243
// attempt to infer the interface type using the initializer expressions.
42444244
if (!PBD->isBeingValidated()) {
42454245
validatePatternBindingEntries(*this, PBD);
4246+
} else if (!VD->getNamingPattern()) {
4247+
// FIXME: This acts as a circularity breaker for overload resolution
4248+
// during pattern binding validation, which is allowed to lookup and
4249+
// find the very VarDecl attached to the binding it's trying to check.
4250+
// In order to tell it to back off, we surface an error type but don't
4251+
// set the interface type so a different caller can come along and
4252+
// do the right thing.
4253+
return;
42464254
}
42474255

42484256
if (PBD->isInvalid()) {

test/NameBinding/name_lookup.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -616,15 +616,15 @@ struct PatternBindingWithTwoVars1 { var x = 3, y = x }
616616
// expected-error@-1 {{cannot use instance member 'x' within property initializer; property initializers run before 'self' is available}}
617617

618618
struct PatternBindingWithTwoVars2 { var x = y, y = 3 }
619-
// expected-error@-1 {{variable 'y' is not bound by any pattern}}
619+
// expected-error@-1 {{type 'PatternBindingWithTwoVars2' has no member 'y'}}
620620

621621
// This one should be accepted, but for now PatternBindingDecl validation
622622
// circularity detection is not fine grained enough.
623623
struct PatternBindingWithTwoVars3 { var x = y, y = x }
624-
// expected-error@-1 {{variable 'y' is not bound by any pattern}}
624+
// expected-error@-1 {{type 'PatternBindingWithTwoVars3' has no member 'y'}}
625625

626626
// https://bugs.swift.org/browse/SR-9015
627627
func sr9015() {
628-
let closure1 = { closure2() } // expected-error {{variable 'closure1' is not bound by any pattern}}
628+
let closure1 = { closure2() } // expected-error {{let 'closure1' references itself}}
629629
let closure2 = { closure1() }
630630
}

test/decl/protocol/conforms/circular_validation.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ protocol P {
1010
struct S : P { // expected-error {{type 'S' does not conform to protocol 'P'}}
1111
static var x = 0 // expected-note {{candidate operates on a type, not an instance as required}}
1212
var x = S.x // expected-note {{candidate references itself}}
13-
// expected-error@-1 {{variable 'x' is not bound by any pattern}}
1413
}
1514

1615
// FIXME: Lousy diagnostics on this case.

test/decl/var/overload_cycle.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// Validating the pattern binding initializer for `raw` causes recursive
4+
// validation of the VarDecl. Overload resolution relies on getting back an
5+
// ErrorType from VarDecl validation to disqualify the recursive candidate.
6+
public struct Cyclic {
7+
static func pickMe(please: Bool) -> Int { return 42 }
8+
public static let pickMe = Cyclic.pickMe(please: true)
9+
}

test/decl/var/variables.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class SomeClass {}
6666
weak let V = SomeClass() // expected-error {{'weak' must be a mutable variable, because it may change at runtime}}
6767

6868
let a = b ; let b = a
69-
// expected-error@-1 {{variable 'a' is not bound by any pattern}}
69+
// expected-error@-1 {{let 'a' references itself}}
7070

7171
// <rdar://problem/17501765> Swift should warn about immutable default initialized values
7272
let uselessValue : String?

0 commit comments

Comments
 (0)