Skip to content

Commit 3dcd9bb

Browse files
authored
Merge pull request #85938 from slavapestov/12-year-old-fixme-strikes-back
Sema: Tighten ridiculous disambiguation hack for overloaded type declarations
2 parents e7d2c16 + 6701e5b commit 3dcd9bb

File tree

8 files changed

+74
-22
lines changed

8 files changed

+74
-22
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -195,16 +195,28 @@ static bool sameDecl(Decl *decl1, Decl *decl2) {
195195
if (decl1 == decl2)
196196
return true;
197197

198-
// All types considered identical.
199-
// FIXME: This is a hack. What we really want is to have substituted the
200-
// base type into the declaration reference, so that we can compare the
201-
// actual types to which two type declarations resolve. If those types are
202-
// equivalent, then it doesn't matter which declaration is chosen.
203-
if (isa<TypeDecl>(decl1) && isa<TypeDecl>(decl2))
204-
return true;
205-
206-
if (decl1->getKind() != decl2->getKind())
207-
return false;
198+
// Special hack to allow type aliases with same underlying type.
199+
//
200+
// FIXME: Check substituted types instead.
201+
//
202+
// FIXME: Perhaps this should be handled earlier in name lookup.
203+
auto *typeDecl1 = dyn_cast<TypeDecl>(decl1);
204+
auto *typeDecl2 = dyn_cast<TypeDecl>(decl2);
205+
if (typeDecl1 && typeDecl2) {
206+
auto type1 = typeDecl1->getDeclaredInterfaceType();
207+
auto type2 = typeDecl2->getDeclaredInterfaceType();
208+
209+
// Handle unbound generic type aliases, eg
210+
//
211+
// struct Array<Element> {}
212+
// typealias MyArray = Array
213+
if (type1->is<UnboundGenericType>())
214+
type1 = type1->getAnyNominal()->getDeclaredInterfaceType();
215+
if (type2->is<UnboundGenericType>())
216+
type2 = type2->getAnyNominal()->getDeclaredInterfaceType();
217+
218+
return type1->isEqual(type2);
219+
}
208220

209221
return false;
210222
}

test/AssociatedTypeInference/type_witness_from_parameterized_protocol.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ struct S4: (P & Q<String>) & R {
4343
}
4444

4545
struct Bad: P<Int, Float> { // expected-error {{type 'Bad' does not conform to protocol 'P'}}
46-
typealias A = String // expected-note {{possibly intended match}}
46+
typealias A = String
47+
// expected-note@-1 {{possibly intended match}}
48+
// expected-note@-2 {{found this candidate}}
4749
}
4850

49-
let x = Bad.A.self
51+
let x = Bad.A.self // expected-error {{ambiguous use of 'A'}}
5052
g(x)
5153

5254
struct Circle: Q<Circle.A> {}

test/Constraints/ambiguous_specialized_name_diagnostics.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ import A
3838
import B
3939

4040
func test() {
41-
_ = S<Int>(t: 42) // expected-error {{ambiguous use of 'init(t:)'}}
41+
_ = S<Int>(t: 42) // expected-error {{ambiguous use of 'S'}}
4242

43-
S<Int>(t: 42).test() // expected-error {{ambiguous use of 'init(t:)'}}
43+
S<Int>(t: 42).test() // expected-error {{ambiguous use of 'S'}}
4444

4545
S<Int>.staticFn()
46-
// expected-error@-1 {{ambiguous use of 'staticFn()'}}
46+
// expected-error@-1 {{ambiguous use of 'S'}}
4747
}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
// RUN: %target-swift-frontend -module-name SomeModule -typecheck -verify -dump-ast -import-objc-header %S/Inputs/imported_type.h %s | %FileCheck %s
1+
// RUN: %target-swift-frontend -module-name SomeModule -typecheck -verify -import-objc-header %S/Inputs/imported_type.h %s -verify-ignore-unrelated
22

33
// REQUIRES: objc_interop
44

55
import Foundation
66

7-
// CHECK: declref_expr type="module<SomeModule>"
8-
// CHECK-NEXT: type_expr type="Data.Type"
9-
let type = SomeModule.Data.self
7+
let type = SomeModule.Data.self // expected-error {{ambiguous use of 'Data'}}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/src)
3+
// RUN: split-file %s %t/src
4+
5+
// RUN: %target-swift-frontend -emit-module %t/src/A.swift \
6+
// RUN: -module-name A \
7+
// RUN: -emit-module-path %t/A.swiftmodule
8+
9+
// RUN: %target-swift-frontend -emit-module %t/src/B.swift \
10+
// RUN: -module-name B \
11+
// RUN: -emit-module-path %t/B.swiftmodule
12+
13+
// RUN: %target-swift-frontend -typecheck -verify -verify-ignore-unrelated -module-name main -I %t %t/src/main.swift
14+
15+
//--- A.swift
16+
public struct Bag {
17+
}
18+
19+
//--- B.swift
20+
public struct Bag {
21+
}
22+
23+
//--- main.swift
24+
import A
25+
import B
26+
27+
protocol P {
28+
}
29+
30+
struct Test {
31+
func inject<T>(_: T.Type = T.self) {}
32+
33+
func inject<T: P>(_: T) {}
34+
35+
func inject<T>(_: T) async -> T {}
36+
}
37+
38+
func test(t: Test) {
39+
t.inject(Bag.self) // expected-error {{ambiguous use of 'Bag'}}
40+
}

test/NameLookup/member_import_visibility.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ extension X {
8585
_ = (NestedInA, NestedInB, NestedInC).self // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}}
8686
_ = GenericType<NestedInB>.self // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}}
8787
_ = NestedInC.self
88-
_ = AmbiguousNestedType.self
88+
_ = AmbiguousNestedType.self // expected-ambiguity-error{{ambiguous use of 'AmbiguousNestedType'}}
8989
}
9090

9191
var hasNestedInAType: NestedInA { fatalError() }

validation-test/Sema/rdar84879566.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ struct TupleBuilder {
2020

2121
struct MyApp: Tupled {
2222
var tuple: some Any {
23-
MyView() // expected-error {{ambiguous use of 'init()'}}
23+
MyView() // expected-error {{ambiguous use of 'MyView'}}
2424
}
2525
}

validation-test/compiler_crashers_fixed/issue-85364.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct S1 { // expected-note {{found this candidate}} \
99
var c: () -> Void
1010
}
1111

12-
S1 {} // expected-error {{ambiguous use of 'init'}}
12+
S1 {} // expected-error {{ambiguous use of 'S1'}}
1313

1414
struct S1 { // expected-note {{found this candidate}} \
1515
// expected-error {{invalid redeclaration of 'S1'}}

0 commit comments

Comments
 (0)