about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2024-06-22 16:34:24 +1000
committerZalathar <Zalathar@users.noreply.github.com>2024-06-26 10:08:05 +1000
commit3262611cc5db7ce83dee4268fb1901311b24e5fc (patch)
tree80dec6e064445041abcacf06b0154a34b1e428d1
parent457fda1701e191d9ff439d9d01ee650e6bbefee6 (diff)
downloadrust-3262611cc5db7ce83dee4268fb1901311b24e5fc.tar.gz
rust-3262611cc5db7ce83dee4268fb1901311b24e5fc.zip
coverage: Apply `#[coverage(..)]` recursively to nested functions
-rw-r--r--compiler/rustc_middle/src/query/mod.rs3
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs12
-rw-r--r--tests/coverage/attr/nested.cov-map82
-rw-r--r--tests/coverage/attr/nested.coverage74
-rw-r--r--tests/coverage/attr/off-on-sandwich.cov-map8
-rw-r--r--tests/coverage/attr/off-on-sandwich.coverage10
-rw-r--r--tests/coverage/no_cov_crate.cov-map13
-rw-r--r--tests/coverage/no_cov_crate.coverage14
8 files changed, 60 insertions, 156 deletions
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 320e21e85da..230a44bcf24 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -572,7 +572,8 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    /// Checks for `#[coverage(off)]` or `#[coverage(on)]`.
+    /// Checks for the nearest `#[coverage(off)]` or `#[coverage(on)]` on
+    /// this def and any enclosing defs, up to the crate root.
     ///
     /// Returns `false` if `#[coverage(off)]` was found, or `true` if
     /// either `#[coverage(on)]` or no coverage attribute was found.
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index 14dcb7ef424..1fce2abbbbf 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -55,6 +55,7 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
 
 /// Query implementation for `coverage_attr_on`.
 fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
+    // Check for annotations directly on this def.
     if let Some(attr) = tcx.get_attr(def_id, sym::coverage) {
         match attr.meta_item_list().as_deref() {
             Some([item]) if item.has_name(sym::off) => return false,
@@ -66,9 +67,14 @@ fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
         }
     }
 
-    // We didn't see an explicit coverage attribute, so
-    // allow coverage instrumentation by default.
-    true
+    match tcx.opt_local_parent(def_id) {
+        // Check the parent def (and so on recursively) until we find an
+        // enclosing attribute or reach the crate root.
+        Some(parent) => tcx.coverage_attr_on(parent),
+        // We reached the crate root without seeing a coverage attribute, so
+        // allow coverage instrumentation by default.
+        None => true,
+    }
 }
 
 /// Query implementation for `coverage_ids_info`.
diff --git a/tests/coverage/attr/nested.cov-map b/tests/coverage/attr/nested.cov-map
index a613bb7f8cd..0f2d5542f75 100644
--- a/tests/coverage/attr/nested.cov-map
+++ b/tests/coverage/attr/nested.cov-map
@@ -1,35 +1,3 @@
-Function name: <<<nested::MyOuter as nested::MyTrait>::trait_method::MyMiddle as nested::MyTrait>::trait_method::MyInner as nested::MyTrait>::trait_method (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 39, 15, 02, 16]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 57, 21) to (start + 2, 22)
-
-Function name: <<<nested::MyOuter>::outer_method::MyMiddle>::middle_method::MyInner>::inner_method (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 23, 15, 02, 16]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 35, 21) to (start + 2, 22)
-
-Function name: <<nested::MyOuter as nested::MyTrait>::trait_method::MyMiddle as nested::MyTrait>::trait_method (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 36, 0d, 08, 0e]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 54, 13) to (start + 8, 14)
-
-Function name: <<nested::MyOuter>::outer_method::MyMiddle>::middle_method (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 20, 0d, 08, 0e]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 32, 13) to (start + 8, 14)
-
 Function name: nested::closure_expr
 Raw bytes (14): 0x[01, 01, 00, 02, 01, 44, 01, 01, 0f, 01, 0b, 05, 01, 02]
 Number of files: 1
@@ -39,23 +7,6 @@ Number of file 0 mappings: 2
 - Code(Counter(0)) at (prev + 68, 1) to (start + 1, 15)
 - Code(Counter(0)) at (prev + 11, 5) to (start + 1, 2)
 
