Skip to content

Commit ca19a9d

Browse files
authored
Merge pull request #27668 from CodaFi/disqualified-lookup
[DiagnosticsQoI] Strike VarDecls in Pattern Binding Initializers From Overloads
2 parents d7d903f + f15544d commit ca19a9d

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/ExistentialLayout.h"
2121
#include "swift/AST/GenericEnvironment.h"
2222
#include "swift/AST/GenericSignature.h"
23+
#include "swift/AST/Initializer.h"
2324
#include "swift/AST/ParameterList.h"
2425
#include "swift/AST/PropertyWrappers.h"
2526
#include "swift/AST/ProtocolConformance.h"
@@ -4864,7 +4865,19 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
48644865
// reasonable choice.
48654866
auto addChoice = [&](OverloadChoice candidate) {
48664867
auto decl = candidate.getDecl();
4867-
4868+
4869+
// In a pattern binding initializer, immediately reject all of its bound
4870+
// variables. These would otherwise allow circular references.
4871+
if (auto *PBI = dyn_cast<PatternBindingInitializer>(DC)) {
4872+
if (auto *VD = dyn_cast<VarDecl>(decl)) {
4873+
if (PBI->getBinding() == VD->getParentPatternBinding()) {
4874+
result.addUnviable(candidate,
4875+
MemberLookupResult::UR_InstanceMemberOnType);
4876+
return;
4877+
}
4878+
}
4879+
}
4880+
48684881
// If the result is invalid, skip it.
48694882
// FIXME(InterfaceTypeRequest): isInvalid() should be based on the interface type.
48704883
(void)decl->getInterfaceType();

test/NameBinding/name_lookup.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,12 +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 {{type 'PatternBindingWithTwoVars2' has no member 'y'}}
619+
// expected-error@-1 {{property 'y' references itself}}
620+
// expected-error@-2 {{cannot use instance member 'y' within property initializer; property initializers run before 'self' is available}}
620621

621622
// This one should be accepted, but for now PatternBindingDecl validation
622623
// circularity detection is not fine grained enough.
623624
struct PatternBindingWithTwoVars3 { var x = y, y = x }
624-
// expected-error@-1 {{type 'PatternBindingWithTwoVars3' has no member 'y'}}
625+
// expected-error@-1 {{cannot use instance member 'x' within property initializer; property initializers run before 'self' is available}}
626+
// expected-error@-2 {{cannot use instance member 'y' within property initializer; property initializers run before 'self' is available}}
627+
// expected-error@-3 {{property 'y' references itself}}
625628

626629
// https://bugs.swift.org/browse/SR-9015
627630
func sr9015() {

test/decl/overload.swift

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -571,23 +571,23 @@ enum SR_10084_E_8 {
571571
}
572572

573573
enum SR_10084_E_9 {
574-
case A // expected-note {{found this candidate}} // expected-note {{'A' previously declared here}}
575-
static let A: SR_10084_E_9 = .A // expected-note {{found this candidate}} // expected-error {{invalid redeclaration of 'A'}} // expected-error {{ambiguous use of 'A'}}
574+
case A // expected-note {{'A' previously declared here}}
575+
static let A: SR_10084_E_9 = .A // expected-error {{invalid redeclaration of 'A'}}
576576
}
577577

578578
enum SR_10084_E_10 {
579-
static let A: SR_10084_E_10 = .A // expected-note {{found this candidate}} // expected-note {{'A' previously declared here}} // expected-error {{ambiguous use of 'A'}}
580-
case A // expected-note {{found this candidate}} // expected-error {{invalid redeclaration of 'A'}}
579+
static let A: SR_10084_E_10 = .A // expected-note {{'A' previously declared here}}
580+
case A // expected-error {{invalid redeclaration of 'A'}}
581581
}
582582

583583
enum SR_10084_E_11 {
584-
case A // expected-note {{found this candidate}} // expected-note {{'A' previously declared here}}
585-
static var A: SR_10084_E_11 = .A // expected-note {{found this candidate}} // expected-error {{invalid redeclaration of 'A'}} // expected-error {{ambiguous use of 'A'}}
584+
case A // expected-note {{'A' previously declared here}}
585+
static var A: SR_10084_E_11 = .A // expected-error {{invalid redeclaration of 'A'}}
586586
}
587587

588588
enum SR_10084_E_12 {
589-
static var A: SR_10084_E_12 = .A // expected-note {{found this candidate}} // expected-note {{'A' previously declared here}} // expected-error {{ambiguous use of 'A'}}
590-
case A // expected-note {{found this candidate}} // expected-error {{invalid redeclaration of 'A'}}
589+
static var A: SR_10084_E_12 = .A // expected-note {{'A' previously declared here}}
590+
case A // expected-error {{invalid redeclaration of 'A'}}
591591
}
592592

593593
enum SR_10084_E_13 {
@@ -609,3 +609,11 @@ enum SR_10084_E_16 {
609609
typealias Z = Int // expected-note {{'Z' previously declared here}}
610610
case Z // expected-error {{invalid redeclaration of 'Z'}}
611611
}
612+
613+
// N.B. Validating the pattern binding initializer for `raw` used to cause
614+
// recursive validation of the VarDecl. Check that we don't regress now that
615+
// this isn't the case.
616+
public struct Cyclic {
617+
static func pickMe(please: Bool) -> Int { return 42 }
618+
public static let pickMe = Cyclic.pickMe(please: true)
619+
}

0 commit comments

Comments
 (0)