diff options
author | Marc Poulhiès <dkm@kataplop.net> | 2024-06-12 21:58:26 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-21 12:32:54 +0100 |
commit | aa0e2abc57f4f43198e2b072a84c34c476aa2fad (patch) | |
tree | 77c6436b01133af70c4453cc4c42d7d936e0d10a /gcc/rust/hir/tree/rust-hir-expr.h | |
parent | ea163c6fe0021e0c6a6d984ebe62d77e31a44c51 (diff) | |
download | gcc-aa0e2abc57f4f43198e2b072a84c34c476aa2fad.zip gcc-aa0e2abc57f4f43198e2b072a84c34c476aa2fad.tar.gz gcc-aa0e2abc57f4f43198e2b072a84c34c476aa2fad.tar.bz2 |
rust: Desugar IfLet* into MatchExpr
Replace the "regular" AST->HIR lowering for IfLet* with a desugaring
into a MatchExpr.
Desugar a simple if let:
if let Some(y) = some_value {
bar();
}
into:
match some_value {
Some(y) => {bar();},
_ => ()
}
Same applies for IfLetExprConseqElse (if let with an else block).
Desugar:
if let Some(y) = some_value {
bar();
} else {
baz();
}
into:
match some_value {
Some(y) => {bar();},
_ => {baz();}
}
Fixes https://github.com/Rust-GCC/gccrs/issues/1177
gcc/rust/ChangeLog:
* backend/rust-compile-block.h: Adjust after removal of
HIR::IfLetExpr and HIR::IfLetExprConseqElse.
* backend/rust-compile-expr.h: Likewise.
* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
(ExprStmtBuilder::visit): Likewise.
* checks/errors/borrowck/rust-bir-builder-expr-stmt.h: Likewise.
* checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h:
Likewise.
* checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
* checks/errors/borrowck/rust-function-collector.h: Likewise.
* checks/errors/privacy/rust-privacy-reporter.cc
(PrivacyReporter::visit): Likewise.
* checks/errors/privacy/rust-privacy-reporter.h: Likewise.
* checks/errors/rust-const-checker.cc (ConstChecker::visit):
Likewise.
* checks/errors/rust-const-checker.h: Likewise.
* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit):
Likewise.
* checks/errors/rust-unsafe-checker.h: Likewise.
* hir/rust-ast-lower-block.h (ASTLoweringIfLetBlock::translate):
Change return type.
* hir/rust-ast-lower.cc (ASTLoweringIfLetBlock::desugar_iflet):
New.
(ASTLoweringIfLetBlock::visit(AST::IfLetExpr &)): Adjust and use
desugar_iflet.
* hir/rust-ast-lower.h: Add comment.
* hir/rust-hir-dump.cc (Dump::do_ifletexpr): Remove.
(Dump::visit(IfLetExpr&)): Remove.
(Dump::visit(IfLetExprConseqElse&)): Remove.
* hir/rust-hir-dump.h (Dump::do_ifletexpr): Remove.
(Dump::visit(IfLetExpr&)): Remove.
(Dump::visit(IfLetExprConseqElse&)): Remove.
* hir/tree/rust-hir-expr.h (class IfLetExpr): Remove.
(class IfLetExprConseqElse): Remove.
* hir/tree/rust-hir-full-decls.h (class IfLetExpr): Remove.
(class IfLetExprConseqElse): Remove.
* hir/tree/rust-hir-visitor.h: Adjust after removal of
HIR::IfLetExpr and HIR::IfLetExprConseqElse.
* hir/tree/rust-hir.cc (IfLetExpr::as_string): Remove.
(IfLetExprConseqElse::as_string): Remove.
(IfLetExpr::accept_vis): Remove.
(IfLetExprConseqElse::accept_vis): Remove.
* hir/tree/rust-hir.h: Adjust after removal of HIR::IfLetExpr and
HIR::IfLetExprConseqElse.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Likewise.
* typecheck/rust-hir-type-check-expr.h: Likewise.
* checks/errors/rust-hir-pattern-analysis.cc
(PatternChecker::visit (IfLetExpr &)): Remove.
(PatternChecker::visit (IfLetExprConseqElse &)): Remove.
* checks/errors/rust-hir-pattern-analysis.h (visit(IfLetExpr &)): Remove.
(visit(IfLetExprConseqElse &)): Remove.
gcc/testsuite/ChangeLog:
* rust/compile/if_let_expr.rs: Adjust.
* rust/compile/if_let_expr_simple.rs: New test.
* rust/compile/iflet.rs: New test.
* rust/execute/torture/iflet.rs: New test.
* rust/compile/nr2/exclude: Add iflet.rs and if_let_expr_simple.rs
Signed-off-by: Marc Poulhiès <dkm@kataplop.net>
Diffstat (limited to 'gcc/rust/hir/tree/rust-hir-expr.h')
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 176 |
1 files changed, 1 insertions, 175 deletions
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 1ee1066..a79aea5 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -32,7 +32,7 @@ namespace HIR { // TODO: inline? class LoopLabel /*: public Node*/ { - Lifetime label; // or type LIFETIME_OR_LABEL + Lifetime label; // of type LIFETIME_OR_LABEL location_t locus; @@ -3108,9 +3108,6 @@ protected: } }; -// forward decl for IfExpr -class IfLetExpr; - // Base if expression with no "else" or "if let" HIR node class IfExpr : public ExprWithBlock { @@ -3258,177 +3255,6 @@ protected: } }; -// Basic "if let" expression HIR node with no else -class IfLetExpr : public ExprWithBlock -{ - // MatchArmPatterns patterns; - std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined - std::unique_ptr<Expr> value; - std::unique_ptr<BlockExpr> if_block; - - location_t locus; - -public: - std::string as_string () const override; - - IfLetExpr (Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Pattern> > match_arm_patterns, - std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, - location_t locus) - : ExprWithBlock (std::move (mappings), AST::AttrVec ()), - match_arm_patterns (std::move (match_arm_patterns)), - value (std::move (value)), if_block (std::move (if_block)), locus (locus) - {} - // outer attributes not allowed on if let exprs either - - // copy constructor with clone - IfLetExpr (IfLetExpr const &other) - : ExprWithBlock (other), - /*match_arm_patterns(other.match_arm_patterns),*/ value ( - other.value->clone_expr ()), - if_block (other.if_block->clone_block_expr ()), locus (other.locus) - { - match_arm_patterns.reserve (other.match_arm_patterns.size ()); - for (const auto &e : other.match_arm_patterns) - match_arm_patterns.push_back (e->clone_pattern ()); - } - - // overload assignment operator to clone - IfLetExpr &operator= (IfLetExpr const &other) - { - ExprWithBlock::operator= (other); - // match_arm_patterns = other.match_arm_patterns; - value = other.value->clone_expr (); - if_block = other.if_block->clone_block_expr (); - locus = other.locus; - - match_arm_patterns.reserve (other.match_arm_patterns.size ()); - for (const auto &e : other.match_arm_patterns) - match_arm_patterns.push_back (e->clone_pattern ()); - - return *this; - } - - // move constructors - IfLetExpr (IfLetExpr &&other) = default; - IfLetExpr &operator= (IfLetExpr &&other) = default; - - // Unique pointer custom clone function - std::unique_ptr<IfLetExpr> clone_if_let_expr () const - { - return std::unique_ptr<IfLetExpr> (clone_if_let_expr_impl ()); - } - - location_t get_locus () const override final { return locus; } - - void accept_vis (HIRFullVisitor &vis) override; - void accept_vis (HIRExpressionVisitor &vis) override; - - std::unique_ptr<Expr> &get_scrutinee_expr () { return value; } - - std::vector<std::unique_ptr<Pattern> > &get_patterns () - { - return match_arm_patterns; - } - - std::unique_ptr<BlockExpr> &get_if_block () { return if_block; } - - ExprType get_expression_type () const final override - { - return ExprType::IfLet; - } - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExpr *clone_expr_impl () const override { return new IfLetExpr (*this); } - - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExpr *clone_expr_with_block_impl () const override - { - return new IfLetExpr (*this); - } - - // Base clone function but still concrete as concrete base class - virtual IfLetExpr *clone_if_let_expr_impl () const - { - return new IfLetExpr (*this); - } -}; - -/* HIR node representing "if let" expression with an "else" expression at the - * end */ -class IfLetExprConseqElse : public IfLetExpr -{ - std::unique_ptr<ExprWithBlock> else_block; - -public: - std::string as_string () const override; - - IfLetExprConseqElse ( - Analysis::NodeMapping mappings, - std::vector<std::unique_ptr<Pattern> > match_arm_patterns, - std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<ExprWithBlock> else_block, location_t locus) - : IfLetExpr (std::move (mappings), std::move (match_arm_patterns), - std::move (value), std::move (if_block), locus), - else_block (std::move (else_block)) - {} - // outer attributes not allowed - - // copy constructor with clone - IfLetExprConseqElse (IfLetExprConseqElse const &other) - : IfLetExpr (other), else_block (other.else_block->clone_expr_with_block ()) - {} - - // overload assignment operator to clone - IfLetExprConseqElse &operator= (IfLetExprConseqElse const &other) - { - IfLetExpr::operator= (other); - // match_arm_patterns = other.match_arm_patterns; - // value = other.value->clone_expr(); - // if_block = other.if_block->clone_block_expr(); - else_block = other.else_block->clone_expr_with_block (); - // outer_attrs = other.outer_attrs; - - return *this; - } - - // move constructors - IfLetExprConseqElse (IfLetExprConseqElse &&other) = default; - IfLetExprConseqElse &operator= (IfLetExprConseqElse &&other) = default; - - void accept_vis (HIRFullVisitor &vis) override; - void accept_vis (HIRExpressionVisitor &vis) override; - - void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); } - - std::unique_ptr<ExprWithBlock> &get_else_block () { return else_block; } - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExprConseqElse *clone_expr_impl () const override - { - return new IfLetExprConseqElse (*this); - } - - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExprConseqElse *clone_expr_with_block_impl () const override - { - return new IfLetExprConseqElse (*this); - } - - /* Use covariance to implement clone function as returning this object rather - * than base */ - IfLetExprConseqElse *clone_if_let_expr_impl () const override - { - return new IfLetExprConseqElse (*this); - } -}; - // Match arm expression struct MatchArm { |