https://gcc.gnu.org/g:d334ef54d14ea846eeee7dc912895d0c735696b9
commit r16-4844-gd334ef54d14ea846eeee7dc912895d0c735696b9 Author: Yap Zhi Heng <[email protected]> Date: Wed Aug 27 21:47:34 2025 +0800 gccrs: Implement missing var decl case for TuplePatternItemsHasRest GIMPLE dump from compiling issue-3930.rs: ... const i32 b; const i32 a; D.114.__0 = 2; D.114.__1 = 3; RUSTTMP.1 = D.114; a = RUSTTMP.1.__0; b = RUSTTMP.1.__1; ... gcc/rust/ChangeLog: * backend/rust-compile-var-decl.h (CompileVarDecl::visit(TuplePattern)): Implement variable declaration bindings for tuple patterns with rest pattern (i.e. TuplePatternItemsHasRest). Signed-off-by: Yap Zhi Heng <[email protected]> Diff: --- gcc/rust/backend/rust-compile-var-decl.h | 59 ++++++++++++++++++++++++++------ gcc/testsuite/rust/compile/issue-3930.rs | 4 +++ 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h index 15f3ebb3a6a7..1f306ade3f9e 100644 --- a/gcc/rust/backend/rust-compile-var-decl.h +++ b/gcc/rust/backend/rust-compile-var-decl.h @@ -77,27 +77,66 @@ public: void visit (HIR::TuplePattern &pattern) override { + rust_assert (TREE_CODE (translated_type) == RECORD_TYPE); switch (pattern.get_items ().get_item_type ()) { case HIR::TuplePatternItems::ItemType::NO_REST: { - rust_assert (TREE_CODE (translated_type) == RECORD_TYPE); - auto &items = static_cast<HIR::TuplePatternItemsNoRest &> ( + auto &items_no_rest = static_cast<HIR::TuplePatternItemsNoRest &> ( pattern.get_items ()); - size_t offs = 0; - for (auto &sub : items.get_patterns ()) + tree field = TYPE_FIELDS (translated_type); + for (auto &sub : items_no_rest.get_patterns ()) { - tree sub_ty = error_mark_node; - tree field = TYPE_FIELDS (translated_type); - for (size_t i = 0; i < offs; i++) + gcc_assert (field != NULL_TREE); + tree sub_ty = TREE_TYPE (field); + CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx); + field = DECL_CHAIN (field); + } + } + break; + + case HIR::TuplePatternItems::ItemType::HAS_REST: + { + auto &items_has_rest = static_cast<HIR::TuplePatternItemsHasRest &> ( + pattern.get_items ()); + + // count total fields in translated_type + size_t total_fields = 0; + for (tree t = TYPE_FIELDS (translated_type); t; t = DECL_CHAIN (t)) + { + total_fields++; + } + + // process lower patterns + tree field = TYPE_FIELDS (translated_type); + for (auto &sub : items_has_rest.get_lower_patterns ()) + { + gcc_assert (field != NULL_TREE); + tree sub_ty = TREE_TYPE (field); + CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx); + field = DECL_CHAIN (field); + } + + // process upper patterns + if (!items_has_rest.get_upper_patterns ().empty ()) + { + size_t upper_start + = total_fields - items_has_rest.get_upper_patterns ().size (); + field = TYPE_FIELDS (translated_type); + for (size_t i = 0; i < upper_start; i++) { field = DECL_CHAIN (field); gcc_assert (field != NULL_TREE); } - sub_ty = TREE_TYPE (field); - CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx); - offs++; + + for (auto &sub : items_has_rest.get_upper_patterns ()) + { + gcc_assert (field != NULL_TREE); + tree sub_ty = TREE_TYPE (field); + CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx); + field = DECL_CHAIN (field); + } } } break; diff --git a/gcc/testsuite/rust/compile/issue-3930.rs b/gcc/testsuite/rust/compile/issue-3930.rs new file mode 100644 index 000000000000..dfcd19a57650 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3930.rs @@ -0,0 +1,4 @@ +// { dg-additional-options "-w" } +fn main() { + let (a, .., b) = (2, 3); +}
