Skip to content

Commit 040f37a

Browse files
committed
Avoid hanging on complex matches
1 parent e67adf4 commit 040f37a

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ impl<'p> MatchCheckCtx<'p> {
6767
) -> Result<UsefulnessReport<'p, Self>, ()> {
6868
// FIXME: Determine place validity correctly. For now, err on the safe side.
6969
let place_validity = PlaceValidity::MaybeInvalid;
70-
compute_match_usefulness(self, arms, scrut_ty, place_validity, None)
70+
// Measured to take ~100ms on modern hardware.
71+
let complexity_limit = Some(500000);
72+
compute_match_usefulness(self, arms, scrut_ty, place_validity, complexity_limit)
7173
}
7274

7375
fn is_uninhabited(&self, ty: &Ty) -> bool {
@@ -476,7 +478,6 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
476478
}
477479

478480
fn complexity_exceeded(&self) -> Result<(), Self::Error> {
479-
// FIXME(Nadrieril): make use of the complexity counter.
480481
Err(())
481482
}
482483
}

crates/ide-diagnostics/src/handlers/missing_match_arms.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,29 @@ fn f() {
10041004
);
10051005
}
10061006

1007+
#[test]
1008+
fn exponential_match() {
1009+
// Constructs a match where match checking takes exponential time. Ensures we bail early.
1010+
use std::fmt::Write;
1011+
let struct_arity = 30;
1012+
let mut code = String::new();
1013+
write!(code, "struct BigStruct {{").unwrap();
1014+
for i in 0..struct_arity {
1015+
write!(code, " field{i}: bool,").unwrap();
1016+
}
1017+
write!(code, "}}").unwrap();
1018+
write!(code, "fn big_match(s: BigStruct) {{").unwrap();
1019+
write!(code, " match s {{").unwrap();
1020+
for i in 0..struct_arity {
1021+
write!(code, " BigStruct {{ field{i}: true, ..}} => {{}},").unwrap();
1022+
write!(code, " BigStruct {{ field{i}: false, ..}} => {{}},").unwrap();
1023+
}
1024+
write!(code, " _ => {{}},").unwrap();
1025+
write!(code, " }}").unwrap();
1026+
write!(code, "}}").unwrap();
1027+
check_diagnostics_no_bails(&code);
1028+
}
1029+
10071030
mod rust_unstable {
10081031
use super::*;
10091032

0 commit comments

Comments
 (0)