@@ -402,6 +402,83 @@ static BinaryExpr *getCompositionExpr(Expr *expr) {
402402 return nullptr ;
403403}
404404
405+ // / Diagnoses an unqualified `init` expression.
406+ // /
407+ // / \param initExpr The \c init expression.
408+ // / \param dc The declaration context of \p initExpr.
409+ // /
410+ // / \returns An expression matching `self.init` or `super.init` that can be used
411+ // / to recover, or `nullptr` if cannot recover.
412+ static UnresolvedDotExpr *
413+ diagnoseUnqualifiedInit (UnresolvedDeclRefExpr *initExpr, DeclContext *dc,
414+ ASTContext &ctx) {
415+ const auto loc = initExpr->getLoc ();
416+
417+ enum class Suggestion : unsigned {
418+ None = 0 ,
419+ Self = 1 ,
420+ Super = 2 ,
421+ };
422+
423+ Suggestion suggestion = [dc]() {
424+ NominalTypeDecl *nominal = nullptr ;
425+ {
426+ auto *typeDC = dc->getInnermostTypeContext ();
427+ if (!typeDC) {
428+ // No type context--no suggestion.
429+ return Suggestion::None;
430+ }
431+
432+ nominal = typeDC->getSelfNominalTypeDecl ();
433+ }
434+
435+ auto *classDecl = dyn_cast<ClassDecl>(nominal);
436+ if (!classDecl || !classDecl->hasSuperclass ()) {
437+ // No class or no superclass--suggest 'self.'.
438+ return Suggestion::Self;
439+ }
440+
441+ if (auto *initDecl = dyn_cast<ConstructorDecl>(dc)) {
442+ if (initDecl->getAttrs ().hasAttribute <ConvenienceAttr>()) {
443+ // Innermost context is a convenience initializer--suggest 'self.'.
444+ return Suggestion::Self;
445+ } else {
446+ // Innermost context is a designated initializer--suggest 'super.'.
447+ return Suggestion::Super;
448+ }
449+ }
450+
451+ // Class context but innermost context is not an initializer--suggest
452+ // 'self.'. 'super.' might be possible too, but is far lesss likely to be
453+ // the right answer.
454+ return Suggestion::Self;
455+ }();
456+
457+ auto diag =
458+ ctx.Diags .diagnose (loc, diag::unqualified_init, (unsigned )suggestion);
459+
460+ Expr *base = nullptr ;
461+ switch (suggestion) {
462+ case Suggestion::None:
463+ return nullptr ;
464+ case Suggestion::Self:
465+ diag.fixItInsert (loc, " self." );
466+ base = new (ctx)
467+ UnresolvedDeclRefExpr (DeclNameRef (ctx.Id_self ), DeclRefKind::Ordinary,
468+ initExpr->getNameLoc ());
469+ base->setImplicit (true );
470+ break ;
471+ case Suggestion::Super:
472+ diag.fixItInsert (loc, " super." );
473+ base = new (ctx) SuperRefExpr (/* Self=*/ nullptr , loc, /* Implicit=*/ true );
474+ break ;
475+ }
476+
477+ return new (ctx)
478+ UnresolvedDotExpr (base, /* dotloc=*/ SourceLoc (), initExpr->getName (),
479+ initExpr->getNameLoc (), /* implicit=*/ true );
480+ }
481+
405482// / Bind an UnresolvedDeclRefExpr by performing name lookup and
406483// / returning the resultant expression. Context is the DeclContext used
407484// / for the lookup.
@@ -867,83 +944,6 @@ TypeChecker::getSelfForInitDelegationInConstructor(DeclContext *DC,
867944 return nullptr ;
868945}
869946
870- // / Diagnoses an unqualified `init` expression.
871- // /
872- // / \param initExpr The \c init expression.
873- // / \param dc The declaration context of \p initExpr.
874- // /
875- // / \returns An expression matching `self.init` or `super.init` that can be used
876- // / to recover, or `nullptr` if cannot recover.
877- static UnresolvedDotExpr *
878- diagnoseUnqualifiedInit (UnresolvedDeclRefExpr *initExpr, DeclContext *dc,
879- ASTContext &ctx) {
880- const auto loc = initExpr->getLoc ();
881-
882- enum class Suggestion : unsigned {
883- None = 0 ,
884- Self = 1 ,
885- Super = 2 ,
886- };
887-
888- Suggestion suggestion = [dc]() {
889- NominalTypeDecl *nominal = nullptr ;
890- {
891- auto *typeDC = dc->getInnermostTypeContext ();
892- if (!typeDC) {
893- // No type context--no suggestion.
894- return Suggestion::None;
895- }
896-
897- nominal = typeDC->getSelfNominalTypeDecl ();
898- }
899-
900- auto *classDecl = dyn_cast<ClassDecl>(nominal);
901- if (!classDecl || !classDecl->hasSuperclass ()) {
902- // No class or no superclass--suggest 'self.'.
903- return Suggestion::Self;
904- }
905-
906- if (auto *initDecl = dyn_cast<ConstructorDecl>(dc)) {
907- if (initDecl->getAttrs ().hasAttribute <ConvenienceAttr>()) {
908- // Innermost context is a convenience initializer--suggest 'self.'.
909- return Suggestion::Self;
910- } else {
911- // Innermost context is a designated initializer--suggest 'super.'.
912- return Suggestion::Super;
913- }
914- }
915-
916- // Class context but innermost context is not an initializer--suggest
917- // 'self.'. 'super.' might be possible too, but is far lesss likely to be
918- // the right answer.
919- return Suggestion::Self;
920- }();
921-
922- auto diag =
923- ctx.Diags .diagnose (loc, diag::unqualified_init, (unsigned )suggestion);
924-
925- Expr *base = nullptr ;
926- switch (suggestion) {
927- case Suggestion::None:
928- return nullptr ;
929- case Suggestion::Self:
930- diag.fixItInsert (loc, " self." );
931- base = new (ctx)
932- UnresolvedDeclRefExpr (DeclNameRef (ctx.Id_self ), DeclRefKind::Ordinary,
933- initExpr->getNameLoc ());
934- base->setImplicit (true );
935- break ;
936- case Suggestion::Super:
937- diag.fixItInsert (loc, " super." );
938- base = new (ctx) SuperRefExpr (/* Self=*/ nullptr , loc, /* Implicit=*/ true );
939- break ;
940- }
941-
942- return new (ctx)
943- UnresolvedDotExpr (base, /* dotloc=*/ SourceLoc (), initExpr->getName (),
944- initExpr->getNameLoc (), /* implicit=*/ true );
945- }
946-
947947namespace {
948948 // / Update the function reference kind based on adding a direct call to a
949949 // / callee with this kind.
0 commit comments