-Function name: nested::closure_expr::{closure#0}::{closure#0} (unused)
-Raw bytes (14): 0x[01, 01, 00, 02, 00, 47, 1a, 01, 17, 00, 04, 0d, 01, 0a]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Zero) at (prev + 71, 26) to (start + 1, 23)
-- Code(Zero) at (prev + 4, 13) to (start + 1, 10)
-
-Function name: nested::closure_expr::{closure#0}::{closure#0}::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 48, 1d, 02, 0e]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 72, 29) to (start + 2, 14)
-
 Function name: nested::closure_tail
 Raw bytes (14): 0x[01, 01, 00, 02, 01, 53, 01, 01, 0f, 01, 11, 05, 01, 02]
 Number of files: 1
@@ -65,36 +16,3 @@ Number of file 0 mappings: 2
 - Code(Counter(0)) at (prev + 83, 1) to (start + 1, 15)
 - Code(Counter(0)) at (prev + 17, 5) to (start + 1, 2)
 
-Function name: nested::closure_tail::{closure#0}::{closure#0} (unused)
-Raw bytes (14): 0x[01, 01, 00, 02, 00, 58, 14, 01, 1f, 00, 06, 15, 01, 12]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 2
-- Code(Zero) at (prev + 88, 20) to (start + 1, 31)
-- Code(Zero) at (prev + 6, 21) to (start + 1, 18)
-
-Function name: nested::closure_tail::{closure#0}::{closure#0}::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 5a, 1c, 02, 1a]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 90, 28) to (start + 2, 26)
-
-Function name: nested::outer_fn::middle_fn (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 05, 05, 06]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 17, 5) to (start + 5, 6)
-
-Function name: nested::outer_fn::middle_fn::inner_fn (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 00, 12, 09, 02, 0a]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Zero) at (prev + 18, 9) to (start + 2, 10)
-
diff --git a/tests/coverage/attr/nested.coverage b/tests/coverage/attr/nested.coverage
index 13129572aec..bdd117b7dfa 100644
--- a/tests/coverage/attr/nested.coverage
+++ b/tests/coverage/attr/nested.coverage
@@ -14,12 +14,12 @@
    LL|       |
    LL|       |#[coverage(off)]
    LL|       |fn outer_fn() {
-   LL|      0|    fn middle_fn() {
-   LL|      0|        fn inner_fn() {
-   LL|      0|            do_stuff();
-   LL|      0|        }
-   LL|      0|        do_stuff();
-   LL|      0|    }
+   LL|       |    fn middle_fn() {
+   LL|       |        fn inner_fn() {
+   LL|       |            do_stuff();
+   LL|       |        }
+   LL|       |        do_stuff();
+   LL|       |    }
    LL|       |    do_stuff();
    LL|       |}
    LL|       |
@@ -29,15 +29,15 @@
    LL|       |    fn outer_method(&self) {
    LL|       |        struct MyMiddle;
    LL|       |        impl MyMiddle {
-   LL|      0|            fn middle_method(&self) {
-   LL|      0|                struct MyInner;
-   LL|      0|                impl MyInner {
-   LL|      0|                    fn inner_method(&self) {
-   LL|      0|                        do_stuff();
-   LL|      0|                    }
-   LL|      0|                }
-   LL|      0|                do_stuff();
-   LL|      0|            }
+   LL|       |            fn middle_method(&self) {
+   LL|       |                struct MyInner;
+   LL|       |                impl MyInner {
+   LL|       |                    fn inner_method(&self) {
+   LL|       |                        do_stuff();
+   LL|       |                    }
+   LL|       |                }
+   LL|       |                do_stuff();
+   LL|       |            }
    LL|       |        }
    LL|       |        do_stuff();
    LL|       |    }
@@ -51,15 +51,15 @@
    LL|       |    fn trait_method(&self) {
    LL|       |        struct MyMiddle;
    LL|       |        impl MyTrait for MyMiddle {
-   LL|      0|            fn trait_method(&self) {
-   LL|      0|                struct MyInner;
-   LL|      0|                impl MyTrait for MyInner {
-   LL|      0|                    fn trait_method(&self) {
-   LL|      0|                        do_stuff();
-   LL|      0|                    }
-   LL|      0|                }
-   LL|      0|                do_stuff();
-   LL|      0|            }
+   LL|       |            fn trait_method(&self) {
+   LL|       |                struct MyInner;
+   LL|       |                impl MyTrait for MyInner {
+   LL|       |                    fn trait_method(&self) {
+   LL|       |                        do_stuff();
+   LL|       |                    }
+   LL|       |                }
+   LL|       |                do_stuff();
+   LL|       |            }
    LL|       |        }
    LL|       |        do_stuff();
    LL|       |    }
@@ -68,12 +68,12 @@
    LL|      1|fn closure_expr() {
    LL|      1|    let _outer = #[coverage(off)]
    LL|       |    || {
-   LL|      0|        let _middle = || {
-   LL|      0|            let _inner = || {
-   LL|      0|                do_stuff();
-   LL|      0|            };
-   LL|      0|            do_stuff();
-   LL|      0|        };
+   LL|       |        let _middle = || {
+   LL|       |            let _inner = || {
+   LL|       |                do_stuff();
+   LL|       |            };
+   LL|       |            do_stuff();
+   LL|       |        };
    LL|       |        do_stuff();
    LL|       |    };
    LL|      1|    do_stuff();
@@ -85,14 +85,14 @@
    LL|       |        #[coverage(off)]
    LL|       |        || {
    LL|       |            let _middle = {
-   LL|      0|                || {
-   LL|      0|                    let _inner = {
-   LL|      0|                        || {
-   LL|      0|                            do_stuff();
-   LL|      0|                        }
+   LL|       |                || {
+   LL|       |                    let _inner = {
+   LL|       |                        || {
+   LL|       |                            do_stuff();
+   LL|       |                        }
    LL|       |                    };
-   LL|      0|                    do_stuff();
-   LL|      0|                }
+   LL|       |                    do_stuff();
+   LL|       |                }
    LL|       |            };
    LL|       |            do_stuff();
    LL|       |        }
diff --git a/tests/coverage/attr/off-on-sandwich.cov-map b/tests/coverage/attr/off-on-sandwich.cov-map
index 72b96420cb5..ed77d7d17e6 100644
--- a/tests/coverage/attr/off-on-sandwich.cov-map
+++ b/tests/coverage/attr/off-on-sandwich.cov-map
@@ -6,14 +6,6 @@ Number of expressions: 0
 Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 20, 5) to (start + 7, 6)
 
-Function name: off_on_sandwich::sparse_a::sparse_b
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 22, 05, 10, 06]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 34, 5) to (start + 16, 6)
-
 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 26, 09, 0b, 0a]
 Number of files: 1
