@@ -402,15 +402,108 @@ 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.
408485Expr *TypeChecker::resolveDeclRefExpr (UnresolvedDeclRefExpr *UDRE,
409486 DeclContext *DC) {
410- // Process UnresolvedDeclRefExpr by doing an unqualified lookup.
487+ auto &Context = DC-> getASTContext ();
411488 DeclNameRef Name = UDRE->getName ();
412489 SourceLoc Loc = UDRE->getLoc ();
413490
491+ auto errorResult = [&]() -> Expr * {
492+ return new (Context) ErrorExpr (UDRE->getSourceRange ());
493+ };
494+
495+ TypeChecker::checkForForbiddenPrefix (Context, Name.getBaseName ());
496+
497+ // Try and recover if we have an unqualified 'init'.
498+ if (Name.getBaseName ().isConstructor ()) {
499+ auto *recoveryExpr = diagnoseUnqualifiedInit (UDRE, DC, Context);
500+ if (!recoveryExpr)
501+ return errorResult ();
502+
503+ return recoveryExpr;
504+ }
505+
506+ // Process UnresolvedDeclRefExpr by doing an unqualified lookup.
414507 DeclNameRef LookupName = Name;
415508 if (Name.isCompoundName ()) {
416509 auto &context = DC->getASTContext ();
@@ -430,12 +523,6 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
430523 LookupName = DeclNameRef (lookupName);
431524 }
432525
433- auto &Context = DC->getASTContext ();
434-
435- auto errorResult = [&]() -> Expr * {
436- return new (Context) ErrorExpr (UDRE->getSourceRange ());
437- };
438-
439526 // Perform standard value name lookup.
440527 NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions;
441528 // TODO: Include all of the possible members to give a solver a
@@ -867,83 +954,6 @@ TypeChecker::getSelfForInitDelegationInConstructor(DeclContext *DC,
867954 return nullptr ;
868955}
869956
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-
947957namespace {
948958 // / Update the function reference kind based on adding a direct call to a
949959 // / callee with this kind.
@@ -1046,9 +1056,6 @@ namespace {
10461056 // / Keep track of acceptable DiscardAssignmentExpr's.
10471057 llvm::SmallPtrSet<DiscardAssignmentExpr*, 2 > CorrectDiscardAssignmentExprs;
10481058
1049- // / The current number of nested \c SequenceExprs that we're within.
1050- unsigned SequenceExprDepth = 0 ;
1051-
10521059 // / The current number of nested \c SingleValueStmtExprs that we're within.
10531060 unsigned SingleValueStmtExprDepth = 0 ;
10541061
@@ -1117,6 +1124,16 @@ namespace {
11171124 PreWalkResult<Expr *> walkToExprPre (Expr *expr) override {
11181125 auto &diags = Ctx.Diags ;
11191126
1127+ // Fold sequence expressions.
1128+ if (auto *seqExpr = dyn_cast<SequenceExpr>(expr)) {
1129+ auto result = TypeChecker::foldSequence (seqExpr, DC);
1130+ result = result->walk (*this );
1131+ if (!result)
1132+ return Action::Stop ();
1133+ // Already walked.
1134+ return Action::SkipNode (result);
1135+ }
1136+
11201137 // FIXME(diagnostics): `InOutType` could appear here as a result
11211138 // of successful re-typecheck of the one of the sub-expressions e.g.
11221139 // `let _: Int = { (s: inout S) in s.bar() }`. On the first
@@ -1148,11 +1165,9 @@ namespace {
11481165 return Action::Stop ();
11491166
11501167 // If we're going to recurse, record this expression on the stack.
1151- if (recursive) {
1152- if (isa<SequenceExpr>(expr))
1153- SequenceExprDepth++;
1168+ if (recursive)
11541169 ExprStack.push_back (expr);
1155- }
1170+
11561171 return Action::VisitNodeIf (recursive, expr);
11571172 };
11581173
@@ -1208,38 +1223,8 @@ namespace {
12081223 return finish (true , expr);
12091224 }
12101225
1211- if (auto unresolved = dyn_cast<UnresolvedDeclRefExpr>(expr)) {
1212- TypeChecker::checkForForbiddenPrefix (
1213- getASTContext (), unresolved->getName ().getBaseName ());
1214-
1215- if (unresolved->getName ().getBaseName ().isConstructor ()) {
1216- if (auto *recoveryExpr =
1217- diagnoseUnqualifiedInit (unresolved, DC, Ctx)) {
1218- return finish (true , recoveryExpr);
1219- }
1220-
1221- return finish (false ,
1222- new (Ctx) ErrorExpr (unresolved->getSourceRange ()));
1223- }
1224-
1225- auto *refExpr = TypeChecker::resolveDeclRefExpr (unresolved, DC);
1226-
1227- // Check whether this is standalone `self` in init accessor, which
1228- // is invalid.
1229- if (auto *accessor = DC->getInnermostPropertyAccessorContext ()) {
1230- if (accessor->isInitAccessor () && isa<DeclRefExpr>(refExpr)) {
1231- auto *DRE = cast<DeclRefExpr>(refExpr);
1232- if (accessor->getImplicitSelfDecl () == DRE->getDecl () &&
1233- !isa_and_nonnull<UnresolvedDotExpr>(Parent.getAsExpr ())) {
1234- diags.diagnose (unresolved->getLoc (),
1235- diag::invalid_use_of_self_in_init_accessor);
1236- refExpr = new (Ctx) ErrorExpr (unresolved->getSourceRange ());
1237- }
1238- }
1239- }
1240-
1241- return finish (true , refExpr);
1242- }
1226+ if (auto *unresolved = dyn_cast<UnresolvedDeclRefExpr>(expr))
1227+ return finish (true , TypeChecker::resolveDeclRefExpr (unresolved, DC));
12431228
12441229 // Let's try to figure out if `InOutExpr` is out of place early
12451230 // otherwise there is a risk of producing solutions which can't
@@ -1312,23 +1297,26 @@ namespace {
13121297 assert (ExprStack.back () == expr);
13131298 ExprStack.pop_back ();
13141299
1315- // Fold sequence expressions.
1316- if (auto *seqExpr = dyn_cast<SequenceExpr>(expr)) {
1317- auto result = TypeChecker::foldSequence (seqExpr, DC);
1318- SequenceExprDepth--;
1319- result = result->walk (*this );
1320- if (!result)
1321- return Action::Stop ();
1322-
1323- return Action::Continue (result);
1324- }
1325-
13261300 // Type check the type parameters in an UnresolvedSpecializeExpr.
13271301 if (auto *us = dyn_cast<UnresolvedSpecializeExpr>(expr)) {
13281302 if (auto *typeExpr = simplifyUnresolvedSpecializeExpr (us))
13291303 return Action::Continue (typeExpr);
13301304 }
1331-
1305+
1306+ // Check whether this is standalone `self` in init accessor, which
1307+ // is invalid.
1308+ if (auto *DRE = dyn_cast<DeclRefExpr>(expr)) {
1309+ if (auto *accessor = DC->getInnermostPropertyAccessorContext ()) {
1310+ if (accessor->isInitAccessor () &&
1311+ accessor->getImplicitSelfDecl () == DRE->getDecl () &&
1312+ !isa_and_nonnull<UnresolvedDotExpr>(Parent.getAsExpr ())) {
1313+ Ctx.Diags .diagnose (DRE->getLoc (),
1314+ diag::invalid_use_of_self_in_init_accessor);
1315+ return Action::Continue (new (Ctx) ErrorExpr (DRE->getSourceRange ()));
1316+ }
1317+ }
1318+ }
1319+
13321320 // If we're about to step out of a ClosureExpr, restore the DeclContext.
13331321 if (auto *ce = dyn_cast<ClosureExpr>(expr)) {
13341322 assert (DC == ce && " DeclContext imbalance" );
@@ -1432,12 +1420,9 @@ namespace {
14321420 return Action::Continue (simplified);
14331421
14341422 // Diagnose a '_' that isn't on the immediate LHS of an assignment. We
1435- // skip diagnostics if we've explicitly marked the expression as valid,
1436- // or if we're inside a SequenceExpr (since the whole tree will be
1437- // re-checked when we finish folding anyway).
1423+ // skip diagnostics if we've explicitly marked the expression as valid.
14381424 if (auto *DAE = dyn_cast<DiscardAssignmentExpr>(expr)) {
1439- if (!CorrectDiscardAssignmentExprs.count (DAE) &&
1440- SequenceExprDepth == 0 ) {
1425+ if (!CorrectDiscardAssignmentExprs.count (DAE)) {
14411426 ctx.Diags .diagnose (expr->getLoc (),
14421427 diag::discard_expr_outside_of_assignment);
14431428 return Action::Stop ();
@@ -1694,7 +1679,7 @@ bool PreCheckExpression::possiblyInTypeContext(Expr *E) {
16941679// / been explicitly marked as correct, and the current AST state allows it.
16951680bool PreCheckExpression::canSimplifyDiscardAssignmentExpr (
16961681 DiscardAssignmentExpr *DAE) {
1697- return !CorrectDiscardAssignmentExprs.count (DAE) && SequenceExprDepth == 0 &&
1682+ return !CorrectDiscardAssignmentExprs.count (DAE) &&
16981683 possiblyInTypeContext (DAE);
16991684}
17001685
0 commit comments