diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-block.h | 2 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 47 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.cc | 51 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-858.rs | 32 |
4 files changed, 86 insertions, 46 deletions
diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h index b14668a..512f4709 100644 --- a/gcc/rust/hir/rust-ast-lower-block.h +++ b/gcc/rust/hir/rust-ast-lower-block.h @@ -191,6 +191,8 @@ public: void visit (AST::WhileLoopExpr &expr) override; + void visit (AST::MatchExpr &expr) override; + private: ASTLoweringExprWithBlock () : ASTLoweringBase (), translated (nullptr), terminated (false) diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index bb25070..022002e 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -674,52 +674,7 @@ public: void visit (AST::MatchExpr &expr) override { - HIR::Expr *branch_value - = ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ()); - - std::vector<HIR::MatchCase> match_arms; - for (auto &match_case : expr.get_match_cases ()) - { - HIR::Expr *kase_expr - = ASTLoweringExpr::translate (match_case.get_expr ().get ()); - - HIR::Expr *kase_guard_expr = nullptr; - if (match_case.get_arm ().has_match_arm_guard ()) - { - kase_guard_expr = ASTLoweringExpr::translate ( - match_case.get_arm ().get_guard_expr ().get ()); - } - - std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns; - for (auto &pattern : match_case.get_arm ().get_patterns ()) - { - HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ()); - match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn)); - } - - HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (), - std::unique_ptr<HIR::Expr> (kase_guard_expr), - match_case.get_arm ().get_outer_attrs ()); - - auto crate_num = mappings->get_current_crate (); - Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), - mappings->get_next_hir_id (crate_num), - UNKNOWN_LOCAL_DEFID); - - HIR::MatchCase kase (std::move (mapping), std::move (arm), - std::unique_ptr<HIR::Expr> (kase_expr)); - match_arms.push_back (std::move (kase)); - } - - auto crate_num = mappings->get_current_crate (); - Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), - mappings->get_next_hir_id (crate_num), - UNKNOWN_LOCAL_DEFID); - - translated - = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value), - std::move (match_arms), expr.get_inner_attrs (), - expr.get_outer_attrs (), expr.get_locus ()); + translated = ASTLoweringExprWithBlock::translate (&expr, &terminated); } void visit (AST::RangeFromToExpr &expr) override diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index 4a344c9..64c8f36 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -299,6 +299,57 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr) expr.get_outer_attrs ()); } +void +ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr) +{ + HIR::Expr *branch_value + = ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ()); + + std::vector<HIR::MatchCase> match_arms; + for (auto &match_case : expr.get_match_cases ()) + { + HIR::Expr *kase_expr + = ASTLoweringExpr::translate (match_case.get_expr ().get ()); + + HIR::Expr *kase_guard_expr = nullptr; + if (match_case.get_arm ().has_match_arm_guard ()) + { + kase_guard_expr = ASTLoweringExpr::translate ( + match_case.get_arm ().get_guard_expr ().get ()); + } + + std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns; + for (auto &pattern : match_case.get_arm ().get_patterns ()) + { + HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ()); + match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn)); + } + + HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (), + std::unique_ptr<HIR::Expr> (kase_guard_expr), + match_case.get_arm ().get_outer_attrs ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + HIR::MatchCase kase (std::move (mapping), std::move (arm), + std::unique_ptr<HIR::Expr> (kase_expr)); + match_arms.push_back (std::move (kase)); + } + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value), + std::move (match_arms), expr.get_inner_attrs (), + expr.get_outer_attrs (), expr.get_locus ()); +} + // rust-ast-lower-expr.h void diff --git a/gcc/testsuite/rust/execute/torture/issue-858.rs b/gcc/testsuite/rust/execute/torture/issue-858.rs new file mode 100644 index 0000000..5a43f3e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-858.rs @@ -0,0 +1,32 @@ +/* { dg-output "Result: 123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo<T> { + A, + B(T), +} + +fn main() -> i32 { + let result = Foo::B(123); + + match result { + Foo::A => unsafe { + let a = "A\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + Foo::B(x) => unsafe { + let a = "Result: %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, x); + }, + } + + 0 +} |