Skip to content

Commit 4a15f76

Browse files
committed
Module selector fix-its in @_dynamicReplacement
1 parent 87285e0 commit 4a15f76

File tree

2 files changed

+52
-19
lines changed

2 files changed

+52
-19
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,6 +2405,28 @@ static void lookupReplacedDecl(DeclNameRef replacedDeclName,
24052405
results);
24062406
}
24072407

2408+
static void
2409+
diagnoseCandidatesEliminatedByModuleSelector(DeclNameRefWithLoc replacedDeclName,
2410+
DeclAttribute *attr,
2411+
const ValueDecl *replacement,
2412+
DiagnosticEngine &Diags) {
2413+
if (replacedDeclName.Name.getModuleSelector().empty())
2414+
return;
2415+
2416+
// Look up without the module selector
2417+
SmallVector<ValueDecl *, 4> results;
2418+
lookupReplacedDecl(DeclNameRef(replacedDeclName.Name.getFullName()),
2419+
attr, replacement, results);
2420+
2421+
auto selectorLoc = replacedDeclName.Loc.getModuleSelectorLoc();
2422+
2423+
for (auto candidate : results)
2424+
Diags.diagnose(selectorLoc, diag::note_change_module_selector,
2425+
candidate->getModuleContext()->getBaseIdentifier())
2426+
.fixItReplace(selectorLoc,
2427+
candidate->getModuleContext()->getBaseIdentifier().str());
2428+
}
2429+
24082430
/// Remove any argument labels from the interface type of the given value that
24092431
/// are extraneous from the type system's point of view, producing the
24102432
/// type to compare against for the purposes of dynamic replacement.
@@ -2424,14 +2446,14 @@ static Type getDynamicComparisonType(ValueDecl *value) {
24242446
return interfaceType->removeArgumentLabels(numArgumentLabels);
24252447
}
24262448

