From: Utkarsh Bahuguna <[email protected]>
PatStack::pop_head_constructor appended the sub-patterns of the head at
the back of the row, while Matrix::specialize puts their types at the
front of the column list. With a nested pattern that has fields inside a
constructor with several fields, the patterns and their types ended up in
different columns and split_constructors hit its ADT assertion. Insert
the sub-patterns in front of the remaining columns instead.
Fixes Rust-GCC/gccrs#4973
gcc/rust/ChangeLog:
* checks/errors/rust-hir-pattern-analysis.cc
(PatStack::pop_head_constructor): Insert the sub-patterns in front of
the remaining columns.
gcc/testsuite/ChangeLog:
* rust/compile/exhaustiveness5.rs: New test.
* rust/compile/issues/issue-4973.rs: New test.
Signed-off-by: Utkarsh Bahuguna <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/fc0c9e3326124b300cb2ad918629ca469eaa7ade
The commit has been mentioned in the following issue(s):
- Rust-GCC/gccrs#4973: https://github.com/Rust-GCC/gccrs/issues/4973
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4974
.../errors/rust-hir-pattern-analysis.cc | 5 ++-
gcc/testsuite/rust/compile/exhaustiveness5.rs | 34 ++++++++++++++++
.../rust/compile/issues/issue-4973.rs | 39 +++++++++++++++++++
3 files changed, 76 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/exhaustiveness5.rs
create mode 100644 gcc/testsuite/rust/compile/issues/issue-4973.rs
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index 456b3afb9..3f4e35b3a 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -927,8 +927,9 @@ PatStack::pop_head_constructor (const Constructor
&other_ctor,
other_ctor.to_string ().c_str (), s.c_str ());
}
pop_head ();
- for (auto &pat : v)
- pats.push_back (pat);
+ // The sub-patterns replace the head, in order, in front of the remaining
+ // columns, matching the order Matrix::specialize gives their types.
+ pats.insert (pats.begin (), v.begin (), v.end ());
}
std::string
diff --git a/gcc/testsuite/rust/compile/exhaustiveness5.rs
b/gcc/testsuite/rust/compile/exhaustiveness5.rs
new file mode 100644
index 000000000..032f75744
--- /dev/null
+++ b/gcc/testsuite/rust/compile/exhaustiveness5.rs
@@ -0,0 +1,34 @@
+#![feature(no_core)]
+#![no_core]
+
+// Adapted from rustc's tests/ui/pattern/issue-6449.rs, which used to crash
+// the exhaustiveness check. The `..` rest patterns of the original are spelled
+// out with wildcards here.
+
+enum Foo {
+ Bar(isize),
+ Baz,
+}
+
+enum Other {
+ Other1(Foo),
+ Other2(Foo, Foo),
+}
+
+fn main() {
+ match Foo::Baz {
+ crate::Foo::Bar(3) => {}
+ crate::Foo::Bar(_) if false => {}
+ crate::Foo::Bar(_) if false => {}
+ crate::Foo::Bar(_n) => {}
+ crate::Foo::Baz => {}
+ }
+
+ match Other::Other1(Foo::Baz) {
+ crate::Other::Other1(crate::Foo::Baz) => {}
+ crate::Other::Other1(crate::Foo::Bar(_)) => {}
+ crate::Other::Other2(crate::Foo::Baz, crate::Foo::Bar(_)) => {}
+ crate::Other::Other2(crate::Foo::Bar(_), crate::Foo::Baz) => {}
+ crate::Other::Other2(_, _) => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issues/issue-4973.rs
b/gcc/testsuite/rust/compile/issues/issue-4973.rs
new file mode 100644
index 000000000..5b9c4331b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issues/issue-4973.rs
@@ -0,0 +1,39 @@
+#![feature(no_core)]
+#![no_core]
+
+// Rust-GCC/gccrs#4973: a pattern with fields nested in a constructor with
+// several fields used to put the sub-patterns and their types in different
+// columns, and crashed.
+
+enum Foo {
+ Bar(isize),
+ Baz(),
+}
+
+struct Pair(Foo, Foo);
+
+// This is a valid match
+fn f(x: Pair) {
+ match x {
+ Pair(Foo::Bar(_), Foo::Bar(_)) => {}
+ Pair(_, _) => {}
+ }
+}
+
+fn f2(x: Pair) {
+ match x {
+ // { dg-error "non-exhaustive patterns: 'Pair . 0: Foo::Bar..., 1:
Foo::Bar... .' not covered" "" { target *-*-* } .-1 }
+ Pair(Foo::Bar(_), Foo::Baz()) => {}
+ Pair(Foo::Baz(), _) => {}
+ }
+}
+
+fn f3(x: Pair) {
+ match x {
+ // { dg-error "non-exhaustive patterns: 'Pair . 0: Foo::Baz.., 1:
Foo::Baz.. .' not covered" "" { target *-*-* } .-1 }
+ Pair(Foo::Baz(), Foo::Bar(_)) => {}
+ Pair(Foo::Bar(_), _) => {}
+ }
+}
+
+fn main() {}
base-commit: 0b70380e60d04b0f47e3657dcbe68899aafe1663
--
2.55.0