Skip to content

Commit 00d9ad7

Browse files
committed
Improve module selector @_dynamicReplacement diagnostics
1 parent 8f492c9 commit 00d9ad7

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
@@ -3809,6 +3809,28 @@ static void lookupReplacedDecl(DeclNameRef replacedDeclName,
38093809
results);
38103810
}
38113811

3812+
static void
3813+
diagnoseCandidatesEliminatedByModuleSelector(DeclNameRefWithLoc replacedDeclName,
3814+
DeclAttribute *attr,
3815+
const ValueDecl *replacement,
3816+
DiagnosticEngine &Diags) {
3817+
if (replacedDeclName.Name.getModuleSelector().empty())
3818+
return;
3819+
3820+
// Look up without the module selector
3821+
SmallVector<ValueDecl *, 4> results;
3822+
lookupReplacedDecl(DeclNameRef(replacedDeclName.Name.getFullName()),
3823+
attr, replacement, results);
3824+
3825+
auto selectorLoc = replacedDeclName.Loc.getModuleSelectorLoc();
3826+
3827+
for (auto candidate : results)
3828+
Diags.diagnose(selectorLoc, diag::note_change_module_selector,
3829+
candidate->getModuleContext()->getBaseIdentifier())
3830+
.fixItReplace(selectorLoc,
3831+
candidate->getModuleContext()->getBaseIdentifier().str());
3832+
}
3833+
38123834
/// Remove any argument labels from the interface type of the given value that
38133835
/// are extraneous from the type system's point of view, producing the
38143836
/// type to compare against for the purposes of dynamic replacement.
@@ -3828,14 +3850,14 @@ static Type getDynamicComparisonType(ValueDecl *value) {
38283850
return interfaceType->removeArgumentLabels(numArgumentLabels);
38293851
}
38303852

