Skip to content

Commit 42fdd1d

Browse files
committed
Improve module selector macro diagnostics
1 parent b65e3c9 commit 42fdd1d

File tree

5 files changed

+47
-20
lines changed

5 files changed

+47
-20
lines changed

lib/Sema/CSGen.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4148,6 +4148,16 @@ namespace {
41484148
auto macros = lookupMacros(moduleIdent, macroIdent, functionRefInfo,
41494149
expr->getMacroRoles());
41504150
if (macros.empty()) {
4151+
// Try removing a module selector if present.
4152+
if (macroIdent.hasModuleSelector()) {
4153+
auto anyMacroIdent = DeclNameRef(macroIdent.getFullName());
4154+
ModuleSelectorCorrection correction(
4155+
lookupMacros(moduleIdent, anyMacroIdent, functionRefInfo,
4156+
expr->getMacroRoles()));
4157+
if (correction.diagnose(ctx, expr->getMacroNameLoc(), macroIdent))
4158+
return Type();
4159+
}
4160+
41514161
ctx.Diags.diagnose(expr->getMacroNameLoc(), diag::macro_undefined,
41524162
macroIdent)
41534163
.highlight(expr->getMacroNameLoc().getSourceRange());

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,15 @@ ModuleSelectorCorrection(const SmallVectorImpl<ValueDecl *> &candidates) {
12001200
}
12011201
}
12021202

1203+
ModuleSelectorCorrection::
1204+
ModuleSelectorCorrection(const SmallVectorImpl<constraints::OverloadChoice> &candidates) {
1205+
for (auto result : candidates) {
1206+
auto owningModule = result.getDecl()->getModuleContext();
1207+
candidateModules.insert(
1208+
{ owningModule->getNameForModuleSelector(), CandidateKind::ContextFree });
1209+
}
1210+
}
1211+
12031212
bool ModuleSelectorCorrection::diagnose(ASTContext &ctx,
12041213
DeclNameLoc nameLoc,
12051214
DeclNameRef originalName) const {

lib/Sema/TypeCheckType.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,18 +1493,8 @@ static Type diagnoseUnknownType(const TypeResolution &resolution,
14931493

14941494
// Unqualified lookup case.
14951495
if (parentType.isNull()) {
1496-
// Tailored diagnostic for custom attributes.
1497-
if (resolution.getOptions().is(TypeResolverContext::CustomAttr)) {
1498-
SmallString<64> scratch;
1499-
llvm::raw_svector_ostream scratchOS(scratch);
1500-
repr->getNameRef().printPretty(scratchOS);
1501-
1502-
diags.diagnose(repr->getNameLoc(), diag::unknown_attr_name, scratch);
1503-
1504-
return ErrorType::get(ctx);
1505-
}
1506-
1507-
if (repr->isSimpleUnqualifiedIdentifier(ctx.Id_Self)) {
1496+
if (!resolution.getOptions().is(TypeResolverContext::CustomAttr)
1497+
&& repr->isSimpleUnqualifiedIdentifier(ctx.Id_Self)) {
15081498
DeclContext *nominalDC = nullptr;
15091499
NominalTypeDecl *nominal = nullptr;
15101500
if ((nominalDC = dc->getInnermostTypeContext()) &&
@@ -1570,6 +1560,17 @@ static Type diagnoseUnknownType(const TypeResolution &resolution,
15701560
return ErrorType::get(ctx);
15711561
}
15721562

1563+
// Tailored diagnostic for custom attributes.
1564+
if (resolution.getOptions().is(TypeResolverContext::CustomAttr)) {
1565+
SmallString<64> scratch;
1566+
llvm::raw_svector_ostream scratchOS(scratch);
1567+
repr->getNameRef().printPretty(scratchOS);
1568+
1569+
diags.diagnose(repr->getNameLoc(), diag::unknown_attr_name, scratch);
1570+
1571+
return ErrorType::get(ctx);
1572+
}
1573+
15731574
// Fallback.
15741575
auto L = repr->getNameLoc();
15751576
SourceRange R = repr->getNameLoc().getSourceRange();

lib/Sema/TypeChecker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ class ModuleSelectorCorrection {
332332
ModuleSelectorCorrection(const LookupResult &candidates);
333333
ModuleSelectorCorrection(const LookupTypeResult &candidates);
334334
ModuleSelectorCorrection(const SmallVectorImpl<ValueDecl *> &candidates);
335+
ModuleSelectorCorrection(const SmallVectorImpl<constraints::OverloadChoice> &candidates);
335336

336337
/// Emit an error and warnings if there were any candidates.
337338
///

test/NameLookup/module_selector.swift

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ extension B: @retroactive main::Equatable {
148148
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{none}}
149149

150150
_ = #main::ExprMacro
151-
// expected-error@-1 {{no macro named 'main::ExprMacro'}}
151+
// expected-error@-1 {{'ExprMacro' is not imported through module 'main'}}
152+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{10-14=ModuleSelectorTestingKit}}
152153
}
153154

154155
@main::PeerMacro func thingy() {}
@@ -307,7 +308,8 @@ extension D: @retroactive Swift::Equatable {
307308
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{none}}
308309

309310
_ = #Swift::ExprMacro
310-
// expected-error@-1 {{no macro named 'Swift::ExprMacro'}}
311+
// expected-error@-1 {{'ExprMacro' is not imported through module 'Swift'}}
312+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{10-15=ModuleSelectorTestingKit}}
311313
}
312314

313315
@Swift::PeerMacro func thingy() {}
@@ -330,25 +332,29 @@ struct AvailableUser {
330332
@available(macOS 10.15, *) var use1: String { "foo" }
331333

332334
@main::available() var use2
333-
// FIXME improve: expected-error@-1 {{unknown attribute 'main::available'}}
334-
// FIXME suppress: expected-error@-2 {{type annotation missing in pattern}}
335+
// expected-error@-1 {{'available' is not imported through module 'main'}}
336+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{4-8=ModuleSelectorTestingKit}}
337+
// FIXME suppress: expected-error@-3 {{type annotation missing in pattern}}
335338

336339
@ModuleSelectorTestingKit::available() var use4
337340
// no-error
338341

339342
@Swift::available() var use5
340-
// FIXME improve: expected-error@-1 {{unknown attribute 'Swift::available'}}
341-
// FIXME suppress: expected-error@-2 {{type annotation missing in pattern}}
343+
// expected-error@-1 {{'available' is not imported through module 'Swift'}}
344+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{4-9=ModuleSelectorTestingKit}}
345+
// FIXME suppress: expected-error@-3 {{type annotation missing in pattern}}
342346
}
343347

344348
func builderUser2(@main::MyBuilder fn: () -> Void) {}
345-
// FIXME improve: expected-error@-1 {{unknown attribute 'main::MyBuilder'}}
349+
// expected-error@-1 {{'MyBuilder' is not imported through module 'main'}}
350+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{20-24=ModuleSelectorTestingKit}}
346351

347352
func builderUser3(@ModuleSelectorTestingKit::MyBuilder fn: () -> Void) {}
348353
// no-error
349354

350355
func builderUser4(@Swift::MyBuilder fn: () -> Void) {}
351-
// FIXME improve: expected-error@-1 {{unknown attribute 'Swift::MyBuilder'}}
356+
// expected-error@-1 {{'MyBuilder' is not imported through module 'Swift'}}
357+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{20-25=ModuleSelectorTestingKit}}
352358

353359
// Error cases
354360

0 commit comments

Comments
 (0)