From: lishin <[email protected]>
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 <[email protected]>
---
gcc/rust/backend/rust-compile-pattern.cc | 52 +++++++++++++++++++++++-
gcc/testsuite/rust/compile/issue-3645.rs | 6 +++
2 files changed, 56 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/issue-3645.rs
diff --git a/gcc/rust/backend/rust-compile-pattern.cc
b/gcc/rust/backend/rust-compile-pattern.cc
index e29dc92ea49..149f6b07411 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -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
index 00000000000..91285f1991b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3645.rs
@@ -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
--
2.50.1