@@ -4664,6 +4664,60 @@ static void diagnoseComparisonWithNaN(const Expr *E, const DeclContext *DC) {
46644664 const_cast <Expr *>(E)->walk (Walker);
46654665}
46664666
4667+ static void diagUnqualifiedAccessToMethodNamedSelf (const Expr *E,
4668+ const DeclContext *DC) {
4669+ if (!E || isa<ErrorExpr>(E) || !E->getType ())
4670+ return ;
4671+
4672+ class DiagnoseWalker : public ASTWalker {
4673+ ASTContext &Ctx;
4674+ const DeclContext *DC;
4675+
4676+ public:
4677+ DiagnoseWalker (const DeclContext *DC) : Ctx(DC->getASTContext ()), DC(DC) {}
4678+
4679+ bool shouldWalkIntoSeparatelyCheckedClosure (ClosureExpr *expr) override {
4680+ return false ;
4681+ }
4682+
4683+ bool shouldWalkIntoTapExpression () override { return false ; }
4684+
4685+ std::pair<bool , Expr *> walkToExprPre (Expr *E) override {
4686+ if (!E || isa<ErrorExpr>(E) || !E->getType ())
4687+ return {false , E};
4688+
4689+ if (auto *declRefExpr = dyn_cast<DeclRefExpr>(E)) {
4690+ if (declRefExpr->getDecl ()->getBaseName () == Ctx.Id_self &&
4691+ declRefExpr->getType ()->is <AnyFunctionType>()) {
4692+ if (auto typeContext = DC->getInnermostTypeContext ()) {
4693+ // self() is not easily confusable
4694+ if (!isa<CallExpr>(Parent.getAsExpr ())) {
4695+
4696+ auto baseType = typeContext->getDeclaredInterfaceType ();
4697+ auto baseTypeString = baseType.getString ();
4698+
4699+ Ctx.Diags .diagnose (E->getLoc (), diag::self_refers_to_method,
4700+ baseTypeString);
4701+
4702+ Ctx.Diags
4703+ .diagnose (E->getLoc (),
4704+ diag::fix_unqualified_access_member_named_self,
4705+ baseTypeString)
4706+ .fixItInsert (E->getLoc (), diag::insert_type_qualification,
4707+ baseType);
4708+ }
4709+ }
4710+ }
4711+ }
4712+
4713+ return {true , E};
4714+ }
4715+ };
4716+
4717+ DiagnoseWalker Walker (DC);
4718+ const_cast <Expr *>(E)->walk (Walker);
4719+ }
4720+
46674721namespace {
46684722
46694723class CompletionHandlerUsageChecker final : public ASTWalker {
@@ -4749,6 +4803,7 @@ void swift::performSyntacticExprDiagnostics(const Expr *E,
47494803 if (ctx.LangOpts .EnableObjCInterop )
47504804 diagDeprecatedObjCSelectors (DC, E);
47514805 diagnoseConstantArgumentRequirement (E, DC);
4806+ diagUnqualifiedAccessToMethodNamedSelf (E, DC);
47524807}
47534808
47544809void swift::performStmtDiagnostics (const Stmt *S, DeclContext *DC) {
0 commit comments