LL| |#![feature(coverage_attribute)] | |
LL| |//@ edition: 2021 | |
LL| |//@ compile-flags: -Zcoverage-options=branch | |
LL| |//@ llvm-cov-flags: --show-branches=count | |
LL| | | |
LL| |// Tests for branch coverage of various kinds of match arms. | |
LL| | | |
LL| |// Helper macro to prevent start-of-function spans from being merged into | |
LL| |// spans on the lines we care about. | |
LL| |macro_rules! no_merge { | |
LL| | () => { | |
LL| | for _ in 0..1 {} | |
LL| | }; | |
LL| |} | |
LL| | | |
LL| |#[derive(Clone, Copy, Debug)] | |
LL| |enum Enum { | |
LL| | A(u32), | |
LL| | B(u32), | |
LL| | C(u32), | |
LL| | D(u32), | |
LL| |} | |
LL| | | |
LL| 15|fn match_arms(value: Enum) { | |
LL| 15| no_merge!(); | |
LL| | | |
LL| 15| match value { | |
LL| 8| Enum::D(d) => consume(d), | |
LL| 4| Enum::C(c) => consume(c), | |
LL| 2| Enum::B(b) => consume(b), | |
LL| 1| Enum::A(a) => consume(a), | |
LL| | } | |
LL| | | |
LL| 15| consume(0); | |
LL| 15|} | |
LL| | | |
LL| 15|fn or_patterns(value: Enum) { | |
LL| 15| no_merge!(); | |
LL| | | |
LL| 15| match value { | |
LL| 12| Enum::D(x) | Enum::C(x) => consume(x), | |
^8 ^4 | |
LL| 3| Enum::B(y) | Enum::A(y) => consume(y), | |
^2 ^1 | |
LL| | } | |
LL| | | |
LL| 15| consume(0); | |
LL| 15|} | |
LL| | | |
LL| 45|fn guards(value: Enum, cond: bool) { | |
LL| 45| no_merge!(); | |
LL| | | |
LL| 3| match value { | |
LL| 8| Enum::D(d) if cond => consume(d), | |
------------------ | |
| Branch (LL:23): [True: 8, False: 16] | |
------------------ | |
LL| 4| Enum::C(c) if cond => consume(c), | |
------------------ | |
| Branch (LL:23): [True: 4, False: 8] | |
------------------ | |
LL| 2| Enum::B(b) if cond => consume(b), | |
------------------ | |
| Branch (LL:23): [True: 2, False: 4] | |
------------------ | |
LL| 1| Enum::A(a) if cond => consume(a), | |
------------------ | |
| Branch (LL:23): [True: 1, False: 2] | |
------------------ | |
LL| 30| _ => consume(0), | |
LL| | } | |
LL| | | |
LL| 45| consume(0); | |
LL| 45|} | |
LL| | | |
LL| |#[coverage(off)] | |
LL| |fn consume<T>(x: T) { | |
LL| | core::hint::black_box(x); | |
LL| |} | |
LL| | | |
LL| |#[coverage(off)] | |
LL| |fn main() { | |
LL| | #[coverage(off)] | |
LL| | fn call_everything(e: Enum) { | |
LL| | match_arms(e); | |
LL| | or_patterns(e); | |
LL| | for cond in [false, false, true] { | |
LL| | guards(e, cond); | |
LL| | } | |
LL| | } | |
LL| | | |
LL| | call_everything(Enum::A(0)); | |
LL| | for b in 0..2 { | |
LL| | call_everything(Enum::B(b)); | |
LL| | } | |
LL| | for c in 0..4 { | |
LL| | call_everything(Enum::C(c)); | |
LL| | } | |
LL| | for d in 0..8 { | |
LL| | call_everything(Enum::D(d)); | |
LL| | } | |
LL| |} | |
LL| | | |
LL| |// FIXME(#124118) Actually instrument match arms for branch coverage. | |