Skip to content

Commit 0aa18fb

Browse files
committed
Improve module selector @_dynamicReplacement diagnostics
1 parent 4df114e commit 0aa18fb

File tree

2 files changed

+53
-19
lines changed

2 files changed

+53
-19
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3686,6 +3686,28 @@ static void lookupReplacedDecl(DeclNameRef replacedDeclName,
36863686
results);
36873687
}
36883688

3689+
static void
3690+
diagnoseCandidatesEliminatedByModuleSelector(DeclNameRefWithLoc replacedDeclName,
3691+
DeclAttribute *attr,
3692+
const ValueDecl *replacement,
3693+
DiagnosticEngine &Diags) {
3694+
if (replacedDeclName.Name.getModuleSelector().empty())
3695+
return;
3696+
3697+
// Look up without the module selector
3698+
SmallVector<ValueDecl *, 4> results;
3699+
lookupReplacedDecl(DeclNameRef(replacedDeclName.Name.getFullName()),
3700+
attr, replacement, results);
3701+
3702+
auto selectorLoc = replacedDeclName.Loc.getModuleSelectorLoc();
3703+
3704+
for (auto candidate : results)
3705+
Diags.diagnose(selectorLoc, diag::note_change_module_selector,
3706+
candidate->getModuleContext()->getBaseIdentifier())
3707+
.fixItReplace(selectorLoc,
3708+
candidate->getModuleContext()->getBaseIdentifier().str());
3709+
}
3710+
36893711
/// Remove any argument labels from the interface type of the given value that
36903712
/// are extraneous from the type system's point of view, producing the
36913713
/// type to compare against for the purposes of dynamic replacement.
@@ -3705,14 +3727,14 @@ static Type getDynamicComparisonType(ValueDecl *value) {
37053727
return interfaceType->removeArgumentLabels(numArgumentLabels);
37063728
}
37073729

