From: lishin Date: Sun, 10 Aug 2025 21:21:59 +0000 (+0100) Subject: gccrs: fix ICE in convert_tree for tuple destructuring with ref X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b76bb3f2260bdbf61577585f2a4476ba88b57c12;p=thirdparty%2Fgcc.git gccrs: fix ICE in convert_tree for tuple destructuring with ref 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 --- 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> &patterns) { + for (const auto &sub : patterns) + { + switch (sub->get_pattern_type ()) + { + case HIR::Pattern::PatternType::IDENTIFIER: + { + auto id = static_cast (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 (pattern.get_items ()); + has_by_ref = check_refs (items.get_patterns ()); + break; + } + case HIR::TuplePatternItems::ItemType::HAS_REST: + { + auto &items + = static_cast (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