mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Avoid hanging on complex matches
This commit is contained in:
parent
e67adf40c9
commit
040f37a99d
@ -67,7 +67,9 @@ impl<'p> MatchCheckCtx<'p> {
|
|||||||
) -> Result<UsefulnessReport<'p, Self>, ()> {
|
) -> Result<UsefulnessReport<'p, Self>, ()> {
|
||||||
// FIXME: Determine place validity correctly. For now, err on the safe side.
|
// FIXME: Determine place validity correctly. For now, err on the safe side.
|
||||||
let place_validity = PlaceValidity::MaybeInvalid;
|
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 {
|
fn is_uninhabited(&self, ty: &Ty) -> bool {
|
||||||
@ -476,7 +478,6 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn complexity_exceeded(&self) -> Result<(), Self::Error> {
|
fn complexity_exceeded(&self) -> Result<(), Self::Error> {
|
||||||
// FIXME(Nadrieril): make use of the complexity counter.
|
|
||||||
Err(())
|
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 {
|
mod rust_unstable {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user