Skip to content

Commit 04e9037

Browse files
committed
Improve diagnostics for types with incorrect module selectors
1 parent 646a317 commit 04e9037

File tree

5 files changed

+150
-34
lines changed

5 files changed

+150
-34
lines changed

include/swift/AST/Decl.h

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

2202-
/// Generates a DeclNameRef referring to this declaration with as much
2203-
/// specificity as possible.
2204-
DeclNameRef createNameRef() const {
2205-
return DeclNameRef(Name);
2206-
}
2202+
/// Generates a DeclNameRef referring to this declaration.
2203+
///
2204+
/// \param moduleSelector If true, the name ref includes the module name.
2205+
DeclNameRef createNameRef(bool moduleSelector = false) const;
22072206

22082207
/// Retrieve the name to use for this declaration when interoperating
22092208
/// with the Objective-C runtime.

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,10 @@ ERROR(cannot_find_type_in_scope,none,
903903
"cannot find type %0 in scope", (DeclNameRef))
904904
ERROR(cannot_find_type_in_scope_did_you_mean,none,
905905
"cannot find type %0 in scope; did you mean to use '%1'?", (DeclNameRef, StringRef))
906+
ERROR(type_not_in_module,none,
907+
"type %0 is not imported through module %1", (DeclName, Identifier))
908+
NOTE(note_change_module_selector,none,
909+
"did you mean module %0?", (Identifier))
906910
NOTE(note_typo_candidate_implicit_member,none,
907911
"did you mean the implicitly-synthesized %1 '%0'?", (StringRef, StringRef))
908912
NOTE(note_remapped_type,none,

lib/AST/Decl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,14 @@ SourceRange IfConfigDecl::getSourceRange() const {
18511851
return SourceRange(getLoc(), EndLoc);
18521852
}
18531853

1854+
DeclNameRef ValueDecl::createNameRef(bool moduleSelector) const {
1855+
if (moduleSelector)
1856+
return DeclNameRef(getASTContext(), getModuleContext()->getName(),
1857+
getName());
1858+
1859+
return DeclNameRef(getName());
1860+
}
1861+
18541862
static bool isPolymorphic(const AbstractStorageDecl *storage) {
18551863
if (storage->shouldUseObjCDispatch())
18561864
return true;

lib/Sema/TypeCheckType.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,33 @@ static Type diagnoseUnknownType(TypeResolution resolution,
11421142
return ErrorType::get(ctx);
11431143
}
11441144

1145+
// Is there an incorrect module selector?
1146+
if (comp->getNameRef().hasModuleSelector()) {
1147+
auto anyModuleName = DeclNameRef(comp->getNameRef().getFullName());
1148+
auto anyModuleResults =
1149+
TypeChecker::lookupUnqualifiedType(dc, anyModuleName,
1150+
comp->getLoc(), lookupOptions);
1151+
if (!anyModuleResults.empty()) {
1152+
diags.diagnose(comp->getNameLoc(), diag::type_not_in_module,
1153+
comp->getNameRef().getFullName(),
1154+
comp->getNameRef().getModuleSelector());
1155+
1156+
SourceLoc moduleSelectorLoc = comp->getNameLoc().getModuleSelectorLoc();
1157+
1158+
for (auto result : anyModuleResults) {
1159+
TypeDecl * decl = static_cast<TypeDecl*>(result.getValueDecl());
1160+
Identifier moduleName = decl->getModuleContext()->getName();
1161+
1162+
diags.diagnose(moduleSelectorLoc, diag::note_change_module_selector,
1163+
moduleName)
1164+
.fixItReplace(moduleSelectorLoc, moduleName.str());
1165+
}
1166+
1167+
// FIXME: Can we recover by assuming the first/best result is correct?
1168+
return ErrorType::get(ctx);
1169+
}
1170+
}
1171+
11451172
// Try ignoring access control.
11461173
NameLookupOptions relookupOptions = lookupOptions;
11471174
relookupOptions |= NameLookupFlags::IgnoreAccessControl;
@@ -1208,6 +1235,32 @@ static Type diagnoseUnknownType(TypeResolution resolution,
12081235
return ErrorType::get(ctx);
12091236
}
12101237

1238+
// Is there an incorrect module selector?
1239+
if (comp->getNameRef().hasModuleSelector()) {
1240+
auto anyModuleName = DeclNameRef(comp->getNameRef().getFullName());
1241+
auto anyModuleResults =
1242+
TypeChecker::lookupMemberType(dc, parentType, anyModuleName, lookupOptions);
1243+
if (anyModuleResults) {
1244+
diags.diagnose(comp->getNameLoc(), diag::type_not_in_module,
1245+
comp->getNameRef().getFullName(),
1246+
comp->getNameRef().getModuleSelector());
1247+
1248+
SourceLoc moduleSelectorLoc = comp->getNameLoc().getModuleSelectorLoc();
1249+
1250+
for (auto result : anyModuleResults) {
1251+
TypeDecl * decl = result.Member;
1252+
Identifier moduleName = decl->getModuleContext()->getName();
1253+
1254+
diags.diagnose(moduleSelectorLoc, diag::note_change_module_selector,
1255+
moduleName)
1256+
.fixItReplace(moduleSelectorLoc, moduleName.str());
1257+
}
1258+
1259+
// FIXME: Can we recover by assuming the first/best result is correct?
1260+
return ErrorType::get(ctx);
1261+
}
1262+
}
1263+
12111264
// Try ignoring access control.
12121265
NameLookupOptions relookupOptions = lookupOptions;
12131266
relookupOptions |= NameLookupFlags::IgnoreAccessControl;

test/NameLookup/module_selector.swift

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

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

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

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

3957
let magnitude: Int.main::Magnitude = main::magnitude
40-
// expected-EVENTUALLY-error@-1 {{can't find 'Int'}}
41-
// FIXME improve: expected-error@-2 {{type alias 'Magnitude' is not a member type of 'Int'}}
42-
// FIXME: expected-error@-3 {{variable used within its own initial value}}
58+
// expected-error@-1 {{type 'Magnitude' is not imported through module 'main'}}
59+
// expected-note@-2 {{did you mean module 'Swift'?}} {{24-28=Swift}}
60+
// FIXME incorrect: expected-error@-3 {{variable used within its own initial value}}
61+
4362
if main::Bool.main::random() {
63+
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'main::Bool'}}
64+
4465
main::negate()
45-
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'main::negate'}}
66+
// FIXME improve, suggest adding 'self.': expected-error@-1 {{use of unresolved identifier 'main::negate'}}
4667
}
4768
else {
4869
self = main::B(value: .main::min)
70+
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'main::B'}}
4971
}
5072

