106 lines
3.4 KiB
Plaintext
106 lines
3.4 KiB
Plaintext
|
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.
|
||
|
|