2024-03-04 15:57:32 +00:00
|
|
|
//! Test the computation of arm intersections.
|
2024-06-19 19:04:30 +00:00
|
|
|
|
2024-03-04 15:57:32 +00:00
|
|
|
use common::*;
|
|
|
|
use rustc_pattern_analysis::MatchArm;
|
|
|
|
use rustc_pattern_analysis::pat::DeconstructedPat;
|
|
|
|
use rustc_pattern_analysis::usefulness::PlaceValidity;
|
|
|
|
|
|
|
|
#[macro_use]
|
|
|
|
mod common;
|
|
|
|
|
|
|
|
/// Analyze a match made of these patterns and returns the computed arm intersections.
|
|
|
|
fn check(patterns: Vec<DeconstructedPat<Cx>>) -> Vec<Vec<usize>> {
|
|
|
|
let ty = *patterns[0].ty();
|
|
|
|
let arms: Vec<_> =
|
|
|
|
patterns.iter().map(|pat| MatchArm { pat, has_guard: false, arm_data: () }).collect();
|
|
|
|
let report =
|
|
|
|
compute_match_usefulness(arms.as_slice(), ty, PlaceValidity::ValidOnly, None).unwrap();
|
|
|
|
report.arm_intersections.into_iter().map(|bitset| bitset.iter().collect()).collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[track_caller]
|
|
|
|
fn assert_intersects(patterns: Vec<DeconstructedPat<Cx>>, intersects: &[&[usize]]) {
|
|
|
|
let computed_intersects = check(patterns);
|
|
|
|
assert_eq!(computed_intersects, intersects);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_int_ranges() {
|
|
|
|
let ty = Ty::U8;
|
|
|
|
assert_intersects(
|
|
|
|
pats!(ty;
|
|
|
|
0..=100,
|
|
|
|
100..,
|
|
|
|
),
|
|
|
|
&[&[], &[0]],
|
|
|
|
);
|
|
|
|
assert_intersects(
|
|
|
|
pats!(ty;
|
|
|
|
0..=101,
|
|
|
|
100..,
|
|
|
|
),
|
|
|
|
&[&[], &[0]],
|
|
|
|
);
|
|
|
|
assert_intersects(
|
|
|
|
pats!(ty;
|
|
|
|
0..100,
|
|
|
|
100..,
|
|
|
|
),
|
|
|
|
&[&[], &[]],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_nested() {
|
|
|
|
let ty = Ty::Tuple(&[Ty::Bool; 2]);
|
|
|
|
assert_intersects(
|
|
|
|
pats!(ty;
|
|
|
|
(true, true),
|
|
|
|
(true, _),
|
|
|
|
(_, true),
|
|
|
|
),
|
|
|
|
&[&[], &[0], &[0, 1]],
|
|
|
|
);
|
|
|
|
// Here we shortcut because `(true, true)` is irrelevant, so we fail to detect the intersection.
|
|
|
|
assert_intersects(
|
|
|
|
pats!(ty;
|
|
|
|
(true, _),
|
|
|
|
(_, true),
|
|
|
|
),
|
|
|
|
&[&[], &[]],
|
|
|
|
);
|
2024-07-21 12:37:10 +00:00
|
|
|
let ty = Ty::Tuple(&[Ty::Bool; 3]);
|
|
|
|
assert_intersects(
|
|
|
|
pats!(ty;
|
|
|
|
(true, true, _),
|
|
|
|
(true, _, true),
|
|
|
|
(false, _, _),
|
|
|
|
),
|
|
|
|
&[&[], &[], &[]],
|
|
|
|
);
|
|
|
|
let ty = Ty::Tuple(&[Ty::Bool, Ty::Bool, Ty::U8]);
|
|
|
|
assert_intersects(
|
|
|
|
pats!(ty;
|
|
|
|
(true, _, _),
|
|
|
|
(_, true, 0..10),
|
|
|
|
(_, true, 10..),
|
|
|
|
(_, true, 3),
|
|
|
|
_,
|
|
|
|
),
|
|
|
|
&[&[], &[], &[], &[1], &[0, 1, 2, 3]],
|
|
|
|
);
|
2024-03-04 15:57:32 +00:00
|
|
|
}
|