Skip to content

Commit 0b27605

Browse files
committed
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 <[email protected]>
1 parent af5f096 commit 0b27605

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

gcc/rust/backend/rust-compile-pattern.cc

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,11 @@ CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
979979
rust_assert (
980980
ctx->lookup_var_decl (pattern.get_mappings ().get_hirid (), &var));
981981

982+
if (pattern.get_is_ref ())
983+
{
984+
init_expr = address_expression (init_expr, EXPR_LOCATION (init_expr));
985+
}
986+
982987
auto fnctx = ctx->peek_fn ();
983988
if (ty->is_unit ())
984989
{
@@ -1013,11 +1018,54 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
10131018
{
10141019
rust_assert (pattern.has_tuple_pattern_items ());
10151020

1016-
tree tuple_type = TyTyResolveCompile::compile (ctx, ty);
1021+
bool has_by_ref = false;
1022+
auto check_refs
1023+
= [] (const std::vector<std::unique_ptr<HIR::Pattern>> &patterns) {
1024+
for (const auto &sub : patterns)
1025+
{
1026+
switch (sub->get_pattern_type ())
1027+
{
1028+
case HIR::PatternType::IDENTIFIER:
1029+
{
1030+
auto id = static_cast<HIR::IdentifierPattern *> (sub.get ());
1031+
if (id->get_is_ref ())
1032+
return true;
1033+
break;
1034+
}
1035+
case HIR::PatternType::REFERENCE:
1036+
return true;
1037+
default:
1038+
break;
1039+
}
1040+
}
1041+
return false;
1042+
};
1043+
switch (pattern.get_items ().get_item_type ())
1044+
{
1045+
case HIR::TuplePatternItems::ItemType::NO_REST:
1046+
{
1047+
auto &items
1048+
= static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
1049+
has_by_ref = check_refs (items.get_patterns ());
1050+
break;
1051+
}
1052+
case HIR::TuplePatternItems::ItemType::HAS_REST:
1053+
{
1054+
auto &items
1055+
= static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
1056+
has_by_ref = check_refs (items.get_lower_patterns ())
1057+
|| check_refs (items.get_upper_patterns ());
1058+
break;
1059+
}
1060+
default:
1061+
break;
1062+
}
1063+
1064+
tree rhs_tuple_type = TYPE_MAIN_VARIANT (TREE_TYPE (init_expr));
10171065
tree init_stmt;
10181066
Bvariable *tmp_var
10191067
= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
1020-
tuple_type, init_expr, false,
1068+
rhs_tuple_type, init_expr, has_by_ref,
10211069
pattern.get_locus (), &init_stmt);
10221070
tree access_expr = Backend::var_expression (tmp_var, pattern.get_locus ());
10231071
ctx->add_statement (init_stmt);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// { dg-warning "unused name 'y'" "" { target *-*-* } 5 }
2+
// { dg-warning "unused name 'z'" "" { target *-*-* } 5 }
3+
4+
fn main() {
5+
let (ref y,z) = (1i32, 2u32);
6+
}

0 commit comments

Comments
 (0)