]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: fix bug in pattern check for tuples
authorPhilip Herron <herron.philip@googlemail.com>
Sun, 4 Feb 2024 17:07:05 +0000 (17:07 +0000)
committerPhilip Herron <philip.herron@embecosm.com>
Mon, 5 Feb 2024 01:57:04 +0000 (01:57 +0000)
We can point to generic parent types which means we need to do the shallow
resolve thing that rustc does. We have destructure which is similar to get
what the parameter type points to.

Fixes #2775

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): use destructure

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/typecheck/rust-hir-type-check-pattern.cc
gcc/testsuite/rust/compile/issue-2775.rs [new file with mode: 0644]

index 7ad0147327cbf7941ae559b04055547b3d0ea10d..9d74def0b5c6b1bb753f873aed7e3562a71578bf 100644 (file)
@@ -302,7 +302,8 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
          = *static_cast<HIR::TuplePatternItemsMultiple *> (
            pattern.get_items ().get ());
 
-       if (parent->get_kind () != TyTy::TUPLE)
+       auto resolved_parent = parent->destructure ();
+       if (resolved_parent->get_kind () != TyTy::TUPLE)
          {
            rust_error_at (pattern.get_locus (), "expected %s, found tuple",
                           parent->as_string ().c_str ());
@@ -312,7 +313,8 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
        const auto &patterns = ref.get_patterns ();
        size_t nitems_to_resolve = patterns.size ();
 
-       TyTy::TupleType &par = *static_cast<TyTy::TupleType *> (parent);
+       TyTy::TupleType &par
+         = *static_cast<TyTy::TupleType *> (resolved_parent);
        if (patterns.size () != par.get_fields ().size ())
          {
            emit_pattern_size_error (pattern, par.get_fields ().size (),
diff --git a/gcc/testsuite/rust/compile/issue-2775.rs b/gcc/testsuite/rust/compile/issue-2775.rs
new file mode 100644 (file)
index 0000000..3ad7085
--- /dev/null
@@ -0,0 +1,11 @@
+// { dg-options "-w" }
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Ref<'a, T> {
+    x: &'a T,
+}
+
+pub fn test<'a, 'b, 'c>() {
+    let (_, &&Ref::<(&'_ i32, i32)> { x: &(a, b) }): (i32, &'_ &'b Ref<'b, (&'c i32, i32)>);
+}