Skip to content

Commit 6918fbb

Browse files
authored
Merge pull request #41969 from xedin/rdar-90624344
[MiscDiagnostics] Produce warnings about confusable `self` iff its ex…
2 parents 13c71c6 + e52c3a0 commit 6918fbb

File tree

2 files changed

+40
-23
lines changed

2 files changed

+40
-23
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4742,31 +4742,43 @@ static void diagUnqualifiedAccessToMethodNamedSelf(const Expr *E,
47424742
if (!E || isa<ErrorExpr>(E) || !E->getType())
47434743
return {false, E};
47444744

4745-
if (auto *declRefExpr = dyn_cast<DeclRefExpr>(E)) {
4746-
if (declRefExpr->getDecl()->getBaseName() == Ctx.Id_self &&
4747-
declRefExpr->getType()->is<AnyFunctionType>()) {
4748-
if (auto typeContext = DC->getInnermostTypeContext()) {
4749-
// self() is not easily confusable
4750-
if (!isa<CallExpr>(Parent.getAsExpr())) {
4751-
auto baseType = typeContext->getDeclaredInterfaceType();
4752-
if (!baseType->getEnumOrBoundGenericEnum()) {
4753-
auto baseTypeString = baseType.getString();
4754-
4755-
Ctx.Diags.diagnose(E->getLoc(), diag::self_refers_to_method,
4756-
baseTypeString);
4757-
4758-
Ctx.Diags
4759-
.diagnose(E->getLoc(),
4760-
diag::fix_unqualified_access_member_named_self,
4761-
baseTypeString)
4762-
.fixItInsert(E->getLoc(), diag::insert_type_qualification,
4763-
baseType);
4764-
}
4765-
}
4766-
}
4767-
}
4745+
auto *DRE = dyn_cast<DeclRefExpr>(E);
4746+
// If this is not an explicit 'self' reference, let's keep searching.
4747+
if (!DRE || DRE->isImplicit())
4748+
return {true, E};
4749+
4750+
// If this not 'self' or it's not a function reference, it's unrelated.
4751+
if (!(DRE->getDecl()->getBaseName() == Ctx.Id_self &&
4752+
DRE->getType()->is<AnyFunctionType>()))
4753+
return {true, E};
4754+
4755+
auto typeContext = DC->getInnermostTypeContext();
4756+
// Use of 'self' in enums is not confusable.
4757+
if (!typeContext || typeContext->getSelfEnumDecl())
4758+
return {true, E};
4759+
4760+
// self(...) is not easily confusable.
4761+
if (auto *parentExpr = Parent.getAsExpr()) {
4762+
if (isa<CallExpr>(parentExpr))
4763+
return {true, E};
4764+
4765+
// Explicit call to a static method 'self' of some type is not
4766+
// confusable.
4767+
if (isa<DotSyntaxCallExpr>(parentExpr) && !parentExpr->isImplicit())
4768+
return {true, E};
47684769
}
47694770

4771+
auto baseType = typeContext->getDeclaredInterfaceType();
4772+
auto baseTypeString = baseType.getString();
4773+
4774+
Ctx.Diags.diagnose(E->getLoc(), diag::self_refers_to_method,
4775+
baseTypeString);
4776+
4777+
Ctx.Diags
4778+
.diagnose(E->getLoc(), diag::fix_unqualified_access_member_named_self,
4779+
baseTypeString)
4780+
.fixItInsert(E->getLoc(), diag::insert_type_qualification, baseType);
4781+
47704782
return {true, E};
47714783
}
47724784
};

test/Parse/self_rebinding.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,8 @@ enum EnumCaseNamedSelf {
126126
self = EnumCaseNamedSelf.`self` // OK
127127
}
128128
}
129+
130+
// rdar://90624344 - warning about `self` which cannot be fixed because it's located in implicitly generated code.
131+
struct TestImplicitSelfUse : Codable {
132+
let `self`: Int // Ok
133+
}

0 commit comments

Comments
 (0)