Skip to content

Commit 51b335f

Browse files
committed
Improve diagnostics for types with incorrect module selectors
1 parent bc0f92f commit 51b335f

File tree

5 files changed

+152
-34
lines changed

5 files changed

+152
-34
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2993,11 +2993,10 @@ class ValueDecl : public Decl {
29932993
return Name.getBaseIdentifier();
29942994
}
29952995

2996-
/// Generates a DeclNameRef referring to this declaration with as much
2997-
/// specificity as possible.
2998-
DeclNameRef createNameRef() const {
2999-
return DeclNameRef(Name);
3000-
}
2996+
/// Generates a DeclNameRef referring to this declaration.
2997+
///
2998+
/// \param moduleSelector If true, the name ref includes the module name.
2999+
DeclNameRef createNameRef(bool moduleSelector = false) const;
30013000

30023001
/// Retrieve the C declaration name that names this function, or empty
30033002
/// string if it has none.

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,10 @@ ERROR(cannot_find_type_in_cast_expression,none,
11591159
"type-casting operator expects a type on its right-hand side (got: %kind0)", (const ValueDecl *))
11601160
ERROR(cannot_find_type_in_scope_did_you_mean,none,
11611161
"cannot find type %0 in scope; did you mean to use '%1'?", (DeclNameRef, StringRef))
1162+
ERROR(type_not_in_module,none,
1163+
"type %0 is not imported through module %1", (DeclName, Identifier))
1164+
NOTE(note_change_module_selector,none,
1165+
"did you mean module %0?", (Identifier))
11621166
NOTE(note_typo_candidate_implicit_member,none,
11631167
"did you mean the implicitly-synthesized %kindbase0?", (const ValueDecl *))
11641168
NOTE(note_remapped_type,none,

lib/AST/Decl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2825,6 +2825,14 @@ SourceRange TopLevelCodeDecl::getSourceRange() const {
28252825
return Body? Body->getSourceRange() : SourceRange();
28262826
}
28272827

2828+
DeclNameRef ValueDecl::createNameRef(bool moduleSelector) const {
2829+
if (moduleSelector)
2830+
return DeclNameRef(getASTContext(), getModuleContext()->getName(),
2831+
getName());
2832+
2833+
return DeclNameRef(getName());
2834+
}
2835+
28282836
static bool isPolymorphic(const AbstractStorageDecl *storage) {
28292837
if (storage->shouldUseObjCDispatch())
28302838
return true;

lib/Sema/TypeCheckType.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,6 +1493,33 @@ static Type diagnoseUnknownType(const TypeResolution &resolution,
14931493
return ErrorType::get(ctx);
14941494
}
14951495

1496+
// Is there an incorrect module selector?
1497+
if (repr->getNameRef().hasModuleSelector()) {
1498+
auto anyModuleName = DeclNameRef(repr->getNameRef().getFullName());
1499+
auto anyModuleResults =
1500+
TypeChecker::lookupUnqualifiedType(dc, anyModuleName,
1501+
repr->getLoc(), lookupOptions);
1502+
if (!anyModuleResults.empty()) {
1503+
diags.diagnose(repr->getNameLoc(), diag::type_not_in_module,
1504+
repr->getNameRef().getFullName(),
1505+
repr->getNameRef().getModuleSelector());
1506+
1507+
SourceLoc moduleSelectorLoc = repr->getNameLoc().getModuleSelectorLoc();
1508+
1509+
for (auto result : anyModuleResults) {
1510+
TypeDecl * decl = static_cast<TypeDecl*>(result.getValueDecl());
1511+
Identifier moduleName = decl->getModuleContext()->getName();
1512+
1513+
diags.diagnose(moduleSelectorLoc, diag::note_change_module_selector,
1514+
moduleName)
1515+
.fixItReplace(moduleSelectorLoc, moduleName.str());
1516+
}
1517+
1518+
// FIXME: Can we recover by assuming the first/best result is correct?
1519+
return ErrorType::get(ctx);
1520+
}
1521+
}
1522+
14961523
// Try ignoring access control.
14971524
NameLookupOptions relookupOptions = lookupOptions;
14981525
relookupOptions |= NameLookupFlags::IgnoreAccessControl;
@@ -1584,6 +1611,32 @@ static Type diagnoseUnknownType(const TypeResolution &resolution,
15841611
return ErrorType::get(ctx);
15851612
}
15861613

1614+
// Is there an incorrect module selector?
1615+
if (repr->getNameRef().hasModuleSelector()) {
1616+
auto anyModuleName = DeclNameRef(repr->getNameRef().getFullName());
1617+
auto anyModuleResults = TypeChecker::lookupMemberType(
1618+
dc, parentType, anyModuleName, repr->getLoc(), lookupOptions);
1619+
if (anyModuleResults) {
1620+
diags.diagnose(repr->getNameLoc(), diag::type_not_in_module,
1621+
repr->getNameRef().getFullName(),
1622+
repr->getNameRef().getModuleSelector());
1623+
1624+
SourceLoc moduleSelectorLoc = repr->getNameLoc().getModuleSelectorLoc();
1625+
1626+
for (auto result : anyModuleResults) {
1627+
TypeDecl * decl = result.Member;
1628+
Identifier moduleName = decl->getModuleContext()->getName();
1629+
1630+
diags.diagnose(moduleSelectorLoc, diag::note_change_module_selector,
1631+
moduleName)
1632+
.fixItReplace(moduleSelectorLoc, moduleName.str());
1633+
}
1634+
1635+
// FIXME: Can we recover by assuming the first/best result is correct?
1636+
return ErrorType::get(ctx);
1637+
}
1638+
}
1639+
15871640
// Try ignoring access control.
15881641
NameLookupOptions relookupOptions = lookupOptions;
15891642
relookupOptions |= NameLookupFlags::IgnoreAccessControl;

test/NameLookup/module_selector.swift

Lines changed: 83 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,59 @@ let magnitude: Never = fatalError()
1515
// Test resolution of main:: using `B`
1616

1717
extension main::B {}
18-
// FIXME improve: expected-error@-1 {{use of undeclared type 'main::B'}}
18+
// expected-error@-1 {{type 'B' is not imported through module 'main'}}
19+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{11-15=ModuleSelectorTestingKit}}
1920

2021
extension B: main::Equatable {
22+
// expected-error@-1 {{type 'Equatable' is not imported through module 'main'}}
23+
// expected-note@-2 {{did you mean module 'Swift'?}} {{14-18=Swift}}
24+
2125
@_implements(main::Equatable, main::==(_:_:))
2226
// expected-error@-1 {{name cannot be qualified with module selector here}} {{33-39=}}
23-
public static func equals(_: main::B, _: main::B) -> main::Bool { main::fatalError() }
24-
27+
// expected-error@-2 {{type 'Equatable' is not imported through module 'main'}}
28+
// expected-note@-3 {{did you mean module 'Swift'?}} {{16-20=Swift}}
29+
public static func equals(_: main::B, _: main::B) -> main::Bool {
30+
// expected-error@-1 2{{type 'B' is not imported through module 'main'}}
31+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{32-36=ModuleSelectorTestingKit}}
32+
// expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{44-48=ModuleSelectorTestingKit}}
33+
// expected-error@-4 {{type 'Bool' is not imported through module 'main'}}
34+
// expected-note@-5 {{did you mean module 'Swift'?}} {{56-60=Swift}}
35+
main::fatalError()
36+
// expected-EVENTUALLY-error@-1 {{type 'fatalError' is not imported through module 'main'}}
37+
// expected-EVENTUALLY-note@-2 {{did you mean module 'Swift'?}} {{4-8=Swift}}
38+
}
39+
2540
// FIXME: Add tests with autodiff @_differentiable(jvp:vjp:) and
2641
// @_derivative(of:)
2742

2843
@_dynamicReplacement(for: main::negate())
2944
// FIXME improve: expected-error@-1 {{replaced function 'main::negate()' could not be found}}
3045
mutating func myNegate() {
3146
let fn: (main::Int, main::Int) -> main::Int =
32-
// FIXME:
47+
// expected-error@-1 3{{type 'Int' is not imported through module 'main'}}
48+
// expected-note@-2 {{did you mean module 'Swift'?}} {{14-18=Swift}}
49+
// expected-note@-3 {{did you mean module 'Swift'?}} {{25-29=Swift}}
50+
// expected-note@-4 {{did you mean module 'Swift'?}} {{39-43=Swift}}
3351
(main::+)
34-
// expected-error@-1 {{cannot convert value of type '()' to specified type '(Int, Int) -> Int'}}
52+
// FIXME: it'd be nice to handle module selectors on operators.
3553
// expected-error@-2 {{expected expression}}
3654
// expected-error@-3 {{expected expression after operator}}
3755

3856
let magnitude: Int.main::Magnitude = main::magnitude
39-
// expected-EVENTUALLY-error@-1 {{can't find 'Int'}}
40-
// FIXME improve: expected-error@-2 {{type alias 'Magnitude' is not a member type of 'Int'}}
41-
// FIXME: expected-error@-3 {{variable used within its own initial value}}
57+
// expected-error@-1 {{type 'Magnitude' is not imported through module 'main'}}
58+
// expected-note@-2 {{did you mean module 'Swift'?}} {{24-28=Swift}}
59+
// FIXME incorrect: expected-error@-3 {{variable used within its own initial value}}
60+
4261
if main::Bool.main::random() {
62+
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'main::Bool'}}
63+
4364
main::negate()
44-
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'main::negate'}}
65+
// FIXME improve, suggest adding 'self.': expected-error@-1 {{use of unresolved identifier 'main::negate'}}
4566
}
4667
else {
4768
self = main::B(value: .main::min)
69+
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'main::B'}}
70+
// expected-error@-2 {{cannot infer contextual base in reference to member 'main::min'}}
4871
}
4972

