diff options
author | Philip Herron <herron.philip@googlemail.com> | 2025-01-07 18:15:37 +0000 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-21 12:56:55 +0100 |
commit | f821a513843baabed8a39601bbc714558110b748 (patch) | |
tree | e5d4bc66d8c721905324d63be3a84b5e25363ee2 /gcc/rust/backend/rust-compile-pattern.cc | |
parent | 2fa9719068774ab7ec5ed4cbe95cfe30fa94dbb1 (diff) | |
download | gcc-f821a513843baabed8a39601bbc714558110b748.zip gcc-f821a513843baabed8a39601bbc714558110b748.tar.gz gcc-f821a513843baabed8a39601bbc714558110b748.tar.bz2 |
gccrs: cleanup our enum type layout to be closer to rustc
This changes our enum type layout so for example:
enum Foo {
A,
B,
C(char),
D { x: i32, y: i32 },
}
Used to get layed out like this in gccrs:
union {
struct A { int RUST$ENUM$DISR; };
struct B { int RUST$ENUM$DISR; };
struct C { int RUST$ENUM$DISR; char __0; };
struct D { int RUST$ENUM$DISR; i64 x; i64 y; };
}
This has some issues notably with the constexpr because this is just a
giant union it means its not simple to constify what enum variant we are
looking at because the discriminant is a mess.
This now gets layed out as:
struct {
int RUST$ENUM$DISR;
union {
struct A { };
struct B { };
struct C { char __0; };
struct D { i64 x; i64 y; };
} payload;
}
This layout is much cleaner and allows for our constexpr to work properly.
gcc/rust/ChangeLog:
* backend/rust-compile-expr.cc (CompileExpr::visit): new layout
* backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit): likewise
(CompilePatternBindings::visit): likewise
* backend/rust-compile-resolve-path.cc: likewise
* backend/rust-compile-type.cc (TyTyResolveCompile::visit): implement new layout
* rust-gcc.cc (constructor_expression): get rid of useless assert
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Diffstat (limited to 'gcc/rust/backend/rust-compile-pattern.cc')
-rw-r--r-- | gcc/rust/backend/rust-compile-pattern.cc | 64 |
1 files changed, 31 insertions, 33 deletions
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index bd534ff..4e352fd 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -21,6 +21,7 @@ #include "rust-compile-resolve-path.h" #include "rust-constexpr.h" #include "rust-compile-type.h" +#include "print-tree.h" namespace Rust { namespace Compile { @@ -57,11 +58,8 @@ CompilePatternCheckExpr::visit (HIR::PathInExpression &pattern) rust_assert (ok); // find discriminant field of scrutinee - tree scrutinee_record_expr - = Backend::struct_field_expression (match_scrutinee_expr, 0, - pattern.get_locus ()); tree scrutinee_expr_qualifier_expr - = Backend::struct_field_expression (scrutinee_record_expr, 0, + = Backend::struct_field_expression (match_scrutinee_expr, 0, pattern.get_locus ()); // must be enum @@ -227,11 +225,8 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern) tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx); // find discriminant field of scrutinee - tree scrutinee_record_expr - = Backend::struct_field_expression (match_scrutinee_expr, variant_index, - pattern.get_path ().get_locus ()); tree scrutinee_expr_qualifier_expr - = Backend::struct_field_expression (scrutinee_record_expr, 0, + = Backend::struct_field_expression (match_scrutinee_expr, 0, pattern.get_path ().get_locus ()); check_expr @@ -240,7 +235,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern) discrim_expr_node, pattern.get_path ().get_locus ()); - match_scrutinee_expr = scrutinee_record_expr; + match_scrutinee_expr = scrutinee_expr_qualifier_expr; } else { @@ -295,8 +290,6 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern) void CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern) { - size_t tuple_field_index; - // lookup the type TyTy::BaseType *lookup = nullptr; bool ok = ctx->get_tyctx ()->lookup_type ( @@ -307,6 +300,7 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern) rust_assert (lookup->get_kind () == TyTy::TypeKind::ADT); TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (lookup); + int variant_index = 0; rust_assert (adt->number_of_variants () > 0); TyTy::VariantDef *variant = nullptr; if (adt->is_enum ()) @@ -317,7 +311,6 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern) pattern.get_path ().get_mappings ().get_hirid (), &variant_id); rust_assert (ok); - int variant_index = 0; ok = adt->lookup_variant_by_id (variant_id, &variant, &variant_index); rust_assert (ok); @@ -326,11 +319,8 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern) tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx); // find discriminant field of scrutinee - tree scrutinee_record_expr - = Backend::struct_field_expression (match_scrutinee_expr, variant_index, - pattern.get_path ().get_locus ()); tree scrutinee_expr_qualifier_expr - = Backend::struct_field_expression (scrutinee_record_expr, 0, + = Backend::struct_field_expression (match_scrutinee_expr, 0, pattern.get_path ().get_locus ()); check_expr @@ -338,17 +328,11 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern) scrutinee_expr_qualifier_expr, discrim_expr_node, pattern.get_path ().get_locus ()); - - match_scrutinee_expr = scrutinee_record_expr; - // we are offsetting by + 1 here since the first field in the record - // is always the discriminator - tuple_field_index = 1; } else { variant = adt->get_variants ().at (0); check_expr = boolean_true_node; - tuple_field_index = 0; } HIR::TupleStructItems &items = pattern.get_items (); @@ -367,10 +351,20 @@ 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 ()) { + // 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 field_expr - = Backend::struct_field_expression (match_scrutinee_expr, + = Backend::struct_field_expression (variant_ref, tuple_field_index++, pattern->get_locus ()); @@ -470,13 +464,15 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern) if (adt->is_enum ()) { - // we are offsetting by + 1 here since the first field in the record - // is always the discriminator - size_t tuple_field_index = 1; + size_t tuple_field_index = 0; for (auto &pattern : items_no_range.get_patterns ()) { + tree payload_accessor_union + = Backend::struct_field_expression (match_scrutinee_expr, 1, + pattern->get_locus ()); + tree variant_accessor - = Backend::struct_field_expression (match_scrutinee_expr, + = Backend::struct_field_expression (payload_accessor_union, variant_index, pattern->get_locus ()); @@ -569,16 +565,18 @@ CompilePatternBindings::visit (HIR::StructPattern &pattern) tree binding = error_mark_node; if (adt->is_enum ()) { + tree payload_accessor_union + = Backend::struct_field_expression (match_scrutinee_expr, 1, + ident.get_locus ()); + tree variant_accessor - = Backend::struct_field_expression (match_scrutinee_expr, + = Backend::struct_field_expression (payload_accessor_union, variant_index, ident.get_locus ()); - // we are offsetting by + 1 here since the first field in the - // record is always the discriminator - binding = Backend::struct_field_expression (variant_accessor, - offs + 1, - ident.get_locus ()); + binding + = Backend::struct_field_expression (variant_accessor, offs, + ident.get_locus ()); } else { |