Avoid hanging on complex matches
This commit is contained in:
parent
e67adf40c9
commit
040f37a99d
2 changed files with 26 additions and 2 deletions
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::*;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue