File: intersection.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg3-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, sid, trixie
  • size: 893,396 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; perl: 29; lisp: 29; ruby: 19; sql: 11
file content (92 lines) | stat: -rw-r--r-- 2,314 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! Test the computation of arm intersections.

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),
        ),
        &[&[], &[]],
    );
    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]],
    );
}