aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOwen Avery <powerboat9.gamer@gmail.com>2025-04-30 21:54:53 -0400
committerPhilip Herron <philip.herron@embecosm.com>2025-05-07 15:34:59 +0000
commit23f933b90bb7d5558eef4d956d2a76160beb0e12 (patch)
tree1b75b995927a1da03092ecb2459715e2ce2bd89a /gcc
parent8592769349a33ff1fca3777021ad6ea8dab56c7d (diff)
downloadgcc-23f933b90bb7d5558eef4d956d2a76160beb0e12.zip
gcc-23f933b90bb7d5558eef4d956d2a76160beb0e12.tar.gz
gcc-23f933b90bb7d5558eef4d956d2a76160beb0e12.tar.bz2
Improve struct pattern compilation
gcc/rust/ChangeLog: * backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit): Fix GENERIC generation in light of enum layout changes since this code was written. (CompilePatternBindings::handle_struct_pattern_ident_pat): Delegate handling of child patterns to another CompilePatternBindings::Compile call. (CompilePatternBindings::make_struct_access): Make field name parameter const qualified. * backend/rust-compile-pattern.h (CompilePatternBindings::make_struct_access): Likewise. gcc/testsuite/ChangeLog: * rust/execute/torture/struct-pattern-match.rs: New test. Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc44
-rw-r--r--gcc/rust/backend/rust-compile-pattern.h2
-rw-r--r--gcc/testsuite/rust/execute/torture/struct-pattern-match.rs13
3 files changed, 30 insertions, 29 deletions
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index 94844fe..121749a 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -209,6 +209,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
rust_assert (adt->number_of_variants () > 0);
TyTy::VariantDef *variant = nullptr;
+ tree variant_accesser_expr = nullptr;
if (adt->is_enum ())
{
// lookup the variant
@@ -223,9 +224,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
// find expected discriminant
// // need to access qualifier the field, if we use QUAL_UNION_TYPE this
- // // would be DECL_QUALIFIER i think. For now this will just access the
- // // first record field and its respective qualifier because it will
- // // always be set because this is all a big special union
+ // // would be DECL_QUALIFIER i think.
HIR::Expr &discrim_expr = variant->get_discriminant ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
@@ -234,6 +233,14 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
= Backend::struct_field_expression (match_scrutinee_expr, 0,
pattern.get_path ().get_locus ());
+ // access variant data
+ tree scrutinee_union_expr
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pattern.get_path ().get_locus ());
+ variant_accesser_expr
+ = Backend::struct_field_expression (scrutinee_union_expr, variant_index,
+ pattern.get_path ().get_locus ());
+
check_expr
= Backend::comparison_expression (ComparisonOperator::EQUAL,
scrutinee_expr_qualifier_expr,
@@ -245,6 +252,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
else
{
variant = adt->get_variants ().at (0);
+ variant_accesser_expr = match_scrutinee_expr;
check_expr = boolean_true_node;
}
@@ -268,11 +276,8 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
nullptr, &offs);
rust_assert (ok);
- // we may be offsetting by + 1 here since the first field in the
- // record is always the discriminator
- offs += adt->is_enum ();
tree field_expr
- = Backend::struct_field_expression (match_scrutinee_expr, offs,
+ = Backend::struct_field_expression (variant_accesser_expr, offs,
ident.get_locus ());
tree check_expr_sub
@@ -512,7 +517,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
tree
CompilePatternBindings::make_struct_access (TyTy::ADTType *adt,
TyTy::VariantDef *variant,
- Identifier &ident,
+ const Identifier &ident,
int variant_index)
{
size_t offs = 0;
@@ -562,26 +567,9 @@ CompilePatternBindings::handle_struct_pattern_ident_pat (
{
auto &pattern = static_cast<HIR::StructPatternFieldIdentPat &> (pat);
- switch (pattern.get_pattern ().get_pattern_type ())
- {
- case HIR::Pattern::IDENTIFIER: {
- auto &id
- = static_cast<HIR::IdentifierPattern &> (pattern.get_pattern ());
-
- CompilePatternBindings::Compile (id, match_scrutinee_expr, ctx);
- }
- break;
- default:
- rust_sorry_at (pat.get_locus (),
- "cannot handle non-identifier struct patterns");
- return;
- }
-
- auto ident = pattern.get_identifier ();
- tree binding = make_struct_access (adt, variant, ident, variant_index);
-
- ctx->insert_pattern_binding (
- pattern.get_pattern ().get_mappings ().get_hirid (), binding);
+ tree binding = make_struct_access (adt, variant, pattern.get_identifier (),
+ variant_index);
+ CompilePatternBindings::Compile (pattern.get_pattern (), binding, ctx);
}
void
diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h
index 8ebc275..32b6db2 100644
--- a/gcc/rust/backend/rust-compile-pattern.h
+++ b/gcc/rust/backend/rust-compile-pattern.h
@@ -81,7 +81,7 @@ public:
}
tree make_struct_access (TyTy::ADTType *adt, TyTy::VariantDef *variant,
- Identifier &ident, int variant_index);
+ const Identifier &ident, int variant_index);
void handle_struct_pattern_ident (HIR::StructPatternField &pat,
TyTy::ADTType *adt,
diff --git a/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs b/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs
new file mode 100644
index 0000000..6aec51f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs
@@ -0,0 +1,13 @@
+enum Foo {
+ A { x: i32 },
+ B { y: i32 }
+}
+
+fn main() -> i32 {
+ let x = Foo::A { x: 12 };
+ match x {
+ Foo::A { x: 10 } => 1,
+ Foo::B { y: 11 } => 2,
+ Foo::A { x: abc } => { abc - 12 }
+ }
+}