diff options
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index bb81d4e..79d9e57 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -419,18 +419,19 @@ public: // compile it tree compiled_adt_type = TyTyResolveCompile::compile (ctx, tyty); - // this assumes all fields are in order from type resolution and if a base - // struct was specified those fields are filed via accesors std::vector<tree> arguments; - for (size_t i = 0; i < struct_expr.get_fields ().size (); i++) + if (adt->is_union ()) { + rust_assert (struct_expr.get_fields ().size () == 1); + // assignments are coercion sites so lets convert the rvalue if // necessary - auto respective_field = variant->get_field_at_index (i); + auto respective_field + = variant->get_field_at_index (union_disriminator); auto expected = respective_field->get_field_type (); // process arguments - auto &argument = struct_expr.get_fields ().at (i); + auto &argument = struct_expr.get_fields ().at (0); auto lvalue_locus = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ()); auto rvalue_locus = argument->get_locus (); @@ -440,8 +441,6 @@ public: bool ok = ctx->get_tyctx ()->lookup_type ( argument->get_mappings ().get_hirid (), &actual); - // coerce it if required/possible see - // compile/torture/struct_base_init_1.rs if (ok) { rvalue = coercion_site (rvalue, actual, expected, lvalue_locus, @@ -451,6 +450,41 @@ public: // add it to the list arguments.push_back (rvalue); } + else + { + // this assumes all fields are in order from type resolution and if a + // base struct was specified those fields are filed via accesors + for (size_t i = 0; i < struct_expr.get_fields ().size (); i++) + { + // assignments are coercion sites so lets convert the rvalue if + // necessary + auto respective_field = variant->get_field_at_index (i); + auto expected = respective_field->get_field_type (); + + // process arguments + auto &argument = struct_expr.get_fields ().at (i); + auto lvalue_locus + = ctx->get_mappings ()->lookup_location (expected->get_ty_ref ()); + auto rvalue_locus = argument->get_locus (); + auto rvalue + = CompileStructExprField::Compile (argument.get (), ctx); + + TyTy::BaseType *actual = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type ( + argument->get_mappings ().get_hirid (), &actual); + + // coerce it if required/possible see + // compile/torture/struct_base_init_1.rs + if (ok) + { + rvalue = coercion_site (rvalue, actual, expected, lvalue_locus, + rvalue_locus); + } + + // add it to the list + arguments.push_back (rvalue); + } + } // the constructor depends on whether this is actually an enum or not if // its an enum we need to setup the discriminator |