diff --git a/tests/coverage/attr/off-on-sandwich.coverage b/tests/coverage/attr/off-on-sandwich.coverage
index e831b0e926e..58c128b8342 100644
--- a/tests/coverage/attr/off-on-sandwich.coverage
+++ b/tests/coverage/attr/off-on-sandwich.coverage
@@ -31,10 +31,10 @@
    LL|       |fn sparse_a() {
    LL|       |    sparse_b();
    LL|       |    sparse_b();
-   LL|      2|    fn sparse_b() {
-   LL|      2|        sparse_c();
-   LL|      2|        sparse_c();
-   LL|      2|        #[coverage(on)]
+   LL|       |    fn sparse_b() {
+   LL|       |        sparse_c();
+   LL|       |        sparse_c();
+   LL|       |        #[coverage(on)]
    LL|      4|        fn sparse_c() {
    LL|      4|            sparse_d();
    LL|      4|            sparse_d();
@@ -47,7 +47,7 @@
    LL|      8|                }
    LL|      8|            }
    LL|      4|        }
-   LL|      2|    }
+   LL|       |    }
    LL|       |}
    LL|       |
    LL|       |#[coverage(off)]
diff --git a/tests/coverage/no_cov_crate.cov-map b/tests/coverage/no_cov_crate.cov-map
index e623f6480b9..281efb6d00d 100644
--- a/tests/coverage/no_cov_crate.cov-map
+++ b/tests/coverage/no_cov_crate.cov-map
@@ -59,16 +59,3 @@ Number of file 0 mappings: 4
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
 
-Function name: no_cov_crate::nested_fns::outer_not_covered::inner
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 26, 09, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 38, 9) to (start + 1, 23)
-- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14)
-- Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14)
-    = (c0 - c1)
-- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
-
diff --git a/tests/coverage/no_cov_crate.coverage b/tests/coverage/no_cov_crate.coverage
index f5a0322bf3e..29ad1f979cf 100644
--- a/tests/coverage/no_cov_crate.coverage
+++ b/tests/coverage/no_cov_crate.coverage
@@ -35,13 +35,13 @@
    LL|       |mod nested_fns {
    LL|       |    #[coverage(off)]
    LL|       |    pub fn outer_not_covered(is_true: bool) {
-   LL|      1|        fn inner(is_true: bool) {
-   LL|      1|            if is_true {
-   LL|      1|                println!("called and covered");
-   LL|      1|            } else {
-   LL|      0|                println!("absolutely not covered");
-   LL|      0|            }
-   LL|      1|        }
+   LL|       |        fn inner(is_true: bool) {
+   LL|       |            if is_true {
+   LL|       |                println!("called and covered");
+   LL|       |            } else {
+   LL|       |                println!("absolutely not covered");
+   LL|       |            }
+   LL|       |        }
    LL|       |        println!("called but not covered");
    LL|       |        inner(is_true);
    LL|       |    }