5073
self.main::myNegate()
@@ -58,30 +81,45 @@ extension B: main::Equatable {
5881
extension C {}
5982

6083
extension ModuleSelectorTestingKit::C: ModuleSelectorTestingKit::Equatable {
61-
// FIXME improve: expected-error@-1 {{use of undeclared type 'ModuleSelectorTestingKit::Equatable'}}
84+
// expected-error@-1 {{type 'Equatable' is not imported through module 'ModuleSelectorTestingKit'}}
85+
// expected-note@-2 {{did you mean module 'Swift'?}} {{39-62=Swift}}
86+
6287
@_implements(ModuleSelectorTestingKit::Equatable, ModuleSelectorTestingKit::==(_:_:))
63-
// FIXME improve: expected-error@-1 {{use of undeclared type 'ModuleSelectorTestingKit::Equatable'}}
64-
// expected-error@-2 {{name cannot be qualified with module selector here}} {{52-77=}}
65-
public static func equals(_: ModuleSelectorTestingKit::C, _: ModuleSelectorTestingKit::C) -> ModuleSelectorTestingKit::Bool { ModuleSelectorTestingKit::fatalError() }
66-
// FIXME improve: expected-error@-1 {{use of undeclared type 'ModuleSelectorTestingKit::Bool'}}
88+
// expected-error@-1 {{name cannot be qualified with module selector here}} {{52-77=}}
89+
// expected-error@-2 {{type 'Equatable' is not imported through module 'ModuleSelectorTestingKit'}}
90+
// expected-note@-3 {{did you mean module 'Swift'?}} {{16-39=Swift}}
91+
92+
public static func equals(_: ModuleSelectorTestingKit::C, _: ModuleSelectorTestingKit::C) -> ModuleSelectorTestingKit::Bool {
93+
// expected-error@-1 {{type 'Bool' is not imported through module 'ModuleSelectorTestingKit'}}
94+
// expected-note@-2 {{did you mean module 'Swift'?}} {{94-117=Swift}}
95+
ModuleSelectorTestingKit::fatalError()
96+
// expected-EVENTUALLY-error@-1 {{type 'fatalError' is not imported through module 'main'}}
97+
// expected-EVENTUALLY-note@-2 {{did you mean module 'Swift'?}} {{4-8=Swift}}
98+
}
6799

68100
// FIXME: Add tests with autodiff @_differentiable(jvp:vjp:) and
69101
// @_derivative(of:)
70102

71103
@_dynamicReplacement(for: ModuleSelectorTestingKit::negate())
72104
mutating func myNegate() {
73105
let fn: (ModuleSelectorTestingKit::Int, ModuleSelectorTestingKit::Int) -> ModuleSelectorTestingKit::Int =
74-
// FIXME improve: expected-error@-1 3{{use of undeclared type 'ModuleSelectorTestingKit::Int'}}
75-
// FIXME:
106+
// expected-error@-1 3{{type 'Int' is not imported through module 'ModuleSelectorTestingKit'}}
107+
// expected-note@-2 {{did you mean module 'Swift'?}} {{14-37=Swift}}
108+
// expected-note@-3 {{did you mean module 'Swift'?}} {{44-67=Swift}}
109+
// expected-note@-4 {{did you mean module 'Swift'?}} {{77-100=Swift}}
76110
(ModuleSelectorTestingKit::+)
77-
// expected-error@-1 {{expected expression}}
78-
// expected-error@-2 {{expected expression after operator}}
111+
// FIXME: it'd be nice to handle module selectors on operators.
112+
// expected-error@-2 {{expected expression}}
113+
// expected-error@-3 {{expected expression after operator}}
114+
79115
let magnitude: Int.ModuleSelectorTestingKit::Magnitude = ModuleSelectorTestingKit::magnitude
80-
// expected-EVENTUALLY-error@-1 {{something about not finding 'magnitude' because we didn't look in self}}
81-
// FIXME improve: expected-error@-2 {{type alias 'Magnitude' is not a member type of 'Int'}}
82-
// FIXME: expected-error@-3 {{variable used within its own initial value}}
116+
// expected-error@-1 {{type 'Magnitude' is not imported through module 'ModuleSelectorTestingKit'}}
117+
// expected-note@-2 {{did you mean module 'Swift'?}} {{24-47=Swift}}
118+
// FIXME incorrect: expected-error@-3 {{variable used within its own initial value}}
119+
83120
if ModuleSelectorTestingKit::Bool.ModuleSelectorTestingKit::random() {
84121
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'ModuleSelectorTestingKit::Bool'}}
122+
85123
ModuleSelectorTestingKit::negate()
86124
// FIXME improve, suggest adding 'self.': expected-error@-1 {{use of unresolved identifier 'ModuleSelectorTestingKit::negate'}}
87125
}
@@ -100,13 +138,22 @@ extension ModuleSelectorTestingKit::C: ModuleSelectorTestingKit::Equatable {
100138
// FIXME: Many more of these should fail once the feature is actually implemented.
101139

102140
extension Swift::D {}
103-
// FIXME improve: expected-error@-1 {{use of undeclared type 'Swift::D'}}
141+
// expected-error@-1 {{type 'D' is not imported through module 'Swift'}}
142+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{11-16=ModuleSelectorTestingKit}}
104143

105144
extension D: @retroactive Swift::Equatable {
145+
// Caused by Swift::D failing to typecheck in `equals(_:_:)`: expected-error@-1 *{{extension outside of file declaring struct 'D' prevents automatic synthesis of '==' for protocol 'Equatable'}} expected-note@-1 *{{add stubs for conformance}}
146+
106147
@_implements(Swift::Equatable, Swift::==(_:_:))
107148
// expected-error@-1 {{name cannot be qualified with module selector here}} {{34-41=}}
108-
public static func equals(_: Swift::D, _: Swift::D) -> Swift::Bool { Swift::fatalError() }
109-
149+
150+
public static func equals(_: Swift::D, _: Swift::D) -> Swift::Bool {
151+
// expected-error@-1 2{{type 'D' is not imported through module 'Swift'}}
152+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{32-37=ModuleSelectorTestingKit}}
153+
// expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{45-50=ModuleSelectorTestingKit}}
154+
Swift::fatalError()
155+
}
156+
110157
// FIXME: Add tests with autodiff @_differentiable(jvp:vjp:) and
111158
// @_derivative(of:)
112159

@@ -128,6 +175,8 @@ extension D: @retroactive Swift::Equatable {
128175
}
129176
else {
130177
self = Swift::D(value: .Swift::min)
178+
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'Swift::D'}}
179+
// expected-error@-2 {{cannot infer contextual base in reference to member 'Swift::min'}}
131180
}
132181

