Skip to content

Commit d860c70

Browse files
committed
Improve module selector type lookup diagnostics
1 parent d2528bc commit d860c70

File tree

3 files changed

+95
-18
lines changed

3 files changed

+95
-18
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,10 @@ ERROR(cannot_find_type_in_cast_expression,none,
11931193
"type-casting operator expects a type on its right-hand side (got: %kind0)", (const ValueDecl *))
11941194
ERROR(cannot_find_type_in_scope_did_you_mean,none,
11951195
"cannot find type %0 in scope; did you mean to use '%1'?", (DeclNameRef, StringRef))
1196+
ERROR(type_not_in_module,none,
1197+
"type %0 is not imported through module %1", (DeclName, Identifier))
1198+
NOTE(note_change_module_selector,none,
1199+
"did you mean module %0?", (Identifier))
11961200
NOTE(note_typo_candidate_implicit_member,none,
11971201
"did you mean the implicitly-synthesized %kindbase0?", (const ValueDecl *))
11981202
NOTE(note_remapped_type,none,

lib/Sema/TypeCheckType.cpp

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

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

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

test/NameLookup/module_selector.swift

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,23 @@ extension A: @retroactive Swift::Equatable {
6464
// Test resolution of main:: using `B`
6565

6666
extension main::B {}
67-
// FIXME improve: expected-error@-1 {{cannot find type 'main::B' in scope}}
67+
// expected-error@-1 {{type 'B' is not imported through module 'main'}}
68+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{11-15=ModuleSelectorTestingKit}}
6869

6970
extension B: @retroactive main::Equatable {
70-
// FIXME improve: expected-error@-1 {{cannot find type 'main::Equatable' in scope}}
71+
// expected-error@-1 {{type 'Equatable' is not imported through module 'main'}}
72+
// expected-note@-2 {{did you mean module 'Swift'?}} {{27-31=Swift}}
7173

7274
@_implements(main::Equatable, ==(_:_:))
73-
// FIXME improve: expected-error@-1 {{cannot find type 'main::Equatable' in scope}}
75+
// expected-error@-1 {{type 'Equatable' is not imported through module 'main'}}
76+
// expected-note@-2 {{did you mean module 'Swift'?}} {{16-20=Swift}}
7477

7578
public static func equals(_: main::B, _: main::B) -> main::Bool {
76-
// FIXME improve: expected-error@-1 {{cannot find type 'main::B' in scope}}
77-
// FIXME improve: expected-error@-2 {{cannot find type 'main::B' in scope}}
78-
// FIXME improve: expected-error@-3 {{cannot find type 'main::Bool' in scope}}
79+
// expected-error@-1 2{{type 'B' is not imported through module 'main'}}
80+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{32-36=ModuleSelectorTestingKit}}
81+
// expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{44-48=ModuleSelectorTestingKit}}
82+
// expected-error@-4 {{type 'Bool' is not imported through module 'main'}}
83+
// expected-note@-5 {{did you mean module 'Swift'?}} {{56-60=Swift}}
7984
main::fatalError() // no-error -- not typechecking function bodies
8085
}
8186

@@ -87,12 +92,16 @@ extension B: @retroactive main::Equatable {
8792

8893
mutating func myNegate() {
8994
let fn: (main::Int, main::Int) -> main::Int =
90-
// FIXME improve: expected-error@-1 3{{cannot find type 'main::Int' in scope}}
95+
// expected-error@-1 3{{type 'Int' is not imported through module 'main'}}
96+
// expected-note@-2 {{did you mean module 'Swift'?}} {{14-18=Swift}}
97+
// expected-note@-3 {{did you mean module 'Swift'?}} {{25-29=Swift}}
98+
// expected-note@-4 {{did you mean module 'Swift'?}} {{39-43=Swift}}
9199
(main::+)
92100
// FIXME: should fail????
93101

94102
let magnitude: Int.main::Magnitude = main::magnitude
95-
// FIXME improve: expected-error@-1 {{'main::Magnitude' is not a member type of struct 'Swift.Int'}}
103+
// expected-error@-1 {{type 'Magnitude' is not imported through module 'main'}}
104+
// expected-note@-2 {{did you mean module 'Swift'?}} {{24-28=Swift}}
96105

97106
_ = (fn, magnitude)
98107

@@ -126,13 +135,16 @@ extension B: @retroactive main::Equatable {
126135
extension ModuleSelectorTestingKit::C {}
127136

128137
extension C: @retroactive ModuleSelectorTestingKit::Equatable {
129-
// FIXME improve: expected-error@-1 {{cannot find type 'ModuleSelectorTestingKit::Equatable' in scope}}
138+
// expected-error@-1 {{type 'Equatable' is not imported through module 'ModuleSelectorTestingKit'}}
139+
// expected-note@-2 {{did you mean module 'Swift'?}} {{27-51=Swift}}
130140

131141
@_implements(ModuleSelectorTestingKit::Equatable, ==(_:_:))
132-
// FIXME improve: expected-error@-1 {{cannot find type 'ModuleSelectorTestingKit::Equatable' in scope}}
142+
// expected-error@-1 {{type 'Equatable' is not imported through module 'ModuleSelectorTestingKit'}}
143+
// expected-note@-2 {{did you mean module 'Swift'?}} {{16-40=Swift}}
133144

134145
public static func equals(_: ModuleSelectorTestingKit::C, _: ModuleSelectorTestingKit::C) -> ModuleSelectorTestingKit::Bool {
135-
// FIXME improve: expected-error@-1 {{cannot find type 'ModuleSelectorTestingKit::Bool' in scope}}
146+
// expected-error@-1 {{type 'Bool' is not imported through module 'ModuleSelectorTestingKit'}}
147+
// expected-note@-2 {{did you mean module 'Swift'?}} {{96-120=Swift}}
136148

137149
ModuleSelectorTestingKit::fatalError() // no-error -- not typechecking function bodies
138150
}
@@ -146,12 +158,16 @@ extension C: @retroactive ModuleSelectorTestingKit::Equatable {
146158
// FIXME improve: expected-note@-1 {{did you mean 'myNegate'?}}
147159

148160
let fn: (ModuleSelectorTestingKit::Int, ModuleSelectorTestingKit::Int) -> ModuleSelectorTestingKit::Int =
149-
// FIXME improve: expected-error@-1 3{{cannot find type 'ModuleSelectorTestingKit::Int' in scope}}
161+
// expected-error@-1 3{{type 'Int' is not imported through module 'ModuleSelectorTestingKit'}}
162+
// expected-note@-2 {{did you mean module 'Swift'?}} {{14-38=Swift}}
163+
// expected-note@-3 {{did you mean module 'Swift'?}} {{45-69=Swift}}
164+
// expected-note@-4 {{did you mean module 'Swift'?}} {{79-103=Swift}}
150165
(ModuleSelectorTestingKit::+)
151166
// FIXME: should fail????
152167

153168
let magnitude: Int.ModuleSelectorTestingKit::Magnitude = ModuleSelectorTestingKit::magnitude
154-
// FIXME improve: expected-error@-1 {{'ModuleSelectorTestingKit::Magnitude' is not a member type of struct 'Swift.Int'}}
169+
// expected-error@-1 {{type 'Magnitude' is not imported through module 'ModuleSelectorTestingKit'}}
170+
// expected-note@-2 {{did you mean module 'Swift'?}} {{24-48=Swift}}
155171

156172
_ = (fn, magnitude)
157173

@@ -181,15 +197,17 @@ extension C: @retroactive ModuleSelectorTestingKit::Equatable {
181197
// Test resolution of Swift:: using `D`
182198

183199
extension Swift::D {}
184-
// FIXME improve: expected-error@-1 {{cannot find type 'Swift::D' in scope}}
200+
// expected-error@-1 {{type 'D' is not imported through module 'Swift'}}
201+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{11-16=ModuleSelectorTestingKit}}
185202

186203
extension D: @retroactive Swift::Equatable {
187204
// 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}}
188205

189206
@_implements(Swift::Equatable, ==(_:_:))
190207
public static func equals(_: Swift::D, _: Swift::D) -> Swift::Bool {
191-
// expected-error@-1 {{cannot find type 'Swift::D' in scope}}
192-
// expected-error@-2 {{cannot find type 'Swift::D' in scope}}
208+
// expected-error@-1 2{{type 'D' is not imported through module 'Swift'}}
209+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{32-37=ModuleSelectorTestingKit}}
210+
// expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{45-50=ModuleSelectorTestingKit}}
193211
Swift::fatalError() // no-error -- not typechecking function bodies
194212
}
195213

@@ -270,7 +288,8 @@ func builderUser4(@Swift::MyBuilder fn: () -> Void) {}
270288

271289
func decl1(
272290
p1: main::A,
273-
// FIXME: expected-error@-1 {{cannot find type 'main::A' in scope}}
291+
// expected-error@-1 {{type 'A' is not imported through module 'main'}}
292+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{7-11=ModuleSelectorTestingKit}}
274293
label p2: inout A,
275294
label p3: @escaping () -> A
276295
) {
@@ -300,7 +319,8 @@ func decl1(
300319
}
301320

302321
typealias decl5 = main::Bool
303-
// FIXME improve: expected-error@-1 {{cannot find type 'main::Bool' in scope}}
322+
// expected-error@-1 {{type 'Bool' is not imported through module 'main'}}
323+
// expected-note@-2 {{did you mean module 'Swift'?}} {{19-23=Swift}}
304324

305325
func badModuleNames() {
306326
NonexistentModule::print()

0 commit comments

Comments
 (0)