Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs5
-rw-r--r--crates/ide-diagnostics/src/handlers/missing_match_arms.rs23
2 files changed, 26 insertions, 2 deletions
diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
index dfe082cb56..f45beb4c92 100644
--- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
+++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -67,7 +67,9 @@ impl<'p> MatchCheckCtx<'p> {
) -> Result<UsefulnessReport<'p, Self>, ()> {
// FIXME: Determine place validity correctly. For now, err on the safe side.
let place_validity = PlaceValidity::MaybeInvalid;
- compute_match_usefulness(self, arms, scrut_ty, place_validity, None)
+ // Measured to take ~100ms on modern hardware.
+ let complexity_limit = Some(500000);
+ compute_match_usefulness(self, arms, scrut_ty, place_validity, complexity_limit)
}
fn is_uninhabited(&self, ty: &Ty) -> bool {
@@ -476,7 +478,6 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
}
fn complexity_exceeded(&self) -> Result<(), Self::Error> {
- // FIXME(Nadrieril): make use of the complexity counter.
Err(())
}
}
diff --git a/crates/ide-diagnostics/src/handlers/missing_match_arms.rs b/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
index 67daa172b2..c03bb3aeb5 100644
--- a/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
+++ b/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
@@ -1004,6 +1004,29 @@ fn f() {
);
}
+ #[test]
+ fn exponential_match() {
+ // Constructs a match where match checking takes exponential time. Ensures we bail early.
+ use std::fmt::Write;
+ let struct_arity = 30;
+ let mut code = String::new();
+ write!(code, "struct BigStruct {{").unwrap();
+ for i in 0..struct_arity {
+ write!(code, " field{i}: bool,").unwrap();
+ }
+ write!(code, "}}").unwrap();
+ write!(code, "fn big_match(s: BigStruct) {{").unwrap();
+ write!(code, " match s {{").unwrap();
+ for i in 0..struct_arity {
+ write!(code, " BigStruct {{ field{i}: true, ..}} => {{}},").unwrap();
+ write!(code, " BigStruct {{ field{i}: false, ..}} => {{}},").unwrap();
+ }
+ write!(code, " _ => {{}},").unwrap();
+ write!(code, " }}").unwrap();
+ write!(code, "}}").unwrap();
+ check_diagnostics_no_bails(&code);
+ }
+
mod rust_unstable {
use super::*;