@@ -4378,206 +4378,6 @@ void VarDeclUsageChecker::handleIfConfig(IfConfigDecl *ICD) {
43784378 }
43794379}
43804380
4381- namespace {
4382- class SingleValueStmtUsageChecker final : public ASTWalker {
4383- ASTContext &Ctx;
4384- DiagnosticEngine &Diags;
4385- llvm::DenseSet<SingleValueStmtExpr *> ValidSingleValueStmtExprs;
4386-
4387- public:
4388- SingleValueStmtUsageChecker (
4389- ASTContext &ctx, ASTNode root,
4390- std::optional<ContextualTypePurpose> contextualPurpose)
4391- : Ctx(ctx), Diags(ctx.Diags) {
4392- assert (!root.is <Expr *>() || contextualPurpose &&
4393- " Must provide contextual purpose for expr" );
4394-
4395- // If we have a contextual purpose, this is for an expression. Check if it's
4396- // an expression in a valid position.
4397- if (contextualPurpose) {
4398- markAnyValidTopLevelSingleValueStmt (root.get <Expr *>(),
4399- *contextualPurpose);
4400- }
4401- }
4402-
4403- private:
4404- // / Mark a given expression as a valid position for a SingleValueStmtExpr.
4405- void markValidSingleValueStmt (Expr *E) {
4406- if (!E)
4407- return ;
4408-
4409- if (auto *SVE = SingleValueStmtExpr::tryDigOutSingleValueStmtExpr (E))
4410- ValidSingleValueStmtExprs.insert (SVE);
4411- }
4412-
4413- // / Mark a valid top-level expression with a given contextual purpose.
4414- void markAnyValidTopLevelSingleValueStmt (Expr *E, ContextualTypePurpose ctp) {
4415- // Allowed in returns, throws, and bindings.
4416- switch (ctp) {
4417- case CTP_ReturnStmt:
4418- case CTP_ThrowStmt:
4419- case CTP_Initialization:
4420- markValidSingleValueStmt (E);
4421- break ;
4422- default :
4423- break ;
4424- }
4425- }
4426-
4427- MacroWalking getMacroWalkingBehavior () const override {
4428- return MacroWalking::ArgumentsAndExpansion;
4429- }
4430-
4431- AssignExpr *findAssignment (Expr *E) const {
4432- // Don't consider assignments if we have a parent expression (as otherwise
4433- // this would be effectively allowing it in an arbitrary expression
4434- // position).
4435- if (Parent.getAsExpr ())
4436- return nullptr ;
4437-
4438- // Look through optional exprs, which are present for e.g x?.y = z, as
4439- // we wrap the entire assign in the optional evaluation of the destination.
4440- if (auto *OEE = dyn_cast<OptionalEvaluationExpr>(E)) {
4441- E = OEE->getSubExpr ();
4442- while (auto *IIO = dyn_cast<InjectIntoOptionalExpr>(E))
4443- E = IIO->getSubExpr ();
4444- }
4445- return dyn_cast<AssignExpr>(E);
4446- }
4447-
4448- PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
4449- if (auto *SVE = dyn_cast<SingleValueStmtExpr>(E)) {
4450- // Diagnose a SingleValueStmtExpr in a context that we do not currently
4451- // support. If we start allowing these in arbitrary places, we'll need
4452- // to ensure that autoclosures correctly contextualize them.
4453- if (!ValidSingleValueStmtExprs.contains (SVE)) {
4454- Diags.diagnose (SVE->getLoc (), diag::single_value_stmt_out_of_place,
4455- SVE->getStmt ()->getKind ());
4456- }
4457-
4458- // Diagnose invalid SingleValueStmtExprs. This should only happen for
4459- // expressions in positions that we didn't support before
4460- // (e.g assignment or *explicit* return).
4461- auto *S = SVE->getStmt ();
4462- auto mayProduceSingleValue = S->mayProduceSingleValue (Ctx);
4463- switch (mayProduceSingleValue.getKind ()) {
4464- case IsSingleValueStmtResult::Kind::Valid:
4465- break ;
4466- case IsSingleValueStmtResult::Kind::UnterminatedBranches: {
4467- for (auto *branch : mayProduceSingleValue.getUnterminatedBranches ()) {
4468- if (auto *BS = dyn_cast<BraceStmt>(branch)) {
4469- if (BS->empty ()) {
4470- Diags.diagnose (branch->getStartLoc (),
4471- diag::single_value_stmt_branch_empty,
4472- S->getKind ());
4473- continue ;
4474- }
4475- }
4476- // TODO: The wording of this diagnostic will need tweaking if either
4477- // implicit last expressions or 'then' statements are enabled by
4478- // default.
4479- Diags.diagnose (branch->getEndLoc (),
4480- diag::single_value_stmt_branch_must_end_in_result,
4481- S->getKind (), isa<SwitchStmt>(S));
4482- }
4483- break ;
4484- }
4485- case IsSingleValueStmtResult::Kind::NonExhaustiveIf: {
4486- Diags.diagnose (S->getStartLoc (),
4487- diag::if_expr_must_be_syntactically_exhaustive);
4488- break ;
4489- }
4490- case IsSingleValueStmtResult::Kind::NonExhaustiveDoCatch: {
4491- Diags.diagnose (S->getStartLoc (),
4492- diag::do_catch_expr_must_be_syntactically_exhaustive);
4493- break ;
4494- }
4495- case IsSingleValueStmtResult::Kind::HasLabel: {
4496- // FIXME: We should offer a fix-it to remove (currently we don't track
4497- // the colon SourceLoc).
4498- auto label = cast<LabeledStmt>(S)->getLabelInfo ();
4499- Diags.diagnose (label.Loc ,
4500- diag::single_value_stmt_must_be_unlabeled, S->getKind ())
4501- .highlight (label.Loc );
4502- break ;
4503- }
4504- case IsSingleValueStmtResult::Kind::InvalidJumps: {
4505- // Diagnose each invalid jump.
4506- for (auto *jump : mayProduceSingleValue.getInvalidJumps ()) {
4507- Diags.diagnose (jump->getStartLoc (),
4508- diag::cannot_jump_in_single_value_stmt,
4509- jump->getKind (), S->getKind ())
4510- .highlight (jump->getSourceRange ());
4511- }
4512- break ;
4513- }
4514- case IsSingleValueStmtResult::Kind::NoResult:
4515- // This is fine, we will have typed the expression as Void (we verify
4516- // as such in the ASTVerifier).
4517- break ;
4518- case IsSingleValueStmtResult::Kind::CircularReference:
4519- // Already diagnosed.
4520- break ;
4521- case IsSingleValueStmtResult::Kind::UnhandledStmt:
4522- break ;
4523- }
4524- return Action::Continue (E);
4525- }
4526-
4527- // Valid as the source of an assignment.
4528- if (auto *AE = findAssignment (E))
4529- markValidSingleValueStmt (AE->getSrc ());
4530-
4531- // Valid as a single expression body of a closure. This is needed in
4532- // addition to ReturnStmt checking, as we will remove the return if the
4533- // expression is inferred to be Never.
4534- if (auto *ACE = dyn_cast<ClosureExpr>(E)) {
4535- if (ACE->hasSingleExpressionBody ())
4536- markValidSingleValueStmt (ACE->getSingleExpressionBody ());
4537- }
4538- return Action::Continue (E);
4539- }
4540-
4541- PreWalkResult<Stmt *> walkToStmtPre (Stmt *S) override {
4542- // Valid in a return/throw/then.
4543- if (auto *RS = dyn_cast<ReturnStmt>(S)) {
4544- if (RS->hasResult ())
4545- markValidSingleValueStmt (RS->getResult ());
4546- }
4547- if (auto *TS = dyn_cast<ThrowStmt>(S))
4548- markValidSingleValueStmt (TS->getSubExpr ());
4549-
4550- if (auto *TS = dyn_cast<ThenStmt>(S))
4551- markValidSingleValueStmt (TS->getResult ());
4552-
4553- return Action::Continue (S);
4554- }
4555-
4556- PreWalkAction walkToDeclPre (Decl *D) override {
4557- // Valid as an initializer of a pattern binding.
4558- if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
4559- for (auto idx : range (PBD->getNumPatternEntries ()))
4560- markValidSingleValueStmt (PBD->getInit (idx));
4561-
4562- return Action::Continue ();
4563- }
4564- // We don't want to walk into any other decl, we will visit them as part of
4565- // typeCheckDecl.
4566- return Action::SkipNode ();
4567- }
4568- };
4569- } // end anonymous namespace
4570-
4571- void swift::diagnoseOutOfPlaceExprs (
4572- ASTContext &ctx, ASTNode root,
4573- std::optional<ContextualTypePurpose> contextualPurpose) {
4574- // TODO: We ought to consider moving this into pre-checking such that we can
4575- // still diagnose on invalid code, and don't have to traverse over implicit
4576- // exprs. We need to first separate out SequenceExpr folding though.
4577- SingleValueStmtUsageChecker sveChecker (ctx, root, contextualPurpose);
4578- root.walk (sveChecker);
4579- }
4580-
45814381// / Apply the warnings managed by VarDeclUsageChecker to the top level
45824382// / code declarations that haven't been checked yet.
45834383void swift::
@@ -6426,10 +6226,9 @@ diagnoseDictionaryLiteralDuplicateKeyEntries(const Expr *E,
64266226// ===----------------------------------------------------------------------===//
64276227
64286228// / Emit diagnostics for syntactic restrictions on a given expression.
6429- void swift::performSyntacticExprDiagnostics (
6430- const Expr *E, const DeclContext *DC,
6431- std::optional<ContextualTypePurpose> contextualPurpose, bool isExprStmt,
6432- bool disableOutOfPlaceExprChecking) {
6229+ void swift::performSyntacticExprDiagnostics (const Expr *E,
6230+ const DeclContext *DC,
6231+ bool isExprStmt) {
64336232 auto &ctx = DC->getASTContext ();
64346233 TypeChecker::diagnoseSelfAssignment (E);
64356234 diagSyntacticUseRestrictions (E, DC, isExprStmt);
@@ -6448,8 +6247,6 @@ void swift::performSyntacticExprDiagnostics(
64486247 diagnoseConstantArgumentRequirement (E, DC);
64496248 diagUnqualifiedAccessToMethodNamedSelf (E, DC);
64506249 diagnoseDictionaryLiteralDuplicateKeyEntries (E, DC);
6451- if (!disableOutOfPlaceExprChecking)
6452- diagnoseOutOfPlaceExprs (ctx, const_cast <Expr *>(E), contextualPurpose);
64536250}
64546251
64556252void swift::performStmtDiagnostics (const Stmt *S, DeclContext *DC) {
0 commit comments