diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs
index 71aefa85c99fd..37ad5f5ea4e38 100644
--- a/src/librustc_mir_build/hair/pattern/_match.rs
+++ b/src/librustc_mir_build/hair/pattern/_match.rs
@@ -480,7 +480,11 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
     /// Pushes a new row to the matrix. If the row starts with an or-pattern, this expands it.
     crate fn push(&mut self, row: PatStack<'p, 'tcx>) {
         if let Some(rows) = row.expand_or_pat() {
-            self.0.extend(rows);
+            for row in rows {
+                // We recursively expand the or-patterns of the new rows.
+                // This is necessary as we might have `0 | (1 | 2)` or e.g., `x @ 0 | x @ (1 | 2)`.
+                self.push(row)
+            }
         } else {
             self.0.push(row);
         }
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs
new file mode 100644
index 0000000000000..59533cefea64c
--- /dev/null
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs
@@ -0,0 +1,9 @@
+#![feature(or_patterns)]
+
+fn main() {
+    let 0 | (1 | 2) = 0; //~ ERROR refutable pattern in local binding
+    match 0 {
+        //~^ ERROR non-exhaustive patterns
+        0 | (1 | 2) => {}
+    }
+}
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
new file mode 100644
index 0000000000000..58286e87869a4
--- /dev/null
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
@@ -0,0 +1,25 @@
+error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `3i32..=std::i32::MAX` not covered
+  --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:4:9
+   |
+LL |     let 0 | (1 | 2) = 0;
+   |         ^^^^^^^^^^^ patterns `std::i32::MIN..=-1i32` and `3i32..=std::i32::MAX` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |     if let 0 | (1 | 2) = 0 { /* */ }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0004]: non-exhaustive patterns: `std::i32::MIN..=-1i32` and `3i32..=std::i32::MAX` not covered
+  --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:5:11
+   |
+LL |     match 0 {
+   |           ^ patterns `std::i32::MIN..=-1i32` and `3i32..=std::i32::MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0004, E0005.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs
new file mode 100644
index 0000000000000..1de563dedbf18
--- /dev/null
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![feature(or_patterns)]
+
+fn main() {
+    let 0 | (1 | _) = 0;
+    if let 0 | (1 | 2) = 0 {}
+    if let x @ 0 | x @ (1 | 2) = 0 {}
+}