@@ -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 };
0 commit comments