about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-01-25 05:51:11 +0100
committerGitHub <noreply@github.com>2022-01-25 05:51:11 +0100
commit8dddc8647731efb6d7f40b176bccdba5cebe46f2 (patch)
tree6ea91de61a8fa173f5824ef3d15bd646e3e9ad11 /src
parentc8ede152a522fcf139b35700b36ec3e788617857 (diff)
parent1a0278e1d17f66ddc5975f38387746f85c6602ce (diff)
downloadrust-8dddc8647731efb6d7f40b176bccdba5cebe46f2.tar.gz
rust-8dddc8647731efb6d7f40b176bccdba5cebe46f2.zip
Rollup merge of #93144 - wesleywiser:uninhabited_type_code_cov2, r=tmandry
Work around missing code coverage data causing llvm-cov failures

If we do not add code coverage instrumentation to the `Body` of a
function, then when we go to generate the function record for it, we
won't write any data and this later causes llvm-cov to fail when
processing data for the entire coverage report.

I've identified two main cases where we do not currently add code
coverage instrumentation to the `Body` of a function:

  1. If the function has a single `BasicBlock` and it ends with a
     `TerminatorKind::Unreachable`.

  2. If the function is created using a proc macro of some kind.

For case 1, this is typically not important as this most often occurs as
a result of function definitions that take or return uninhabited
types. These kinds of functions, by definition, cannot even be called so
they logically should not be counted in code coverage statistics.

For case 2, I haven't looked into this very much but I've noticed while
testing this patch that (other than functions which are covered by case
1) the skipped function coverage debug message is occasionally triggered
in large crate graphs by functions generated from a proc macro. This may
have something to do with weird spans being generated by the proc macro
but this is just a guess.

I think it's reasonable to land this change since currently, we fail to
generate *any* results from llvm-cov when a function has no coverage
instrumentation applied to it. With this change, we get coverage data
for all functions other than the two cases discussed above.

Fixes #93054 which occurs because of uncallable functions which shouldn't
have code coverage anyway.

I will open an issue for missing code coverage of proc macro generated
functions and leave a link here once I have a more minimal repro.

r? ``@tmandry``
cc ``@richkadel``
Diffstat (limited to 'src')
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-93054.txt29
-rw-r--r--src/test/run-make-fulldeps/coverage/issue-93054.rs28
2 files changed, 57 insertions, 0 deletions
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-93054.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-93054.txt
new file mode 100644
index 00000000000..a1655adedd4
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-93054.txt
@@ -0,0 +1,29 @@
+    1|       |// Regression test for #93054: Functions using uninhabited types often only have a single,
+    2|       |// unreachable basic block which doesn't get instrumented. This should not cause llvm-cov to fail.
+    3|       |// Since these kinds functions can't be invoked anyway, it's ok to not have coverage data for them.
+    4|       |
+    5|       |// compile-flags: --edition=2021
+    6|       |
+    7|       |enum Never { }
+    8|       |
+    9|       |impl Never {
+   10|       |    fn foo(self) {
+   11|       |        match self { }
+   12|       |        make().map(|never| match never { });
+   13|       |    }
+   14|       |
+   15|       |    fn bar(&self) {
+   16|       |        match *self { }
+   17|       |    }
+   18|       |}
+   19|       |
+   20|      0|async fn foo2(never: Never) {
+   21|       |    match never { }
+   22|       |}
+   23|       |
+   24|      0|fn make() -> Option<Never> {
+   25|      0|    None
+   26|      0|}
+   27|       |
+   28|      1|fn main() { }
+
diff --git a/src/test/run-make-fulldeps/coverage/issue-93054.rs b/src/test/run-make-fulldeps/coverage/issue-93054.rs
new file mode 100644
index 00000000000..c160b3db03f
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage/issue-93054.rs
@@ -0,0 +1,28 @@
+// Regression test for #93054: Functions using uninhabited types often only have a single,
+// unreachable basic block which doesn't get instrumented. This should not cause llvm-cov to fail.
+// Since these kinds functions can't be invoked anyway, it's ok to not have coverage data for them.
+
+// compile-flags: --edition=2021
+
+enum Never { }
+
+impl Never {
+    fn foo(self) {
+        match self { }
+        make().map(|never| match never { });
+    }
+
+    fn bar(&self) {
+        match *self { }
+    }
+}
+
+async fn foo2(never: Never) {
+    match never { }
+}
+
+fn make() -> Option<Never> {
+    None
+}
+
+fn main() { }