From: Pierre-Emmanuel Patry Date: Tue, 1 Apr 2025 13:57:47 +0000 (+0200) Subject: Make loop label truly optional X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f77aeb99dde12544ea7c29004e88d46a8d5aa7b2;p=thirdparty%2Fgcc.git Make loop label truly optional A loop label error state was in use to represent missing loop label but this may be easily forgotten and the optional nature of the label was misrepresented. gcc/rust/ChangeLog: * ast/rust-ast-builder.cc (Builder::block): Call with a nullopt instead of an error loop label. (WhileLetLoopExpr::as_string): Use getter function and adapt to newtype. * ast/rust-ast.cc (WhileLoopExpr::as_string): Likewise. (LoopExpr::as_string): Likewise. (BreakExpr::as_string): Likewise. (ForLoopExpr::as_string): Likewise. * ast/rust-expr.h (class BlockExpr): Make loop label optional. (class BreakExpr): Likewise. * expand/rust-derive-clone.cc (DeriveClone::clone_fn): Use nullopt. * expand/rust-derive-debug.cc (DeriveDebug::stub_debug_fn): Likewise. * expand/rust-derive-default.cc (DeriveDefault::default_fn): Likewise. * expand/rust-derive-eq.cc: Likewise. * parse/rust-parse-impl.h (Parser::parse_block_expr): Use optional for arguments. (Parser::parse_loop_expr): Likewise. (Parser::parse_while_loop_expr): Likewise. (Parser::parse_while_let_loop_expr): Likewise. (Parser::parse_for_loop_expr): Likewise. (Parser::parse_labelled_loop_expr): Likewise. (Parser::parse_loop_label): Return an optional. * parse/rust-parse.h: Update function prototype and use nullopt for default values. Signed-off-by: Pierre-Emmanuel Patry --- diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index 2e3685f2b19..437ba1b56ea 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -335,9 +335,9 @@ std::unique_ptr Builder::block (std::vector> &&stmts, std::unique_ptr &&tail_expr) const { - return std::unique_ptr ( - new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {}, - LoopLabel::error (), loc, loc)); + return std::unique_ptr (new BlockExpr (std::move (stmts), + std::move (tail_expr), {}, + {}, tl::nullopt, loc, loc)); } std::unique_ptr diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 43f1ee2f526..2d286cdf3d7 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -2095,7 +2095,7 @@ WhileLoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else - str += loop_label.as_string (); + str += get_loop_label ().as_string (); str += "\n Conditional expr: " + condition->as_string (); @@ -2115,7 +2115,7 @@ WhileLetLoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else - str += loop_label.as_string (); + str += get_loop_label ().as_string (); str += "\n Match arm patterns: "; if (match_arm_patterns.empty ()) @@ -2146,7 +2146,7 @@ LoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else - str += loop_label.as_string (); + str += get_loop_label ().as_string (); str += "\n Loop block: " + loop_block->as_string (); @@ -2183,7 +2183,7 @@ BreakExpr::as_string () const std::string str ("break "); if (has_label ()) - str += label.as_string () + " "; + str += get_label ().as_string () + " "; if (has_break_expr ()) str += break_expr->as_string (); @@ -2545,7 +2545,7 @@ ForLoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else - str += loop_label.as_string (); + str += get_loop_label ().as_string (); str += "\n Pattern: " + pattern->as_string (); diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index cff09fe17d7..3ce78c643c7 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -2590,7 +2590,7 @@ class BlockExpr : public ExprWithBlock std::vector inner_attrs; std::vector > statements; std::unique_ptr expr; - LoopLabel label; + tl::optional label; location_t start_locus; location_t end_locus; bool marked_for_strip = false; @@ -2607,8 +2607,9 @@ public: BlockExpr (std::vector > block_statements, std::unique_ptr block_expr, std::vector inner_attribs, - std::vector outer_attribs, LoopLabel label, - location_t start_locus, location_t end_locus) + std::vector outer_attribs, + tl::optional label, location_t start_locus, + location_t end_locus) : outer_attrs (std::move (outer_attribs)), inner_attrs (std::move (inner_attribs)), statements (std::move (block_statements)), expr (std::move (block_expr)), @@ -2727,8 +2728,8 @@ public: outer_attrs = std::move (new_attrs); } - bool has_label () { return !label.is_error (); } - LoopLabel &get_label () { return label; } + bool has_label () { return label.has_value (); } + LoopLabel &get_label () { return label.value (); } Expr::Kind get_expr_kind () const override { return Expr::Kind::Block; } @@ -2901,7 +2902,7 @@ protected: class BreakExpr : public ExprWithoutBlock { std::vector outer_attrs; - LoopLabel label; + tl::optional label; std::unique_ptr break_expr; location_t locus; @@ -2912,7 +2913,7 @@ public: std::string as_string () const override; // Returns whether the break expression has a label or not. - bool has_label () const { return !label.is_error (); } + bool has_label () const { return label.has_value (); } /* Returns whether the break expression has an expression used in the break or * not. */ @@ -2981,7 +2982,8 @@ public: outer_attrs = std::move (new_attrs); } - LoopLabel &get_label () { return label; } + LoopLabel &get_label () { return label.value (); } + const LoopLabel &get_label () const { return label.value (); } Expr::Kind get_expr_kind () const override { return Expr::Kind::Break; } @@ -3657,7 +3659,7 @@ class BaseLoopExpr : public ExprWithBlock protected: // protected to allow subclasses better use of them std::vector outer_attrs; - LoopLabel loop_label; + tl::optional loop_label; std::unique_ptr loop_block; private: @@ -3666,7 +3668,7 @@ private: protected: // Constructor for BaseLoopExpr BaseLoopExpr (std::unique_ptr loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional loop_label = tl::nullopt, std::vector outer_attribs = std::vector ()) : outer_attrs (std::move (outer_attribs)), @@ -3706,9 +3708,10 @@ protected: BaseLoopExpr &operator= (BaseLoopExpr &&other) = default; public: - bool has_loop_label () const { return !loop_label.is_error (); } + bool has_loop_label () const { return loop_label.has_value (); } - LoopLabel &get_loop_label () { return loop_label; } + LoopLabel &get_loop_label () { return loop_label.value (); } + const LoopLabel &get_loop_label () const { return loop_label.value (); } location_t get_locus () const override final { return locus; } @@ -3752,7 +3755,7 @@ public: // Constructor for LoopExpr LoopExpr (std::unique_ptr loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional loop_label = tl::nullopt, std::vector outer_attribs = std::vector ()) : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label), std::move (outer_attribs)) @@ -3785,7 +3788,7 @@ public: // Constructor for while loop with loop label WhileLoopExpr (std::unique_ptr loop_condition, std::unique_ptr loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional loop_label = tl::nullopt, std::vector outer_attribs = std::vector ()) : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label), @@ -3851,7 +3854,7 @@ public: WhileLetLoopExpr (std::vector > match_arm_patterns, std::unique_ptr scrutinee, std::unique_ptr loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional loop_label = tl::nullopt, std::vector outer_attribs = std::vector ()) : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label), @@ -3938,7 +3941,7 @@ public: ForLoopExpr (std::unique_ptr loop_pattern, std::unique_ptr iterator_expr, std::unique_ptr loop_body, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional loop_label = tl::nullopt, std::vector outer_attribs = std::vector ()) : BaseLoopExpr (std::move (loop_body), locus, std::move (loop_label), std::move (outer_attribs)), diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc index 00abb593c17..d8f79d00106 100644 --- a/gcc/rust/expand/rust-derive-clone.cc +++ b/gcc/rust/expand/rust-derive-clone.cc @@ -61,8 +61,7 @@ std::unique_ptr DeriveClone::clone_fn (std::unique_ptr &&clone_expr) { auto block = std::unique_ptr ( - new BlockExpr ({}, std::move (clone_expr), {}, {}, AST::LoopLabel::error (), - loc, loc)); + new BlockExpr ({}, std::move (clone_expr), {}, {}, tl::nullopt, loc, loc)); auto big_self_type = builder.single_type_path ("Self"); std::unique_ptr self (new SelfParam (Lifetime::error (), diff --git a/gcc/rust/expand/rust-derive-debug.cc b/gcc/rust/expand/rust-derive-debug.cc index 7ad3908483a..a0bf9d86972 100644 --- a/gcc/rust/expand/rust-derive-debug.cc +++ b/gcc/rust/expand/rust-derive-debug.cc @@ -50,8 +50,7 @@ DeriveDebug::stub_debug_fn () // we can't use builder.block() here as it returns a unique_ptr and // Function's constructor expects a unique_ptr auto block = std::unique_ptr ( - new BlockExpr ({}, std::move (stub_return), {}, {}, - AST::LoopLabel::error (), loc, loc)); + new BlockExpr ({}, std::move (stub_return), {}, {}, tl::nullopt, loc, loc)); auto self = builder.self_ref_param (); diff --git a/gcc/rust/expand/rust-derive-default.cc b/gcc/rust/expand/rust-derive-default.cc index c54f8c318dd..2e8b4568199 100644 --- a/gcc/rust/expand/rust-derive-default.cc +++ b/gcc/rust/expand/rust-derive-default.cc @@ -58,8 +58,7 @@ DeriveDefault::default_fn (std::unique_ptr &&return_expr) = std::unique_ptr (new TypePath (builder.type_path ("Self"))); auto block = std::unique_ptr ( - new BlockExpr ({}, std::move (return_expr), {}, {}, - AST::LoopLabel::error (), loc, loc)); + new BlockExpr ({}, std::move (return_expr), {}, {}, tl::nullopt, loc, loc)); return builder.function ("default", {}, std::move (self_ty), std::move (block)); diff --git a/gcc/rust/expand/rust-derive-eq.cc b/gcc/rust/expand/rust-derive-eq.cc index dc173defd67..5e7a8946dfd 100644 --- a/gcc/rust/expand/rust-derive-eq.cc +++ b/gcc/rust/expand/rust-derive-eq.cc @@ -49,8 +49,7 @@ DeriveEq::assert_receiver_is_total_eq_fn ( stmts.emplace_back (assert_type_is_eq (std::move (type))); auto block = std::unique_ptr ( - new BlockExpr (std::move (stmts), nullptr, {}, {}, AST::LoopLabel::error (), - loc, loc)); + new BlockExpr (std::move (stmts), nullptr, {}, {}, tl::nullopt, loc, loc)); auto self = builder.self_ref_param (); diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index bd501132914..e2a3440efa9 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -7153,9 +7153,9 @@ Parser::parse_expr_stmt (AST::AttrVec outer_attrs, // Parses a block expression, including the curly braces at start and end. template std::unique_ptr -Parser::parse_block_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label, - location_t pratt_parsed_loc) +Parser::parse_block_expr ( + AST::AttrVec outer_attrs, tl::optional label, + location_t pratt_parsed_loc) { location_t locus = pratt_parsed_loc; if (locus == UNKNOWN_LOCATION) @@ -7563,14 +7563,14 @@ Parser::parse_continue_expr (AST::AttrVec outer_attrs, // Parses a loop label used in loop expressions. template -AST::LoopLabel +tl::optional Parser::parse_loop_label (const_TokenPtr tok) { // parse lifetime - if doesn't exist, assume no label if (tok->get_id () != LIFETIME) { // not necessarily an error - return AST::LoopLabel::error (); + return tl::nullopt; } /* FIXME: check for named lifetime requirement here? or check in semantic * analysis phase? */ @@ -7579,10 +7579,11 @@ Parser::parse_loop_label (const_TokenPtr tok) if (!skip_token (COLON)) { // skip somewhere? - return AST::LoopLabel::error (); + return tl::nullopt; } - return AST::LoopLabel (std::move (label), tok->get_locus ()); + return tl::optional ( + AST::LoopLabel (std::move (label), tok->get_locus ())); } /* Parses an if expression of any kind, including with else, else if, else if @@ -7935,16 +7936,16 @@ Parser::parse_if_let_expr (AST::AttrVec outer_attrs, template std::unique_ptr Parser::parse_loop_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label, + tl::optional label, location_t pratt_parsed_loc) { location_t locus = pratt_parsed_loc; if (locus == UNKNOWN_LOCATION) { - if (label.is_error ()) - locus = lexer.peek_token ()->get_locus (); + if (label) + locus = label->get_locus (); else - locus = label.get_locus (); + locus = lexer.peek_token ()->get_locus (); if (!skip_token (LOOP)) { @@ -7954,8 +7955,8 @@ Parser::parse_loop_expr (AST::AttrVec outer_attrs, } else { - if (!label.is_error ()) - locus = label.get_locus (); + if (label) + locus = label->get_locus (); } // parse loop body, which is required @@ -7978,17 +7979,17 @@ Parser::parse_loop_expr (AST::AttrVec outer_attrs, * via parse_labelled_loop_expr, which would call this. */ template std::unique_ptr -Parser::parse_while_loop_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label, - location_t pratt_parsed_loc) +Parser::parse_while_loop_expr ( + AST::AttrVec outer_attrs, tl::optional label, + location_t pratt_parsed_loc) { location_t locus = pratt_parsed_loc; if (locus == UNKNOWN_LOCATION) { - if (label.is_error ()) - locus = lexer.peek_token ()->get_locus (); + if (label) + locus = label->get_locus (); else - locus = label.get_locus (); + locus = lexer.peek_token ()->get_locus (); if (!skip_token (WHILE)) { @@ -7998,8 +7999,8 @@ Parser::parse_while_loop_expr (AST::AttrVec outer_attrs, } else { - if (!label.is_error ()) - locus = label.get_locus (); + if (label) + locus = label->get_locus (); } // ensure it isn't a while let loop @@ -8051,14 +8052,14 @@ Parser::parse_while_loop_expr (AST::AttrVec outer_attrs, * parsed via parse_labelled_loop_expr, which would call this. */ template std::unique_ptr -Parser::parse_while_let_loop_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label) +Parser::parse_while_let_loop_expr ( + AST::AttrVec outer_attrs, tl::optional label) { location_t locus = UNKNOWN_LOCATION; - if (label.is_error ()) - locus = lexer.peek_token ()->get_locus (); + if (label) + locus = label->get_locus (); else - locus = label.get_locus (); + locus = lexer.peek_token ()->get_locus (); maybe_skip_token (WHILE); /* check for possible accidental recognition of a while loop as a while let @@ -8125,14 +8126,14 @@ Parser::parse_while_let_loop_expr (AST::AttrVec outer_attrs, * parse_labelled_loop_expr, which would call this. */ template std::unique_ptr -Parser::parse_for_loop_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label) +Parser::parse_for_loop_expr ( + AST::AttrVec outer_attrs, tl::optional label) { location_t locus = UNKNOWN_LOCATION; - if (label.is_error ()) - locus = lexer.peek_token ()->get_locus (); + if (label) + locus = label->get_locus (); else - locus = label.get_locus (); + locus = lexer.peek_token ()->get_locus (); maybe_skip_token (FOR); // parse pattern, which is required @@ -8210,8 +8211,9 @@ Parser::parse_labelled_loop_expr (const_TokenPtr tok, } // parse loop label (required) - AST::LoopLabel label = parse_loop_label (tok); - if (label.is_error ()) + // TODO: Convert this return type to tl::expected instead of tl::optional + tl::optional label = parse_loop_label (tok); + if (!label) { Error error (lexer.peek_token ()->get_locus (), "failed to parse loop label in labelled loop expr"); @@ -12400,8 +12402,8 @@ Parser::null_denotation_not_path ( return parse_continue_expr (std::move (outer_attrs), tok->get_locus ()); case LEFT_CURLY: // ok - this is an expression with block for once. - return parse_block_expr (std::move (outer_attrs), - AST::LoopLabel::error (), tok->get_locus ()); + return parse_block_expr (std::move (outer_attrs), tl::nullopt, + tok->get_locus ()); case IF: // if or if let, so more lookahead to find out if (lexer.peek_token ()->get_id () == LET) @@ -12417,7 +12419,7 @@ Parser::null_denotation_not_path ( case LIFETIME: return parse_labelled_loop_expr (tok, std::move (outer_attrs)); case LOOP: - return parse_loop_expr (std::move (outer_attrs), AST::LoopLabel::error (), + return parse_loop_expr (std::move (outer_attrs), tl::nullopt, tok->get_locus ()); case WHILE: if (lexer.peek_token ()->get_id () == LET) @@ -12426,13 +12428,11 @@ Parser::null_denotation_not_path ( } else { - return parse_while_loop_expr (std::move (outer_attrs), - AST::LoopLabel::error (), + return parse_while_loop_expr (std::move (outer_attrs), tl::nullopt, tok->get_locus ()); } case FOR: - return parse_for_loop_expr (std::move (outer_attrs), - AST::LoopLabel::error ()); + return parse_for_loop_expr (std::move (outer_attrs), tl::nullopt); case MATCH_KW: // also an expression with block return parse_match_expr (std::move (outer_attrs), tok->get_locus ()); diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 6c50ba9523d..fc548141c44 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -148,7 +148,7 @@ public: std::unique_ptr parse_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error (), + tl::optional = tl::nullopt, location_t pratt_parsed_loc = UNKNOWN_LOCATION); bool is_macro_rules_def (const_TokenPtr t); @@ -588,18 +588,18 @@ private: location_t pratt_parsed_loc = UNKNOWN_LOCATION); std::unique_ptr parse_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error (), + tl::optional label = tl::nullopt, location_t pratt_parsed_loc = UNKNOWN_LOCATION); std::unique_ptr parse_while_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error (), + tl::optional label = tl::nullopt, location_t pratt_parsed_loc = UNKNOWN_LOCATION); std::unique_ptr parse_while_let_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error ()); + tl::optional label = tl::nullopt); std::unique_ptr parse_for_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error ()); + tl::optional label = tl::nullopt); std::unique_ptr parse_match_expr (AST::AttrVec outer_attrs = AST::AttrVec (), location_t pratt_parsed_loc = UNKNOWN_LOCATION); @@ -609,7 +609,7 @@ private: std::unique_ptr parse_labelled_loop_expr (const_TokenPtr tok, AST::AttrVec outer_attrs = AST::AttrVec ()); - AST::LoopLabel parse_loop_label (const_TokenPtr tok); + tl::optional parse_loop_label (const_TokenPtr tok); std::unique_ptr parse_async_block_expr (AST::AttrVec outer_attrs = AST::AttrVec ()); std::unique_ptr parse_grouped_expr (AST::AttrVec outer_attrs