3831-
static FuncDecl *findSimilarAccessor(DeclNameRef replacedVarName,
3853+
static FuncDecl *findSimilarAccessor(DeclNameRefWithLoc replacedVarName,
38323854
const AccessorDecl *replacement,
38333855
DeclAttribute *attr, ASTContext &ctx,
38343856
bool forDynamicReplacement) {
38353857

38363858
// Retrieve the replaced abstract storage decl.
38373859
SmallVector<ValueDecl *, 4> results;
3838-
lookupReplacedDecl(replacedVarName, attr, replacement, results);
3860+
lookupReplacedDecl(replacedVarName.Name, attr, replacement, results);
38393861

38403862
// Filter out any accessors that won't work.
38413863
if (!results.empty()) {
@@ -3868,15 +3890,19 @@ static FuncDecl *findSimilarAccessor(DeclNameRef replacedVarName,
38683890
if (results.empty()) {
38693891
Diags.diagnose(attr->getLocation(),
38703892
diag::dynamic_replacement_accessor_not_found,
3871-
replacedVarName);
3893+
replacedVarName.Name);
38723894
attr->setInvalid();
3895+
3896+
diagnoseCandidatesEliminatedByModuleSelector(replacedVarName, attr,
3897+
replacement, Diags);
3898+
38733899
return nullptr;
38743900
}
38753901

38763902
if (results.size() > 1) {
38773903
Diags.diagnose(attr->getLocation(),
38783904
diag::dynamic_replacement_accessor_ambiguous,
3879-
replacedVarName);
3905+
replacedVarName.Name);
38803906
for (auto result : results) {
38813907
Diags.diagnose(result,
38823908
diag::dynamic_replacement_accessor_ambiguous_candidate,
@@ -3918,15 +3944,15 @@ static FuncDecl *findSimilarAccessor(DeclNameRef replacedVarName,
39183944
return origAccessor;
39193945
}
39203946

3921-
static FuncDecl *findReplacedAccessor(DeclNameRef replacedVarName,
3947+
static FuncDecl *findReplacedAccessor(DeclNameRefWithLoc replacedVarName,
39223948
const AccessorDecl *replacement,
39233949
DeclAttribute *attr,
39243950
ASTContext &ctx) {
39253951
return findSimilarAccessor(replacedVarName, replacement, attr, ctx,
39263952
/*forDynamicReplacement*/ true);
39273953
}
39283954

3929-
static FuncDecl *findTargetAccessor(DeclNameRef replacedVarName,
3955+
static FuncDecl *findTargetAccessor(DeclNameRefWithLoc replacedVarName,
39303956
const AccessorDecl *replacement,
39313957
DeclAttribute *attr,
39323958
ASTContext &ctx) {
@@ -3935,15 +3961,15 @@ static FuncDecl *findTargetAccessor(DeclNameRef replacedVarName,
39353961
}
39363962

39373963
static AbstractFunctionDecl *
3938-
findSimilarFunction(DeclNameRef replacedFunctionName,
3964+
findSimilarFunction(DeclNameRefWithLoc replacedFunctionName,
39393965
const AbstractFunctionDecl *base, DeclAttribute *attr,
39403966
DiagnosticEngine *Diags, bool forDynamicReplacement) {
39413967

39423968
// Note: we might pass a constant attribute when typechecker is nullptr.
39433969
// Any modification to attr must be guarded by a null check on TC.
39443970
//
39453971
SmallVector<ValueDecl *, 4> lookupResults;
3946-
lookupReplacedDecl(replacedFunctionName, attr, base, lookupResults);
3972+
lookupReplacedDecl(replacedFunctionName.Name, attr, base, lookupResults);
39473973

39483974
SmallVector<AbstractFunctionDecl *, 4> candidates;
39493975
for (auto *result : lookupResults) {
@@ -3964,7 +3990,9 @@ findSimilarFunction(DeclNameRef replacedFunctionName,
39643990
forDynamicReplacement
39653991
? diag::dynamic_replacement_function_not_found
39663992
: diag::specialize_target_function_not_found,
3967-
replacedFunctionName);
3993+
replacedFunctionName.Name);
3994+
diagnoseCandidatesEliminatedByModuleSelector(replacedFunctionName, attr,
3995+
base, *Diags);
39683996
}
39693997

39703998
attr->setInvalid();
@@ -4030,7 +4058,7 @@ findSimilarFunction(DeclNameRef replacedFunctionName,
40304058
forDynamicReplacement
40314059
? diag::dynamic_replacement_function_of_type_not_found
40324060
: diag::specialize_target_function_of_type_not_found,
4033-
replacedFunctionName,
4061+
replacedFunctionName.Name,
40344062
base->getInterfaceType()->getCanonicalType());
40354063

40364064
for (auto *result : matches) {
@@ -4046,15 +4074,15 @@ findSimilarFunction(DeclNameRef replacedFunctionName,
40464074
}
40474075

40484076
static AbstractFunctionDecl *
4049-
findReplacedFunction(DeclNameRef replacedFunctionName,
4077+
findReplacedFunction(DeclNameRefWithLoc replacedFunctionName,
40504078
const AbstractFunctionDecl *replacement,
40514079
DynamicReplacementAttr *attr, DiagnosticEngine *Diags) {
40524080
return findSimilarFunction(replacedFunctionName, replacement, attr, Diags,
40534081
true /*forDynamicReplacement*/);
40544082
}
40554083

40564084
static AbstractFunctionDecl *
4057-
findTargetFunction(DeclNameRef targetFunctionName,
4085+
findTargetFunction(DeclNameRefWithLoc targetFunctionName,
40584086
const AbstractFunctionDecl *base,
40594087
AbstractSpecializeAttr * attr, DiagnosticEngine *diags) {
40604088
return findSimilarFunction(targetFunctionName, base, attr, diags,
@@ -5707,13 +5735,15 @@ DynamicallyReplacedDeclRequest::evaluate(Evaluator &evaluator,
57075735
}
57085736

57095737
auto &Ctx = VD->getASTContext();
5738+
DeclNameRefWithLoc nameWithLoc{attr->getReplacedFunctionName(),
5739+
attr->getReplacedFunctionNameLoc(),
5740+
std::nullopt};
57105741
if (auto *AD = dyn_cast<AccessorDecl>(VD)) {
5711-
return findReplacedAccessor(attr->getReplacedFunctionName(), AD, attr, Ctx);
5742+
return findReplacedAccessor(nameWithLoc, AD, attr, Ctx);
57125743
}
57135744

57145745
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(VD)) {
5715-
return findReplacedFunction(attr->getReplacedFunctionName(), AFD,
5716-
attr, &Ctx.Diags);
5746+
return findReplacedFunction(nameWithLoc, AFD, attr, &Ctx.Diags);
57175747
}
57185748

57195749
if (auto *SD = dyn_cast<AbstractStorageDecl>(VD)) {
@@ -5736,8 +5766,10 @@ SpecializeAttrTargetDeclRequest::evaluate(Evaluator &evaluator,
57365766

57375767
auto &ctx = vd->getASTContext();
57385768

5739-
auto targetFunctionName = attr->getTargetFunctionName();
5740-
if (!targetFunctionName)
5769+
DeclNameRefWithLoc targetFunctionName{attr->getTargetFunctionName(),
5770+
attr->getTargetFunctionNameLoc(),
5771+
std::nullopt};
5772+
if (!targetFunctionName.Name)
57415773
return nullptr;
57425774

57435775
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
@@ -88,7 +88,8 @@ extension B: @retroactive main::Equatable {
8888
// @_derivative(of:)
8989

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

9394
mutating func myNegate() {
9495
let fn: (main::Int, main::Int) -> main::Int =
@@ -224,7 +225,8 @@ extension D: @retroactive Swift::Equatable {
224225
// @_derivative(of:)
225226

226227
@_dynamicReplacement(for: Swift::negate())
227-
// FIXME improve: expected-error@-1 {{replaced function 'Swift::negate()' could not be found}}
228+
// expected-error@-1 {{replaced function 'Swift::negate()' could not be found}}
229+
// expected-note@-2 {{did you mean module 'ModuleSelectorTestingKit'?}} {{29-34=ModuleSelectorTestingKit}}
228230

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

0 commit comments

Comments
 (0)