2427-
static FuncDecl *findSimilarAccessor(DeclNameRef replacedVarName,
2449+
static FuncDecl *findSimilarAccessor(DeclNameRefWithLoc replacedVarName,
24282450
const AccessorDecl *replacement,
24292451
DeclAttribute *attr, ASTContext &ctx,
24302452
bool forDynamicReplacement) {
24312453

24322454
// Retrieve the replaced abstract storage decl.
24332455
SmallVector<ValueDecl *, 4> results;
2434-
lookupReplacedDecl(replacedVarName, attr, replacement, results);
2456+
lookupReplacedDecl(replacedVarName.Name, attr, replacement, results);
24352457

24362458
// Filter out any accessors that won't work.
24372459
if (!results.empty()) {
@@ -2464,15 +2486,19 @@ static FuncDecl *findSimilarAccessor(DeclNameRef replacedVarName,
24642486
if (results.empty()) {
24652487
Diags.diagnose(attr->getLocation(),
24662488
diag::dynamic_replacement_accessor_not_found,
2467-
replacedVarName);
2489+
replacedVarName.Name);
24682490
attr->setInvalid();
2491+
2492+
diagnoseCandidatesEliminatedByModuleSelector(replacedVarName, attr,
2493+
replacement, Diags);
2494+
24692495
return nullptr;
24702496
}
24712497

24722498
if (results.size() > 1) {
24732499
Diags.diagnose(attr->getLocation(),
24742500
diag::dynamic_replacement_accessor_ambiguous,
2475-
replacedVarName);
2501+
replacedVarName.Name);
24762502
for (auto result : results) {
24772503
Diags.diagnose(result,
24782504
diag::dynamic_replacement_accessor_ambiguous_candidate,
@@ -2513,15 +2539,15 @@ static FuncDecl *findSimilarAccessor(DeclNameRef replacedVarName,
25132539
return origAccessor;
25142540
}
25152541

2516-
static FuncDecl *findReplacedAccessor(DeclNameRef replacedVarName,
2542+
static FuncDecl *findReplacedAccessor(DeclNameRefWithLoc replacedVarName,
25172543
const AccessorDecl *replacement,
25182544
DeclAttribute *attr,
25192545
ASTContext &ctx) {
25202546
return findSimilarAccessor(replacedVarName, replacement, attr, ctx,
25212547
/*forDynamicReplacement*/ true);
25222548
}
25232549

2524-
static FuncDecl *findTargetAccessor(DeclNameRef replacedVarName,
2550+
static FuncDecl *findTargetAccessor(DeclNameRefWithLoc replacedVarName,
25252551
const AccessorDecl *replacement,
25262552
DeclAttribute *attr,
25272553
ASTContext &ctx) {
@@ -2530,15 +2556,15 @@ static FuncDecl *findTargetAccessor(DeclNameRef replacedVarName,
25302556
}
25312557

25322558
static AbstractFunctionDecl *
2533-
findSimilarFunction(DeclNameRef replacedFunctionName,
2559+
findSimilarFunction(DeclNameRefWithLoc replacedFunctionName,
25342560
const AbstractFunctionDecl *base, DeclAttribute *attr,
25352561
DiagnosticEngine *Diags, bool forDynamicReplacement) {
25362562

25372563
// Note: we might pass a constant attribute when typechecker is nullptr.
25382564
// Any modification to attr must be guarded by a null check on TC.
25392565
//
25402566
SmallVector<ValueDecl *, 4> results;
2541-
lookupReplacedDecl(replacedFunctionName, attr, base, results);
2567+
lookupReplacedDecl(replacedFunctionName.Name, attr, base, results);
25422568

25432569
for (auto *result : results) {
25442570
// Protocol requirements are not replaceable.
@@ -2574,13 +2600,16 @@ findSimilarFunction(DeclNameRef replacedFunctionName,
25742600
forDynamicReplacement
25752601
? diag::dynamic_replacement_function_not_found
25762602
: diag::specialize_target_function_not_found,
2577-
replacedFunctionName);
2603+
replacedFunctionName.Name);
2604+
2605+
diagnoseCandidatesEliminatedByModuleSelector(replacedFunctionName, attr,
2606+
base, *Diags);
25782607
} else {
25792608
Diags->diagnose(attr->getLocation(),
25802609
forDynamicReplacement
25812610
? diag::dynamic_replacement_function_of_type_not_found
25822611
: diag::specialize_target_function_of_type_not_found,
2583-
replacedFunctionName,
2612+
replacedFunctionName.Name,
25842613
base->getInterfaceType()->getCanonicalType());
25852614

25862615
for (auto *result : results) {
@@ -2597,15 +2626,15 @@ findSimilarFunction(DeclNameRef replacedFunctionName,
25972626
}
25982627

25992628
static AbstractFunctionDecl *
2600-
findReplacedFunction(DeclNameRef replacedFunctionName,
2629+
findReplacedFunction(DeclNameRefWithLoc replacedFunctionName,
26012630
const AbstractFunctionDecl *replacement,
26022631
DynamicReplacementAttr *attr, DiagnosticEngine *Diags) {
26032632
return findSimilarFunction(replacedFunctionName, replacement, attr, Diags,
26042633
true /*forDynamicReplacement*/);
26052634
}
26062635

26072636
static AbstractFunctionDecl *
2608-
findTargetFunction(DeclNameRef targetFunctionName,
2637+
findTargetFunction(DeclNameRefWithLoc targetFunctionName,
26092638
const AbstractFunctionDecl *base,
26102639
SpecializeAttr * attr, DiagnosticEngine *diags) {
26112640
return findSimilarFunction(targetFunctionName, base, attr, diags,
@@ -3507,13 +3536,14 @@ DynamicallyReplacedDeclRequest::evaluate(Evaluator &evaluator,
35073536
}
35083537

35093538
auto &Ctx = VD->getASTContext();
3539+
DeclNameRefWithLoc nameWithLoc{attr->getReplacedFunctionName(),
3540+
attr->getReplacedFunctionNameLoc(), None};
35103541
if (auto *AD = dyn_cast<AccessorDecl>(VD)) {
3511-
return findReplacedAccessor(attr->getReplacedFunctionName(), AD, attr, Ctx);
3542+
return findReplacedAccessor(nameWithLoc, AD, attr, Ctx);
35123543
}
35133544

35143545
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(VD)) {
3515-
return findReplacedFunction(attr->getReplacedFunctionName(), AFD,
3516-
attr, &Ctx.Diags);
3546+
return findReplacedFunction(nameWithLoc, AFD, attr, &Ctx.Diags);
35173547
}
35183548

35193549
if (auto *SD = dyn_cast<AbstractStorageDecl>(VD)) {
@@ -3536,8 +3566,9 @@ SpecializeAttrTargetDeclRequest::evaluate(Evaluator &evaluator,
35363566

35373567
auto &ctx = vd->getASTContext();
35383568

3539-
auto targetFunctionName = attr->getTargetFunctionName();
3540-
if (!targetFunctionName)
3569+
DeclNameRefWithLoc targetFunctionName{attr->getTargetFunctionName(),
3570+
attr->getTargetFunctionNameLoc(), None};
3571+
if (!targetFunctionName.Name)
35413572
return nullptr;
35423573

35433574
if (auto *ad = dyn_cast<AccessorDecl>(vd)) {

test/NameLookup/module_selector.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ extension B: main::Equatable {
8484
// @_derivative(of:)
8585

8686
@_dynamicReplacement(for: main::negate())
87-
// FIXME improve: expected-error@-1 {{replaced function 'main::negate()' could not be found}}
87+
// FIXME shouldn't this succeed?: expected-error@-1 {{replaced function 'main::negate()' could not be found}}
88+
// FIXME: expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{29-33=ModuleSelectorTestingKit}}
8889
mutating func myNegate() {
8990
let fn: (main::Int, main::Int) -> main::Int =
9091
// expected-error@-1 3{{type 'Int' is not imported through module 'main'}}
@@ -206,7 +207,8 @@ extension D: Swift::Equatable {
206207
// @_derivative(of:)
207208

208209
@_dynamicReplacement(for: Swift::negate())
209-
// FIXME improve: expected-error@-1 {{replaced function 'Swift::negate()' could not be found}}
210+
// expected-error@-1 {{replaced function 'Swift::negate()' could not be found}}
211+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{29-34=ModuleSelectorTestingKit}}
210212
mutating func myNegate() {
211213
// FIXME improve: expected-note@-1 {{did you mean 'myNegate'?}}
212214

0 commit comments

Comments
 (0)