5173
self.main::myNegate()
@@ -59,30 +81,45 @@ extension B: main::Equatable {
5981
extension C {}
6082

6183
extension ModuleSelectorTestingKit::C: ModuleSelectorTestingKit::Equatable {
62-
// 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+
6387
@_implements(ModuleSelectorTestingKit::Equatable, ModuleSelectorTestingKit::==(_:_:))
64-
// FIXME improve: expected-error@-1 {{use of undeclared type 'ModuleSelectorTestingKit::Equatable'}}
65-
// expected-error@-2 {{name cannot be qualified with module selector here}} {{52-77=}}
66-
public static func equals(_: ModuleSelectorTestingKit::C, _: ModuleSelectorTestingKit::C) -> ModuleSelectorTestingKit::Bool { ModuleSelectorTestingKit::fatalError() }
67-
// 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+
}
6899

69100
// FIXME: Add tests with autodiff @_differentiable(jvp:vjp:) and
70101
// @_derivative(of:)
71102

72103
@_dynamicReplacement(for: ModuleSelectorTestingKit::negate())
73104
mutating func myNegate() {
74105
let fn: (ModuleSelectorTestingKit::Int, ModuleSelectorTestingKit::Int) -> ModuleSelectorTestingKit::Int =
75-
// FIXME improve: expected-error@-1 3{{use of undeclared type 'ModuleSelectorTestingKit::Int'}}
76-
// 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}}
77110
(ModuleSelectorTestingKit::+)
78-
// expected-error@-1 {{expected expression}}
79-
// 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+
80115
let magnitude: Int.ModuleSelectorTestingKit::Magnitude = ModuleSelectorTestingKit::magnitude
81-
// expected-EVENTUALLY-error@-1 {{something about not finding 'magnitude' because we didn't look in self}}
82-
// FIXME improve: expected-error@-2 {{type alias 'Magnitude' is not a member type of 'Int'}}
83-
// 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+
84120
if ModuleSelectorTestingKit::Bool.ModuleSelectorTestingKit::random() {
85121
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'ModuleSelectorTestingKit::Bool'}}
122+
86123
ModuleSelectorTestingKit::negate()
87124
// FIXME improve, suggest adding 'self.': expected-error@-1 {{use of unresolved identifier 'ModuleSelectorTestingKit::negate'}}
88125
}
@@ -101,13 +138,22 @@ extension ModuleSelectorTestingKit::C: ModuleSelectorTestingKit::Equatable {
101138
// FIXME: Many more of these should fail once the feature is actually implemented.
102139

103140
extension Swift::D {}
104-
// 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}}
105143

106144
extension D: Swift::Equatable {
145+
// FIXME wat: expected-error@-1 2{{implementation of 'Equatable' cannot be automatically synthesized in an extension in a different file to the type}}
146+
107147
@_implements(Swift::Equatable, Swift::==(_:_:))
108148
// expected-error@-1 {{name cannot be qualified with module selector here}} {{34-41=}}
109-
public static func equals(_: Swift::D, _: Swift::D) -> Swift::Bool { Swift::fatalError() }
110-
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+
111157
// FIXME: Add tests with autodiff @_differentiable(jvp:vjp:) and
112158
// @_derivative(of:)
113159

@@ -129,6 +175,7 @@ extension D: Swift::Equatable {
129175
}
130176
else {
131177
self = Swift::D(value: .ModuleSelectorTestingKit::min)
178+
// FIXME improve: expected-error@-1 {{use of unresolved identifier 'Swift::D'}}
132179
}
133180

134181
self.Swift::myNegate()
@@ -203,13 +250,16 @@ func main::decl1(
203250
// expected-error@-1 {{name of function declaration cannot be qualified with module selector}}
204251
main::p1: main::A,
205252
// expected-error@-1 {{argument label cannot be qualified with module selector}}
206-
// FIXME access path: expected-error@-2 {{use of undeclared type 'main::A'}}
253+
// FIXME access path: expected-error@-2 {{type 'A' is not imported through module 'main'}}
254+
// FIXME access path: expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{13-17=ModuleSelectorTestingKit}}
207255
main::label p2: main::A,
208256
// expected-error@-1 {{argument label cannot be qualified with module selector}}
209-
// FIXME access path: expected-error@-2 {{use of undeclared type 'main::A'}}
257+
// FIXME access path: expected-error@-2 {{type 'A' is not imported through module 'main'}}
258+
// FIXME access path: expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{19-23=ModuleSelectorTestingKit}}
210259
label main::p3: main::A
211260
// expected-error@-1 {{name of parameter declaration cannot be qualified with module selector}}
212-
// FIXME access path: expected-error@-2 {{use of undeclared type 'main::A'}}
261+
// FIXME access path: expected-error@-2 {{type 'A' is not imported through module 'main'}}
262+
// FIXME access path: expected-note@-3 {{did you mean module 'ModuleSelectorTestingKit'?}} {{19-23=ModuleSelectorTestingKit}}
213263
) {
214264
let main::decl1a = "a"
215265
// expected-error@-1 {{name of constant declaration cannot be qualified with module selector}}
@@ -293,7 +343,8 @@ class main::decl4<main::T> {}
293343

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

298349
protocol main::decl6 {
299350
// expected-error@-1 {{name of protocol declaration cannot be qualified with module selector}}
@@ -334,7 +385,8 @@ struct Parent {
334385

335386
typealias main::decl5 = main::Bool
336387
// expected-error@-1 {{name of typealias declaration cannot be qualified with module selector}}
337-
// FIXME improve: expected-error@-2 {{use of undeclared type 'main::Bool'}}
388+
// expected-error@-2 {{type 'Bool' is not imported through module 'main'}}
389+
// expected-note@-3 {{did you mean module 'Swift'?}} {{27-31=Swift}}
338390
}
339391

340392
@_swift_native_objc_runtime_base(main::BaseClass)

0 commit comments

Comments
 (0)