about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2024-06-18 20:02:21 +1000
committerZalathar <Zalathar@users.noreply.github.com>2024-06-18 21:27:34 +1000
commit50936586323eefb6504945f444fe9e4928f2bb86 (patch)
tree34b8dfa7acec64719901dfa26765776a6d95c3ab
parent9a084e6310671aa0e3e35efb73953eeef8092d7d (diff)
downloadrust-50936586323eefb6504945f444fe9e4928f2bb86.tar.gz
rust-50936586323eefb6504945f444fe9e4928f2bb86.zip
Add more thorough coverage tests for `#[coverage(..)]` in nested functions
These tests reflect the current implementation behaviour, which is not
necessarily the desired behaviour.
-rw-r--r--tests/coverage/attr/nested.cov-map100
-rw-r--r--tests/coverage/attr/nested.coverage111
-rw-r--r--tests/coverage/attr/nested.rs110
-rw-r--r--tests/coverage/attr/off-on-sandwich.cov-map32
-rw-r--r--tests/coverage/attr/off-on-sandwich.coverage58
-rw-r--r--tests/coverage/attr/off-on-sandwich.rs57
6 files changed, 468 insertions, 0 deletions
diff --git a/tests/coverage/attr/nested.cov-map b/tests/coverage/attr/nested.cov-map
new file mode 100644
index 00000000000..a613bb7f8cd
--- /dev/null
+++ b/tests/coverage/attr/nested.cov-map
@@ -0,0 +1,100 @@
+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
+- file 0 => global file 1
+Number of expressions: 0
+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
+- file 0 => global file 1
+Number of expressions: 0
+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
new file mode 100644
index 00000000000..13129572aec
--- /dev/null
+++ b/tests/coverage/attr/nested.coverage
@@ -0,0 +1,111 @@
+   LL|       |#![feature(coverage_attribute, stmt_expr_attributes)]
+   LL|       |//@ edition: 2021
+   LL|       |
+   LL|       |// Demonstrates the interaction between #[coverage(off)] and various kinds of
+   LL|       |// nested function.
+   LL|       |
+   LL|       |// FIXME(#126625): Coverage attributes should apply recursively to nested functions.
+   LL|       |// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`,
+   LL|       |// its lines can still be marked with misleading execution counts from its enclosing
+   LL|       |// function.
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn do_stuff() {}
+   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|       |    do_stuff();
+   LL|       |}
+   LL|       |
+   LL|       |struct MyOuter;
+   LL|       |impl MyOuter {
+   LL|       |    #[coverage(off)]
+   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|       |        }
+   LL|       |        do_stuff();
+   LL|       |    }
+   LL|       |}
+   LL|       |
+   LL|       |trait MyTrait {
+   LL|       |    fn trait_method(&self);
+   LL|       |}
+   LL|       |impl MyTrait for MyOuter {
+   LL|       |    #[coverage(off)]
+   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|       |        }
+   LL|       |        do_stuff();
+   LL|       |    }
+   LL|       |}
+   LL|       |
+   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|       |        do_stuff();
+   LL|       |    };
+   LL|      1|    do_stuff();
+   LL|      1|}
+   LL|       |
+   LL|       |// This syntax is allowed, even without #![feature(stmt_expr_attributes)].
+   LL|      1|fn closure_tail() {
+   LL|      1|    let _outer = {
+   LL|       |        #[coverage(off)]
+   LL|       |        || {
+   LL|       |            let _middle = {
+   LL|      0|                || {
+   LL|      0|                    let _inner = {
+   LL|      0|                        || {
+   LL|      0|                            do_stuff();
+   LL|      0|                        }
+   LL|       |                    };
+   LL|      0|                    do_stuff();
+   LL|      0|                }
+   LL|       |            };
+   LL|       |            do_stuff();
+   LL|       |        }
+   LL|       |    };
+   LL|      1|    do_stuff();
+   LL|      1|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    outer_fn();
+   LL|       |    MyOuter.outer_method();
+   LL|       |    MyOuter.trait_method();
+   LL|       |    closure_expr();
+   LL|       |    closure_tail();
+   LL|       |}
+
diff --git a/tests/coverage/attr/nested.rs b/tests/coverage/attr/nested.rs
new file mode 100644
index 00000000000..c7ff835f44f
--- /dev/null
+++ b/tests/coverage/attr/nested.rs
@@ -0,0 +1,110 @@
+#![feature(coverage_attribute, stmt_expr_attributes)]
+//@ edition: 2021
+
+// Demonstrates the interaction between #[coverage(off)] and various kinds of
+// nested function.
+
+// FIXME(#126625): Coverage attributes should apply recursively to nested functions.
+// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`,
+// its lines can still be marked with misleading execution counts from its enclosing
+// function.
+
+#[coverage(off)]
+fn do_stuff() {}
+
+#[coverage(off)]
+fn outer_fn() {
+    fn middle_fn() {
+        fn inner_fn() {
+            do_stuff();
+        }
+        do_stuff();
+    }
+    do_stuff();
+}
+
+struct MyOuter;
+impl MyOuter {
+    #[coverage(off)]
+    fn outer_method(&self) {
+        struct MyMiddle;
+        impl MyMiddle {
+            fn middle_method(&self) {
+                struct MyInner;
+                impl MyInner {
+                    fn inner_method(&self) {
+                        do_stuff();
+                    }
+                }
+                do_stuff();
+            }
+        }
+        do_stuff();
+    }
+}
+
+trait MyTrait {
+    fn trait_method(&self);
+}
+impl MyTrait for MyOuter {
+    #[coverage(off)]
+    fn trait_method(&self) {
+        struct MyMiddle;
+        impl MyTrait for MyMiddle {
+            fn trait_method(&self) {
+                struct MyInner;
+                impl MyTrait for MyInner {
+                    fn trait_method(&self) {
+                        do_stuff();
+                    }
+                }
+                do_stuff();
+            }
+        }
+        do_stuff();
+    }
+}
+
+fn closure_expr() {
+    let _outer = #[coverage(off)]
+    || {
+        let _middle = || {
+            let _inner = || {
+                do_stuff();
+            };
+            do_stuff();
+        };
+        do_stuff();
+    };
+    do_stuff();
+}
+
+// This syntax is allowed, even without #![feature(stmt_expr_attributes)].
+fn closure_tail() {
+    let _outer = {
+        #[coverage(off)]
+        || {
+            let _middle = {
+                || {
+                    let _inner = {
+                        || {
+                            do_stuff();
+                        }
+                    };
+                    do_stuff();
+                }
+            };
+            do_stuff();
+        }
+    };
+    do_stuff();
+}
+
+#[coverage(off)]
+fn main() {
+    outer_fn();
+    MyOuter.outer_method();
+    MyOuter.trait_method();
+    closure_expr();
+    closure_tail();
+}
diff --git a/tests/coverage/attr/off-on-sandwich.cov-map b/tests/coverage/attr/off-on-sandwich.cov-map
new file mode 100644
index 00000000000..72b96420cb5
--- /dev/null
+++ b/tests/coverage/attr/off-on-sandwich.cov-map
@@ -0,0 +1,32 @@
+Function name: off_on_sandwich::dense_a::dense_b
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 14, 05, 07, 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 + 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
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Counter(0)) at (prev + 38, 9) to (start + 11, 10)
+
+Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c::sparse_d
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 29, 0d, 07, 0e]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Counter(0)) at (prev + 41, 13) to (start + 7, 14)
+
diff --git a/tests/coverage/attr/off-on-sandwich.coverage b/tests/coverage/attr/off-on-sandwich.coverage
new file mode 100644
index 00000000000..e831b0e926e
--- /dev/null
+++ b/tests/coverage/attr/off-on-sandwich.coverage
@@ -0,0 +1,58 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |//@ edition: 2021
+   LL|       |
+   LL|       |// Demonstrates the interaction of `#[coverage(off)]` and `#[coverage(on)]`
+   LL|       |// in nested functions.
+   LL|       |
+   LL|       |// FIXME(#126625): Coverage attributes should apply recursively to nested functions.
+   LL|       |// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`,
+   LL|       |// its lines can still be marked with misleading execution counts from its enclosing
+   LL|       |// function.
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn do_stuff() {}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn dense_a() {
+   LL|       |    dense_b();
+   LL|       |    dense_b();
+   LL|       |    #[coverage(on)]
+   LL|      2|    fn dense_b() {
+   LL|      2|        dense_c();
+   LL|      2|        dense_c();
+   LL|      2|        #[coverage(off)]
+   LL|      2|        fn dense_c() {
+   LL|      2|            do_stuff();
+   LL|      2|        }
+   LL|      2|    }
+   LL|       |}
+   LL|       |
+   LL|       |#[coverage(off)]
+   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|      4|        fn sparse_c() {
+   LL|      4|            sparse_d();
+   LL|      4|            sparse_d();
+   LL|      8|            fn sparse_d() {
+   LL|      8|                sparse_e();
+   LL|      8|                sparse_e();
+   LL|      8|                #[coverage(off)]
+   LL|      8|                fn sparse_e() {
+   LL|      8|                    do_stuff();
+   LL|      8|                }
+   LL|      8|            }
+   LL|      4|        }
+   LL|      2|    }
+   LL|       |}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    dense_a();
+   LL|       |    sparse_a();
+   LL|       |}
+
diff --git a/tests/coverage/attr/off-on-sandwich.rs b/tests/coverage/attr/off-on-sandwich.rs
new file mode 100644
index 00000000000..6b21b180223
--- /dev/null
+++ b/tests/coverage/attr/off-on-sandwich.rs
@@ -0,0 +1,57 @@
+#![feature(coverage_attribute)]
+//@ edition: 2021
+
+// Demonstrates the interaction of `#[coverage(off)]` and `#[coverage(on)]`
+// in nested functions.
+
+// FIXME(#126625): Coverage attributes should apply recursively to nested functions.
+// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`,
+// its lines can still be marked with misleading execution counts from its enclosing
+// function.
+
+#[coverage(off)]
+fn do_stuff() {}
+
+#[coverage(off)]
+fn dense_a() {
+    dense_b();
+    dense_b();
+    #[coverage(on)]
+    fn dense_b() {
+        dense_c();
+        dense_c();
+        #[coverage(off)]
+        fn dense_c() {
+            do_stuff();
+        }
+    }
+}
+
+#[coverage(off)]
+fn sparse_a() {
+    sparse_b();
+    sparse_b();
+    fn sparse_b() {
+        sparse_c();
+        sparse_c();
+        #[coverage(on)]
+        fn sparse_c() {
+            sparse_d();
+            sparse_d();
+            fn sparse_d() {
+                sparse_e();
+                sparse_e();
+                #[coverage(off)]
+                fn sparse_e() {
+                    do_stuff();
+                }
+            }
+        }
+    }
+}
+
+#[coverage(off)]
+fn main() {
+    dense_a();
+    sparse_a();
+}