From: Yap Zhi Heng <[email protected]>
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]>
---
gcc/rust/backend/rust-compile-var-decl.h | 59 ++++++++++++++++++++----
gcc/testsuite/rust/compile/issue-3930.rs | 4 ++
2 files changed, 53 insertions(+), 10 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/issue-3930.rs
diff --git a/gcc/rust/backend/rust-compile-var-decl.h
b/gcc/rust/backend/rust-compile-var-decl.h
index 15f3ebb3a6a..1f306ade3f9 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 00000000000..dfcd19a5765
--- /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);
+}
--
2.50.1