diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-03-05 06:40:33 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-05 06:40:33 +0100 |
| commit | 44bd2b516609933a573403a0985ff9decde314ad (patch) | |
| tree | f9e65327bab8b6eb0be517e07ee6c40bc0246b28 /compiler/rustc_pattern_analysis | |
| parent | c483e637f3c58452308ae1a959d6a54a9043c49f (diff) | |
| parent | 2af01a2fef8909e65171fed6e45e5d568f736773 (diff) | |
| download | rust-44bd2b516609933a573403a0985ff9decde314ad.tar.gz rust-44bd2b516609933a573403a0985ff9decde314ad.zip | |
Rollup merge of #121987 - Nadrieril:abort-on-arity-mismatch, r=compiler-errors
pattern analysis: abort on arity mismatch This is one more PR replacing panics by `Err()` aborts. I recently audited all the `unwrap()` calls, but I had forgotten about array accesses. (Again [discovered by rust-analyzer](https://github.com/rust-lang/rust-analyzer/issues/16746)). r? ```@compiler-errors```
Diffstat (limited to 'compiler/rustc_pattern_analysis')
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/usefulness.rs | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 0261768d916..c518844cc5e 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -1001,19 +1001,26 @@ impl<'p, Cx: TypeCx> PatStack<'p, Cx> { /// Only call if `ctor.is_covered_by(self.head().ctor())` is true. fn pop_head_constructor( &self, + cx: &Cx, ctor: &Constructor<Cx>, ctor_arity: usize, ctor_is_relevant: bool, - ) -> PatStack<'p, Cx> { + ) -> Result<PatStack<'p, Cx>, Cx::Error> { // We pop the head pattern and push the new fields extracted from the arguments of // `self.head()`. let mut new_pats = self.head().specialize(ctor, ctor_arity); + if new_pats.len() != ctor_arity { + return Err(cx.bug(format_args!( + "uncaught type error: pattern {:?} has inconsistent arity (expected arity {ctor_arity})", + self.head().as_pat().unwrap() + ))); + } new_pats.extend_from_slice(&self.pats[1..]); // `ctor` is relevant for this row if it is the actual constructor of this row, or if the // row has a wildcard and `ctor` is relevant for wildcards. let ctor_is_relevant = !matches!(self.head().ctor(), Constructor::Wildcard) || ctor_is_relevant; - PatStack { pats: new_pats, relevant: self.relevant && ctor_is_relevant } + Ok(PatStack { pats: new_pats, relevant: self.relevant && ctor_is_relevant }) } } @@ -1083,18 +1090,19 @@ impl<'p, Cx: TypeCx> MatrixRow<'p, Cx> { /// Only call if `ctor.is_covered_by(self.head().ctor())` is true. fn pop_head_constructor( &self, + cx: &Cx, ctor: &Constructor<Cx>, ctor_arity: usize, ctor_is_relevant: bool, parent_row: usize, - ) -> MatrixRow<'p, Cx> { - MatrixRow { - pats: self.pats.pop_head_constructor(ctor, ctor_arity, ctor_is_relevant), + ) -> Result<MatrixRow<'p, Cx>, Cx::Error> { + Ok(MatrixRow { + pats: self.pats.pop_head_constructor(cx, ctor, ctor_arity, ctor_is_relevant)?, parent_row, is_under_guard: self.is_under_guard, useful: false, intersects: BitSet::new_empty(0), // Initialized in `Matrix::expand_and_push`. - } + }) } } @@ -1217,7 +1225,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> { }; for (i, row) in self.rows().enumerate() { if ctor.is_covered_by(pcx.cx, row.head().ctor())? { - let new_row = row.pop_head_constructor(ctor, arity, ctor_is_relevant, i); + let new_row = row.pop_head_constructor(pcx.cx, ctor, arity, ctor_is_relevant, i)?; matrix.expand_and_push(new_row); } } |
