Skip to content

Commit d1fd377

Browse files
committed
Fix evaluation order in struct field expressions
Fixes #4445 gcc/rust/ChangeLog: * backend/rust-compile-expr.cc (CompileExpr::visit): Get struct field type with field name * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::resolve): Cancel reordering of struct field exprs Signed-off-by: Mohamed El Shorbagy <mohrizq895@gmail.com>
1 parent 461ab85 commit d1fd377

File tree

2 files changed

+27
-22
lines changed

2 files changed

+27
-22
lines changed

gcc/rust/backend/rust-compile-expr.cc

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -595,17 +595,39 @@ CompileExpr::visit (HIR::StructExprStructFields &struct_expr)
595595
}
596596
else
597597
{
598-
// this assumes all fields are in order from type resolution and if a
599-
// base struct was specified those fields are filed via accessors
600598
for (size_t i = 0; i < struct_expr.get_fields ().size (); i++)
601599
{
600+
std::string field_name;
601+
auto &argument = struct_expr.get_fields ().at (i);
602+
switch (argument->get_kind ())
603+
{
604+
case HIR::StructExprField::StructExprFieldKind::IDENTIFIER:
605+
field_name
606+
= (static_cast<HIR::StructExprFieldIdentifier &> (*argument))
607+
.get_field_name ();
608+
break;
609+
610+
case HIR::StructExprField::StructExprFieldKind::IDENTIFIER_VALUE:
611+
field_name = (static_cast<HIR::StructExprFieldIdentifierValue &> (
612+
*argument))
613+
.get_field_name ();
614+
break;
615+
616+
case HIR::StructExprField::StructExprFieldKind::INDEX_VALUE:
617+
field_name = std::to_string (
618+
(static_cast<HIR::StructExprFieldIndexValue &> (*argument))
619+
.get_tuple_index ());
620+
break;
621+
}
622+
602623
// assignments are coercion sites so lets convert the rvalue if
603624
// necessary
604-
auto respective_field = variant->get_field_at_index (i);
625+
TyTy::StructFieldType *respective_field = nullptr;
626+
auto _ok
627+
= variant->lookup_field (field_name, &respective_field, nullptr);
628+
rust_assert (_ok);
605629
auto expected = respective_field->get_field_type ();
606630

607-
// process arguments
608-
auto &argument = struct_expr.get_fields ().at (i);
609631
auto lvalue_locus
610632
= ctx->get_mappings ().lookup_location (expected->get_ty_ref ());
611633
auto rvalue_locus = argument->get_locus ();

gcc/rust/typecheck/rust-hir-type-check-struct.cc

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -235,23 +235,6 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
235235
}
236236
rust_assert (struct_expr.union_index != -1);
237237
}
238-
else
239-
{
240-
// everything is ok, now we need to ensure all field values are ordered
241-
// correctly. The GIMPLE backend uses a simple algorithm that assumes each
242-
// assigned field in the constructor is in the same order as the field in
243-
// the type
244-
for (auto &field : struct_expr.get_fields ())
245-
field.release ();
246-
247-
std::vector<std::unique_ptr<HIR::StructExprField> > ordered_fields;
248-
ordered_fields.reserve (adtFieldIndexToField.size ());
249-
250-
for (size_t i = 0; i < adtFieldIndexToField.size (); i++)
251-
ordered_fields.emplace_back (adtFieldIndexToField[i]);
252-
253-
struct_expr.set_fields_as_owner (std::move (ordered_fields));
254-
}
255238

256239
resolved = struct_def;
257240
}

0 commit comments

Comments
 (0)