]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: fix ICE in convert_tree for tuple destructuring with ref
authorlishin <lishin1008@gmail.com>
Sun, 10 Aug 2025 21:21:59 +0000 (22:21 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 19:58:41 +0000 (20:58 +0100)
gcc/rust/ChangeLog:

* backend/rust-compile-pattern.cc (CompilePatternLet::visit):
Handle tuple destructuring containing by-ref.

gcc/testsuite/ChangeLog:

* rust/compile/issue-3645.rs: New test.

Signed-off-by: lishin <lishin1008@gmail.com>
gcc/rust/backend/rust-compile-pattern.cc
gcc/testsuite/rust/compile/issue-3645.rs [new file with mode: 0644]

index e29dc92ea49b44ba944cef4f1f96a068298a5a27..149f6b0741135475dd0e72e4dce740da1b79cb83 100644 (file)
@@ -1165,6 +1165,11 @@ CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
   rust_assert (
     ctx->lookup_var_decl (pattern.get_mappings ().get_hirid (), &var));
 
+  if (pattern.get_is_ref ())
+    {
+      init_expr = address_expression (init_expr, EXPR_LOCATION (init_expr));
+    }
+
   auto fnctx = ctx->peek_fn ();
   if (ty->is_unit ())
     {
@@ -1204,11 +1209,54 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
 {
   rust_assert (pattern.has_tuple_pattern_items ());
 
-  tree tuple_type = TyTyResolveCompile::compile (ctx, ty);
+  bool has_by_ref = false;
+  auto check_refs
+    = [] (const std::vector<std::unique_ptr<HIR::Pattern>> &patterns) {
+       for (const auto &sub : patterns)
+         {
+           switch (sub->get_pattern_type ())
+             {
+             case HIR::Pattern::PatternType::IDENTIFIER:
+               {
+                 auto id = static_cast<HIR::IdentifierPattern *> (sub.get ());
+                 if (id->get_is_ref ())
+                   return true;
+                 break;
+               }
+             case HIR::Pattern::PatternType::REFERENCE:
+               return true;
+             default:
+               break;
+             }
+         }
+       return false;
+      };
+  switch (pattern.get_items ().get_item_type ())
+    {
+    case HIR::TuplePatternItems::ItemType::NO_REST:
+      {
+       auto &items
+         = static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
+       has_by_ref = check_refs (items.get_patterns ());
+       break;
+      }
+    case HIR::TuplePatternItems::ItemType::HAS_REST:
+      {
+       auto &items
+         = static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
+       has_by_ref = check_refs (items.get_lower_patterns ())
+                    || check_refs (items.get_upper_patterns ());
+       break;
+      }
+    default:
+      break;
+    }
+
+  tree rhs_tuple_type = TYPE_MAIN_VARIANT (TREE_TYPE (init_expr));
   tree init_stmt;
   Bvariable *tmp_var
     = Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
-                                  tuple_type, init_expr, false,
+                                  rhs_tuple_type, init_expr, has_by_ref,
                                   pattern.get_locus (), &init_stmt);
   tree access_expr = Backend::var_expression (tmp_var, pattern.get_locus ());
   ctx->add_statement (init_stmt);
diff --git a/gcc/testsuite/rust/compile/issue-3645.rs b/gcc/testsuite/rust/compile/issue-3645.rs
new file mode 100644 (file)
index 0000000..91285f1
--- /dev/null
@@ -0,0 +1,6 @@
+// { dg-warning "unused name 'y'" "" { target *-*-* } 5 }
+// { dg-warning "unused name 'z'" "" { target *-*-* } 5 }
+
+fn main() {
+    let (ref y,z) = (1i32, 2u32);
+}
\ No newline at end of file