133182
self.Swift::myNegate()
@@ -202,13 +251,16 @@ func main::decl1(
202251
// expected-error@-1 {{name of function declaration cannot be qualified with module selector}}
203252
main::p1: main::A,
204253
// expected-error@-1 {{argument label cannot be qualified with module selector}}
205-
// FIXME access path: expected-error@-2 {{use of undeclared type 'main::A'}}
254+
// FIXME access path: expected-error@-2 {{type 'A' is not imported through module 'main'}}
255+
// FIXME access path: expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{13-17=ModuleSelectorTestingKit}}
206256
main::label p2: main::A,
207257
// expected-error@-1 {{argument label cannot be qualified with module selector}}
208-
// FIXME access path: expected-error@-2 {{use of undeclared type 'main::A'}}
258+
// FIXME access path: expected-error@-2 {{type 'A' is not imported through module 'main'}}
259+
// FIXME access path: expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{19-23=ModuleSelectorTestingKit}}
209260
label main::p3: main::A
210261
// expected-error@-1 {{name of parameter declaration cannot be qualified with module selector}}
211-
// FIXME access path: expected-error@-2 {{use of undeclared type 'main::A'}}
262+
// FIXME access path: expected-error@-2 {{type 'A' is not imported through module 'main'}}
263+
// FIXME access path: expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{19-23=ModuleSelectorTestingKit}}
212264
) {
213265
let main::decl1a = "a"
214266
// expected-error@-1 {{name of constant declaration cannot be qualified with module selector}}
@@ -292,7 +344,8 @@ class main::decl4<main::T> {}
292344

293345
typealias main::decl5 = main::Bool
294346
// expected-error@-1 {{name of typealias declaration cannot be qualified with module selector}}
295-
// FIXME improve: expected-error@-2 {{use of undeclared type 'main::Bool'}}
347+
// expected-error@-2 {{type 'Bool' is not imported through module 'main'}}
348+
// expected-note@-3 {{did you mean module 'Swift'?}} {{25-29=Swift}}
296349

297350
protocol main::decl6 {
298351
// expected-error@-1 {{name of protocol declaration cannot be qualified with module selector}}
@@ -333,7 +386,8 @@ struct Parent {
333386

334387
typealias main::decl5 = main::Bool
335388
// expected-error@-1 {{name of typealias declaration cannot be qualified with module selector}}
336-
// FIXME improve: expected-error@-2 {{use of undeclared type 'main::Bool'}}
389+
// expected-error@-2 {{type 'Bool' is not imported through module 'main'}}
390+
// expected-note@-3 {{did you mean module 'Swift'?}} {{27-31=Swift}}
337391
}
338392

339393
@_swift_native_objc_runtime_base(main::BaseClass)

0 commit comments

Comments
 (0)