Skip to content

Commit 99edb1b

Browse files
Emit a warning if a match is too complex
1 parent a42873e commit 99edb1b

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

compiler/rustc_pattern_analysis/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ pub trait PatCx: Sized + fmt::Debug {
151151
_gapped_with: &[&DeconstructedPat<Self>],
152152
) {
153153
}
154+
155+
fn too_complex_match(&self);
154156
}
155157

156158
/// The arm of a match expression.

compiler/rustc_pattern_analysis/src/rustc.rs

+5
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,11 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
979979
);
980980
}
981981
}
982+
983+
fn too_complex_match(&self) {
984+
let span = self.whole_match_span.unwrap_or(self.scrut_span);
985+
self.tcx.dcx().span_warn(span, "`match` is too complex");
986+
}
982987
}
983988

984989
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.

compiler/rustc_pattern_analysis/src/usefulness.rs

+8
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ struct UsefulnessCtxt<'a, Cx: PatCx> {
736736
useful_subpatterns: FxHashSet<PatId>,
737737
complexity_limit: Option<usize>,
738738
complexity_level: usize,
739+
error_emitted: bool,
739740
}
740741

741742
impl<'a, Cx: PatCx> UsefulnessCtxt<'a, Cx> {
@@ -745,8 +746,14 @@ impl<'a, Cx: PatCx> UsefulnessCtxt<'a, Cx> {
745746
.complexity_limit
746747
.is_some_and(|complexity_limit| complexity_limit < self.complexity_level)
747748
{
749+
// We change it to `None` to prevent it from being called more than once.
750+
self.complexity_limit = None;
748751
return self.tycx.complexity_exceeded();
749752
}
753+
if !self.error_emitted && self.complexity_level > 10_000_000 {
754+
self.tycx.too_complex_match();
755+
self.error_emitted = true;
756+
}
750757
Ok(())
751758
}
752759
}
@@ -1754,6 +1761,7 @@ pub fn compute_match_usefulness<'p, Cx: PatCx>(
17541761
useful_subpatterns: FxHashSet::default(),
17551762
complexity_limit,
17561763
complexity_level: 0,
1764+
error_emitted: false,
17571765
};
17581766
let mut matrix = Matrix::new(arms, scrut_ty, scrut_validity);
17591767
let non_exhaustiveness_witnesses = compute_exhaustiveness_and_usefulness(&mut cx, &mut matrix)?;

0 commit comments

Comments
 (0)