From: Zhi Heng <yapz...@gmail.com> Code for TupleStructPattern compilation previously only assumes that it is derived from an enum. This commit adds a check for that, and compiles non-enum TupleStructPatterns similarly to TuplePatterns if it is not an enum.
gcc/rust/ChangeLog: * backend/rust-compile-pattern.cc(CompilePatternCheckExpr::visit(TupleStructPattern)): Fix error thrown when compiling non-enum TupleStructPattern. Signed-off-by: Yap Zhi Heng <yapz...@gmail.com> --- gcc/rust/backend/rust-compile-pattern.cc | 62 +++++++++++++------ .../rust/compile/match-tuplestructpattern.rs | 9 +++ .../torture/match-tuplestructpattern.rs | 12 ++++ 3 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/rust/compile/match-tuplestructpattern.rs create mode 100644 gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index bd3aea01b53..cd1c77be5eb 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -369,31 +369,55 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern) rust_assert (items_no_range.get_patterns ().size () == variant->num_fields ()); - size_t tuple_field_index = 0; - for (auto &pattern : items_no_range.get_patterns ()) + if (adt->is_enum ()) { - // find payload union field of scrutinee - tree payload_ref - = Backend::struct_field_expression (match_scrutinee_expr, 1, - pattern->get_locus ()); + size_t tuple_field_index = 0; + for (auto &pattern : items_no_range.get_patterns ()) + { + // find payload union field of scrutinee + tree payload_ref + = Backend::struct_field_expression (match_scrutinee_expr, 1, + pattern->get_locus ()); - tree variant_ref - = Backend::struct_field_expression (payload_ref, variant_index, - pattern->get_locus ()); + tree variant_ref + = Backend::struct_field_expression (payload_ref, + variant_index, + pattern->get_locus ()); - tree field_expr - = Backend::struct_field_expression (variant_ref, - tuple_field_index++, - pattern->get_locus ()); + tree field_expr + = Backend::struct_field_expression (variant_ref, + tuple_field_index++, + pattern->get_locus ()); - tree check_expr_sub - = CompilePatternCheckExpr::Compile (*pattern, field_expr, ctx); - check_expr = Backend::arithmetic_or_logical_expression ( - ArithmeticOrLogicalOperator::BITWISE_AND, check_expr, - check_expr_sub, pattern->get_locus ()); + tree check_expr_sub + = CompilePatternCheckExpr::Compile (*pattern, field_expr, + ctx); + check_expr = Backend::arithmetic_or_logical_expression ( + ArithmeticOrLogicalOperator::BITWISE_AND, check_expr, + check_expr_sub, pattern->get_locus ()); + } + } + else + { + // For non-enum TupleStructPatterns + size_t tuple_field_index = 0; + for (auto &pattern : items_no_range.get_patterns ()) + { + tree field_expr + = Backend::struct_field_expression (match_scrutinee_expr, + tuple_field_index++, + pattern->get_locus ()); + + tree check_expr_sub + = CompilePatternCheckExpr::Compile (*pattern, field_expr, + ctx); + check_expr = Backend::arithmetic_or_logical_expression ( + ArithmeticOrLogicalOperator::BITWISE_AND, check_expr, + check_expr_sub, pattern->get_locus ()); + } } + break; } - break; } } diff --git a/gcc/testsuite/rust/compile/match-tuplestructpattern.rs b/gcc/testsuite/rust/compile/match-tuplestructpattern.rs new file mode 100644 index 00000000000..0dae71ea005 --- /dev/null +++ b/gcc/testsuite/rust/compile/match-tuplestructpattern.rs @@ -0,0 +1,9 @@ +fn main() { + struct A (i32, i32); + let a = A (0, 1); + + match a { + A (0, 1) => {}, + _ => {} + } +} diff --git a/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs new file mode 100644 index 00000000000..323109cd496 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs @@ -0,0 +1,12 @@ +fn main() -> i32 { + struct A (i32, i32); + let a = A (0, 1); + let mut ret = 1; + + match a { + A (0, b) => { ret -= b }, + _ => {} + } + + ret +} -- 2.49.0