@@ -402,6 +402,83 @@ static BinaryExpr *getCompositionExpr(Expr *expr) {
402
402
return nullptr ;
403
403
}
404
404
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
+
405
482
// / Bind an UnresolvedDeclRefExpr by performing name lookup and
406
483
// / returning the resultant expression. Context is the DeclContext used
407
484
// / for the lookup.
@@ -867,83 +944,6 @@ TypeChecker::getSelfForInitDelegationInConstructor(DeclContext *DC,
867
944
return nullptr ;
868
945
}
869
946
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
-
947
947
namespace {
948
948
// / Update the function reference kind based on adding a direct call to a
949
949
// / callee with this kind.
0 commit comments