Skip to content

Commit 1a22a8d

Browse files
authored
Merge pull request swiftlang#6777 from slavapestov/fix-unqualified-lookup-rdar29961715
AST: Restore unqualified lookup quirk for Swift 3 mode
2 parents d99834e + fbdeceb commit 1a22a8d

File tree

6 files changed

+67
-9
lines changed

6 files changed

+67
-9
lines changed

lib/AST/NameLookup.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -649,13 +649,16 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
649649
ValueDecl *MetaBaseDecl = nullptr;
650650
GenericParamList *GenericParams = nullptr;
651651
Type ExtendedType;
652-
652+
bool isTypeLookup = false;
653+
653654
// If this declcontext is an initializer for a static property, then we're
654655
// implicitly doing a static lookup into the parent declcontext.
655656
if (auto *PBI = dyn_cast<PatternBindingInitializer>(DC))
656657
if (!DC->getParent()->isModuleScopeContext()) {
657-
if (PBI->getBinding())
658+
if (auto *PBD = PBI->getBinding()) {
659+
isTypeLookup = PBD->isStatic();
658660
DC = DC->getParent();
661+
}
659662
}
660663

661664
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {
@@ -694,6 +697,10 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
694697
->getAsNominalTypeOrNominalTypeExtensionContext();
695698
DC = DC->getParent();
696699

700+
if (auto *FD = dyn_cast<FuncDecl>(AFD))
701+
if (FD->isStatic())
702+
isTypeLookup = true;
703+
697704
// If we're not in the body of the function, the base declaration
698705
// is the nominal type, not 'self'.
699706
if (Loc.isValid() &&
@@ -780,6 +787,23 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
780787
DC->lookupQualified(ExtendedType, Name, options, TypeResolver, Lookup);
781788
bool FoundAny = false;
782789
for (auto Result : Lookup) {
790+
// In Swift 3 mode, unqualified lookup skips static methods when
791+
// performing lookup from instance context.
792+
//
793+
// We don't want to carry this forward to Swift 4, since it makes
794+
// for poor diagnostics.
795+
//
796+
// Also, it was quite a special case and not as general as it
797+
// should be -- it didn't apply to properties or subscripts, and
798+
// the opposite case where we're in static context and an instance
799+
// member shadows the module member wasn't handled either.
800+
if (Ctx.isSwiftVersion3() &&
801+
!isTypeLookup &&
802+
isa<FuncDecl>(Result) &&
803+
cast<FuncDecl>(Result)->isStatic()) {
804+
continue;
805+
}
806+
783807
// Classify this declaration.
784808
FoundAny = true;
785809

test/Compatibility/members.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 3
2+
3+
struct X {
4+
func f1(_ i: Int) { }
5+
mutating func f1(_ f: Float) { }
6+
}
7+
8+
func g0(_: (inout X) -> (Float) -> ()) {}
9+
10+
// This becomes an error in Swift 4 mode -- probably a bug
11+
g0(X.f1)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 3
2+
3+
// Stupid Swift 3 unqualified lookup quirk
4+
5+
func f3(_ x: Int, _ y: Int, z: Int) { } // expected-note{{did you mean 'f3'?}}
6+
7+
struct S0 {
8+
func testS0() {
9+
_ = f3(_:y:z:) // expected-error{{use of unresolved identifier 'f3(_:y:z:)'}}
10+
}
11+
12+
static func f3(_ x: Int, y: Int, z: Int) -> S0 { return S0() }
13+
}
14+
15+
extension Float {
16+
func isClose(to: Float, epiValue: Float = 1e-5) -> Bool {
17+
// Float.abs() and Swift.abs() are both visible here, but
18+
// Swift 3 drops 'Float.abs()'.
19+
return abs(self - to) < epiValue
20+
}
21+
}

test/Constraints/members.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift
2-
3-
import Swift
1+
// RUN: %target-typecheck-verify-swift -swift-version 4
42

53
////
64
// Members of structs
@@ -9,9 +7,9 @@ import Swift
97
struct X {
108
func f0(_ i: Int) -> X { }
119

12-
func f1(_ i: Int) { }
10+
func f1(_ i: Int) { } // expected-note {{found this candidate}}
1311

14-
mutating func f1(_ f: Float) { }
12+
mutating func f1(_ f: Float) { } // expected-note {{found this candidate}}
1513

1614
func f2<T>(_ x: T) -> T { }
1715
}
@@ -29,7 +27,11 @@ func g0(_: (inout X) -> (Float) -> ()) {}
2927

3028
_ = x.f0(i)
3129
x.f0(i).f1(i)
30+
31+
// FIXME: Is this a bug in Swift 4 mode?
3232
g0(X.f1)
33+
// expected-error@-1 {{ambiguous reference to member 'f1'}}
34+
3335
_ = x.f0(x.f2(1))
3436
_ = x.f0(1).f2(i)
3537
_ = yf.f0(1)

test/expr/primary/unqualified_name.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift -swift-version 4
22

33
func f0(_ x: Int, y: Int, z: Int) { }
44
func f1(_ x: Int, while: Int) { }

test/expr/unary/selector/property.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-objc-attr-requires-foundation-module -typecheck -primary-file %s %S/Inputs/property_helper.swift -verify
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-objc-attr-requires-foundation-module -typecheck -primary-file %s %S/Inputs/property_helper.swift -verify -swift-version 4
22
import ObjectiveC
33

44
// REQUIRES: objc_interop

0 commit comments

Comments
 (0)