diff options
author | Owen Avery <powerboat9.gamer@gmail.com> | 2025-04-30 21:54:53 -0400 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2025-05-07 15:34:59 +0000 |
commit | 23f933b90bb7d5558eef4d956d2a76160beb0e12 (patch) | |
tree | 1b75b995927a1da03092ecb2459715e2ce2bd89a /gcc | |
parent | 8592769349a33ff1fca3777021ad6ea8dab56c7d (diff) | |
download | gcc-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.cc | 44 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-pattern.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/struct-pattern-match.rs | 13 |
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 } + } +} |