3708-
static FuncDecl *findSimilarAccessor(DeclNameRef replacedVarName,
3730+
static FuncDecl *findSimilarAccessor(DeclNameRefWithLoc replacedVarName,
37093731
const AccessorDecl *replacement,
37103732
DeclAttribute *attr, ASTContext &ctx,
37113733
bool forDynamicReplacement) {
37123734

37133735
// Retrieve the replaced abstract storage decl.
37143736
SmallVector<ValueDecl *, 4> results;
3715-
lookupReplacedDecl(replacedVarName, attr, replacement, results);
3737+
lookupReplacedDecl(replacedVarName.Name, attr, replacement, results);
37163738

37173739
// Filter out any accessors that won't work.
37183740
if (!results.empty()) {
@@ -3745,15 +3767,19 @@ static FuncDecl *findSimilarAccessor(DeclNameRef replacedVarName,
37453767
if (results.empty()) {
37463768
Diags.diagnose(attr->getLocation(),
37473769
diag::dynamic_replacement_accessor_not_found,
3748-
replacedVarName);
3770+
replacedVarName.Name);
37493771
attr->setInvalid();
3772+
3773+
diagnoseCandidatesEliminatedByModuleSelector(replacedVarName, attr,
3774+
replacement, Diags);
3775+
37503776
return nullptr;
37513777
}
37523778

37533779
if (results.size() > 1) {
37543780
Diags.diagnose(attr->getLocation(),
37553781
diag::dynamic_replacement_accessor_ambiguous,
3756-
replacedVarName);
3782+
replacedVarName.Name);
37573783
for (auto result : results) {
37583784
Diags.diagnose(result,
37593785
diag::dynamic_replacement_accessor_ambiguous_candidate,
@@ -3795,15 +3821,15 @@ static FuncDecl *findSimilarAccessor(DeclNameRef replacedVarName,
37953821
return origAccessor;
37963822
}
37973823

3798-
static FuncDecl *findReplacedAccessor(DeclNameRef replacedVarName,
3824+
static FuncDecl *findReplacedAccessor(DeclNameRefWithLoc replacedVarName,
37993825
const AccessorDecl *replacement,
38003826
DeclAttribute *attr,
38013827
ASTContext &ctx) {
38023828
return findSimilarAccessor(replacedVarName, replacement, attr, ctx,
38033829
/*forDynamicReplacement*/ true);
38043830
}
38053831

3806-
static FuncDecl *findTargetAccessor(DeclNameRef replacedVarName,
3832+
static FuncDecl *findTargetAccessor(DeclNameRefWithLoc replacedVarName,
38073833
const AccessorDecl *replacement,
38083834
DeclAttribute *attr,
38093835
ASTContext &ctx) {
@@ -3812,15 +3838,15 @@ static FuncDecl *findTargetAccessor(DeclNameRef replacedVarName,
38123838
}
38133839

38143840
static AbstractFunctionDecl *
3815-
findSimilarFunction(DeclNameRef replacedFunctionName,
3841+
findSimilarFunction(DeclNameRefWithLoc replacedFunctionName,
38163842
const AbstractFunctionDecl *base, DeclAttribute *attr,
38173843
DiagnosticEngine *Diags, bool forDynamicReplacement) {
38183844

38193845
// Note: we might pass a constant attribute when typechecker is nullptr.
38203846
// Any modification to attr must be guarded by a null check on TC.
38213847
//
38223848
SmallVector<ValueDecl *, 4> lookupResults;
3823-
lookupReplacedDecl(replacedFunctionName, attr, base, lookupResults);
3849+
lookupReplacedDecl(replacedFunctionName.Name, attr, base, lookupResults);
38243850

38253851
SmallVector<AbstractFunctionDecl *, 4> candidates;
38263852
for (auto *result : lookupResults) {
@@ -3841,7 +3867,9 @@ findSimilarFunction(DeclNameRef replacedFunctionName,
38413867
forDynamicReplacement
38423868
? diag::dynamic_replacement_function_not_found
38433869
: diag::specialize_target_function_not_found,
3844-
replacedFunctionName);
3870+
replacedFunctionName.Name);
3871+
diagnoseCandidatesEliminatedByModuleSelector(replacedFunctionName, attr,
3872+
base, *Diags);
38453873
}
38463874

38473875
attr->setInvalid();
@@ -3907,7 +3935,7 @@ findSimilarFunction(DeclNameRef replacedFunctionName,
39073935
forDynamicReplacement
39083936
? diag::dynamic_replacement_function_of_type_not_found
39093937
: diag::specialize_target_function_of_type_not_found,
3910-
replacedFunctionName,
3938+
replacedFunctionName.Name,
39113939
base->getInterfaceType()->getCanonicalType());
39123940

39133941
for (auto *result : matches) {
@@ -3923,15 +3951,15 @@ findSimilarFunction(DeclNameRef replacedFunctionName,
39233951
}
39243952

39253953
static AbstractFunctionDecl *
3926-
findReplacedFunction(DeclNameRef replacedFunctionName,
3954+
findReplacedFunction(DeclNameRefWithLoc replacedFunctionName,
39273955
const AbstractFunctionDecl *replacement,
39283956
DynamicReplacementAttr *attr, DiagnosticEngine *Diags) {
39293957
return findSimilarFunction(replacedFunctionName, replacement, attr, Diags,
39303958
true /*forDynamicReplacement*/);
39313959
}
39323960

39333961
static AbstractFunctionDecl *
3934-
findTargetFunction(DeclNameRef targetFunctionName,
3962+
findTargetFunction(DeclNameRefWithLoc targetFunctionName,
39353963
const AbstractFunctionDecl *base,
39363964
SpecializeAttr * attr, DiagnosticEngine *diags) {
39373965
return findSimilarFunction(targetFunctionName, base, attr, diags,
@@ -5589,13 +5617,15 @@ DynamicallyReplacedDeclRequest::evaluate(Evaluator &evaluator,
55895617
}
55905618

55915619
auto &Ctx = VD->getASTContext();
5620+
DeclNameRefWithLoc nameWithLoc{attr->getReplacedFunctionName(),
5621+
attr->getReplacedFunctionNameLoc(),
5622+
std::nullopt};
55925623
if (auto *AD = dyn_cast<AccessorDecl>(VD)) {
5593-
return findReplacedAccessor(attr->getReplacedFunctionName(), AD, attr, Ctx);
5624+
return findReplacedAccessor(nameWithLoc, AD, attr, Ctx);
55945625
}
55955626

55965627
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(VD)) {
5597-
return findReplacedFunction(attr->getReplacedFunctionName(), AFD,
5598-
attr, &Ctx.Diags);
5628+
return findReplacedFunction(nameWithLoc, AFD, attr, &Ctx.Diags);
55995629
}
56005630

56015631
if (auto *SD = dyn_cast<AbstractStorageDecl>(VD)) {
@@ -5618,8 +5648,10 @@ SpecializeAttrTargetDeclRequest::evaluate(Evaluator &evaluator,
56185648

56195649
auto &ctx = vd->getASTContext();
56205650

5621-
auto targetFunctionName = attr->getTargetFunctionName();
5622-
if (!targetFunctionName)
5651+
DeclNameRefWithLoc targetFunctionName{attr->getTargetFunctionName(),
5652+
attr->getTargetFunctionNameLoc(),
5653+
std::nullopt};
5654+
if (!targetFunctionName.Name)
56235655
return nullptr;
56245656

56255657
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
@@ -91,7 +91,8 @@ extension B: @retroactive main::Equatable {
9191
// @_derivative(of:)
9292

9393
@_dynamicReplacement(for: main::negate())
94-
// FIXME improve: expected-error@-1 {{replaced function 'main::negate()' could not be found}}
94+
// expected-error@-1 {{replaced function 'main::negate()' could not be found}}
95+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{29-33=ModuleSelectorTestingKit}}
9596

9697
mutating func myNegate() {
9798
let fn: (main::Int, main::Int) -> main::Int =
@@ -230,7 +231,8 @@ extension D: @retroactive Swift::Equatable {
230231
// @_derivative(of:)
231232

232233
@_dynamicReplacement(for: Swift::negate())
233-
// FIXME improve: expected-error@-1 {{replaced function 'Swift::negate()' could not be found}}
234+
// expected-error@-1 {{replaced function 'Swift::negate()' could not be found}}
235+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{29-34=ModuleSelectorTestingKit}}
234236

235237
mutating func myNegate() {
236238
// expected-note@-1 {{'myNegate()' declared here}}

0 commit comments

Comments
 (0)