Skip to content

Fix evaluation order in struct field expressions - #4448

Open
elshorbagyx wants to merge 1 commit into
Rust-GCC:masterfrom
elshorbagyx:fix-4445
Open

elshorbagyx wants to merge 1 commit into
Rust-GCC:masterfrom
elshorbagyx:fix-4445

Conversation

@elshorbagyx

@elshorbagyx elshorbagyx commented Feb 25, 2026 •

Copy link
Copy Markdown

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

gccrs evaluates struct field expressions in the order they are declared inside the struct definition. The current logic reorders the struct field expressions to match the struct field types, which results in incorrect behavior compared to the Rust reference (as mentioned in #4445). Instead, we could fetch the struct field type by field name through lookup_field.

@elshorbagyx
elshorbagyx force-pushed the fix-4445 branch 4 times, most recently from 188de4d to d1fd377 Compare February 25, 2026 04:00
@philberty

Copy link
Copy Markdown
Member

the tests are failing:

FAIL: rust/compile/torture/struct_init_7.rs   -O0  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_7.rs   -O0   at line 7 (test for warnings, line 6)
FAIL: rust/compile/torture/struct_init_7.rs   -O0   at line 13 (test for warnings, line 12)
FAIL: rust/compile/torture/struct_init_7.rs   -O0  (test for excess errors)
FAIL: rust/compile/torture/struct_init_7.rs   -O1  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_7.rs   -O1   at line 7 (test for warnings, line 6)
FAIL: rust/compile/torture/struct_init_7.rs   -O1   at line 13 (test for warnings, line 12)
FAIL: rust/compile/torture/struct_init_7.rs   -O1  (test for excess errors)
FAIL: rust/compile/torture/struct_init_7.rs   -O2  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_7.rs   -O2   at line 7 (test for warnings, line 6)
FAIL: rust/compile/torture/struct_init_7.rs   -O2   at line 13 (test for warnings, line 12)
FAIL: rust/compile/torture/struct_init_7.rs   -O2  (test for excess errors)
FAIL: rust/compile/torture/struct_init_7.rs   -O3 -g  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_7.rs   -O3 -g   at line 7 (test for warnings, line 6)
FAIL: rust/compile/torture/struct_init_7.rs   -O3 -g   at line 13 (test for warnings, line 12)
FAIL: rust/compile/torture/struct_init_7.rs   -O3 -g  (test for excess errors)
FAIL: rust/compile/torture/struct_init_7.rs   -Os  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_7.rs   -Os   at line 7 (test for warnings, line 6)
FAIL: rust/compile/torture/struct_init_7.rs   -Os   at line 13 (test for warnings, line 12)
FAIL: rust/compile/torture/struct_init_7.rs   -Os  (test for excess errors)
FAIL: rust/compile/torture/struct_init_7.rs   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_7.rs   -O2 -flto -fno-use-linker-plugin -flto-partition=none   at line 7 (test for warnings, line 6)
FAIL: rust/compile/torture/struct_init_7.rs   -O2 -flto -fno-use-linker-plugin -flto-partition=none   at line 13 (test for warnings, line 12)
FAIL: rust/compile/torture/struct_init_7.rs   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
FAIL: rust/compile/torture/struct_init_7.rs   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_7.rs   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects   at line 7 (test for warnings, line 6)
FAIL: rust/compile/torture/struct_init_7.rs   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects   at line 13 (test for warnings, line 12)
FAIL: rust/compile/torture/struct_init_7.rs   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
FAIL: rust/compile/torture/struct_init_8.rs   -O0  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_8.rs   -O0   at line 9 (test for warnings, line 8)
FAIL: rust/compile/torture/struct_init_8.rs   -O0  (test for excess errors)
FAIL: rust/compile/torture/struct_init_8.rs   -O1  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_8.rs   -O1   at line 9 (test for warnings, line 8)
FAIL: rust/compile/torture/struct_init_8.rs   -O1  (test for excess errors)
FAIL: rust/compile/torture/struct_init_8.rs   -O2  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_8.rs   -O2   at line 9 (test for warnings, line 8)
FAIL: rust/compile/torture/struct_init_8.rs   -O2  (test for excess errors)
FAIL: rust/compile/torture/struct_init_8.rs   -O3 -g  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_8.rs   -O3 -g   at line 9 (test for warnings, line 8)
FAIL: rust/compile/torture/struct_init_8.rs   -O3 -g  (test for excess errors)
FAIL: rust/compile/torture/struct_init_8.rs   -Os  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_8.rs   -Os   at line 9 (test for warnings, line 8)
FAIL: rust/compile/torture/struct_init_8.rs   -Os  (test for excess errors)
FAIL: rust/compile/torture/struct_init_8.rs   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_8.rs   -O2 -flto -fno-use-linker-plugin -flto-partition=none   at line 9 (test for warnings, line 8)
FAIL: rust/compile/torture/struct_init_8.rs   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
FAIL: rust/compile/torture/struct_init_8.rs   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error: in fold_convert_loc, at fold-const.cc:2672)
FAIL: rust/compile/torture/struct_init_8.rs   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects   at line 9 (test for warnings, line 8)
FAIL: rust/compile/torture/struct_init_8.rs   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)

but also i am pretty sure we update the ordering within the typecheck pass to sort this out.

@elshorbagyx

Copy link
Copy Markdown
Author

the tests are failing:

I am working on that.

@powerboat9

Copy link
Copy Markdown
Collaborator

Make sure to double-check that the generated GIMPLE doesn't have unspecified evaluation order (I'm not sure about TREE_CONSTRUCTOR)

@elshorbagyx

elshorbagyx commented Feb 27, 2026 •

Copy link
Copy Markdown
Author

@philberty @powerboat9
Tests are passing now.

@philberty

Copy link
Copy Markdown
Member

you need to fix your change log here to match gcc style

Fixes Rust-GCC#4445

gcc/rust/ChangeLog:

	* backend/rust-compile-expr.cc (CompileExpr::visit): Get the struct
	field type by field name instead of relying on declaration order,
	and only reorder fields for struct ADTs.
	* typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::resolve):
	Cancel reordering of struct field expressions.

Signed-off-by: Mohamed El Shorbagy <mohrizq895@gmail.com>
@elshorbagyx

elshorbagyx commented Sep 1, 2026 •

Copy link
Copy Markdown
Author

@philberty

I believe it is now ready

Comment on lines +831 to +833
auto _adt = static_cast<TyTy::ADTType *> (adt->clone ());
_adt->get_variants ()[0]->get_fields () = ordered_variant_fields;
tyty = _adt;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure creating a new type with reordered fields and treating trees constructed with that type the same as trees constructed with the old type will work.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I understand your concern -- could you elaborate ?


// it must be an ADT
rust_assert (tyty->get_kind () == TyTy::TypeKind::ADT);
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyty);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and adt, while used after tyty is updated, is not itself updated

@powerboat9

Copy link
Copy Markdown
Collaborator

It'd probably be better to create temporary variables, initialize them in order, then use them in the constructor expression

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Evaluation order in struct expressions can be incorrect

3 participants