]> git.lizzy.rs Git - rust.git/commitdiff
Move coverage tests from run-make-fulldeps to run-make
authorTomasz Miąsko <tomasz.miasko@gmail.com>
Mon, 25 Jul 2022 00:00:00 +0000 (00:00 +0000)
committerTomasz Miąsko <tomasz.miasko@gmail.com>
Thu, 28 Jul 2022 12:33:29 +0000 (14:33 +0200)
198 files changed:
src/test/run-make-fulldeps/coverage-llvmir/Makefile [deleted file]
src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt [deleted file]
src/test/run-make-fulldeps/coverage-llvmir/testprog.rs [deleted file]
src/test/run-make-fulldeps/coverage-reports/Makefile [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.abort.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async2.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro_async.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.conditions.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.continue.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.dead_code.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.drop_trait.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generator.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if_else.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline-dead.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inner_items.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-83601.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-85461.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-93054.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.lazy_boolean.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loop_break_value.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.nested_loops.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.no_cov_crate.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.partial_eq.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_loop.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_match.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.tight_inf_loop.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.try_error_result.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused_mod.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while_early_ret.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.yield.txt [deleted file]
src/test/run-make-fulldeps/coverage-reports/normalize_paths.py [deleted file]
src/test/run-make-fulldeps/coverage/WARNING_KEEP_NAMES_SHORT.txt [deleted file]
src/test/run-make-fulldeps/coverage/abort.rs [deleted file]
src/test/run-make-fulldeps/coverage/assert.rs [deleted file]
src/test/run-make-fulldeps/coverage/async.rs [deleted file]
src/test/run-make-fulldeps/coverage/async2.rs [deleted file]
src/test/run-make-fulldeps/coverage/closure.rs [deleted file]
src/test/run-make-fulldeps/coverage/closure_macro.rs [deleted file]
src/test/run-make-fulldeps/coverage/closure_macro_async.rs [deleted file]
src/test/run-make-fulldeps/coverage/compiletest-ignore-dir [deleted file]
src/test/run-make-fulldeps/coverage/conditions.rs [deleted file]
src/test/run-make-fulldeps/coverage/continue.rs [deleted file]
src/test/run-make-fulldeps/coverage/coverage_tools.mk [deleted file]
src/test/run-make-fulldeps/coverage/dead_code.rs [deleted file]
src/test/run-make-fulldeps/coverage/doctest.rs [deleted file]
src/test/run-make-fulldeps/coverage/drop_trait.rs [deleted file]
src/test/run-make-fulldeps/coverage/generator.rs [deleted file]
src/test/run-make-fulldeps/coverage/generics.rs [deleted file]
src/test/run-make-fulldeps/coverage/if.rs [deleted file]
src/test/run-make-fulldeps/coverage/if_else.rs [deleted file]
src/test/run-make-fulldeps/coverage/inline-dead.rs [deleted file]
src/test/run-make-fulldeps/coverage/inline.rs [deleted file]
src/test/run-make-fulldeps/coverage/inner_items.rs [deleted file]
src/test/run-make-fulldeps/coverage/issue-83601.rs [deleted file]
src/test/run-make-fulldeps/coverage/issue-84561.rs [deleted file]
src/test/run-make-fulldeps/coverage/issue-85461.rs [deleted file]
src/test/run-make-fulldeps/coverage/issue-93054.rs [deleted file]
src/test/run-make-fulldeps/coverage/lazy_boolean.rs [deleted file]
src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs [deleted file]
src/test/run-make-fulldeps/coverage/lib/inline_always_with_dead_code.rs [deleted file]
src/test/run-make-fulldeps/coverage/lib/unused_mod_helper.rs [deleted file]
src/test/run-make-fulldeps/coverage/lib/used_crate.rs [deleted file]
src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs [deleted file]
src/test/run-make-fulldeps/coverage/loop_break_value.rs [deleted file]
src/test/run-make-fulldeps/coverage/loops_branches.rs [deleted file]
src/test/run-make-fulldeps/coverage/match_or_pattern.rs [deleted file]
src/test/run-make-fulldeps/coverage/nested_loops.rs [deleted file]
src/test/run-make-fulldeps/coverage/no_cov_crate.rs [deleted file]
src/test/run-make-fulldeps/coverage/overflow.rs [deleted file]
src/test/run-make-fulldeps/coverage/panic_unwind.rs [deleted file]
src/test/run-make-fulldeps/coverage/partial_eq.rs [deleted file]
src/test/run-make-fulldeps/coverage/simple_loop.rs [deleted file]
src/test/run-make-fulldeps/coverage/simple_match.rs [deleted file]
src/test/run-make-fulldeps/coverage/tight_inf_loop.rs [deleted file]
src/test/run-make-fulldeps/coverage/try_error_result.rs [deleted file]
src/test/run-make-fulldeps/coverage/unused.rs [deleted file]
src/test/run-make-fulldeps/coverage/unused_mod.rs [deleted file]
src/test/run-make-fulldeps/coverage/uses_crate.rs [deleted file]
src/test/run-make-fulldeps/coverage/uses_inline_crate.rs [deleted file]
src/test/run-make-fulldeps/coverage/while.rs [deleted file]
src/test/run-make-fulldeps/coverage/while_early_ret.rs [deleted file]
src/test/run-make-fulldeps/coverage/yield.rs [deleted file]
src/test/run-make/coverage-llvmir/Makefile [new file with mode: 0644]
src/test/run-make/coverage-llvmir/filecheck.testprog.txt [new file with mode: 0644]
src/test/run-make/coverage-llvmir/testprog.rs [new file with mode: 0644]
src/test/run-make/coverage-reports/Makefile [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.abort.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.assert.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.async.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.async2.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.closure.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.closure_macro.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.closure_macro_async.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.conditions.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.continue.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.dead_code.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.drop_trait.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.generator.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.generics.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.if.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.if_else.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.inline-dead.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.inline.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.inner_items.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.issue-85461.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.issue-93054.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.lazy_boolean.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.loop_break_value.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.loops_branches.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.match_or_pattern.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.nested_loops.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.no_cov_crate.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.overflow.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.panic_unwind.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.simple_loop.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.simple_match.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.tight_inf_loop.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.try_error_result.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.unused.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.unused_mod.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.uses_crate.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.while.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.while_early_ret.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/expected_show_coverage.yield.txt [new file with mode: 0644]
src/test/run-make/coverage-reports/normalize_paths.py [new file with mode: 0755]
src/test/run-make/coverage/WARNING_KEEP_NAMES_SHORT.txt [new file with mode: 0644]
src/test/run-make/coverage/abort.rs [new file with mode: 0644]
src/test/run-make/coverage/assert.rs [new file with mode: 0644]
src/test/run-make/coverage/async.rs [new file with mode: 0644]
src/test/run-make/coverage/async2.rs [new file with mode: 0644]
src/test/run-make/coverage/closure.rs [new file with mode: 0644]
src/test/run-make/coverage/closure_macro.rs [new file with mode: 0644]
src/test/run-make/coverage/closure_macro_async.rs [new file with mode: 0644]
src/test/run-make/coverage/compiletest-ignore-dir [new file with mode: 0644]
src/test/run-make/coverage/conditions.rs [new file with mode: 0644]
src/test/run-make/coverage/continue.rs [new file with mode: 0644]
src/test/run-make/coverage/coverage_tools.mk [new file with mode: 0644]
src/test/run-make/coverage/dead_code.rs [new file with mode: 0644]
src/test/run-make/coverage/doctest.rs [new file with mode: 0644]
src/test/run-make/coverage/drop_trait.rs [new file with mode: 0644]
src/test/run-make/coverage/generator.rs [new file with mode: 0644]
src/test/run-make/coverage/generics.rs [new file with mode: 0644]
src/test/run-make/coverage/if.rs [new file with mode: 0644]
src/test/run-make/coverage/if_else.rs [new file with mode: 0644]
src/test/run-make/coverage/inline-dead.rs [new file with mode: 0644]
src/test/run-make/coverage/inline.rs [new file with mode: 0644]
src/test/run-make/coverage/inner_items.rs [new file with mode: 0644]
src/test/run-make/coverage/issue-83601.rs [new file with mode: 0644]
src/test/run-make/coverage/issue-84561.rs [new file with mode: 0644]
src/test/run-make/coverage/issue-85461.rs [new file with mode: 0644]
src/test/run-make/coverage/issue-93054.rs [new file with mode: 0644]
src/test/run-make/coverage/lazy_boolean.rs [new file with mode: 0644]
src/test/run-make/coverage/lib/doctest_crate.rs [new file with mode: 0644]
src/test/run-make/coverage/lib/inline_always_with_dead_code.rs [new file with mode: 0644]
src/test/run-make/coverage/lib/unused_mod_helper.rs [new file with mode: 0644]
src/test/run-make/coverage/lib/used_crate.rs [new file with mode: 0644]
src/test/run-make/coverage/lib/used_inline_crate.rs [new file with mode: 0644]
src/test/run-make/coverage/loop_break_value.rs [new file with mode: 0644]
src/test/run-make/coverage/loops_branches.rs [new file with mode: 0644]
src/test/run-make/coverage/match_or_pattern.rs [new file with mode: 0644]
src/test/run-make/coverage/nested_loops.rs [new file with mode: 0644]
src/test/run-make/coverage/no_cov_crate.rs [new file with mode: 0644]
src/test/run-make/coverage/overflow.rs [new file with mode: 0644]
src/test/run-make/coverage/panic_unwind.rs [new file with mode: 0644]
src/test/run-make/coverage/partial_eq.rs [new file with mode: 0644]
src/test/run-make/coverage/simple_loop.rs [new file with mode: 0644]
src/test/run-make/coverage/simple_match.rs [new file with mode: 0644]
src/test/run-make/coverage/tight_inf_loop.rs [new file with mode: 0644]
src/test/run-make/coverage/try_error_result.rs [new file with mode: 0644]
src/test/run-make/coverage/unused.rs [new file with mode: 0644]
src/test/run-make/coverage/unused_mod.rs [new file with mode: 0644]
src/test/run-make/coverage/uses_crate.rs [new file with mode: 0644]
src/test/run-make/coverage/uses_inline_crate.rs [new file with mode: 0644]
src/test/run-make/coverage/while.rs [new file with mode: 0644]
src/test/run-make/coverage/while_early_ret.rs [new file with mode: 0644]
src/test/run-make/coverage/yield.rs [new file with mode: 0644]

diff --git a/src/test/run-make-fulldeps/coverage-llvmir/Makefile b/src/test/run-make-fulldeps/coverage-llvmir/Makefile
deleted file mode 100644 (file)
index fbe0a5c..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-# needs-profiler-support
-
-# Rust coverage maps support LLVM Coverage Mapping Format versions 5 and 6,
-# corresponding with LLVM versions 12 and 13, respectively.
-# When upgrading LLVM versions, consider whether to enforce a minimum LLVM
-# version during testing, with an additional directive at the top of this file
-# that sets, for example: `min-llvm-version: 12.0`
-
--include ../coverage/coverage_tools.mk
-
-BASEDIR=../coverage-llvmir
-
-ifeq ($(UNAME),Darwin)
-       INSTR_PROF_DATA_SUFFIX=,regular,live_support
-       DATA_SECTION_PREFIX=__DATA,
-       LLVM_COV_SECTION_PREFIX=__LLVM_COV,
-       COMDAT_IF_SUPPORTED=
-else
-       INSTR_PROF_DATA_SUFFIX=
-       DATA_SECTION_PREFIX=
-       LLVM_COV_SECTION_PREFIX=
-       COMDAT_IF_SUPPORTED=, comdat
-endif
-
-DEFINE_INTERNAL=define internal
-
-ifdef IS_WINDOWS
-       LLVM_FILECHECK_OPTIONS=\
-               -check-prefixes=CHECK,WINDOWS \
-               -DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \
-               -DCOMDAT_IF_SUPPORTED='$(COMDAT_IF_SUPPORTED)' \
-               -DINSTR_PROF_DATA='.lprfd$$M' \
-               -DINSTR_PROF_NAME='.lprfn$$M' \
-               -DINSTR_PROF_CNTS='.lprfc$$M' \
-               -DINSTR_PROF_VALS='.lprfv$$M' \
-               -DINSTR_PROF_VNODES='.lprfnd$$M' \
-               -DINSTR_PROF_COVMAP='.lcovmap$$M' \
-               -DINSTR_PROF_COVFUN='.lcovfun$$M' \
-               -DINSTR_PROF_ORDERFILE='.lorderfile$$M'
-else
-       LLVM_FILECHECK_OPTIONS=\
-               -check-prefixes=CHECK \
-               -DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \
-               -DCOMDAT_IF_SUPPORTED='$(COMDAT_IF_SUPPORTED)' \
-               -DINSTR_PROF_DATA='$(DATA_SECTION_PREFIX)__llvm_prf_data$(INSTR_PROF_DATA_SUFFIX)' \
-               -DINSTR_PROF_NAME='$(DATA_SECTION_PREFIX)__llvm_prf_names' \
-               -DINSTR_PROF_CNTS='$(DATA_SECTION_PREFIX)__llvm_prf_cnts' \
-               -DINSTR_PROF_VALS='$(DATA_SECTION_PREFIX)__llvm_prf_vals' \
-               -DINSTR_PROF_VNODES='$(DATA_SECTION_PREFIX)__llvm_prf_vnds' \
-               -DINSTR_PROF_COVMAP='$(LLVM_COV_SECTION_PREFIX)__llvm_covmap' \
-               -DINSTR_PROF_COVFUN='$(LLVM_COV_SECTION_PREFIX)__llvm_covfun' \
-               -DINSTR_PROF_ORDERFILE='$(DATA_SECTION_PREFIX)__llvm_orderfile'
-endif
-
-all: test_llvm_ir
-
-test_llvm_ir:
-       # Compile the test program with non-experimental coverage instrumentation, and generate LLVM IR
-       $(RUSTC) $(BASEDIR)/testprog.rs \
-                       -Cinstrument-coverage \
-                       --emit=llvm-ir
-
-       cat "$(TMPDIR)"/testprog.ll | \
-                       "$(LLVM_FILECHECK)" $(BASEDIR)/filecheck.testprog.txt $(LLVM_FILECHECK_OPTIONS)
diff --git a/src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt b/src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt
deleted file mode 100644 (file)
index 7a5f219..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# Check for metadata, variables, declarations, and function definitions injected
-# into LLVM IR when compiling with -Cinstrument-coverage.
-
-WINDOWS:      $__llvm_profile_runtime_user = comdat any
-
-CHECK:        @__covrec_{{[A-F0-9]+}}u = linkonce_odr hidden constant
-CHECK-SAME:   section "[[INSTR_PROF_COVFUN]]"[[COMDAT_IF_SUPPORTED]], align 8
-
-CHECK:        @__llvm_coverage_mapping = private constant
-CHECK-SAME:   section "[[INSTR_PROF_COVMAP]]", align 8
-
-WINDOWS:      @__llvm_profile_runtime = external global i32
-
-CHECK:        @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
-CHECK-SAME:   section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
-
-CHECK:        @__profd__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
-CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called
-CHECK-SAME:   section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
-
-CHECK:        @__profc__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
-CHECK-SAME:   section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
-
-CHECK:        @__profd__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
-CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog4main
-CHECK-SAME:   section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
-
-CHECK:        @__llvm_prf_nm = private constant
-CHECK-SAME:   section "[[INSTR_PROF_NAME]]", align 1
-
-CHECK:        @llvm.used = appending global
-CHECK-SAME:   @__llvm_coverage_mapping
-CHECK-SAME:   @__llvm_prf_nm
-CHECK-SAME:   section "llvm.metadata"
-
-CHECK:        [[DEFINE_INTERNAL]] { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} {
-CHECK-NEXT:   start:
-CHECK-NOT:    [[DEFINE_INTERNAL]]
-CHECK:        %pgocount = load i64, {{i64\*|ptr}}
-CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called,
-
-CHECK:        declare void @llvm.instrprof.increment({{i8\*|ptr}}, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]
-
-WINDOWS:      define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat {
-WINDOWS-NEXT: %1 = load i32, {{i32\*|ptr}} @__llvm_profile_runtime
-WINDOWS-NEXT: ret i32 %1
-WINDOWS-NEXT: }
-
-CHECK:        attributes #[[LLVM_INSTRPROF_INCREMENT_ATTR]] = { nounwind }
-WINDOWS:      attributes #[[LLVM_PROFILE_RUNTIME_USER_ATTR]] = { noinline }
diff --git a/src/test/run-make-fulldeps/coverage-llvmir/testprog.rs b/src/test/run-make-fulldeps/coverage-llvmir/testprog.rs
deleted file mode 100644 (file)
index 358c256..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-pub fn will_be_called() -> &'static str {
-    let val = "called";
-    println!("{}", val);
-    val
-}
-
-pub fn will_not_be_called() -> bool {
-    println!("should not have been called");
-    false
-}
-
-pub fn print<T>(left: &str, value: T, right: &str)
-where
-    T: std::fmt::Display,
-{
-    println!("{}{}{}", left, value, right);
-}
-
-pub fn wrap_with<F, T>(inner: T, should_wrap: bool, wrapper: F)
-where
-    F: FnOnce(&T)
-{
-    if should_wrap {
-        wrapper(&inner)
-    }
-}
-
-fn main() {
-    let less = 1;
-    let more = 100;
-
-    if less < more {
-        wrap_with(will_be_called(), less < more, |inner| print(" ***", inner, "*** "));
-        wrap_with(will_be_called(), more < less, |inner| print(" ***", inner, "*** "));
-    } else {
-        wrap_with(will_not_be_called(), true, |inner| print("wrapped result is: ", inner, ""));
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/Makefile b/src/test/run-make-fulldeps/coverage-reports/Makefile
deleted file mode 100644 (file)
index 78723e7..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-# needs-profiler-support
-# ignore-windows-gnu
-
-# Rust coverage maps support LLVM Coverage Mapping Format versions 5 and 6,
-# corresponding with LLVM versions 12 and 13, respectively.
-# When upgrading LLVM versions, consider whether to enforce a minimum LLVM
-# version during testing, with an additional directive at the top of this file
-# that sets, for example: `min-llvm-version: 12.0`
-
-# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
-# properly. Since we only have GCC on the CI ignore the test for now.
-
--include ../coverage/coverage_tools.mk
-
-BASEDIR=../coverage-reports
-SOURCEDIR=../coverage
-
-# The `llvm-cov show` flag `--debug`, used to generate the `counters` output files, is only
-# enabled if LLVM assertions are enabled. This requires Rust config `llvm/optimize` and not
-# `llvm/release_debuginfo`. Note that some CI builds disable debug assertions (by setting
-# `NO_LLVM_ASSERTIONS=1`), so the tests must still pass even if the `--debug` flag is
-# not supported. (Note that `counters` files are only produced in the `$(TMPDIR)`
-# directory, for inspection and debugging support. They are *not* copied to `expected_*`
-# files when `--bless`ed.)
-LLVM_COV_DEBUG := $(shell \
-               "$(LLVM_BIN_DIR)"/llvm-cov show --debug 2>&1 | \
-               grep -q "Unknown command line argument '--debug'"; \
-               echo $$?)
-ifeq ($(LLVM_COV_DEBUG), 1)
-DEBUG_FLAG=--debug
-endif
-
-# FIXME(richkadel): I'm adding `--ignore-filename-regex=` line(s) for specific test(s) that produce
-# `llvm-cov` results for multiple files (for example `uses_crate.rs` and `used_crate/mod.rs`) as a
-# workaround for two problems causing tests to fail on Windows:
-#
-# 1. When multiple files appear in the `llvm-cov show` results, each file's coverage results can
-#    appear in different a different order. Whether this is random or, somehow, platform-specific,
-#    the Windows output flips the order of the files, compared to Linux. In the `uses_crate.rs`
-#    test, the only test-unique (interesting) results we care about are the results for only one
-#    of the two files, `mod/uses_crate.rs`, so the workaround is to ignore all but this one file.
-#    In the future, we may want a more sophisticated solution that splits apart `llvm-cov show`
-#    results into separate results files for each result (taking care not to create new file
-#    paths that might be too long for Windows MAX_PATH limits when creating these new sub-results,
-#    as well).
-# 2. When multiple files appear in the `llvm-cov show` results, the results for each file are
-#    prefixed with their filename, including platform-specific path separators (`\` for Windows,
-#    and `/` everywhere else). This could be filtered or normalized of course, but by ignoring
-#    coverage results for all but one of the file, the filenames are no longer included anyway.
-#    If this changes (if/when we decide to support `llvm-cov show` results for multiple files),
-#    the file path separator differences may need to be addressed.
-#
-# Since this is only a workaround, I decided to implement the override by adding an option for
-# each file to be ignored, using a `--ignore-filename-regex=` entry for each one, rather than
-# implement some more sophisticated solution with a new custom test directive in the test file
-# itself (similar to `expect-exit-status`) because that would add a lot of complexity and still
-# be a workaround, with the same result, with no benefit.
-#
-# Yes these `--ignore-filename-regex=` options are included in all invocations of `llvm-cov show`
-# for now, but it is effectively ignored for all tests that don't include this file anyway.
-#
-# (Note that it's also possible the `_counters.<test>.txt` and `<test>.json` files (if generated)
-# may order results from multiple files inconsistently, which might also have to be accomodated
-# if and when we allow `llvm-cov` to produce results for multiple files. Note, the path separators
-# appear to be normalized to `/` in those files, thankfully.)
-LLVM_COV_IGNORE_FILES=\
-       --ignore-filename-regex='(uses_crate.rs|uses_inline_crate.rs|unused_mod.rs)'
-
-all: $(patsubst $(SOURCEDIR)/lib/%.rs,%,$(wildcard $(SOURCEDIR)/lib/*.rs)) $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs))
-
-# Ensure there are no `expected` results for tests that may have been removed or renamed
-.PHONY: clear_expected_if_blessed
-clear_expected_if_blessed:
-ifdef RUSTC_BLESS_TEST
-       rm -f expected_*
-endif
-
--include clear_expected_if_blessed
-
-%: $(SOURCEDIR)/lib/%.rs
-       # Compile the test library with coverage instrumentation
-       $(RUSTC) $(SOURCEDIR)/lib/$@.rs \
-                       $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/lib/$@.rs ) \
-                       --crate-type rlib -Cinstrument-coverage
-
-%: $(SOURCEDIR)/%.rs
-       # Compile the test program with coverage instrumentation
-       $(RUSTC) $(SOURCEDIR)/$@.rs \
-                       $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \
-                       -L "$(TMPDIR)" -Cinstrument-coverage
-
-       # Run it in order to generate some profiling data,
-       # with `LLVM_PROFILE_FILE=<profdata_file>` environment variable set to
-       # output the coverage stats for this run.
-       LLVM_PROFILE_FILE="$(TMPDIR)"/$@.profraw \
-                       $(call RUN,$@) || \
-                       ( \
-                               status=$$?; \
-                               grep -q "^\/\/ expect-exit-status-$$status" $(SOURCEDIR)/$@.rs || \
-                               ( >&2 echo "program exited with an unexpected exit status: $$status"; \
-                                       false \
-                               ) \
-                       )
-
-       # Run it through rustdoc as well to cover doctests.
-       # `%p` is the pid, and `%m` the binary signature. We suspect that the pid alone
-       # might result in overwritten files and failed tests, as rustdoc spawns each
-       # doctest as its own process, so make sure the filename is as unique as possible.
-       LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p-%m.profraw \
-                       $(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \
-                       $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \
-                       -L "$(TMPDIR)" -Cinstrument-coverage \
-                       -Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@
-
-       # Postprocess the profiling data so it can be used by the llvm-cov tool
-       "$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \
-                       "$(TMPDIR)"/$@*.profraw \
-                       -o "$(TMPDIR)"/$@.profdata
-
-       # Generate a coverage report using `llvm-cov show`.
-       "$(LLVM_BIN_DIR)"/llvm-cov show \
-                       $(DEBUG_FLAG) \
-                       $(LLVM_COV_IGNORE_FILES) \
-                       --compilation-dir=. \
-                       --Xdemangler="$(RUST_DEMANGLER)" \
-                       --show-line-counts-or-regions \
-                       --instr-profile="$(TMPDIR)"/$@.profdata \
-                       $(call BIN,"$(TMPDIR)"/$@) \
-                       $$( \
-                               for file in $(TMPDIR)/rustdoc-$@/*/rust_out; do \
-                               [ -x "$$file" ] && printf "%s %s " -object $$file; \
-                               done \
-                       ) \
-               2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \
-               | "$(PYTHON)" $(BASEDIR)/normalize_paths.py \
-               > "$(TMPDIR)"/actual_show_coverage.$@.txt || \
-       ( status=$$? ; \
-               >&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \
-               exit $$status \
-       )
-
-ifdef DEBUG_FLAG
-       # The first line (beginning with "Args:" contains hard-coded, build-specific
-       # file paths. Strip that line and keep the remaining lines with counter debug
-       # data.
-       tail -n +2 "$(TMPDIR)"/show_coverage_stderr.$@.txt \
-               > "$(TMPDIR)"/actual_show_coverage_counters.$@.txt
-endif
-
-ifdef RUSTC_BLESS_TEST
-       cp "$(TMPDIR)"/actual_show_coverage.$@.txt \
-                       expected_show_coverage.$@.txt
-else
-       # Compare the show coverage output (`--bless` refreshes `typical` files).
-       #
-       # FIXME(richkadel): None of the Rust test source samples have the
-       # `// ignore-llvm-cov-show-diffs` anymore. This directive exists to work around a limitation
-       # with `llvm-cov show`. When reporting coverage for multiple instantiations of a generic function,
-       # with different type substitutions, `llvm-cov show` prints these in a non-deterministic order,
-       # breaking the `diff` comparision.
-       #
-       # A partial workaround is implemented below, with `diff --ignore-matching-lines=RE`
-       # to ignore each line prefixing each generic instantiation coverage code region.
-       #
-       # This workaround only works if the coverage counts are identical across all reported
-       # instantiations. If there is no way to ensure this, you may need to apply the
-       # `// ignore-llvm-cov-show-diffs` directive, and check for differences using the
-       # `.json` files to validate that results have not changed. (Until then, the JSON
-       # files are redundant, so there is no need to generate `expected_*.json` files or
-       # compare actual JSON results.)
-
-       $(DIFF) --ignore-matching-lines='^  | .*::<.*>.*:$$' --ignore-matching-lines='^  | <.*>::.*:$$' \
-               expected_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \
-               ( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \
-                       >&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \
-               ) || \
-               ( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \
-                       false \
-               )
-endif
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.abort.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.abort.txt
deleted file mode 100644 (file)
index 00f46f4..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-    1|       |#![feature(c_unwind)]
-    2|       |#![allow(unused_assignments)]
-    3|       |
-    4|     12|extern "C" fn might_abort(should_abort: bool) {
-    5|     12|    if should_abort {
-    6|      0|        println!("aborting...");
-    7|      0|        panic!("panics and aborts");
-    8|     12|    } else {
-    9|     12|        println!("Don't Panic");
-   10|     12|    }
-   11|     12|}
-   12|       |
-   13|      1|fn main() -> Result<(), u8> {
-   14|      1|    let mut countdown = 10;
-   15|     11|    while countdown > 0 {
-   16|     10|        if countdown < 5 {
-   17|      4|            might_abort(false);
-   18|      6|        }
-   19|       |        // See discussion (below the `Notes` section) on coverage results for the closing brace.
-   20|     10|        if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
-                                       ^4                     ^6
-   21|       |        // For the following example, the closing brace is the last character on the line.
-   22|       |        // This shows the character after the closing brace is highlighted, even if that next
-   23|       |        // character is a newline.
-   24|     10|        if countdown < 5 { might_abort(false); }
-                                       ^4                     ^6
-   25|     10|        countdown -= 1;
-   26|       |    }
-   27|      1|    Ok(())
-   28|      1|}
-   29|       |
-   30|       |// Notes:
-   31|       |//   1. Compare this program and its coverage results to those of the similar tests
-   32|       |//      `panic_unwind.rs` and `try_error_result.rs`.
-   33|       |//   2. This test confirms the coverage generated when a program includes `TerminatorKind::Abort`.
-   34|       |//   3. The test does not invoke the abort. By executing to a successful completion, the coverage
-   35|       |//      results show where the program did and did not execute.
-   36|       |//   4. If the program actually aborted, the coverage counters would not be saved (which "works as
-   37|       |//      intended"). Coverage results would show no executed coverage regions.
-   38|       |//   6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
-   39|       |//      (on Linux at least).
-   40|       |
-   41|       |/*
-   42|       |
-   43|       |Expect the following coverage results:
-   44|       |
-   45|       |```text
-   46|       |    16|     11|    while countdown > 0 {
-   47|       |    17|     10|        if countdown < 5 {
-   48|       |    18|      4|            might_abort(false);
-   49|       |    19|      6|        }
-   50|       |```
-   51|       |
-   52|       |This is actually correct.
-   53|       |
-   54|       |The condition `countdown < 5` executed 10 times (10 loop iterations).
-   55|       |
-   56|       |It evaluated to `true` 4 times, and executed the `might_abort()` call.
-   57|       |
-   58|       |It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
-   59|       |`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
-   60|       |closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
-   61|       |non-true condition.
-   62|       |
-   63|       |As another example of why this is important, say the condition was `countdown < 50`, which is always
-   64|       |`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
-   65|       |The closing brace would have a count of `0`, highlighting the missed coverage.
-   66|       |*/
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt
deleted file mode 100644 (file)
index 4056888..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-    1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-101
-    3|       |
-    4|      4|fn might_fail_assert(one_plus_one: u32) {
-    5|      4|    println!("does 1 + 1 = {}?", one_plus_one);
-    6|      4|    assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
-                                                  ^1
-    7|      3|}
-    8|       |
-    9|      1|fn main() -> Result<(),u8> {
-   10|      1|    let mut countdown = 10;
-   11|     11|    while countdown > 0 {
-   12|     11|        if countdown == 1 {
-   13|      1|            might_fail_assert(3);
-   14|     10|        } else if countdown < 5 {
-   15|      3|            might_fail_assert(2);
-   16|      6|        }
-   17|     10|        countdown -= 1;
-   18|       |    }
-   19|      0|    Ok(())
-   20|      0|}
-   21|       |
-   22|       |// Notes:
-   23|       |//   1. Compare this program and its coverage results to those of the very similar test
-   24|       |//      `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
-   25|       |//   2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
-   26|       |//      related `assert_*!()` macro.
-   27|       |//   3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
-   28|       |//      conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
-   29|       |//      `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
-   30|       |//   4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
-   31|       |//      (and in many other coverage tests). The `Assert` terminator is typically generated by the
-   32|       |//      Rust compiler to check for runtime failures, such as numeric overflows.
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt
deleted file mode 100644 (file)
index 2f69adb..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-    1|       |#![allow(unused_assignments, dead_code)]
-    2|       |
-    3|       |// compile-flags: --edition=2018 -C opt-level=1
-    4|       |
-    5|      1|async fn c(x: u8) -> u8 {
-    6|      1|    if x == 8 {
-    7|      1|        1
-    8|       |    } else {
-    9|      0|        0
-   10|       |    }
-   11|      1|}
-   12|       |
-   13|      0|async fn d() -> u8 { 1 }
-   14|       |
-   15|      0|async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
-   16|       |
-   17|      1|async fn f() -> u8 { 1 }
-   18|       |
-   19|      0|async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
-   20|       |
-   21|      1|pub async fn g(x: u8) {
-   22|      0|    match x {
-   23|      0|        y if e().await == y => (),
-   24|      0|        y if f().await == y => (),
-   25|      0|        _ => (),
-   26|       |    }
-   27|      0|}
-   28|       |
-   29|      1|async fn h(x: usize) { // The function signature is counted when called, but the body is not
-   30|      0|                       // executed (not awaited) so the open brace has a `0` count (at least when
-   31|      0|                       // displayed with `llvm-cov show` in color-mode).
-   32|      0|    match x {
-   33|      0|        y if foo().await[y] => (),
-   34|      0|        _ => (),
-   35|       |    }
-   36|      0|}
-   37|       |
-   38|      1|async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
-   39|      1|                    // (a) the function signature, counted when the function is called; and
-   40|      1|                    // (b) the open brace for the function body, counted once when the body is
-   41|      1|                    // executed asynchronously.
-   42|      1|    match x {
-   43|      1|        y if c(x).await == y + 1 => { d().await; }
-                      ^0       ^0                   ^0 ^0
-   44|      1|        y if f().await == y + 1 => (),
-                      ^0      ^0                 ^0
-   45|      1|        _ => (),
-   46|       |    }
-   47|      1|}
-   48|       |
-   49|      1|fn j(x: u8) {
-   50|      1|    // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`.
-   51|      1|    fn c(x: u8) -> u8 {
-   52|      1|        if x == 8 {
-   53|      1|            1 // This line appears covered, but the 1-character expression span covering the `1`
-                          ^0
-   54|      1|              // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
-   55|      1|              // `fn j()` executes the open brace for the funciton body, followed by the function's
-   56|      1|              // first executable statement, `match x`. Inner function declarations are not
-   57|      1|              // "visible" to the MIR for `j()`, so the code region counts all lines between the
-   58|      1|              // open brace and the first statement as executed, which is, in a sense, true.
-   59|      1|              // `llvm-cov show` overcomes this kind of situation by showing the actual counts
-   60|      1|              // of the enclosed coverages, (that is, the `1` expression was not executed, and
-   61|      1|              // accurately displays a `0`).
-   62|      1|        } else {
-   63|      1|            0
-   64|      1|        }
-   65|      1|    }
-   66|      1|    fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed
-                  ^0
-   67|      1|    fn f() -> u8 { 1 }
-   68|      1|    match x {
-   69|      1|        y if c(x) == y + 1 => { d(); }
-                      ^0                    ^0
-   70|      1|        y if f() == y + 1 => (),
-                      ^0                   ^0
-   71|      1|        _ => (),
-   72|       |    }
-   73|      1|}
-   74|       |
-   75|      0|fn k(x: u8) { // unused function
-   76|      0|    match x {
-   77|      0|        1 => (),
-   78|      0|        2 => (),
-   79|      0|        _ => (),
-   80|       |    }
-   81|      0|}
-   82|       |
-   83|      1|fn l(x: u8) {
-   84|      1|    match x {
-   85|      0|        1 => (),
-   86|      0|        2 => (),
-   87|      1|        _ => (),
-   88|       |    }
-   89|      1|}
-   90|       |
-   91|      1|async fn m(x: u8) -> u8 { x - 1 }
-                                      ^0
-   92|       |
-   93|      1|fn main() {
-   94|      1|    let _ = g(10);
-   95|      1|    let _ = h(9);
-   96|      1|    let mut future = Box::pin(i(8));
-   97|      1|    j(7);
-   98|      1|    l(6);
-   99|      1|    let _ = m(5);
-  100|      1|    executor::block_on(future.as_mut());
-  101|      1|}
-  102|       |
-  103|       |mod executor {
-  104|       |    use core::{
-  105|       |        future::Future,
-  106|       |        pin::Pin,
-  107|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-  108|       |    };
-  109|       |
-  110|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-  111|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-  112|      1|        use std::hint::unreachable_unchecked;
-  113|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-  114|      1|            |_| unsafe { unreachable_unchecked() }, // clone
-                              ^0
-  115|      1|            |_| unsafe { unreachable_unchecked() }, // wake
-                              ^0
-  116|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-                              ^0
-  117|      1|            |_| (),
-  118|      1|        );
-  119|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-  120|      1|        let mut context = Context::from_waker(&waker);
-  121|       |
-  122|       |        loop {
-  123|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-  124|      1|                break val;
-  125|      0|            }
-  126|       |        }
-  127|      1|    }
-  128|       |}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async2.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async2.txt
deleted file mode 100644 (file)
index dc06a48..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-    1|       |// compile-flags: --edition=2018
-    2|       |
-    3|       |use core::{
-    4|       |    future::Future,
-    5|       |    marker::Send,
-    6|       |    pin::Pin,
-    7|       |};
-    8|       |
-    9|      1|fn non_async_func() {
-   10|      1|    println!("non_async_func was covered");
-   11|      1|    let b = true;
-   12|      1|    if b {
-   13|      1|        println!("non_async_func println in block");
-   14|      1|    }
-                   ^0
-   15|      1|}
-   16|       |
-   17|       |
-   18|       |
-   19|       |
-   20|      1|async fn async_func() {
-   21|      1|    println!("async_func was covered");
-   22|      1|    let b = true;
-   23|      1|    if b {
-   24|      1|        println!("async_func println in block");
-   25|      1|    }
-                   ^0
-   26|      1|}
-   27|       |
-   28|       |
-   29|       |
-   30|       |
-   31|      1|async fn async_func_just_println() {
-   32|      1|    println!("async_func_just_println was covered");
-   33|      1|}
-   34|       |
-   35|      1|fn main() {
-   36|      1|    println!("codecovsample::main");
-   37|      1|
-   38|      1|    non_async_func();
-   39|      1|
-   40|      1|    executor::block_on(async_func());
-   41|      1|    executor::block_on(async_func_just_println());
-   42|      1|}
-   43|       |
-   44|       |mod executor {
-   45|       |    use core::{
-   46|       |        future::Future,
-   47|       |        pin::Pin,
-   48|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-   49|       |    };
-   50|       |
-   51|      2|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-   52|      2|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-   53|      2|        use std::hint::unreachable_unchecked;
-   54|      2|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-   55|      2|            |_| unsafe { unreachable_unchecked() }, // clone
-                              ^0
-   56|      2|            |_| unsafe { unreachable_unchecked() }, // wake
-                              ^0
-   57|      2|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-                              ^0
-   58|      2|            |_| (),
-   59|      2|        );
-   60|      2|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-   61|      2|        let mut context = Context::from_waker(&waker);
-   62|       |
-   63|       |        loop {
-   64|      2|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-   65|      2|                break val;
-   66|      0|            }
-   67|       |        }
-   68|      2|    }
-  ------------------
-  | async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func::{closure#0}>>:
-  |   51|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-  |   52|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-  |   53|      1|        use std::hint::unreachable_unchecked;
-  |   54|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-  |   55|      1|            |_| unsafe { unreachable_unchecked() }, // clone
-  |   56|      1|            |_| unsafe { unreachable_unchecked() }, // wake
-  |   57|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-  |   58|      1|            |_| (),
-  |   59|      1|        );
-  |   60|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-  |   61|      1|        let mut context = Context::from_waker(&waker);
-  |   62|       |
-  |   63|       |        loop {
-  |   64|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-  |   65|      1|                break val;
-  |   66|      0|            }
-  |   67|       |        }
-  |   68|      1|    }
-  ------------------
-  | async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func_just_println::{closure#0}>>:
-  |   51|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-  |   52|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-  |   53|      1|        use std::hint::unreachable_unchecked;
-  |   54|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-  |   55|      1|            |_| unsafe { unreachable_unchecked() }, // clone
-  |   56|      1|            |_| unsafe { unreachable_unchecked() }, // wake
-  |   57|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-  |   58|      1|            |_| (),
-  |   59|      1|        );
-  |   60|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-  |   61|      1|        let mut context = Context::from_waker(&waker);
-  |   62|       |
-  |   63|       |        loop {
-  |   64|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-  |   65|      1|                break val;
-  |   66|      0|            }
-  |   67|       |        }
-  |   68|      1|    }
-  ------------------
-   69|       |}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure.txt
deleted file mode 100644 (file)
index 09ad276..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |// compile-flags: -C opt-level=2 # fix described in rustc_middle/mir/mono.rs
-    3|      1|fn main() {
-    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    6|      1|    // dependent conditions.
-    7|      1|    let is_true = std::env::args().len() == 1;
-    8|      1|    let is_false = ! is_true;
-    9|      1|
-   10|      1|    let mut some_string = Some(String::from("the string content"));
-   11|      1|    println!(
-   12|      1|        "The string or alt: {}"
-   13|      1|        ,
-   14|      1|        some_string
-   15|      1|            .
-   16|      1|            unwrap_or_else
-   17|      1|        (
-   18|      1|            ||
-   19|      0|            {
-   20|      0|                let mut countdown = 0;
-   21|      0|                if is_false {
-   22|      0|                    countdown = 10;
-   23|      0|                }
-   24|      0|                "alt string 1".to_owned()
-   25|      1|            }
-   26|      1|        )
-   27|      1|    );
-   28|      1|
-   29|      1|    some_string = Some(String::from("the string content"));
-   30|      1|    let
-   31|      1|        a
-   32|      1|    =
-   33|      1|        ||
-   34|      0|    {
-   35|      0|        let mut countdown = 0;
-   36|      0|        if is_false {
-   37|      0|            countdown = 10;
-   38|      0|        }
-   39|      0|        "alt string 2".to_owned()
-   40|       |    };
-   41|      1|    println!(
-   42|      1|        "The string or alt: {}"
-   43|      1|        ,
-   44|      1|        some_string
-   45|      1|            .
-   46|      1|            unwrap_or_else
-   47|      1|        (
-   48|      1|            a
-   49|      1|        )
-   50|      1|    );
-   51|      1|
-   52|      1|    some_string = None;
-   53|      1|    println!(
-   54|      1|        "The string or alt: {}"
-   55|      1|        ,
-   56|      1|        some_string
-   57|      1|            .
-   58|      1|            unwrap_or_else
-   59|      1|        (
-   60|      1|            ||
-   61|      1|            {
-   62|      1|                let mut countdown = 0;
-   63|      1|                if is_false {
-   64|      0|                    countdown = 10;
-   65|      1|                }
-   66|      1|                "alt string 3".to_owned()
-   67|      1|            }
-   68|      1|        )
-   69|      1|    );
-   70|      1|
-   71|      1|    some_string = None;
-   72|      1|    let
-   73|      1|        a
-   74|      1|    =
-   75|      1|        ||
-   76|      1|    {
-   77|      1|        let mut countdown = 0;
-   78|      1|        if is_false {
-   79|      0|            countdown = 10;
-   80|      1|        }
-   81|      1|        "alt string 4".to_owned()
-   82|       |    };
-   83|      1|    println!(
-   84|      1|        "The string or alt: {}"
-   85|      1|        ,
-   86|      1|        some_string
-   87|      1|            .
-   88|      1|            unwrap_or_else
-   89|      1|        (
-   90|      1|            a
-   91|      1|        )
-   92|      1|    );
-   93|      1|
-   94|      1|    let
-   95|      1|        quote_closure
-   96|      1|    =
-   97|      1|        |val|
-   98|      5|    {
-   99|      5|        let mut countdown = 0;
-  100|      5|        if is_false {
-  101|      0|            countdown = 10;
-  102|      5|        }
-  103|      5|        format!("'{}'", val)
-  104|       |    };
-  105|      1|    println!(
-  106|      1|        "Repeated, quoted string: {:?}"
-  107|      1|        ,
-  108|      1|        std::iter::repeat("repeat me")
-  109|      1|            .take(5)
-  110|      1|            .map
-  111|      1|        (
-  112|      1|            quote_closure
-  113|      1|        )
-  114|      1|            .collect::<Vec<_>>()
-  115|      1|    );
-  116|      1|
-  117|      1|    let
-  118|      1|        _unused_closure
-  119|       |    =
-  120|       |        |
-  121|       |            mut countdown
-  122|       |        |
-  123|      0|    {
-  124|      0|        if is_false {
-  125|      0|            countdown = 10;
-  126|      0|        }
-  127|      0|        "closure should be unused".to_owned()
-  128|       |    };
-  129|       |
-  130|      1|    let mut countdown = 10;
-  131|      1|    let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
-                                                                  ^0
-  132|       |
-  133|       |
-  134|      1|    let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
-  135|      1|    let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
-                                                                              ^0
-  136|      1|    let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
-                                                                        ^0
-  137|       |
-  138|       |
-  139|       |
-  140|       |
-  141|      1|    let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
-                                                                        ^0
-  142|       |
-  143|      1|    let _shortish_unused_closure = | _unused_arg: u8 | {
-  144|      0|        println!("not called")
-  145|      0|    };
-  146|       |
-  147|      1|    let _as_short_unused_closure = |
-  148|       |        _unused_arg: u8
-  149|      0|    | { println!("not called") };
-  150|       |
-  151|      1|    let _almost_as_short_unused_closure = |
-  152|       |        _unused_arg: u8
-  153|      0|    | { println!("not called") }
-  154|       |    ;
-  155|       |
-  156|       |
-  157|       |
-  158|       |
-  159|       |
-  160|      1|    let _short_unused_closure_line_break_no_block = | _unused_arg: u8 |
-  161|      0|println!("not called")
-  162|       |    ;
-  163|       |
-  164|      1|    let _short_unused_closure_line_break_no_block2 =
-  165|       |        | _unused_arg: u8 |
-  166|      0|            println!(
-  167|      0|                "not called"
-  168|      0|            )
-  169|       |    ;
-  170|       |
-  171|      1|    let short_used_not_covered_closure_line_break_no_block_embedded_branch =
-  172|       |        | _unused_arg: u8 |
-  173|      0|            println!(
-  174|      0|                "not called: {}",
-  175|      0|                if is_true { "check" } else { "me" }
-  176|       |            )
-  177|       |    ;
-  178|       |
-  179|      1|    let short_used_not_covered_closure_line_break_block_embedded_branch =
-  180|      1|        | _unused_arg: u8 |
-  181|      0|        {
-  182|      0|            println!(
-  183|      0|                "not called: {}",
-  184|      0|                if is_true { "check" } else { "me" }
-  185|       |            )
-  186|       |        }
-  187|       |    ;
-  188|       |
-  189|      1|    let short_used_covered_closure_line_break_no_block_embedded_branch =
-  190|      1|        | _unused_arg: u8 |
-  191|      1|            println!(
-  192|      1|                "not called: {}",
-  193|      1|                if is_true { "check" } else { "me" }
-                                                            ^0
-  194|       |            )
-  195|       |    ;
-  196|       |
-  197|      1|    let short_used_covered_closure_line_break_block_embedded_branch =
-  198|      1|        | _unused_arg: u8 |
-  199|      1|        {
-  200|      1|            println!(
-  201|      1|                "not called: {}",
-  202|      1|                if is_true { "check" } else { "me" }
-                                                            ^0
-  203|       |            )
-  204|       |        }
-  205|       |    ;
-  206|       |
-  207|      1|    if is_false {
-  208|      0|        short_used_not_covered_closure_macro(0);
-  209|      0|        short_used_not_covered_closure_line_break_no_block_embedded_branch(0);
-  210|      0|        short_used_not_covered_closure_line_break_block_embedded_branch(0);
-  211|      1|    }
-  212|      1|    short_used_covered_closure_macro(0);
-  213|      1|    short_used_covered_closure_line_break_no_block_embedded_branch(0);
-  214|      1|    short_used_covered_closure_line_break_block_embedded_branch(0);
-  215|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro.txt
deleted file mode 100644 (file)
index 87f7014..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-    1|       |// compile-flags: --edition=2018
-    2|       |#![feature(no_coverage)]
-    3|       |
-    4|       |macro_rules! bail {
-    5|       |    ($msg:literal $(,)?) => {
-    6|       |        if $msg.len() > 0 {
-    7|       |            println!("no msg");
-    8|       |        } else {
-    9|       |            println!($msg);
-   10|       |        }
-   11|       |        return Err(String::from($msg));
-   12|       |    };
-   13|       |}
-   14|       |
-   15|       |macro_rules! on_error {
-   16|       |    ($value:expr, $error_message:expr) => {
-   17|       |        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
-   18|       |            let message = format!($error_message, e);
-   19|       |            if message.len() > 0 {
-   20|       |                println!("{}", message);
-   21|       |                Ok(String::from("ok"))
-   22|       |            } else {
-   23|       |                bail!("error");
-   24|       |            }
-   25|       |        })
-   26|       |    };
-   27|       |}
-   28|       |
-   29|      1|fn load_configuration_files() -> Result<String, String> {
-   30|      1|    Ok(String::from("config"))
-   31|      1|}
-   32|       |
-   33|      1|pub fn main() -> Result<(), String> {
-   34|      1|    println!("Starting service");
-   35|      1|    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
-                                                                                                 ^0
-   36|       |
-   37|      1|    let startup_delay_duration = String::from("arg");
-   38|      1|    let _ = (config, startup_delay_duration);
-   39|      1|    Ok(())
-   40|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro_async.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro_async.txt
deleted file mode 100644 (file)
index 2b54181..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-    1|       |// compile-flags: --edition=2018
-    2|       |#![feature(no_coverage)]
-    3|       |
-    4|       |macro_rules! bail {
-    5|       |    ($msg:literal $(,)?) => {
-    6|       |        if $msg.len() > 0 {
-    7|       |            println!("no msg");
-    8|       |        } else {
-    9|       |            println!($msg);
-   10|       |        }
-   11|       |        return Err(String::from($msg));
-   12|       |    };
-   13|       |}
-   14|       |
-   15|       |macro_rules! on_error {
-   16|       |    ($value:expr, $error_message:expr) => {
-   17|       |        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
-   18|       |            let message = format!($error_message, e);
-   19|       |            if message.len() > 0 {
-   20|       |                println!("{}", message);
-   21|       |                Ok(String::from("ok"))
-   22|       |            } else {
-   23|       |                bail!("error");
-   24|       |            }
-   25|       |        })
-   26|       |    };
-   27|       |}
-   28|       |
-   29|      1|fn load_configuration_files() -> Result<String, String> {
-   30|      1|    Ok(String::from("config"))
-   31|      1|}
-   32|       |
-   33|      1|pub async fn test() -> Result<(), String> {
-   34|      1|    println!("Starting service");
-   35|      1|    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
-                                                                                                 ^0
-   36|       |
-   37|      1|    let startup_delay_duration = String::from("arg");
-   38|      1|    let _ = (config, startup_delay_duration);
-   39|      1|    Ok(())
-   40|      1|}
-   41|       |
-   42|       |#[no_coverage]
-   43|       |fn main() {
-   44|       |    executor::block_on(test());
-   45|       |}
-   46|       |
-   47|       |mod executor {
-   48|       |    use core::{
-   49|       |        future::Future,
-   50|       |        pin::Pin,
-   51|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-   52|       |    };
-   53|       |
-   54|       |    #[no_coverage]
-   55|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-   56|       |        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-   57|       |        use std::hint::unreachable_unchecked;
-   58|       |        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-   59|       |
-   60|       |            #[no_coverage]
-   61|       |            |_| unsafe { unreachable_unchecked() }, // clone
-   62|       |
-   63|       |            #[no_coverage]
-   64|       |            |_| unsafe { unreachable_unchecked() }, // wake
-   65|       |
-   66|       |            #[no_coverage]
-   67|       |            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-   68|       |
-   69|       |            #[no_coverage]
-   70|       |            |_| (),
-   71|       |        );
-   72|       |        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-   73|       |        let mut context = Context::from_waker(&waker);
-   74|       |
-   75|       |        loop {
-   76|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-   77|       |                break val;
-   78|       |            }
-   79|       |        }
-   80|       |    }
-   81|       |}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.conditions.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.conditions.txt
deleted file mode 100644 (file)
index 2d8a98a..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    let mut countdown = 0;
-    5|      1|    if true {
-    6|      1|        countdown = 10;
-    7|      1|    }
-                   ^0
-    8|       |
-    9|       |    const B: u32 = 100;
-   10|      1|    let x = if countdown > 7 {
-   11|      1|        countdown -= 4;
-   12|      1|        B
-   13|      0|    } else if countdown > 2 {
-   14|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
-   15|      0|            countdown = 0;
-   16|      0|        }
-   17|      0|        countdown -= 5;
-   18|      0|        countdown
-   19|       |    } else {
-   20|      0|        return;
-   21|       |    };
-   22|       |
-   23|      1|    let mut countdown = 0;
-   24|      1|    if true {
-   25|      1|        countdown = 10;
-   26|      1|    }
-                   ^0
-   27|       |
-   28|      1|    if countdown > 7 {
-   29|      1|        countdown -= 4;
-   30|      1|    } else if countdown > 2 {
-                            ^0
-   31|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
-   32|      0|            countdown = 0;
-   33|      0|        }
-   34|      0|        countdown -= 5;
-   35|       |    } else {
-   36|      0|        return;
-   37|       |    }
-   38|       |
-   39|      1|    if true {
-   40|      1|        let mut countdown = 0;
-   41|      1|        if true {
-   42|      1|            countdown = 10;
-   43|      1|        }
-                       ^0
-   44|       |
-   45|      1|        if countdown > 7 {
-   46|      1|            countdown -= 4;
-   47|      1|        }
-   48|      0|        else if countdown > 2 {
-   49|      0|            if countdown < 1 || countdown > 5 || countdown != 9 {
-   50|      0|                countdown = 0;
-   51|      0|            }
-   52|      0|            countdown -= 5;
-   53|       |        } else {
-   54|      0|            return;
-   55|       |        }
-   56|      0|    }
-   57|       |
-   58|       |
-   59|      1|    let mut countdown = 0;
-   60|      1|    if true {
-   61|      1|        countdown = 1;
-   62|      1|    }
-                   ^0
-   63|       |
-   64|      1|    let z = if countdown > 7 {
-                      ^0
-   65|      0|        countdown -= 4;
-   66|      1|    } else if countdown > 2 {
-   67|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
-   68|      0|            countdown = 0;
-   69|      0|        }
-   70|      0|        countdown -= 5;
-   71|       |    } else {
-   72|      1|        let should_be_reachable = countdown;
-   73|      1|        println!("reached");
-   74|      1|        return;
-   75|       |    };
-   76|       |
-   77|      0|    let w = if countdown > 7 {
-   78|      0|        countdown -= 4;
-   79|      0|    } else if countdown > 2 {
-   80|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
-   81|      0|            countdown = 0;
-   82|      0|        }
-   83|      0|        countdown -= 5;
-   84|       |    } else {
-   85|      0|        return;
-   86|       |    };
-   87|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.continue.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.continue.txt
deleted file mode 100644 (file)
index 1c64ead..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    let is_true = std::env::args().len() == 1;
-    5|      1|
-    6|      1|    let mut x = 0;
-    7|     11|    for _ in 0..10 {
-    8|     10|        match is_true {
-    9|       |            true => {
-   10|     10|                continue;
-   11|       |            }
-   12|      0|            _ => {
-   13|      0|                x = 1;
-   14|      0|            }
-   15|      0|        }
-   16|      0|        x = 3;
-   17|       |    }
-   18|     11|    for _ in 0..10 {
-   19|     10|        match is_true {
-   20|      0|            false => {
-   21|      0|                x = 1;
-   22|      0|            }
-   23|       |            _ => {
-   24|     10|                continue;
-   25|       |            }
-   26|       |        }
-   27|      0|        x = 3;
-   28|       |    }
-   29|     11|    for _ in 0..10 {
-   30|     10|        match is_true {
-   31|     10|            true => {
-   32|     10|                x = 1;
-   33|     10|            }
-   34|       |            _ => {
-   35|      0|                continue;
-   36|       |            }
-   37|       |        }
-   38|     10|        x = 3;
-   39|       |    }
-   40|     11|    for _ in 0..10 {
-   41|     10|        if is_true {
-   42|     10|            continue;
-   43|      0|        }
-   44|      0|        x = 3;
-   45|       |    }
-   46|     11|    for _ in 0..10 {
-   47|     10|        match is_true {
-   48|      0|            false => {
-   49|      0|                x = 1;
-   50|      0|            }
-   51|     10|            _ => {
-   52|     10|                let _ = x;
-   53|     10|            }
-   54|       |        }
-   55|     10|        x = 3;
-   56|       |    }
-   57|      1|    for _ in 0..10 {
-   58|      1|        match is_true {
-   59|      0|            false => {
-   60|      0|                x = 1;
-   61|      0|            }
-   62|       |            _ => {
-   63|      1|                break;
-   64|       |            }
-   65|       |        }
-   66|      0|        x = 3;
-   67|       |    }
-   68|       |    let _ = x;
-   69|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.dead_code.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.dead_code.txt
deleted file mode 100644 (file)
index 09ff14c..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |
-    3|      0|pub fn unused_pub_fn_not_in_library() {
-    4|      0|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    5|      0|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    6|      0|    // dependent conditions.
-    7|      0|    let is_true = std::env::args().len() == 1;
-    8|      0|
-    9|      0|    let mut countdown = 0;
-   10|      0|    if is_true {
-   11|      0|        countdown = 10;
-   12|      0|    }
-   13|      0|}
-   14|       |
-   15|      0|fn unused_fn() {
-   16|      0|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   17|      0|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   18|      0|    // dependent conditions.
-   19|      0|    let is_true = std::env::args().len() == 1;
-   20|      0|
-   21|      0|    let mut countdown = 0;
-   22|      0|    if is_true {
-   23|      0|        countdown = 10;
-   24|      0|    }
-   25|      0|}
-   26|       |
-   27|      1|fn main() {
-   28|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   29|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   30|      1|    // dependent conditions.
-   31|      1|    let is_true = std::env::args().len() == 1;
-   32|      1|
-   33|      1|    let mut countdown = 0;
-   34|      1|    if is_true {
-   35|      1|        countdown = 10;
-   36|      1|    }
-                   ^0
-   37|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt
deleted file mode 100644 (file)
index 7ae0e97..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-../coverage/doctest.rs:
-    1|       |//! This test ensures that code from doctests is properly re-mapped.
-    2|       |//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
-    3|       |//!
-    4|       |//! Just some random code:
-    5|      1|//! ```
-    6|      1|//! if true {
-    7|       |//!     // this is executed!
-    8|      1|//!     assert_eq!(1, 1);
-    9|       |//! } else {
-   10|       |//!     // this is not!
-   11|      0|//!     assert_eq!(1, 2);
-   12|       |//! }
-   13|      1|//! ```
-   14|       |//!
-   15|       |//! doctest testing external code:
-   16|       |//! ```
-   17|      1|//! extern crate doctest_crate;
-   18|      1|//! doctest_crate::fn_run_in_doctests(1);
-   19|      1|//! ```
-   20|       |//!
-   21|       |//! doctest returning a result:
-   22|      1|//! ```
-   23|      2|//! #[derive(Debug, PartialEq)]
-                       ^1
-  ------------------
-  | Unexecuted instantiation: <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::ne
-  ------------------
-  | <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::eq:
-  |   23|      2|//! #[derive(Debug, PartialEq)]
-  ------------------
-   24|      1|//! struct SomeError {
-   25|      1|//!     msg: String,
-   26|      1|//! }
-   27|      1|//! let mut res = Err(SomeError { msg: String::from("a message") });
-   28|      1|//! if res.is_ok() {
-   29|      0|//!     res?;
-   30|       |//! } else {
-   31|      1|//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
-   32|      1|//!         println!("{:?}", res);
-   33|      1|//!     }
-                   ^0
-   34|      1|//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
-   35|      1|//!         res = Ok(1);
-   36|      1|//!     }
-                   ^0
-   37|      1|//!     res = Ok(0);
-   38|       |//! }
-   39|       |//! // need to be explicit because rustdoc cant infer the return type
-   40|      1|//! Ok::<(), SomeError>(())
-   41|      1|//! ```
-   42|       |//!
-   43|       |//! doctest with custom main:
-   44|       |//! ```
-   45|      1|//! fn some_func() {
-   46|      1|//!     println!("called some_func()");
-   47|      1|//! }
-   48|       |//!
-   49|      0|//! #[derive(Debug)]
-   50|       |//! struct SomeError;
-   51|       |//!
-   52|       |//! extern crate doctest_crate;
-   53|       |//!
-   54|      1|//! fn doctest_main() -> Result<(), SomeError> {
-   55|      1|//!     some_func();
-   56|      1|//!     doctest_crate::fn_run_in_doctests(2);
-   57|      1|//!     Ok(())
-   58|      1|//! }
-   59|       |//!
-   60|       |//! // this `main` is not shown as covered, as it clashes with all the other
-   61|       |//! // `main` functions that were automatically generated for doctests
-   62|       |//! fn main() -> Result<(), SomeError> {
-   63|       |//!     doctest_main()
-   64|       |//! }
-   65|       |//! ```
-   66|       |
-   67|       |/// doctest attached to fn testing external code:
-   68|       |/// ```
-   69|      1|/// extern crate doctest_crate;
-   70|      1|/// doctest_crate::fn_run_in_doctests(3);
-   71|      1|/// ```
-   72|       |///
-   73|      1|fn main() {
-   74|      1|    if true {
-   75|      1|        assert_eq!(1, 1);
-   76|       |    } else {
-   77|      0|        assert_eq!(1, 2);
-   78|       |    }
-   79|      1|}
-   80|       |
-   81|       |// FIXME(Swatinem): Fix known issue that coverage code region columns need to be offset by the
-   82|       |// doc comment line prefix (`///` or `//!`) and any additional indent (before or after the doc
-   83|       |// comment characters). This test produces `llvm-cov show` results demonstrating the problem.
-   84|       |//
-   85|       |// One of the above tests now includes: `derive(Debug, PartialEq)`, producing an `llvm-cov show`
-   86|       |// result with a distinct count for `Debug`, denoted by `^1`, but the caret points to the wrong
-   87|       |// column. Similarly, the `if` blocks without `else` blocks show `^0`, which should point at, or
-   88|       |// one character past, the `if` block's closing brace. In both cases, these are most likely off
-   89|       |// by the number of characters stripped from the beginning of each doc comment line: indent
-   90|       |// whitespace, if any, doc comment prefix (`//!` in this case) and (I assume) one space character
-   91|       |// (?). Note, when viewing `llvm-cov show` results in `--color` mode, the column offset errors are
-   92|       |// more pronounced, and show up in more places, with background color used to show some distinct
-   93|       |// code regions with different coverage counts.
-   94|       |//
-   95|       |// NOTE: Since the doc comment line prefix may vary, one possible solution is to replace each
-   96|       |// character stripped from the beginning of doc comment lines with a space. This will give coverage
-   97|       |// results the correct column offsets, and I think it should compile correctly, but I don't know
-   98|       |// what affect it might have on diagnostic messages from the compiler, and whether anyone would care
-   99|       |// if the indentation changed. I don't know if there is a more viable solution.
-
-../coverage/lib/doctest_crate.rs:
-    1|       |/// A function run only from within doctests
-    2|      3|pub fn fn_run_in_doctests(conditional: usize) {
-    3|      3|    match conditional {
-    4|      1|        1 => assert_eq!(1, 1), // this is run,
-    5|      1|        2 => assert_eq!(1, 1), // this,
-    6|      1|        3 => assert_eq!(1, 1), // and this too
-    7|      0|        _ => assert_eq!(1, 2), // however this is not
-    8|       |    }
-    9|      3|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.drop_trait.txt
deleted file mode 100644 (file)
index fe6a9e9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-    1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-1
-    3|       |
-    4|       |struct Firework {
-    5|       |    strength: i32,
-    6|       |}
-    7|       |
-    8|       |impl Drop for Firework {
-    9|      2|    fn drop(&mut self) {
-   10|      2|        println!("BOOM times {}!!!", self.strength);
-   11|      2|    }
-   12|       |}
-   13|       |
-   14|      1|fn main() -> Result<(),u8> {
-   15|      1|    let _firecracker = Firework { strength: 1 };
-   16|      1|
-   17|      1|    let _tnt = Firework { strength: 100 };
-   18|      1|
-   19|      1|    if true {
-   20|      1|        println!("Exiting with error...");
-   21|      1|        return Err(1);
-   22|      0|    }
-   23|      0|
-   24|      0|    let _ = Firework { strength: 1000 };
-   25|      0|
-   26|      0|    Ok(())
-   27|      1|}
-   28|       |
-   29|       |// Expected program output:
-   30|       |//   Exiting with error...
-   31|       |//   BOOM times 100!!!
-   32|       |//   BOOM times 1!!!
-   33|       |//   Error: 1
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generator.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generator.txt
deleted file mode 100644 (file)
index d70e12e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-    1|       |#![feature(generators, generator_trait)]
-    2|       |
-    3|       |use std::ops::{Generator, GeneratorState};
-    4|       |use std::pin::Pin;
-    5|       |
-    6|       |// The following implementation of a function called from a `yield` statement
-    7|       |// (apparently requiring the Result and the `String` type or constructor)
-    8|       |// creates conditions where the `generator::StateTransform` MIR transform will
-    9|       |// drop all `Counter` `Coverage` statements from a MIR. `simplify.rs` has logic
-   10|       |// to handle this condition, and still report dead block coverage.
-   11|      1|fn get_u32(val: bool) -> Result<u32, String> {
-   12|      1|    if val { Ok(1) } else { Err(String::from("some error")) }
-                                          ^0
-   13|      1|}
-   14|       |
-   15|      1|fn main() {
-   16|      1|    let is_true = std::env::args().len() == 1;
-   17|      1|    let mut generator = || {
-   18|      1|        yield get_u32(is_true);
-   19|      1|        return "foo";
-   20|       |    };
-   21|       |
-   22|      1|    match Pin::new(&mut generator).resume(()) {
-   23|      1|        GeneratorState::Yielded(Ok(1)) => {}
-   24|      0|        _ => panic!("unexpected return from resume"),
-   25|       |    }
-   26|      1|    match Pin::new(&mut generator).resume(()) {
-   27|      1|        GeneratorState::Complete("foo") => {}
-   28|      0|        _ => panic!("unexpected return from resume"),
-   29|       |    }
-   30|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt
deleted file mode 100644 (file)
index 48983ba..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-    1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-1
-    3|       |
-    4|       |struct Firework<T> where T: Copy + std::fmt::Display {
-    5|       |    strength: T,
-    6|       |}
-    7|       |
-    8|       |impl<T> Firework<T> where T: Copy + std::fmt::Display {
-    9|       |    #[inline(always)]
-   10|      3|    fn set_strength(&mut self, new_strength: T) {
-   11|      3|        self.strength = new_strength;
-   12|      3|    }
-  ------------------
-  | <generics::Firework<i32>>::set_strength:
-  |   10|      1|    fn set_strength(&mut self, new_strength: T) {
-  |   11|      1|        self.strength = new_strength;
-  |   12|      1|    }
-  ------------------
-  | <generics::Firework<f64>>::set_strength:
-  |   10|      2|    fn set_strength(&mut self, new_strength: T) {
-  |   11|      2|        self.strength = new_strength;
-  |   12|      2|    }
-  ------------------
-   13|       |}
-   14|       |
-   15|       |impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
-   16|       |    #[inline(always)]
-   17|      2|    fn drop(&mut self) {
-   18|      2|        println!("BOOM times {}!!!", self.strength);
-   19|      2|    }
-  ------------------
-  | <generics::Firework<f64> as core::ops::drop::Drop>::drop:
-  |   17|      1|    fn drop(&mut self) {
-  |   18|      1|        println!("BOOM times {}!!!", self.strength);
-  |   19|      1|    }
-  ------------------
-  | <generics::Firework<i32> as core::ops::drop::Drop>::drop:
-  |   17|      1|    fn drop(&mut self) {
-  |   18|      1|        println!("BOOM times {}!!!", self.strength);
-  |   19|      1|    }
-  ------------------
-   20|       |}
-   21|       |
-   22|      1|fn main() -> Result<(),u8> {
-   23|      1|    let mut firecracker = Firework { strength: 1 };
-   24|      1|    firecracker.set_strength(2);
-   25|      1|
-   26|      1|    let mut tnt = Firework { strength: 100.1 };
-   27|      1|    tnt.set_strength(200.1);
-   28|      1|    tnt.set_strength(300.3);
-   29|      1|
-   30|      1|    if true {
-   31|      1|        println!("Exiting with error...");
-   32|      1|        return Err(1);
-   33|      0|    }
-   34|      0|
-   35|      0|
-   36|      0|
-   37|      0|
-   38|      0|
-   39|      0|    let _ = Firework { strength: 1000 };
-   40|      0|
-   41|      0|    Ok(())
-   42|      1|}
-   43|       |
-   44|       |// Expected program output:
-   45|       |//   Exiting with error...
-   46|       |//   BOOM times 100!!!
-   47|       |//   BOOM times 1!!!
-   48|       |//   Error: 1
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if.txt
deleted file mode 100644 (file)
index 0c9eff2..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    6|      1|    // dependent conditions.
-    7|      1|    let
-    8|      1|    is_true
-    9|      1|    =
-   10|      1|        std::env::args().len()
-   11|      1|    ==
-   12|      1|        1
-   13|      1|    ;
-   14|      1|    let
-   15|      1|        mut
-   16|      1|    countdown
-   17|      1|    =
-   18|      1|        0
-   19|      1|    ;
-   20|      1|    if
-   21|      1|        is_true
-   22|      1|    {
-   23|      1|        countdown
-   24|      1|        =
-   25|      1|            10
-   26|      1|        ;
-   27|      1|    }
-                   ^0
-   28|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if_else.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if_else.txt
deleted file mode 100644 (file)
index 4285d31..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    6|      1|    // dependent conditions.
-    7|      1|    let is_true = std::env::args().len() == 1;
-    8|      1|
-    9|      1|    let mut countdown = 0;
-   10|      1|    if
-   11|      1|        is_true
-   12|      1|    {
-   13|      1|        countdown
-   14|      1|        =
-   15|      1|            10
-   16|      1|        ;
-   17|      1|    }
-   18|       |    else // Note coverage region difference without semicolon
-   19|       |    {
-   20|      0|        countdown
-   21|      0|        =
-   22|      0|            100
-   23|       |    }
-   24|       |
-   25|       |    if
-   26|      1|        is_true
-   27|      1|    {
-   28|      1|        countdown
-   29|      1|        =
-   30|      1|            10
-   31|      1|        ;
-   32|      1|    }
-   33|       |    else
-   34|      0|    {
-   35|      0|        countdown
-   36|      0|        =
-   37|      0|            100
-   38|      0|        ;
-   39|      0|    }
-   40|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline-dead.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline-dead.txt
deleted file mode 100644 (file)
index effdef8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-    1|       |// Regression test for issue #98833.
-    2|       |// compile-flags: -Zinline-mir -Cdebug-assertions=off
-    3|       |
-    4|      1|fn main() {
-    5|      1|    println!("{}", live::<false>());
-    6|      1|
-    7|      1|    let f = |x: bool| {
-    8|       |        debug_assert!(
-    9|       |            x
-   10|       |        );
-   11|      1|    };
-   12|      1|    f(false);
-   13|      1|}
-   14|       |
-   15|       |#[inline]
-   16|      1|fn live<const B: bool>() -> u32 {
-   17|      1|    if B {
-   18|      0|        dead()
-   19|       |    } else {
-   20|      1|        0
-   21|       |    }
-   22|      1|}
-   23|       |
-   24|       |#[inline]
-   25|      0|fn dead() -> u32 {
-   26|      0|    42
-   27|      0|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt
deleted file mode 100644 (file)
index 6f5d154..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-    1|       |// compile-flags: -Zinline-mir
-    2|       |
-    3|       |use std::fmt::Display;
-    4|       |
-    5|      1|fn main() {
-    6|      1|    permutations(&['a', 'b', 'c']);
-    7|      1|}
-    8|       |
-    9|       |#[inline(always)]
-   10|      1|fn permutations<T: Copy + Display>(xs: &[T]) {
-   11|      1|    let mut ys = xs.to_owned();
-   12|      1|    permutate(&mut ys, 0);
-   13|      1|}
-   14|       |
-   15|     16|fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
-   16|     16|    let n = length(xs);
-   17|     16|    if k == n {
-   18|      6|        display(xs);
-   19|     10|    } else if k < n {
-   20|     15|        for i in k..n {
-                               ^10
-   21|     15|            swap(xs, i, k);
-   22|     15|            permutate(xs, k + 1);
-   23|     15|            swap(xs, i, k);
-   24|     15|        }
-   25|      0|    } else {
-   26|      0|        error();
-   27|      0|    }
-   28|     16|}
-   29|       |
-   30|     16|fn length<T>(xs: &[T]) -> usize {
-   31|     16|    xs.len()
-   32|     16|}
-   33|       |
-   34|       |#[inline]
-   35|     30|fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
-   36|     30|    let t = xs[i];
-   37|     30|    xs[i] = xs[j];
-   38|     30|    xs[j] = t;
-   39|     30|}
-   40|       |
-   41|      6|fn display<T: Display>(xs: &[T]) {
-   42|     24|    for x in xs {
-                      ^18
-   43|     18|        print!("{}", x);
-   44|     18|    }
-   45|      6|    println!();
-   46|      6|}
-   47|       |
-   48|       |#[inline(always)]
-   49|      0|fn error() {
-   50|      0|    panic!("error");
-   51|      0|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inner_items.txt
deleted file mode 100644 (file)
index 883254a..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables, dead_code)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    6|      1|    // dependent conditions.
-    7|      1|    let is_true = std::env::args().len() == 1;
-    8|      1|
-    9|      1|    let mut countdown = 0;
-   10|      1|    if is_true {
-   11|      1|        countdown = 10;
-   12|      1|    }
-                   ^0
-   13|       |
-   14|       |    mod in_mod {
-   15|       |        const IN_MOD_CONST: u32 = 1000;
-   16|       |    }
-   17|       |
-   18|      3|    fn in_func(a: u32) {
-   19|      3|        let b = 1;
-   20|      3|        let c = a + b;
-   21|      3|        println!("c = {}", c)
-   22|      3|    }
-   23|       |
-   24|       |    struct InStruct {
-   25|       |        in_struct_field: u32,
-   26|       |    }
-   27|       |
-   28|       |    const IN_CONST: u32 = 1234;
-   29|       |
-   30|       |    trait InTrait {
-   31|       |        fn trait_func(&mut self, incr: u32);
-   32|       |
-   33|      1|        fn default_trait_func(&mut self) {
-   34|      1|            in_func(IN_CONST);
-   35|      1|            self.trait_func(IN_CONST);
-   36|      1|        }
-   37|       |    }
-   38|       |
-   39|       |    impl InTrait for InStruct {
-   40|      1|        fn trait_func(&mut self, incr: u32) {
-   41|      1|            self.in_struct_field += incr;
-   42|      1|            in_func(self.in_struct_field);
-   43|      1|        }
-   44|       |    }
-   45|       |
-   46|       |    type InType = String;
-   47|       |
-   48|      1|    if is_true {
-   49|      1|        in_func(countdown);
-   50|      1|    }
-                   ^0
-   51|       |
-   52|      1|    let mut val = InStruct {
-   53|      1|        in_struct_field: 101,
-   54|      1|    };
-   55|      1|
-   56|      1|    val.default_trait_func();
-   57|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-83601.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-83601.txt
deleted file mode 100644 (file)
index de32c88..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-    1|       |// Shows that rust-lang/rust/83601 is resolved
-    2|       |
-    3|      3|#[derive(Debug, PartialEq, Eq)]
-                              ^2
-  ------------------
-  | <issue_83601::Foo as core::cmp::PartialEq>::eq:
-  |    3|      2|#[derive(Debug, PartialEq, Eq)]
-  ------------------
-  | Unexecuted instantiation: <issue_83601::Foo as core::cmp::PartialEq>::ne
-  ------------------
-    4|       |struct Foo(u32);
-    5|       |
-    6|      1|fn main() {
-    7|      1|    let bar = Foo(1);
-    8|      1|    assert_eq!(bar, Foo(1));
-    9|      1|    let baz = Foo(0);
-   10|      1|    assert_ne!(baz, Foo(1));
-   11|      1|    println!("{:?}", Foo(1));
-   12|      1|    println!("{:?}", bar);
-   13|      1|    println!("{:?}", baz);
-   14|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt
deleted file mode 100644 (file)
index f24f7c6..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-    1|       |// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
-    2|       |
-    3|       |// expect-exit-status-101
-    4|     21|#[derive(PartialEq, Eq)]
-  ------------------
-  | <issue_84561::Foo as core::cmp::PartialEq>::eq:
-  |    4|     21|#[derive(PartialEq, Eq)]
-  ------------------
-  | Unexecuted instantiation: <issue_84561::Foo as core::cmp::PartialEq>::ne
-  ------------------
-    5|       |struct Foo(u32);
-    6|      1|fn test3() {
-    7|      1|    let is_true = std::env::args().len() == 1;
-    8|      1|    let bar = Foo(1);
-    9|      1|    assert_eq!(bar, Foo(1));
-   10|      1|    let baz = Foo(0);
-   11|      1|    assert_ne!(baz, Foo(1));
-   12|      1|    println!("{:?}", Foo(1));
-   13|      1|    println!("{:?}", bar);
-   14|      1|    println!("{:?}", baz);
-   15|      1|
-   16|      1|    assert_eq!(Foo(1), Foo(1));
-   17|      1|    assert_ne!(Foo(0), Foo(1));
-   18|      1|    assert_eq!(Foo(2), Foo(2));
-   19|      1|    let bar = Foo(0);
-   20|      1|    assert_ne!(bar, Foo(3));
-   21|      1|    assert_ne!(Foo(0), Foo(4));
-   22|      1|    assert_eq!(Foo(3), Foo(3), "with a message");
-                                             ^0
-   23|      1|    println!("{:?}", bar);
-   24|      1|    println!("{:?}", Foo(1));
-   25|      1|
-   26|      1|    assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
-                                             ^0                 ^0                      ^0
-   27|      1|    assert_ne!(
-   28|       |        Foo(0)
-   29|       |        ,
-   30|       |        Foo(5)
-   31|       |        ,
-   32|      0|        "{}"
-   33|      0|        ,
-   34|      0|        if
-   35|      0|        is_true
-   36|       |        {
-   37|      0|            "true message"
-   38|       |        } else {
-   39|      0|            "false message"
-   40|       |        }
-   41|       |    );
-   42|       |
-   43|      1|    let is_true = std::env::args().len() == 1;
-   44|      1|
-   45|      1|    assert_eq!(
-   46|      1|        Foo(1),
-   47|      1|        Foo(1)
-   48|      1|    );
-   49|      1|    assert_ne!(
-   50|      1|        Foo(0),
-   51|      1|        Foo(1)
-   52|      1|    );
-   53|      1|    assert_eq!(
-   54|      1|        Foo(2),
-   55|      1|        Foo(2)
-   56|      1|    );
-   57|      1|    let bar = Foo(1);
-   58|      1|    assert_ne!(
-   59|      1|        bar,
-   60|      1|        Foo(3)
-   61|      1|    );
-   62|      1|    if is_true {
-   63|      1|        assert_ne!(
-   64|      1|            Foo(0),
-   65|      1|            Foo(4)
-   66|      1|        );
-   67|       |    } else {
-   68|      0|        assert_eq!(
-   69|      0|            Foo(3),
-   70|      0|            Foo(3)
-   71|      0|        );
-   72|       |    }
-   73|      1|    if is_true {
-   74|      1|        assert_ne!(
-   75|       |            Foo(0),
-   76|       |            Foo(4),
-   77|      0|            "with a message"
-   78|       |        );
-   79|       |    } else {
-   80|      0|        assert_eq!(
-   81|       |            Foo(3),
-   82|       |            Foo(3),
-   83|      0|            "with a message"
-   84|       |        );
-   85|       |    }
-   86|      1|    assert_ne!(
-   87|      1|        if is_true {
-   88|      1|            Foo(0)
-   89|       |        } else {
-   90|      0|            Foo(1)
-   91|       |        },
-   92|       |        Foo(5)
-   93|       |    );
-   94|      1|    assert_ne!(
-   95|      1|        Foo(5),
-   96|      1|        if is_true {
-   97|      1|            Foo(0)
-   98|       |        } else {
-   99|      0|            Foo(1)
-  100|       |        }
-  101|       |    );
-  102|      1|    assert_ne!(
-  103|      1|        if is_true {
-  104|      1|            assert_eq!(
-  105|      1|                Foo(3),
-  106|      1|                Foo(3)
-  107|      1|            );
-  108|      1|            Foo(0)
-  109|       |        } else {
-  110|      0|            assert_ne!(
-  111|      0|                if is_true {
-  112|      0|                    Foo(0)
-  113|       |                } else {
-  114|      0|                    Foo(1)
-  115|       |                },
-  116|       |                Foo(5)
-  117|       |            );
-  118|      0|            Foo(1)
-  119|       |        },
-  120|       |        Foo(5),
-  121|      0|        "with a message"
-  122|       |    );
-  123|      1|    assert_eq!(
-  124|       |        Foo(1),
-  125|       |        Foo(3),
-  126|      1|        "this assert should fail"
-  127|       |    );
-  128|      0|    assert_eq!(
-  129|       |        Foo(3),
-  130|       |        Foo(3),
-  131|      0|        "this assert should not be reached"
-  132|       |    );
-  133|      0|}
-  134|       |
-  135|       |impl std::fmt::Debug for Foo {
-  136|       |    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-  137|      7|        write!(f, "try and succeed")?;
-                                                  ^0
-  138|      7|        Ok(())
-  139|      7|    }
-  140|       |}
-  141|       |
-  142|       |static mut DEBUG_LEVEL_ENABLED: bool = false;
-  143|       |
-  144|       |macro_rules! debug {
-  145|       |    ($($arg:tt)+) => (
-  146|       |        if unsafe { DEBUG_LEVEL_ENABLED } {
-  147|       |            println!($($arg)+);
-  148|       |        }
-  149|       |    );
-  150|       |}
-  151|       |
-  152|      1|fn test1() {
-  153|      1|    debug!("debug is enabled");
-                         ^0
-  154|      1|    debug!("debug is enabled");
-                         ^0
-  155|      1|    let _ = 0;
-  156|      1|    debug!("debug is enabled");
-                         ^0
-  157|      1|    unsafe {
-  158|      1|        DEBUG_LEVEL_ENABLED = true;
-  159|      1|    }
-  160|      1|    debug!("debug is enabled");
-  161|      1|}
-  162|       |
-  163|       |macro_rules! call_debug {
-  164|       |    ($($arg:tt)+) => (
-  165|      1|        fn call_print(s: &str) {
-  166|      1|            print!("{}", s);
-  167|      1|        }
-  168|       |
-  169|       |        call_print("called from call_debug: ");
-  170|       |        debug!($($arg)+);
-  171|       |    );
-  172|       |}
-  173|       |
-  174|      1|fn test2() {
-  175|      1|    call_debug!("debug is enabled");
-  176|      1|}
-  177|       |
-  178|      1|fn main() {
-  179|      1|    test1();
-  180|      1|    test2();
-  181|      1|    test3();
-  182|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-85461.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-85461.txt
deleted file mode 100644 (file)
index 1aa4a22..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-../coverage/issue-85461.rs:
-    1|       |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
-    2|       |
-    3|       |extern crate inline_always_with_dead_code;
-    4|       |
-    5|       |use inline_always_with_dead_code::{bar, baz};
-    6|       |
-    7|      1|fn main() {
-    8|      1|    bar::call_me();
-    9|      1|    baz::call_me();
-   10|      1|}
-
-../coverage/lib/inline_always_with_dead_code.rs:
-    1|       |// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
-    2|       |
-    3|       |#![allow(dead_code)]
-    4|       |
-    5|       |mod foo {
-    6|       |    #[inline(always)]
-    7|      2|    pub fn called() { }
-    8|       |
-    9|      0|    fn uncalled() { }
-   10|       |}
-   11|       |
-   12|       |pub mod bar {
-   13|      1|    pub fn call_me() {
-   14|      1|        super::foo::called();
-   15|      1|    }
-   16|       |}
-   17|       |
-   18|       |pub mod baz {
-   19|      1|    pub fn call_me() {
-   20|      1|        super::foo::called();
-   21|      1|    }
-   22|       |}
-
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
deleted file mode 100644 (file)
index a1655ad..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-    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-reports/expected_show_coverage.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.lazy_boolean.txt
deleted file mode 100644 (file)
index bd349df..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    6|      1|    // dependent conditions.
-    7|      1|    let is_true = std::env::args().len() == 1;
-    8|      1|
-    9|      1|    let (mut a, mut b, mut c) = (0, 0, 0);
-   10|      1|    if is_true {
-   11|      1|        a = 1;
-   12|      1|        b = 10;
-   13|      1|        c = 100;
-   14|      1|    }
-                   ^0
-   15|       |    let
-   16|      1|        somebool
-   17|       |        =
-   18|      1|            a < b
-   19|       |        ||
-   20|      0|            b < c
-   21|       |    ;
-   22|       |    let
-   23|      1|        somebool
-   24|       |        =
-   25|      1|            b < a
-   26|       |        ||
-   27|      1|            b < c
-   28|       |    ;
-   29|      1|    let somebool = a < b && b < c;
-   30|      1|    let somebool = b < a && b < c;
-                                          ^0
-   31|       |
-   32|       |    if
-   33|      1|        !
-   34|      1|        is_true
-   35|      0|    {
-   36|      0|        a = 2
-   37|      0|        ;
-   38|      1|    }
-   39|       |
-   40|       |    if
-   41|      1|        is_true
-   42|      1|    {
-   43|      1|        b = 30
-   44|      1|        ;
-   45|      1|    }
-   46|       |    else
-   47|      0|    {
-   48|      0|        c = 400
-   49|      0|        ;
-   50|      0|    }
-   51|       |
-   52|      1|    if !is_true {
-   53|      0|        a = 2;
-   54|      1|    }
-   55|       |
-   56|      1|    if is_true {
-   57|      1|        b = 30;
-   58|      1|    } else {
-   59|      0|        c = 400;
-   60|      0|    }
-   61|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loop_break_value.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loop_break_value.txt
deleted file mode 100644 (file)
index 022fe4c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    let result
-    5|      1|        =
-    6|      1|            loop
-    7|      1|        {
-    8|      1|            break
-    9|      1|            10
-   10|      1|            ;
-   11|      1|        }
-   12|      1|    ;
-   13|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt
deleted file mode 100644 (file)
index b7ad79a..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables, while_true)]
-    2|       |
-    3|       |// This test confirms that (1) unexecuted infinite loops are handled correctly by the
-    4|       |// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped.
-    5|       |
-    6|       |struct DebugTest;
-    7|       |
-    8|       |impl std::fmt::Debug for DebugTest {
-    9|      1|    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-   10|      1|        if true {
-   11|      1|            if false {
-   12|      0|                while true {
-   13|      0|                }
-   14|      1|            }
-   15|      1|            write!(f, "cool")?;
-                                           ^0
-   16|      0|        } else {
-   17|      0|        }
-   18|       |
-   19|     11|        for i in 0..10 {
-                          ^10
-   20|     10|            if true {
-   21|     10|                if false {
-   22|      0|                    while true {}
-   23|     10|                }
-   24|     10|                write!(f, "cool")?;
-                                               ^0
-   25|      0|            } else {
-   26|      0|            }
-   27|       |        }
-   28|      1|        Ok(())
-   29|      1|    }
-   30|       |}
-   31|       |
-   32|       |struct DisplayTest;
-   33|       |
-   34|       |impl std::fmt::Display for DisplayTest {
-   35|      1|    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-   36|      1|        if false {
-   37|      0|        } else {
-   38|      1|            if false {
-   39|      0|                while true {}
-   40|      1|            }
-   41|      1|            write!(f, "cool")?;
-                                           ^0
-   42|       |        }
-   43|     11|        for i in 0..10 {
-                          ^10
-   44|     10|            if false {
-   45|      0|            } else {
-   46|     10|                if false {
-   47|      0|                    while true {}
-   48|     10|                }
-   49|     10|                write!(f, "cool")?;
-                                               ^0
-   50|       |            }
-   51|       |        }
-   52|      1|        Ok(())
-   53|      1|    }
-   54|       |}
-   55|       |
-   56|      1|fn main() {
-   57|      1|    let debug_test = DebugTest;
-   58|      1|    println!("{:?}", debug_test);
-   59|      1|    let display_test = DisplayTest;
-   60|      1|    println!("{}", display_test);
-   61|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt
deleted file mode 100644 (file)
index a0fccb2..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-    1|       |#![feature(or_patterns)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    6|      1|    // dependent conditions.
-    7|      1|    let is_true = std::env::args().len() == 1;
-    8|      1|
-    9|      1|    let mut a: u8 = 0;
-   10|      1|    let mut b: u8 = 0;
-   11|      1|    if is_true {
-   12|      1|        a = 2;
-   13|      1|        b = 0;
-   14|      1|    }
-                   ^0
-   15|      1|    match (a, b) {
-   16|       |        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
-   17|       |        // This test confirms a fix for Issue #79569.
-   18|      0|        (0 | 1, 2 | 3) => {}
-   19|      1|        _ => {}
-   20|       |    }
-   21|      1|    if is_true {
-   22|      1|        a = 0;
-   23|      1|        b = 0;
-   24|      1|    }
-                   ^0
-   25|      1|    match (a, b) {
-   26|      0|        (0 | 1, 2 | 3) => {}
-   27|      1|        _ => {}
-   28|       |    }
-   29|      1|    if is_true {
-   30|      1|        a = 2;
-   31|      1|        b = 2;
-   32|      1|    }
-                   ^0
-   33|      1|    match (a, b) {
-   34|      0|        (0 | 1, 2 | 3) => {}
-   35|      1|        _ => {}
-   36|       |    }
-   37|      1|    if is_true {
-   38|      1|        a = 0;
-   39|      1|        b = 2;
-   40|      1|    }
-                   ^0
-   41|      1|    match (a, b) {
-   42|      1|        (0 | 1, 2 | 3) => {}
-   43|      0|        _ => {}
-   44|       |    }
-   45|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.nested_loops.txt
deleted file mode 100644 (file)
index 0dbd6bc..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-    1|      1|fn main() {
-    2|      1|    let is_true = std::env::args().len() == 1;
-    3|      1|    let mut countdown = 10;
-    4|       |
-    5|      1|    'outer: while countdown > 0 {
-    6|      1|        let mut a = 100;
-    7|      1|        let mut b = 100;
-    8|      3|        for _ in 0..50 {
-    9|      3|            if a < 30 {
-   10|      0|                break;
-   11|      3|            }
-   12|      3|            a -= 5;
-   13|      3|            b -= 5;
-   14|      3|            if b < 90 {
-   15|      1|                a -= 10;
-   16|      1|                if is_true {
-   17|      1|                    break 'outer;
-   18|      0|                } else {
-   19|      0|                    a -= 2;
-   20|      0|                }
-   21|      2|            }
-   22|       |        }
-   23|      0|        countdown -= 1;
-   24|       |    }
-   25|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.no_cov_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.no_cov_crate.txt
deleted file mode 100644 (file)
index 83a9204..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-    1|       |// Enables `no_coverage` on the entire crate
-    2|       |#![feature(no_coverage)]
-    3|       |
-    4|       |#[no_coverage]
-    5|       |fn do_not_add_coverage_1() {
-    6|       |    println!("called but not covered");
-    7|       |}
-    8|       |
-    9|       |fn do_not_add_coverage_2() {
-   10|       |    #![no_coverage]
-   11|       |    println!("called but not covered");
-   12|       |}
-   13|       |
-   14|       |#[no_coverage]
-   15|       |fn do_not_add_coverage_not_called() {
-   16|       |    println!("not called and not covered");
-   17|       |}
-   18|       |
-   19|      1|fn add_coverage_1() {
-   20|      1|    println!("called and covered");
-   21|      1|}
-   22|       |
-   23|      1|fn add_coverage_2() {
-   24|      1|    println!("called and covered");
-   25|      1|}
-   26|       |
-   27|      0|fn add_coverage_not_called() {
-   28|      0|    println!("not called but covered");
-   29|      0|}
-   30|       |
-   31|       |// FIXME: These test-cases illustrate confusing results of nested functions.
-   32|       |// See https://github.com/rust-lang/rust/issues/93319
-   33|       |mod nested_fns {
-   34|       |    #[no_coverage]
-   35|       |    pub fn outer_not_covered(is_true: bool) {
-   36|      1|        fn inner(is_true: bool) {
-   37|      1|            if is_true {
-   38|      1|                println!("called and covered");
-   39|      1|            } else {
-   40|      0|                println!("absolutely not covered");
-   41|      0|            }
-   42|      1|        }
-   43|       |        println!("called but not covered");
-   44|       |        inner(is_true);
-   45|       |    }
-   46|       |
-   47|      1|    pub fn outer(is_true: bool) {
-   48|      1|        println!("called and covered");
-   49|      1|        inner_not_covered(is_true);
-   50|      1|
-   51|      1|        #[no_coverage]
-   52|      1|        fn inner_not_covered(is_true: bool) {
-   53|      1|            if is_true {
-   54|      1|                println!("called but not covered");
-   55|      1|            } else {
-   56|      1|                println!("absolutely not covered");
-   57|      1|            }
-   58|      1|        }
-   59|      1|    }
-   60|       |
-   61|      1|    pub fn outer_both_covered(is_true: bool) {
-   62|      1|        println!("called and covered");
-   63|      1|        inner(is_true);
-   64|      1|
-   65|      1|        fn inner(is_true: bool) {
-   66|      1|            if is_true {
-   67|      1|                println!("called and covered");
-   68|      1|            } else {
-   69|      0|                println!("absolutely not covered");
-   70|      0|            }
-   71|      1|        }
-   72|      1|    }
-   73|       |}
-   74|       |
-   75|      1|fn main() {
-   76|      1|    let is_true = std::env::args().len() == 1;
-   77|      1|
-   78|      1|    do_not_add_coverage_1();
-   79|      1|    do_not_add_coverage_2();
-   80|      1|    add_coverage_1();
-   81|      1|    add_coverage_2();
-   82|      1|
-   83|      1|    nested_fns::outer_not_covered(is_true);
-   84|      1|    nested_fns::outer(is_true);
-   85|      1|    nested_fns::outer_both_covered(is_true);
-   86|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt
deleted file mode 100644 (file)
index 25e822b..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-    1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-101
-    3|       |
-    4|      4|fn might_overflow(to_add: u32) -> u32 {
-    5|      4|    if to_add > 5 {
-    6|      1|        println!("this will probably overflow");
-    7|      3|    }
-    8|      4|    let add_to = u32::MAX - 5;
-    9|      4|    println!("does {} + {} overflow?", add_to, to_add);
-   10|      4|    let result = to_add + add_to;
-   11|      4|    println!("continuing after overflow check");
-   12|      4|    result
-   13|      4|}
-   14|       |
-   15|      1|fn main() -> Result<(),u8> {
-   16|      1|    let mut countdown = 10;
-   17|     11|    while countdown > 0 {
-   18|     11|        if countdown == 1 {
-   19|      1|            let result = might_overflow(10);
-   20|      1|            println!("Result: {}", result);
-   21|     10|        } else if countdown < 5 {
-   22|      3|            let result = might_overflow(1);
-   23|      3|            println!("Result: {}", result);
-   24|      6|        }
-   25|     10|        countdown -= 1;
-   26|       |    }
-   27|      0|    Ok(())
-   28|      0|}
-   29|       |
-   30|       |// Notes:
-   31|       |//   1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
-   32|       |//      and similar tests `panic_unwind.rs`, abort.rs` and `try_error_result.rs`.
-   33|       |//   2. This test confirms the coverage generated when a program passes or fails a
-   34|       |//      compiler-generated `TerminatorKind::Assert` (based on an overflow check, in this case).
-   35|       |//   3. Similar to how the coverage instrumentation handles `TerminatorKind::Call`,
-   36|       |//      compiler-generated assertion failures are assumed to be a symptom of a program bug, not
-   37|       |//      expected behavior. To simplify the coverage graphs and keep instrumented programs as
-   38|       |//      small and fast as possible, `Assert` terminators are assumed to always succeed, and
-   39|       |//      therefore are considered "non-branching" terminators. So, an `Assert` terminator does not
-   40|       |//      get its own coverage counter.
-   41|       |//   4. After an unhandled panic or failed Assert, coverage results may not always be intuitive.
-   42|       |//      In this test, the final count for the statements after the `if` block in `might_overflow()`
-   43|       |//      is 4, even though the lines after `to_add + add_to` were executed only 3 times. Depending
-   44|       |//      on the MIR graph and the structure of the code, this count could have been 3 (which might
-   45|       |//      have been valid for the overflowed add `+`, but should have been 4 for the lines before
-   46|       |//      the overflow. The reason for this potential uncertainty is, a `CounterKind` is incremented
-   47|       |//      via StatementKind::Counter at the end of the block, but (as in the case in this test),
-   48|       |//      a CounterKind::Expression is always evaluated. In this case, the expression was based on
-   49|       |//      a `Counter` incremented as part of the evaluation of the `if` expression, which was
-   50|       |//      executed, and counted, 4 times, before reaching the overflow add.
-   51|       |
-   52|       |// If the program did not overflow, the coverage for `might_overflow()` would look like this:
-   53|       |//
-   54|       |//     4|       |fn might_overflow(to_add: u32) -> u32 {
-   55|       |//     5|      4|    if to_add > 5 {
-   56|       |//     6|      0|        println!("this will probably overflow");
-   57|       |//     7|      4|    }
-   58|       |//     8|      4|    let add_to = u32::MAX - 5;
-   59|       |//     9|      4|    println!("does {} + {} overflow?", add_to, to_add);
-   60|       |//    10|      4|    let result = to_add + add_to;
-   61|       |//    11|      4|    println!("continuing after overflow check");
-   62|       |//    12|      4|    result
-   63|       |//    13|      4|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt
deleted file mode 100644 (file)
index 114507d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-    1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-101
-    3|       |
-    4|      4|fn might_panic(should_panic: bool) {
-    5|      4|    if should_panic {
-    6|      1|        println!("panicking...");
-    7|      1|        panic!("panics");
-    8|      3|    } else {
-    9|      3|        println!("Don't Panic");
-   10|      3|    }
-   11|      3|}
-   12|       |
-   13|      1|fn main() -> Result<(), u8> {
-   14|      1|    let mut countdown = 10;
-   15|     11|    while countdown > 0 {
-   16|     11|        if countdown == 1 {
-   17|      1|            might_panic(true);
-   18|     10|        } else if countdown < 5 {
-   19|      3|            might_panic(false);
-   20|      6|        }
-   21|     10|        countdown -= 1;
-   22|       |    }
-   23|      0|    Ok(())
-   24|      0|}
-   25|       |
-   26|       |// Notes:
-   27|       |//   1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
-   28|       |//      `try_error_result.rs`.
-   29|       |//   2. Since the `panic_unwind.rs` test is allowed to unwind, it is also allowed to execute the
-   30|       |//      normal program exit cleanup, including writing out the current values of the coverage
-   31|       |//      counters.
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.partial_eq.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.partial_eq.txt
deleted file mode 100644 (file)
index fc26665..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-    1|       |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
-    2|       |// structure of this test.
-    3|       |
-    4|      2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
-                       ^0            ^0      ^0     ^1       ^1 ^0^0
-  ------------------
-  | Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::ne
-  ------------------
-  | Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::eq
-  ------------------
-    5|       |pub struct Version {
-    6|       |    major: usize,
-    7|       |    minor: usize,
-    8|       |    patch: usize,
-    9|       |}
-   10|       |
-   11|       |impl Version {
-   12|      2|    pub fn new(major: usize, minor: usize, patch: usize) -> Self {
-   13|      2|        Self {
-   14|      2|            major,
-   15|      2|            minor,
-   16|      2|            patch,
-   17|      2|        }
-   18|      2|    }
-   19|       |}
-   20|       |
-   21|      1|fn main() {
-   22|      1|    let version_3_2_1 = Version::new(3, 2, 1);
-   23|      1|    let version_3_3_0 = Version::new(3, 3, 0);
-   24|      1|
-   25|      1|    println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0);
-   26|      1|}
-   27|       |
-   28|       |/*
-   29|       |
-   30|       |This test verifies a bug was fixed that otherwise generated this error:
-   31|       |
-   32|       |thread 'rustc' panicked at 'No counters provided the source_hash for function:
-   33|       |    Instance {
-   34|       |        def: Item(WithOptConstParam {
-   35|       |            did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp),
-   36|       |            const_param_did: None
-   37|       |        }),
-   38|       |        substs: []
-   39|       |    }'
-   40|       |The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage
-   41|       |without a code region associated with any `Counter`. Code regions were associated with at least
-   42|       |one expression, which is allowed, but the `function_source_hash` was only passed to the codegen
-   43|       |(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the
-   44|       |`function_source_hash` without a code region, if necessary.
-   45|       |
-   46|       |*/
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_loop.txt
deleted file mode 100644 (file)
index feb83ba..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-    1|       |#![allow(unused_assignments)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    6|      1|    // dependent conditions.
-    7|      1|    let is_true = std::env::args().len() == 1;
-    8|      1|
-    9|      1|    let mut countdown = 0;
-   10|      1|
-   11|      1|    if
-   12|      1|        is_true
-   13|      1|    {
-   14|      1|        countdown
-   15|      1|        =
-   16|      1|            10
-   17|      1|        ;
-   18|      1|    }
-                   ^0
-   19|       |
-   20|       |    loop
-   21|       |    {
-   22|       |        if
-   23|     11|            countdown
-   24|     11|                ==
-   25|     11|            0
-   26|       |        {
-   27|      1|            break
-   28|       |            ;
-   29|     10|        }
-   30|     10|        countdown
-   31|     10|        -=
-   32|     10|        1
-   33|       |        ;
-   34|       |    }
-   35|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_match.txt
deleted file mode 100644 (file)
index b929821..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |
-    3|      1|fn main() {
-    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    6|      1|    // dependent conditions.
-    7|      1|    let is_true = std::env::args().len() == 1;
-    8|      1|
-    9|      1|    let mut countdown = 1;
-   10|      1|    if is_true {
-   11|      1|        countdown = 0;
-   12|      1|    }
-                   ^0
-   13|       |
-   14|       |    for
-   15|       |        _
-   16|       |    in
-   17|      3|        0..2
-   18|       |    {
-   19|       |        let z
-   20|       |        ;
-   21|       |        match
-   22|      2|            countdown
-   23|       |        {
-   24|      1|            x
-   25|       |            if
-   26|      2|                x
-   27|      2|                    <
-   28|      2|                1
-   29|       |            =>
-   30|      1|            {
-   31|      1|                z = countdown
-   32|      1|                ;
-   33|      1|                let y = countdown
-   34|      1|                ;
-   35|      1|                countdown = 10
-   36|      1|                ;
-   37|      1|            }
-   38|       |            _
-   39|       |            =>
-   40|      1|            {}
-   41|       |        }
-   42|       |    }
-   43|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.tight_inf_loop.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.tight_inf_loop.txt
deleted file mode 100644 (file)
index 2d4c57f..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-    1|      1|fn main() {
-    2|      1|    if false {
-    3|      0|        loop {}
-    4|      1|    }
-    5|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.try_error_result.txt
deleted file mode 100644 (file)
index 0ad0180..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-    1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-1
-    3|       |
-    4|      6|fn call(return_error: bool) -> Result<(),()> {
-    5|      6|    if return_error {
-    6|      1|        Err(())
-    7|       |    } else {
-    8|      5|        Ok(())
-    9|       |    }
-   10|      6|}
-   11|       |
-   12|      1|fn test1() -> Result<(),()> {
-   13|      1|    let mut
-   14|      1|        countdown = 10
-   15|       |    ;
-   16|       |    for
-   17|       |        _
-   18|       |    in
-   19|      6|        0..10
-   20|       |    {
-   21|      6|        countdown
-   22|      6|            -= 1
-   23|      6|        ;
-   24|      6|        if
-   25|      6|            countdown < 5
-   26|       |        {
-   27|      1|            call(/*return_error=*/ true)?;
-   28|      0|            call(/*return_error=*/ false)?;
-   29|       |        }
-   30|       |        else
-   31|       |        {
-   32|      5|            call(/*return_error=*/ false)?;
-                                                       ^0
-   33|       |        }
-   34|       |    }
-   35|      0|    Ok(())
-   36|      1|}
-   37|       |
-   38|       |struct Thing1;
-   39|       |impl Thing1 {
-   40|     18|    fn get_thing_2(&self, return_error: bool) -> Result<Thing2,()> {
-   41|     18|        if return_error {
-   42|      1|            Err(())
-   43|       |        } else {
-   44|     17|            Ok(Thing2{})
-   45|       |        }
-   46|     18|    }
-   47|       |}
-   48|       |
-   49|       |struct Thing2;
-   50|       |impl Thing2 {
-   51|     17|    fn call(&self, return_error: bool) -> Result<u32,()> {
-   52|     17|        if return_error {
-   53|      2|            Err(())
-   54|       |        } else {
-   55|     15|            Ok(57)
-   56|       |        }
-   57|     17|    }
-   58|       |}
-   59|       |
-   60|      1|fn test2() -> Result<(),()> {
-   61|      1|    let thing1 = Thing1{};
-   62|      1|    let mut
-   63|      1|        countdown = 10
-   64|       |    ;
-   65|       |    for
-   66|       |        _
-   67|       |    in
-   68|      6|        0..10
-   69|       |    {
-   70|      6|        countdown
-   71|      6|            -= 1
-   72|      6|        ;
-   73|      6|        if
-   74|      6|            countdown < 5
-   75|       |        {
-   76|      1|            thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
-                                                            ^0
-   77|      1|            thing1
-   78|      1|                .
-   79|      1|                get_thing_2(/*return_error=*/ false)
-   80|      0|                ?
-   81|       |                .
-   82|      1|                call(/*return_error=*/ true)
-   83|      1|                .
-   84|      1|                expect_err(
-   85|      1|                    "call should fail"
-   86|      1|                );
-   87|      1|            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ true)?;
-                              ^0                                                ^0                          ^0
-   88|      0|            assert_eq!(val, 57);
-   89|      0|            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ false)?;
-   90|      0|            assert_eq!(val, 57);
-   91|       |        }
-   92|       |        else
-   93|       |        {
-   94|      5|            let val = thing1.get_thing_2(/*return_error=*/ false)?.call(/*return_error=*/ false)?;
-                                                                               ^0                             ^0
-   95|      5|            assert_eq!(val, 57);
-   96|      5|            let val = thing1
-   97|      5|                .get_thing_2(/*return_error=*/ false)?
-                                                                   ^0
-   98|      5|                .call(/*return_error=*/ false)?;
-                                                            ^0
-   99|      5|            assert_eq!(val, 57);
-  100|      5|            let val = thing1
-  101|      5|                .get_thing_2(/*return_error=*/ false)
-  102|      0|                ?
-  103|      5|                .call(/*return_error=*/ false)
-  104|      0|                ?
-  105|       |                ;
-  106|      5|            assert_eq!(val, 57);
-  107|       |        }
-  108|       |    }
-  109|      0|    Ok(())
-  110|      1|}
-  111|       |
-  112|      1|fn main() -> Result<(),()> {
-  113|      1|    test1().expect_err("test1 should fail");
-  114|      1|    test2()
-  115|      1|    ?
-  116|       |    ;
-  117|      0|    Ok(())
-  118|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused.txt
deleted file mode 100644 (file)
index 15fcf21..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-    1|      2|fn foo<T>(x: T) {
-    2|      2|    let mut i = 0;
-    3|     22|    while i < 10 {
-    4|     20|        i != 0 || i != 0;
-                                ^2
-    5|     20|        i += 1;
-    6|       |    }
-    7|      2|}
-  ------------------
-  | unused::foo::<f32>:
-  |    1|      1|fn foo<T>(x: T) {
-  |    2|      1|    let mut i = 0;
-  |    3|     11|    while i < 10 {
-  |    4|     10|        i != 0 || i != 0;
-  |                                ^1
-  |    5|     10|        i += 1;
-  |    6|       |    }
-  |    7|      1|}
-  ------------------
-  | unused::foo::<u32>:
-  |    1|      1|fn foo<T>(x: T) {
-  |    2|      1|    let mut i = 0;
-  |    3|     11|    while i < 10 {
-  |    4|     10|        i != 0 || i != 0;
-  |                                ^1
-  |    5|     10|        i += 1;
-  |    6|       |    }
-  |    7|      1|}
-  ------------------
-    8|       |
-    9|      0|fn unused_template_func<T>(x: T) {
-   10|      0|    let mut i = 0;
-   11|      0|    while i < 10 {
-   12|      0|        i != 0 || i != 0;
-   13|      0|        i += 1;
-   14|       |    }
-   15|      0|}
-   16|       |
-   17|      0|fn unused_func(mut a: u32) {
-   18|      0|    if a != 0 {
-   19|      0|        a += 1;
-   20|      0|    }
-   21|      0|}
-   22|       |
-   23|      0|fn unused_func2(mut a: u32) {
-   24|      0|    if a != 0 {
-   25|      0|        a += 1;
-   26|      0|    }
-   27|      0|}
-   28|       |
-   29|      0|fn unused_func3(mut a: u32) {
-   30|      0|    if a != 0 {
-   31|      0|        a += 1;
-   32|      0|    }
-   33|      0|}
-   34|       |
-   35|      1|fn main() -> Result<(), u8> {
-   36|      1|    foo::<u32>(0);
-   37|      1|    foo::<f32>(0.0);
-   38|      1|    Ok(())
-   39|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused_mod.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused_mod.txt
deleted file mode 100644 (file)
index 82d6fcc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-    1|      0|pub fn never_called_function() {
-    2|      0|    println!("I am never called");
-    3|      0|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt
deleted file mode 100644 (file)
index 65eb100..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-    3|       |use std::fmt::Debug;
-    4|       |
-    5|      1|pub fn used_function() {
-    6|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    7|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    8|      1|    // dependent conditions.
-    9|      1|    let is_true = std::env::args().len() == 1;
-   10|      1|    let mut countdown = 0;
-   11|      1|    if is_true {
-   12|      1|        countdown = 10;
-   13|      1|    }
-                   ^0
-   14|      1|    use_this_lib_crate();
-   15|      1|}
-   16|       |
-   17|      2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
-   18|      2|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
-   19|      2|}
-  ------------------
-  | used_crate::used_only_from_bin_crate_generic_function::<&str>:
-  |   17|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
-  |   18|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
-  |   19|      1|}
-  ------------------
-  | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
-  |   17|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
-  |   18|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
-  |   19|      1|}
-  ------------------
-  | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
-  ------------------
-   20|       |// Expect for above function: `Unexecuted instantiation` (see below)
-   21|      2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
-   22|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
-   23|      2|}
-  ------------------
-  | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
-  |   21|      1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   22|      1|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
-  |   23|      1|}
-  ------------------
-  | used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
-  |   21|      1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   22|      1|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
-  |   23|      1|}
-  ------------------
-   24|       |
-   25|      2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-   26|      2|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-   27|      2|}
-  ------------------
-  | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
-  |   25|      1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   26|      1|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-  |   27|      1|}
-  ------------------
-  | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
-  |   25|      1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   26|      1|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-  |   27|      1|}
-  ------------------
-   28|       |
-   29|      2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-   30|      2|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-   31|      2|}
-  ------------------
-  | used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
-  |   29|      1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   30|      1|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-  |   31|      1|}
-  ------------------
-  | used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
-  |   29|      1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   30|      1|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-  |   31|      1|}
-  ------------------
-   32|       |
-   33|      0|pub fn unused_generic_function<T: Debug>(arg: T) {
-   34|      0|    println!("unused_generic_function with {:?}", arg);
-   35|      0|}
-   36|       |
-   37|      0|pub fn unused_function() {
-   38|      0|    let is_true = std::env::args().len() == 1;
-   39|      0|    let mut countdown = 2;
-   40|      0|    if !is_true {
-   41|      0|        countdown = 20;
-   42|      0|    }
-   43|      0|}
-   44|       |
-   45|      0|fn unused_private_function() {
-   46|      0|    let is_true = std::env::args().len() == 1;
-   47|      0|    let mut countdown = 2;
-   48|      0|    if !is_true {
-   49|      0|        countdown = 20;
-   50|      0|    }
-   51|      0|}
-   52|       |
-   53|      1|fn use_this_lib_crate() {
-   54|      1|    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
-   55|      1|    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
-   56|      1|        "used from library used_crate.rs",
-   57|      1|    );
-   58|      1|    let some_vec = vec![5, 6, 7, 8];
-   59|      1|    used_only_from_this_lib_crate_generic_function(some_vec);
-   60|      1|    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
-   61|      1|}
-   62|       |
-   63|       |// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
-   64|       |// for example:
-   65|       |//
-   66|       |// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
-   67|       |//
-   68|       |// These notices appear when `llvm-cov` shows instantiations. This may be a
-   69|       |// default option, but it can be suppressed with:
-   70|       |//
-   71|       |// ```shell
-   72|       |// $ `llvm-cov show --show-instantiations=0 ...`
-   73|       |// ```
-   74|       |//
-   75|       |// The notice is triggered because the function is unused by the library itself,
-   76|       |// and when the library is compiled, a synthetic function is generated, so
-   77|       |// unused function coverage can be reported. Coverage can be skipped for unused
-   78|       |// generic functions with:
-   79|       |//
-   80|       |// ```shell
-   81|       |// $ `rustc -Zunstable-options -C instrument-coverage=except-unused-generics ...`
-   82|       |// ```
-   83|       |//
-   84|       |// Even though this function is used by `uses_crate.rs` (and
-   85|       |// counted), with substitutions for `T`, those instantiations are only generated
-   86|       |// when the generic function is actually used (from the binary, not from this
-   87|       |// library crate). So the test result shows coverage for all instantiated
-   88|       |// versions and their generic type substitutions, plus the `Unexecuted
-   89|       |// instantiation` message for the non-substituted version. This is valid, but
-   90|       |// unfortunately a little confusing.
-   91|       |//
-   92|       |// The library crate has its own coverage map, and the only way to show unused
-   93|       |// coverage of a generic function is to include the generic function in the
-   94|       |// coverage map, marked as an "unused function". If the library were used by
-   95|       |// another binary that never used this generic function, then it would be valid
-   96|       |// to show the unused generic, with unknown substitution (`_`).
-   97|       |//
-   98|       |// The alternative is to exclude all generics from being included in the "unused
-   99|       |// functions" list, which would then omit coverage results for
-  100|       |// `unused_generic_function<T>()`, below.
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt
deleted file mode 100644 (file)
index dab31cb..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-    1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |
-    3|       |// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-    4|       |
-    5|       |use std::fmt::Debug;
-    6|       |
-    7|      1|pub fn used_function() {
-    8|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    9|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   10|      1|    // dependent conditions.
-   11|      1|    let is_true = std::env::args().len() == 1;
-   12|      1|    let mut countdown = 0;
-   13|      1|    if is_true {
-   14|      1|        countdown = 10;
-   15|      1|    }
-                   ^0
-   16|      1|    use_this_lib_crate();
-   17|      1|}
-   18|       |
-   19|       |#[inline(always)]
-   20|      1|pub fn used_inline_function() {
-   21|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-   22|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-   23|      1|    // dependent conditions.
-   24|      1|    let is_true = std::env::args().len() == 1;
-   25|      1|    let mut countdown = 0;
-   26|      1|    if is_true {
-   27|      1|        countdown = 10;
-   28|      1|    }
-                   ^0
-   29|      1|    use_this_lib_crate();
-   30|      1|}
-   31|       |
-   32|       |
-   33|       |
-   34|       |
-   35|       |
-   36|       |
-   37|       |
-   38|       |#[inline(always)]
-   39|      2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
-   40|      2|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
-   41|      2|}
-  ------------------
-  | used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
-  |   39|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
-  |   40|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
-  |   41|      1|}
-  ------------------
-  | used_inline_crate::used_only_from_bin_crate_generic_function::<&str>:
-  |   39|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
-  |   40|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
-  |   41|      1|}
-  ------------------
-  | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_>
-  ------------------
-   42|       |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
-   43|       |
-   44|       |#[inline(always)]
-   45|      4|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
-   46|      4|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
-   47|      4|}
-  ------------------
-  | used_inline_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
-  |   45|      2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   46|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
-  |   47|      2|}
-  ------------------
-  | used_inline_crate::used_only_from_this_lib_crate_generic_function::<&str>:
-  |   45|      2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   46|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
-  |   47|      2|}
-  ------------------
-   48|       |
-   49|       |#[inline(always)]
-   50|      3|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-   51|      3|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-   52|      3|}
-  ------------------
-  | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
-  |   50|      1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   51|      1|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-  |   52|      1|}
-  ------------------
-  | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
-  |   50|      2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   51|      2|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-  |   52|      2|}
-  ------------------
-   53|       |
-   54|       |#[inline(always)]
-   55|      3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-   56|      3|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-   57|      3|}
-  ------------------
-  | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
-  |   55|      1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   56|      1|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-  |   57|      1|}
-  ------------------
-  | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
-  |   55|      2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-  |   56|      2|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-  |   57|      2|}
-  ------------------
-   58|       |
-   59|       |#[inline(always)]
-   60|      0|pub fn unused_generic_function<T: Debug>(arg: T) {
-   61|      0|    println!("unused_generic_function with {:?}", arg);
-   62|      0|}
-   63|       |
-   64|       |#[inline(always)]
-   65|      0|pub fn unused_function() {
-   66|      0|    let is_true = std::env::args().len() == 1;
-   67|      0|    let mut countdown = 2;
-   68|      0|    if !is_true {
-   69|      0|        countdown = 20;
-   70|      0|    }
-   71|      0|}
-   72|       |
-   73|       |#[inline(always)]
-   74|      0|fn unused_private_function() {
-   75|      0|    let is_true = std::env::args().len() == 1;
-   76|      0|    let mut countdown = 2;
-   77|      0|    if !is_true {
-   78|      0|        countdown = 20;
-   79|      0|    }
-   80|      0|}
-   81|       |
-   82|      2|fn use_this_lib_crate() {
-   83|      2|    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
-   84|      2|    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
-   85|      2|        "used from library used_crate.rs",
-   86|      2|    );
-   87|      2|    let some_vec = vec![5, 6, 7, 8];
-   88|      2|    used_only_from_this_lib_crate_generic_function(some_vec);
-   89|      2|    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
-   90|      2|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while.txt
deleted file mode 100644 (file)
index efa7d08..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-    1|      1|fn main() {
-    2|      1|    let num = 9;
-    3|      1|    while num >= 10 {
-    4|      0|    }
-    5|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while_early_ret.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while_early_ret.txt
deleted file mode 100644 (file)
index d19afc0..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-    1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-1
-    3|       |
-    4|      1|fn main() -> Result<(),u8> {
-    5|      1|    let mut countdown = 10;
-    6|       |    while
-    7|      7|        countdown
-    8|      7|            >
-    9|      7|        0
-   10|       |    {
-   11|       |        if
-   12|      7|            countdown
-   13|      7|                <
-   14|      7|            5
-   15|       |        {
-   16|       |            return
-   17|       |                if
-   18|      1|                    countdown
-   19|      1|                        >
-   20|      1|                    8
-   21|       |                {
-   22|      0|                    Ok(())
-   23|       |                }
-   24|       |                else
-   25|       |                {
-   26|      1|                    Err(1)
-   27|       |                }
-   28|       |                ;
-   29|      6|        }
-   30|      6|        countdown
-   31|      6|            -=
-   32|      6|        1
-   33|       |        ;
-   34|       |    }
-   35|      0|    Ok(())
-   36|      1|}
-   37|       |
-   38|       |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and
-   39|       |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux
-   40|       |// and MacOS. But on Windows (MSVC, at least), the call to `std::process::exit()` exits the program
-   41|       |// without saving the InstrProf coverage counters. The use of `std::process:exit()` is not critical
-   42|       |// to the coverage test for early returns, but this is a limitation that should be fixed.
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.yield.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.yield.txt
deleted file mode 100644 (file)
index 60a8d94..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-    1|       |#![feature(generators, generator_trait)]
-    2|       |#![allow(unused_assignments)]
-    3|       |
-    4|       |use std::ops::{Generator, GeneratorState};
-    5|       |use std::pin::Pin;
-    6|       |
-    7|      1|fn main() {
-    8|      1|    let mut generator = || {
-    9|      1|        yield 1;
-   10|      1|        return "foo"
-   11|       |    };
-   12|       |
-   13|      1|    match Pin::new(&mut generator).resume(()) {
-   14|      1|        GeneratorState::Yielded(1) => {}
-   15|      0|        _ => panic!("unexpected value from resume"),
-   16|       |    }
-   17|      1|    match Pin::new(&mut generator).resume(()) {
-   18|      1|        GeneratorState::Complete("foo") => {}
-   19|      0|        _ => panic!("unexpected value from resume"),
-   20|       |    }
-   21|       |
-   22|      1|    let mut generator = || {
-   23|      1|        yield 1;
-   24|      1|        yield 2;
-   25|      0|        yield 3;
-   26|      0|        return "foo"
-   27|       |    };
-   28|       |
-   29|      1|    match Pin::new(&mut generator).resume(()) {
-   30|      1|        GeneratorState::Yielded(1) => {}
-   31|      0|        _ => panic!("unexpected value from resume"),
-   32|       |    }
-   33|      1|    match Pin::new(&mut generator).resume(()) {
-   34|      1|        GeneratorState::Yielded(2) => {}
-   35|      0|        _ => panic!("unexpected value from resume"),
-   36|       |    }
-   37|      1|}
-
diff --git a/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py b/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py
deleted file mode 100755 (executable)
index e5777ad..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import print_function
-
-import sys
-
-# Normalize file paths in output
-for line in sys.stdin:
-    if line.startswith("..") and line.rstrip().endswith(".rs:"):
-        print(line.replace("\\", "/"), end='')
-    else:
-        print(line, end='')
diff --git a/src/test/run-make-fulldeps/coverage/WARNING_KEEP_NAMES_SHORT.txt b/src/test/run-make-fulldeps/coverage/WARNING_KEEP_NAMES_SHORT.txt
deleted file mode 100644 (file)
index 6a1403b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-IMPORTANT: The Rust test programs in this directory generate various output
-files in the `../coverage*` directories (`expected` and `actual` files).
-
-Microsoft Windows has a relatively short limit on file paths (not individual
-path components, but the entire path). The files generated by these
-`../coverage*` tests typically have file paths that include the program
-source file name plus function and type names (depending on the program).
-
-Keep the test file names short, and keep function names and other symbols
-short as well, to avoid hitting the Windows limits.
diff --git a/src/test/run-make-fulldeps/coverage/abort.rs b/src/test/run-make-fulldeps/coverage/abort.rs
deleted file mode 100644 (file)
index 3dac43d..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#![feature(c_unwind)]
-#![allow(unused_assignments)]
-
-extern "C" fn might_abort(should_abort: bool) {
-    if should_abort {
-        println!("aborting...");
-        panic!("panics and aborts");
-    } else {
-        println!("Don't Panic");
-    }
-}
-
-fn main() -> Result<(), u8> {
-    let mut countdown = 10;
-    while countdown > 0 {
-        if countdown < 5 {
-            might_abort(false);
-        }
-        // See discussion (below the `Notes` section) on coverage results for the closing brace.
-        if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
-        // For the following example, the closing brace is the last character on the line.
-        // This shows the character after the closing brace is highlighted, even if that next
-        // character is a newline.
-        if countdown < 5 { might_abort(false); }
-        countdown -= 1;
-    }
-    Ok(())
-}
-
-// Notes:
-//   1. Compare this program and its coverage results to those of the similar tests
-//      `panic_unwind.rs` and `try_error_result.rs`.
-//   2. This test confirms the coverage generated when a program includes `TerminatorKind::Abort`.
-//   3. The test does not invoke the abort. By executing to a successful completion, the coverage
-//      results show where the program did and did not execute.
-//   4. If the program actually aborted, the coverage counters would not be saved (which "works as
-//      intended"). Coverage results would show no executed coverage regions.
-//   6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
-//      (on Linux at least).
-
-/*
-
-Expect the following coverage results:
-
-```text
-    16|     11|    while countdown > 0 {
-    17|     10|        if countdown < 5 {
-    18|      4|            might_abort(false);
-    19|      6|        }
-```
-
-This is actually correct.
-
-The condition `countdown < 5` executed 10 times (10 loop iterations).
-
-It evaluated to `true` 4 times, and executed the `might_abort()` call.
-
-It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
-`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
-closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
-non-true condition.
-
-As another example of why this is important, say the condition was `countdown < 50`, which is always
-`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
-The closing brace would have a count of `0`, highlighting the missed coverage.
-*/
diff --git a/src/test/run-make-fulldeps/coverage/assert.rs b/src/test/run-make-fulldeps/coverage/assert.rs
deleted file mode 100644 (file)
index c85f274..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#![allow(unused_assignments)]
-// expect-exit-status-101
-
-fn might_fail_assert(one_plus_one: u32) {
-    println!("does 1 + 1 = {}?", one_plus_one);
-    assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
-}
-
-fn main() -> Result<(),u8> {
-    let mut countdown = 10;
-    while countdown > 0 {
-        if countdown == 1 {
-            might_fail_assert(3);
-        } else if countdown < 5 {
-            might_fail_assert(2);
-        }
-        countdown -= 1;
-    }
-    Ok(())
-}
-
-// Notes:
-//   1. Compare this program and its coverage results to those of the very similar test
-//      `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
-//   2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
-//      related `assert_*!()` macro.
-//   3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
-//      conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
-//      `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
-//   4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
-//      (and in many other coverage tests). The `Assert` terminator is typically generated by the
-//      Rust compiler to check for runtime failures, such as numeric overflows.
diff --git a/src/test/run-make-fulldeps/coverage/async.rs b/src/test/run-make-fulldeps/coverage/async.rs
deleted file mode 100644 (file)
index a6e3877..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-#![allow(unused_assignments, dead_code)]
-
-// compile-flags: --edition=2018 -C opt-level=1
-
-async fn c(x: u8) -> u8 {
-    if x == 8 {
-        1
-    } else {
-        0
-    }
-}
-
-async fn d() -> u8 { 1 }
-
-async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
-
-async fn f() -> u8 { 1 }
-
-async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
-
-pub async fn g(x: u8) {
-    match x {
-        y if e().await == y => (),
-        y if f().await == y => (),
-        _ => (),
-    }
-}
-
-async fn h(x: usize) { // The function signature is counted when called, but the body is not
-                       // executed (not awaited) so the open brace has a `0` count (at least when
-                       // displayed with `llvm-cov show` in color-mode).
-    match x {
-        y if foo().await[y] => (),
-        _ => (),
-    }
-}
-
-async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
-                    // (a) the function signature, counted when the function is called; and
-                    // (b) the open brace for the function body, counted once when the body is
-                    // executed asynchronously.
-    match x {
-        y if c(x).await == y + 1 => { d().await; }
-        y if f().await == y + 1 => (),
-        _ => (),
-    }
-}
-
-fn j(x: u8) {
-    // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`.
-    fn c(x: u8) -> u8 {
-        if x == 8 {
-            1 // This line appears covered, but the 1-character expression span covering the `1`
-              // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
-              // `fn j()` executes the open brace for the funciton body, followed by the function's
-              // first executable statement, `match x`. Inner function declarations are not
-              // "visible" to the MIR for `j()`, so the code region counts all lines between the
-              // open brace and the first statement as executed, which is, in a sense, true.
-              // `llvm-cov show` overcomes this kind of situation by showing the actual counts
-              // of the enclosed coverages, (that is, the `1` expression was not executed, and
-              // accurately displays a `0`).
-        } else {
-            0
-        }
-    }
-    fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed
-    fn f() -> u8 { 1 }
-    match x {
-        y if c(x) == y + 1 => { d(); }
-        y if f() == y + 1 => (),
-        _ => (),
-    }
-}
-
-fn k(x: u8) { // unused function
-    match x {
-        1 => (),
-        2 => (),
-        _ => (),
-    }
-}
-
-fn l(x: u8) {
-    match x {
-        1 => (),
-        2 => (),
-        _ => (),
-    }
-}
-
-async fn m(x: u8) -> u8 { x - 1 }
-
-fn main() {
-    let _ = g(10);
-    let _ = h(9);
-    let mut future = Box::pin(i(8));
-    j(7);
-    l(6);
-    let _ = m(5);
-    executor::block_on(future.as_mut());
-}
-
-mod executor {
-    use core::{
-        future::Future,
-        pin::Pin,
-        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-    };
-
-    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-        use std::hint::unreachable_unchecked;
-        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-            |_| unsafe { unreachable_unchecked() }, // clone
-            |_| unsafe { unreachable_unchecked() }, // wake
-            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-            |_| (),
-        );
-        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-        let mut context = Context::from_waker(&waker);
-
-        loop {
-            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-                break val;
-            }
-        }
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/async2.rs b/src/test/run-make-fulldeps/coverage/async2.rs
deleted file mode 100644 (file)
index 959d48c..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-// compile-flags: --edition=2018
-
-use core::{
-    future::Future,
-    marker::Send,
-    pin::Pin,
-};
-
-fn non_async_func() {
-    println!("non_async_func was covered");
-    let b = true;
-    if b {
-        println!("non_async_func println in block");
-    }
-}
-
-
-
-
-async fn async_func() {
-    println!("async_func was covered");
-    let b = true;
-    if b {
-        println!("async_func println in block");
-    }
-}
-
-
-
-
-async fn async_func_just_println() {
-    println!("async_func_just_println was covered");
-}
-
-fn main() {
-    println!("codecovsample::main");
-
-    non_async_func();
-
-    executor::block_on(async_func());
-    executor::block_on(async_func_just_println());
-}
-
-mod executor {
-    use core::{
-        future::Future,
-        pin::Pin,
-        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-    };
-
-    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-        use std::hint::unreachable_unchecked;
-        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-            |_| unsafe { unreachable_unchecked() }, // clone
-            |_| unsafe { unreachable_unchecked() }, // wake
-            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-            |_| (),
-        );
-        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-        let mut context = Context::from_waker(&waker);
-
-        loop {
-            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-                break val;
-            }
-        }
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/closure.rs b/src/test/run-make-fulldeps/coverage/closure.rs
deleted file mode 100644 (file)
index 32ec0bc..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-// compile-flags: -C opt-level=2 # fix described in rustc_middle/mir/mono.rs
-fn main() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-    let is_false = ! is_true;
-
-    let mut some_string = Some(String::from("the string content"));
-    println!(
-        "The string or alt: {}"
-        ,
-        some_string
-            .
-            unwrap_or_else
-        (
-            ||
-            {
-                let mut countdown = 0;
-                if is_false {
-                    countdown = 10;
-                }
-                "alt string 1".to_owned()
-            }
-        )
-    );
-
-    some_string = Some(String::from("the string content"));
-    let
-        a
-    =
-        ||
-    {
-        let mut countdown = 0;
-        if is_false {
-            countdown = 10;
-        }
-        "alt string 2".to_owned()
-    };
-    println!(
-        "The string or alt: {}"
-        ,
-        some_string
-            .
-            unwrap_or_else
-        (
-            a
-        )
-    );
-
-    some_string = None;
-    println!(
-        "The string or alt: {}"
-        ,
-        some_string
-            .
-            unwrap_or_else
-        (
-            ||
-            {
-                let mut countdown = 0;
-                if is_false {
-                    countdown = 10;
-                }
-                "alt string 3".to_owned()
-            }
-        )
-    );
-
-    some_string = None;
-    let
-        a
-    =
-        ||
-    {
-        let mut countdown = 0;
-        if is_false {
-            countdown = 10;
-        }
-        "alt string 4".to_owned()
-    };
-    println!(
-        "The string or alt: {}"
-        ,
-        some_string
-            .
-            unwrap_or_else
-        (
-            a
-        )
-    );
-
-    let
-        quote_closure
-    =
-        |val|
-    {
-        let mut countdown = 0;
-        if is_false {
-            countdown = 10;
-        }
-        format!("'{}'", val)
-    };
-    println!(
-        "Repeated, quoted string: {:?}"
-        ,
-        std::iter::repeat("repeat me")
-            .take(5)
-            .map
-        (
-            quote_closure
-        )
-            .collect::<Vec<_>>()
-    );
-
-    let
-        _unused_closure
-    =
-        |
-            mut countdown
-        |
-    {
-        if is_false {
-            countdown = 10;
-        }
-        "closure should be unused".to_owned()
-    };
-
-    let mut countdown = 10;
-    let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
-
-
-    let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
-    let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
-    let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
-
-
-
-
-    let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
-
-    let _shortish_unused_closure = | _unused_arg: u8 | {
-        println!("not called")
-    };
-
-    let _as_short_unused_closure = |
-        _unused_arg: u8
-    | { println!("not called") };
-
-    let _almost_as_short_unused_closure = |
-        _unused_arg: u8
-    | { println!("not called") }
-    ;
-
-
-
-
-
-    let _short_unused_closure_line_break_no_block = | _unused_arg: u8 |
-println!("not called")
-    ;
-
-    let _short_unused_closure_line_break_no_block2 =
-        | _unused_arg: u8 |
-            println!(
-                "not called"
-            )
-    ;
-
-    let short_used_not_covered_closure_line_break_no_block_embedded_branch =
-        | _unused_arg: u8 |
-            println!(
-                "not called: {}",
-                if is_true { "check" } else { "me" }
-            )
-    ;
-
-    let short_used_not_covered_closure_line_break_block_embedded_branch =
-        | _unused_arg: u8 |
-        {
-            println!(
-                "not called: {}",
-                if is_true { "check" } else { "me" }
-            )
-        }
-    ;
-
-    let short_used_covered_closure_line_break_no_block_embedded_branch =
-        | _unused_arg: u8 |
-            println!(
-                "not called: {}",
-                if is_true { "check" } else { "me" }
-            )
-    ;
-
-    let short_used_covered_closure_line_break_block_embedded_branch =
-        | _unused_arg: u8 |
-        {
-            println!(
-                "not called: {}",
-                if is_true { "check" } else { "me" }
-            )
-        }
-    ;
-
-    if is_false {
-        short_used_not_covered_closure_macro(0);
-        short_used_not_covered_closure_line_break_no_block_embedded_branch(0);
-        short_used_not_covered_closure_line_break_block_embedded_branch(0);
-    }
-    short_used_covered_closure_macro(0);
-    short_used_covered_closure_line_break_no_block_embedded_branch(0);
-    short_used_covered_closure_line_break_block_embedded_branch(0);
-}
diff --git a/src/test/run-make-fulldeps/coverage/closure_macro.rs b/src/test/run-make-fulldeps/coverage/closure_macro.rs
deleted file mode 100644 (file)
index 5e3b00d..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// compile-flags: --edition=2018
-#![feature(no_coverage)]
-
-macro_rules! bail {
-    ($msg:literal $(,)?) => {
-        if $msg.len() > 0 {
-            println!("no msg");
-        } else {
-            println!($msg);
-        }
-        return Err(String::from($msg));
-    };
-}
-
-macro_rules! on_error {
-    ($value:expr, $error_message:expr) => {
-        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
-            let message = format!($error_message, e);
-            if message.len() > 0 {
-                println!("{}", message);
-                Ok(String::from("ok"))
-            } else {
-                bail!("error");
-            }
-        })
-    };
-}
-
-fn load_configuration_files() -> Result<String, String> {
-    Ok(String::from("config"))
-}
-
-pub fn main() -> Result<(), String> {
-    println!("Starting service");
-    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
-
-    let startup_delay_duration = String::from("arg");
-    let _ = (config, startup_delay_duration);
-    Ok(())
-}
diff --git a/src/test/run-make-fulldeps/coverage/closure_macro_async.rs b/src/test/run-make-fulldeps/coverage/closure_macro_async.rs
deleted file mode 100644 (file)
index e3e89e9..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-// compile-flags: --edition=2018
-#![feature(no_coverage)]
-
-macro_rules! bail {
-    ($msg:literal $(,)?) => {
-        if $msg.len() > 0 {
-            println!("no msg");
-        } else {
-            println!($msg);
-        }
-        return Err(String::from($msg));
-    };
-}
-
-macro_rules! on_error {
-    ($value:expr, $error_message:expr) => {
-        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
-            let message = format!($error_message, e);
-            if message.len() > 0 {
-                println!("{}", message);
-                Ok(String::from("ok"))
-            } else {
-                bail!("error");
-            }
-        })
-    };
-}
-
-fn load_configuration_files() -> Result<String, String> {
-    Ok(String::from("config"))
-}
-
-pub async fn test() -> Result<(), String> {
-    println!("Starting service");
-    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
-
-    let startup_delay_duration = String::from("arg");
-    let _ = (config, startup_delay_duration);
-    Ok(())
-}
-
-#[no_coverage]
-fn main() {
-    executor::block_on(test());
-}
-
-mod executor {
-    use core::{
-        future::Future,
-        pin::Pin,
-        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
-    };
-
-    #[no_coverage]
-    pub fn block_on<F: Future>(mut future: F) -> F::Output {
-        let mut future = unsafe { Pin::new_unchecked(&mut future) };
-        use std::hint::unreachable_unchecked;
-        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-
-            #[no_coverage]
-            |_| unsafe { unreachable_unchecked() }, // clone
-
-            #[no_coverage]
-            |_| unsafe { unreachable_unchecked() }, // wake
-
-            #[no_coverage]
-            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-
-            #[no_coverage]
-            |_| (),
-        );
-        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
-        let mut context = Context::from_waker(&waker);
-
-        loop {
-            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
-                break val;
-            }
-        }
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir b/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir
deleted file mode 100644 (file)
index d1824d1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Directory "coverage" supports the tests at prefix ../coverage-*
-
-# Use ./x.py [options] test src/test/run-make-fulldeps/coverage to run all related tests.
diff --git a/src/test/run-make-fulldeps/coverage/conditions.rs b/src/test/run-make-fulldeps/coverage/conditions.rs
deleted file mode 100644 (file)
index 057599d..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-fn main() {
-    let mut countdown = 0;
-    if true {
-        countdown = 10;
-    }
-
-    const B: u32 = 100;
-    let x = if countdown > 7 {
-        countdown -= 4;
-        B
-    } else if countdown > 2 {
-        if countdown < 1 || countdown > 5 || countdown != 9 {
-            countdown = 0;
-        }
-        countdown -= 5;
-        countdown
-    } else {
-        return;
-    };
-
-    let mut countdown = 0;
-    if true {
-        countdown = 10;
-    }
-
-    if countdown > 7 {
-        countdown -= 4;
-    } else if countdown > 2 {
-        if countdown < 1 || countdown > 5 || countdown != 9 {
-            countdown = 0;
-        }
-        countdown -= 5;
-    } else {
-        return;
-    }
-
-    if true {
-        let mut countdown = 0;
-        if true {
-            countdown = 10;
-        }
-
-        if countdown > 7 {
-            countdown -= 4;
-        }
-        else if countdown > 2 {
-            if countdown < 1 || countdown > 5 || countdown != 9 {
-                countdown = 0;
-            }
-            countdown -= 5;
-        } else {
-            return;
-        }
-    }
-
-
-    let mut countdown = 0;
-    if true {
-        countdown = 1;
-    }
-
-    let z = if countdown > 7 {
-        countdown -= 4;
-    } else if countdown > 2 {
-        if countdown < 1 || countdown > 5 || countdown != 9 {
-            countdown = 0;
-        }
-        countdown -= 5;
-    } else {
-        let should_be_reachable = countdown;
-        println!("reached");
-        return;
-    };
-
-    let w = if countdown > 7 {
-        countdown -= 4;
-    } else if countdown > 2 {
-        if countdown < 1 || countdown > 5 || countdown != 9 {
-            countdown = 0;
-        }
-        countdown -= 5;
-    } else {
-        return;
-    };
-}
diff --git a/src/test/run-make-fulldeps/coverage/continue.rs b/src/test/run-make-fulldeps/coverage/continue.rs
deleted file mode 100644 (file)
index 624aa98..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-fn main() {
-    let is_true = std::env::args().len() == 1;
-
-    let mut x = 0;
-    for _ in 0..10 {
-        match is_true {
-            true => {
-                continue;
-            }
-            _ => {
-                x = 1;
-            }
-        }
-        x = 3;
-    }
-    for _ in 0..10 {
-        match is_true {
-            false => {
-                x = 1;
-            }
-            _ => {
-                continue;
-            }
-        }
-        x = 3;
-    }
-    for _ in 0..10 {
-        match is_true {
-            true => {
-                x = 1;
-            }
-            _ => {
-                continue;
-            }
-        }
-        x = 3;
-    }
-    for _ in 0..10 {
-        if is_true {
-            continue;
-        }
-        x = 3;
-    }
-    for _ in 0..10 {
-        match is_true {
-            false => {
-                x = 1;
-            }
-            _ => {
-                let _ = x;
-            }
-        }
-        x = 3;
-    }
-    for _ in 0..10 {
-        match is_true {
-            false => {
-                x = 1;
-            }
-            _ => {
-                break;
-            }
-        }
-        x = 3;
-    }
-    let _ = x;
-}
diff --git a/src/test/run-make-fulldeps/coverage/coverage_tools.mk b/src/test/run-make-fulldeps/coverage/coverage_tools.mk
deleted file mode 100644 (file)
index aa1dc7b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# Common Makefile include for Rust `run-make-fulldeps/coverage-* tests. Include this
-# file with the line:
-#
-# -include ../coverage/coverage_tools.mk
-
--include ../tools.mk
diff --git a/src/test/run-make-fulldeps/coverage/dead_code.rs b/src/test/run-make-fulldeps/coverage/dead_code.rs
deleted file mode 100644 (file)
index a1285df..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-pub fn unused_pub_fn_not_in_library() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-
-    let mut countdown = 0;
-    if is_true {
-        countdown = 10;
-    }
-}
-
-fn unused_fn() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-
-    let mut countdown = 0;
-    if is_true {
-        countdown = 10;
-    }
-}
-
-fn main() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-
-    let mut countdown = 0;
-    if is_true {
-        countdown = 10;
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/doctest.rs b/src/test/run-make-fulldeps/coverage/doctest.rs
deleted file mode 100644 (file)
index ec04ea5..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-//! This test ensures that code from doctests is properly re-mapped.
-//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
-//!
-//! Just some random code:
-//! ```
-//! if true {
-//!     // this is executed!
-//!     assert_eq!(1, 1);
-//! } else {
-//!     // this is not!
-//!     assert_eq!(1, 2);
-//! }
-//! ```
-//!
-//! doctest testing external code:
-//! ```
-//! extern crate doctest_crate;
-//! doctest_crate::fn_run_in_doctests(1);
-//! ```
-//!
-//! doctest returning a result:
-//! ```
-//! #[derive(Debug, PartialEq)]
-//! struct SomeError {
-//!     msg: String,
-//! }
-//! let mut res = Err(SomeError { msg: String::from("a message") });
-//! if res.is_ok() {
-//!     res?;
-//! } else {
-//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
-//!         println!("{:?}", res);
-//!     }
-//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
-//!         res = Ok(1);
-//!     }
-//!     res = Ok(0);
-//! }
-//! // need to be explicit because rustdoc cant infer the return type
-//! Ok::<(), SomeError>(())
-//! ```
-//!
-//! doctest with custom main:
-//! ```
-//! fn some_func() {
-//!     println!("called some_func()");
-//! }
-//!
-//! #[derive(Debug)]
-//! struct SomeError;
-//!
-//! extern crate doctest_crate;
-//!
-//! fn doctest_main() -> Result<(), SomeError> {
-//!     some_func();
-//!     doctest_crate::fn_run_in_doctests(2);
-//!     Ok(())
-//! }
-//!
-//! // this `main` is not shown as covered, as it clashes with all the other
-//! // `main` functions that were automatically generated for doctests
-//! fn main() -> Result<(), SomeError> {
-//!     doctest_main()
-//! }
-//! ```
-
-/// doctest attached to fn testing external code:
-/// ```
-/// extern crate doctest_crate;
-/// doctest_crate::fn_run_in_doctests(3);
-/// ```
-///
-fn main() {
-    if true {
-        assert_eq!(1, 1);
-    } else {
-        assert_eq!(1, 2);
-    }
-}
-
-// FIXME(Swatinem): Fix known issue that coverage code region columns need to be offset by the
-// doc comment line prefix (`///` or `//!`) and any additional indent (before or after the doc
-// comment characters). This test produces `llvm-cov show` results demonstrating the problem.
-//
-// One of the above tests now includes: `derive(Debug, PartialEq)`, producing an `llvm-cov show`
-// result with a distinct count for `Debug`, denoted by `^1`, but the caret points to the wrong
-// column. Similarly, the `if` blocks without `else` blocks show `^0`, which should point at, or
-// one character past, the `if` block's closing brace. In both cases, these are most likely off
-// by the number of characters stripped from the beginning of each doc comment line: indent
-// whitespace, if any, doc comment prefix (`//!` in this case) and (I assume) one space character
-// (?). Note, when viewing `llvm-cov show` results in `--color` mode, the column offset errors are
-// more pronounced, and show up in more places, with background color used to show some distinct
-// code regions with different coverage counts.
-//
-// NOTE: Since the doc comment line prefix may vary, one possible solution is to replace each
-// character stripped from the beginning of doc comment lines with a space. This will give coverage
-// results the correct column offsets, and I think it should compile correctly, but I don't know
-// what affect it might have on diagnostic messages from the compiler, and whether anyone would care
-// if the indentation changed. I don't know if there is a more viable solution.
diff --git a/src/test/run-make-fulldeps/coverage/drop_trait.rs b/src/test/run-make-fulldeps/coverage/drop_trait.rs
deleted file mode 100644 (file)
index d15bfc0..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#![allow(unused_assignments)]
-// expect-exit-status-1
-
-struct Firework {
-    strength: i32,
-}
-
-impl Drop for Firework {
-    fn drop(&mut self) {
-        println!("BOOM times {}!!!", self.strength);
-    }
-}
-
-fn main() -> Result<(),u8> {
-    let _firecracker = Firework { strength: 1 };
-
-    let _tnt = Firework { strength: 100 };
-
-    if true {
-        println!("Exiting with error...");
-        return Err(1);
-    }
-
-    let _ = Firework { strength: 1000 };
-
-    Ok(())
-}
-
-// Expected program output:
-//   Exiting with error...
-//   BOOM times 100!!!
-//   BOOM times 1!!!
-//   Error: 1
diff --git a/src/test/run-make-fulldeps/coverage/generator.rs b/src/test/run-make-fulldeps/coverage/generator.rs
deleted file mode 100644 (file)
index 4319991..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#![feature(generators, generator_trait)]
-
-use std::ops::{Generator, GeneratorState};
-use std::pin::Pin;
-
-// The following implementation of a function called from a `yield` statement
-// (apparently requiring the Result and the `String` type or constructor)
-// creates conditions where the `generator::StateTransform` MIR transform will
-// drop all `Counter` `Coverage` statements from a MIR. `simplify.rs` has logic
-// to handle this condition, and still report dead block coverage.
-fn get_u32(val: bool) -> Result<u32, String> {
-    if val { Ok(1) } else { Err(String::from("some error")) }
-}
-
-fn main() {
-    let is_true = std::env::args().len() == 1;
-    let mut generator = || {
-        yield get_u32(is_true);
-        return "foo";
-    };
-
-    match Pin::new(&mut generator).resume(()) {
-        GeneratorState::Yielded(Ok(1)) => {}
-        _ => panic!("unexpected return from resume"),
-    }
-    match Pin::new(&mut generator).resume(()) {
-        GeneratorState::Complete("foo") => {}
-        _ => panic!("unexpected return from resume"),
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/generics.rs b/src/test/run-make-fulldeps/coverage/generics.rs
deleted file mode 100644 (file)
index 18b3886..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#![allow(unused_assignments)]
-// expect-exit-status-1
-
-struct Firework<T> where T: Copy + std::fmt::Display {
-    strength: T,
-}
-
-impl<T> Firework<T> where T: Copy + std::fmt::Display {
-    #[inline(always)]
-    fn set_strength(&mut self, new_strength: T) {
-        self.strength = new_strength;
-    }
-}
-
-impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
-    #[inline(always)]
-    fn drop(&mut self) {
-        println!("BOOM times {}!!!", self.strength);
-    }
-}
-
-fn main() -> Result<(),u8> {
-    let mut firecracker = Firework { strength: 1 };
-    firecracker.set_strength(2);
-
-    let mut tnt = Firework { strength: 100.1 };
-    tnt.set_strength(200.1);
-    tnt.set_strength(300.3);
-
-    if true {
-        println!("Exiting with error...");
-        return Err(1);
-    }
-
-
-
-
-
-    let _ = Firework { strength: 1000 };
-
-    Ok(())
-}
-
-// Expected program output:
-//   Exiting with error...
-//   BOOM times 100!!!
-//   BOOM times 1!!!
-//   Error: 1
diff --git a/src/test/run-make-fulldeps/coverage/if.rs b/src/test/run-make-fulldeps/coverage/if.rs
deleted file mode 100644 (file)
index 8ad5042..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-fn main() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let
-    is_true
-    =
-        std::env::args().len()
-    ==
-        1
-    ;
-    let
-        mut
-    countdown
-    =
-        0
-    ;
-    if
-        is_true
-    {
-        countdown
-        =
-            10
-        ;
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/if_else.rs b/src/test/run-make-fulldeps/coverage/if_else.rs
deleted file mode 100644 (file)
index 3244e1e..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-fn main() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-
-    let mut countdown = 0;
-    if
-        is_true
-    {
-        countdown
-        =
-            10
-        ;
-    }
-    else // Note coverage region difference without semicolon
-    {
-        countdown
-        =
-            100
-    }
-
-    if
-        is_true
-    {
-        countdown
-        =
-            10
-        ;
-    }
-    else
-    {
-        countdown
-        =
-            100
-        ;
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/inline-dead.rs b/src/test/run-make-fulldeps/coverage/inline-dead.rs
deleted file mode 100644 (file)
index 854fa06..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Regression test for issue #98833.
-// compile-flags: -Zinline-mir -Cdebug-assertions=off
-
-fn main() {
-    println!("{}", live::<false>());
-
-    let f = |x: bool| {
-        debug_assert!(
-            x
-        );
-    };
-    f(false);
-}
-
-#[inline]
-fn live<const B: bool>() -> u32 {
-    if B {
-        dead()
-    } else {
-        0
-    }
-}
-
-#[inline]
-fn dead() -> u32 {
-    42
-}
diff --git a/src/test/run-make-fulldeps/coverage/inline.rs b/src/test/run-make-fulldeps/coverage/inline.rs
deleted file mode 100644 (file)
index 9cfab9d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// compile-flags: -Zinline-mir
-
-use std::fmt::Display;
-
-fn main() {
-    permutations(&['a', 'b', 'c']);
-}
-
-#[inline(always)]
-fn permutations<T: Copy + Display>(xs: &[T]) {
-    let mut ys = xs.to_owned();
-    permutate(&mut ys, 0);
-}
-
-fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
-    let n = length(xs);
-    if k == n {
-        display(xs);
-    } else if k < n {
-        for i in k..n {
-            swap(xs, i, k);
-            permutate(xs, k + 1);
-            swap(xs, i, k);
-        }
-    } else {
-        error();
-    }
-}
-
-fn length<T>(xs: &[T]) -> usize {
-    xs.len()
-}
-
-#[inline]
-fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
-    let t = xs[i];
-    xs[i] = xs[j];
-    xs[j] = t;
-}
-
-fn display<T: Display>(xs: &[T]) {
-    for x in xs {
-        print!("{}", x);
-    }
-    println!();
-}
-
-#[inline(always)]
-fn error() {
-    panic!("error");
-}
diff --git a/src/test/run-make-fulldeps/coverage/inner_items.rs b/src/test/run-make-fulldeps/coverage/inner_items.rs
deleted file mode 100644 (file)
index bcb62b3..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#![allow(unused_assignments, unused_variables, dead_code)]
-
-fn main() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-
-    let mut countdown = 0;
-    if is_true {
-        countdown = 10;
-    }
-
-    mod in_mod {
-        const IN_MOD_CONST: u32 = 1000;
-    }
-
-    fn in_func(a: u32) {
-        let b = 1;
-        let c = a + b;
-        println!("c = {}", c)
-    }
-
-    struct InStruct {
-        in_struct_field: u32,
-    }
-
-    const IN_CONST: u32 = 1234;
-
-    trait InTrait {
-        fn trait_func(&mut self, incr: u32);
-
-        fn default_trait_func(&mut self) {
-            in_func(IN_CONST);
-            self.trait_func(IN_CONST);
-        }
-    }
-
-    impl InTrait for InStruct {
-        fn trait_func(&mut self, incr: u32) {
-            self.in_struct_field += incr;
-            in_func(self.in_struct_field);
-        }
-    }
-
-    type InType = String;
-
-    if is_true {
-        in_func(countdown);
-    }
-
-    let mut val = InStruct {
-        in_struct_field: 101,
-    };
-
-    val.default_trait_func();
-}
diff --git a/src/test/run-make-fulldeps/coverage/issue-83601.rs b/src/test/run-make-fulldeps/coverage/issue-83601.rs
deleted file mode 100644 (file)
index 0b72a81..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Shows that rust-lang/rust/83601 is resolved
-
-#[derive(Debug, PartialEq, Eq)]
-struct Foo(u32);
-
-fn main() {
-    let bar = Foo(1);
-    assert_eq!(bar, Foo(1));
-    let baz = Foo(0);
-    assert_ne!(baz, Foo(1));
-    println!("{:?}", Foo(1));
-    println!("{:?}", bar);
-    println!("{:?}", baz);
-}
diff --git a/src/test/run-make-fulldeps/coverage/issue-84561.rs b/src/test/run-make-fulldeps/coverage/issue-84561.rs
deleted file mode 100644 (file)
index b39a289..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
-
-// expect-exit-status-101
-#[derive(PartialEq, Eq)]
-struct Foo(u32);
-fn test3() {
-    let is_true = std::env::args().len() == 1;
-    let bar = Foo(1);
-    assert_eq!(bar, Foo(1));
-    let baz = Foo(0);
-    assert_ne!(baz, Foo(1));
-    println!("{:?}", Foo(1));
-    println!("{:?}", bar);
-    println!("{:?}", baz);
-
-    assert_eq!(Foo(1), Foo(1));
-    assert_ne!(Foo(0), Foo(1));
-    assert_eq!(Foo(2), Foo(2));
-    let bar = Foo(0);
-    assert_ne!(bar, Foo(3));
-    assert_ne!(Foo(0), Foo(4));
-    assert_eq!(Foo(3), Foo(3), "with a message");
-    println!("{:?}", bar);
-    println!("{:?}", Foo(1));
-
-    assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
-    assert_ne!(
-        Foo(0)
-        ,
-        Foo(5)
-        ,
-        "{}"
-        ,
-        if
-        is_true
-        {
-            "true message"
-        } else {
-            "false message"
-        }
-    );
-
-    let is_true = std::env::args().len() == 1;
-
-    assert_eq!(
-        Foo(1),
-        Foo(1)
-    );
-    assert_ne!(
-        Foo(0),
-        Foo(1)
-    );
-    assert_eq!(
-        Foo(2),
-        Foo(2)
-    );
-    let bar = Foo(1);
-    assert_ne!(
-        bar,
-        Foo(3)
-    );
-    if is_true {
-        assert_ne!(
-            Foo(0),
-            Foo(4)
-        );
-    } else {
-        assert_eq!(
-            Foo(3),
-            Foo(3)
-        );
-    }
-    if is_true {
-        assert_ne!(
-            Foo(0),
-            Foo(4),
-            "with a message"
-        );
-    } else {
-        assert_eq!(
-            Foo(3),
-            Foo(3),
-            "with a message"
-        );
-    }
-    assert_ne!(
-        if is_true {
-            Foo(0)
-        } else {
-            Foo(1)
-        },
-        Foo(5)
-    );
-    assert_ne!(
-        Foo(5),
-        if is_true {
-            Foo(0)
-        } else {
-            Foo(1)
-        }
-    );
-    assert_ne!(
-        if is_true {
-            assert_eq!(
-                Foo(3),
-                Foo(3)
-            );
-            Foo(0)
-        } else {
-            assert_ne!(
-                if is_true {
-                    Foo(0)
-                } else {
-                    Foo(1)
-                },
-                Foo(5)
-            );
-            Foo(1)
-        },
-        Foo(5),
-        "with a message"
-    );
-    assert_eq!(
-        Foo(1),
-        Foo(3),
-        "this assert should fail"
-    );
-    assert_eq!(
-        Foo(3),
-        Foo(3),
-        "this assert should not be reached"
-    );
-}
-
-impl std::fmt::Debug for Foo {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        write!(f, "try and succeed")?;
-        Ok(())
-    }
-}
-
-static mut DEBUG_LEVEL_ENABLED: bool = false;
-
-macro_rules! debug {
-    ($($arg:tt)+) => (
-        if unsafe { DEBUG_LEVEL_ENABLED } {
-            println!($($arg)+);
-        }
-    );
-}
-
-fn test1() {
-    debug!("debug is enabled");
-    debug!("debug is enabled");
-    let _ = 0;
-    debug!("debug is enabled");
-    unsafe {
-        DEBUG_LEVEL_ENABLED = true;
-    }
-    debug!("debug is enabled");
-}
-
-macro_rules! call_debug {
-    ($($arg:tt)+) => (
-        fn call_print(s: &str) {
-            print!("{}", s);
-        }
-
-        call_print("called from call_debug: ");
-        debug!($($arg)+);
-    );
-}
-
-fn test2() {
-    call_debug!("debug is enabled");
-}
-
-fn main() {
-    test1();
-    test2();
-    test3();
-}
diff --git a/src/test/run-make-fulldeps/coverage/issue-85461.rs b/src/test/run-make-fulldeps/coverage/issue-85461.rs
deleted file mode 100644 (file)
index a1b9ebb..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
-
-extern crate inline_always_with_dead_code;
-
-use inline_always_with_dead_code::{bar, baz};
-
-fn main() {
-    bar::call_me();
-    baz::call_me();
-}
diff --git a/src/test/run-make-fulldeps/coverage/issue-93054.rs b/src/test/run-make-fulldeps/coverage/issue-93054.rs
deleted file mode 100644 (file)
index c160b3d..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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() { }
diff --git a/src/test/run-make-fulldeps/coverage/lazy_boolean.rs b/src/test/run-make-fulldeps/coverage/lazy_boolean.rs
deleted file mode 100644 (file)
index bb6219e..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-fn main() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-
-    let (mut a, mut b, mut c) = (0, 0, 0);
-    if is_true {
-        a = 1;
-        b = 10;
-        c = 100;
-    }
-    let
-        somebool
-        =
-            a < b
-        ||
-            b < c
-    ;
-    let
-        somebool
-        =
-            b < a
-        ||
-            b < c
-    ;
-    let somebool = a < b && b < c;
-    let somebool = b < a && b < c;
-
-    if
-        !
-        is_true
-    {
-        a = 2
-        ;
-    }
-
-    if
-        is_true
-    {
-        b = 30
-        ;
-    }
-    else
-    {
-        c = 400
-        ;
-    }
-
-    if !is_true {
-        a = 2;
-    }
-
-    if is_true {
-        b = 30;
-    } else {
-        c = 400;
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs b/src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs
deleted file mode 100644 (file)
index c321014..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/// A function run only from within doctests
-pub fn fn_run_in_doctests(conditional: usize) {
-    match conditional {
-        1 => assert_eq!(1, 1), // this is run,
-        2 => assert_eq!(1, 1), // this,
-        3 => assert_eq!(1, 1), // and this too
-        _ => assert_eq!(1, 2), // however this is not
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/lib/inline_always_with_dead_code.rs b/src/test/run-make-fulldeps/coverage/lib/inline_always_with_dead_code.rs
deleted file mode 100644 (file)
index 2b21dee..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
-
-#![allow(dead_code)]
-
-mod foo {
-    #[inline(always)]
-    pub fn called() { }
-
-    fn uncalled() { }
-}
-
-pub mod bar {
-    pub fn call_me() {
-        super::foo::called();
-    }
-}
-
-pub mod baz {
-    pub fn call_me() {
-        super::foo::called();
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/lib/unused_mod_helper.rs b/src/test/run-make-fulldeps/coverage/lib/unused_mod_helper.rs
deleted file mode 100644 (file)
index ae1cc15..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-pub fn never_called_function() {
-    println!("I am never called");
-}
diff --git a/src/test/run-make-fulldeps/coverage/lib/used_crate.rs b/src/test/run-make-fulldeps/coverage/lib/used_crate.rs
deleted file mode 100644 (file)
index 8b8b1f7..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-use std::fmt::Debug;
-
-pub fn used_function() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-    let mut countdown = 0;
-    if is_true {
-        countdown = 10;
-    }
-    use_this_lib_crate();
-}
-
-pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
-    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
-}
-// Expect for above function: `Unexecuted instantiation` (see below)
-pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
-    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
-}
-
-pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-}
-
-pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-}
-
-pub fn unused_generic_function<T: Debug>(arg: T) {
-    println!("unused_generic_function with {:?}", arg);
-}
-
-pub fn unused_function() {
-    let is_true = std::env::args().len() == 1;
-    let mut countdown = 2;
-    if !is_true {
-        countdown = 20;
-    }
-}
-
-fn unused_private_function() {
-    let is_true = std::env::args().len() == 1;
-    let mut countdown = 2;
-    if !is_true {
-        countdown = 20;
-    }
-}
-
-fn use_this_lib_crate() {
-    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
-    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
-        "used from library used_crate.rs",
-    );
-    let some_vec = vec![5, 6, 7, 8];
-    used_only_from_this_lib_crate_generic_function(some_vec);
-    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
-}
-
-// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
-// for example:
-//
-// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
-//
-// These notices appear when `llvm-cov` shows instantiations. This may be a
-// default option, but it can be suppressed with:
-//
-// ```shell
-// $ `llvm-cov show --show-instantiations=0 ...`
-// ```
-//
-// The notice is triggered because the function is unused by the library itself,
-// and when the library is compiled, a synthetic function is generated, so
-// unused function coverage can be reported. Coverage can be skipped for unused
-// generic functions with:
-//
-// ```shell
-// $ `rustc -Zunstable-options -C instrument-coverage=except-unused-generics ...`
-// ```
-//
-// Even though this function is used by `uses_crate.rs` (and
-// counted), with substitutions for `T`, those instantiations are only generated
-// when the generic function is actually used (from the binary, not from this
-// library crate). So the test result shows coverage for all instantiated
-// versions and their generic type substitutions, plus the `Unexecuted
-// instantiation` message for the non-substituted version. This is valid, but
-// unfortunately a little confusing.
-//
-// The library crate has its own coverage map, and the only way to show unused
-// coverage of a generic function is to include the generic function in the
-// coverage map, marked as an "unused function". If the library were used by
-// another binary that never used this generic function, then it would be valid
-// to show the unused generic, with unknown substitution (`_`).
-//
-// The alternative is to exclude all generics from being included in the "unused
-// functions" list, which would then omit coverage results for
-// `unused_generic_function<T>()`, below.
diff --git a/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs b/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs
deleted file mode 100644 (file)
index 4a05275..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-
-use std::fmt::Debug;
-
-pub fn used_function() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-    let mut countdown = 0;
-    if is_true {
-        countdown = 10;
-    }
-    use_this_lib_crate();
-}
-
-#[inline(always)]
-pub fn used_inline_function() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-    let mut countdown = 0;
-    if is_true {
-        countdown = 10;
-    }
-    use_this_lib_crate();
-}
-
-
-
-
-
-
-
-#[inline(always)]
-pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
-    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
-}
-// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
-
-#[inline(always)]
-pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
-    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
-}
-
-#[inline(always)]
-pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-}
-
-#[inline(always)]
-pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
-    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
-}
-
-#[inline(always)]
-pub fn unused_generic_function<T: Debug>(arg: T) {
-    println!("unused_generic_function with {:?}", arg);
-}
-
-#[inline(always)]
-pub fn unused_function() {
-    let is_true = std::env::args().len() == 1;
-    let mut countdown = 2;
-    if !is_true {
-        countdown = 20;
-    }
-}
-
-#[inline(always)]
-fn unused_private_function() {
-    let is_true = std::env::args().len() == 1;
-    let mut countdown = 2;
-    if !is_true {
-        countdown = 20;
-    }
-}
-
-fn use_this_lib_crate() {
-    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
-    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
-        "used from library used_crate.rs",
-    );
-    let some_vec = vec![5, 6, 7, 8];
-    used_only_from_this_lib_crate_generic_function(some_vec);
-    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
-}
diff --git a/src/test/run-make-fulldeps/coverage/loop_break_value.rs b/src/test/run-make-fulldeps/coverage/loop_break_value.rs
deleted file mode 100644 (file)
index dbc4fad..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-fn main() {
-    let result
-        =
-            loop
-        {
-            break
-            10
-            ;
-        }
-    ;
-}
diff --git a/src/test/run-make-fulldeps/coverage/loops_branches.rs b/src/test/run-make-fulldeps/coverage/loops_branches.rs
deleted file mode 100644 (file)
index 7116ce4..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#![allow(unused_assignments, unused_variables, while_true)]
-
-// This test confirms that (1) unexecuted infinite loops are handled correctly by the
-// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped.
-
-struct DebugTest;
-
-impl std::fmt::Debug for DebugTest {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        if true {
-            if false {
-                while true {
-                }
-            }
-            write!(f, "cool")?;
-        } else {
-        }
-
-        for i in 0..10 {
-            if true {
-                if false {
-                    while true {}
-                }
-                write!(f, "cool")?;
-            } else {
-            }
-        }
-        Ok(())
-    }
-}
-
-struct DisplayTest;
-
-impl std::fmt::Display for DisplayTest {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        if false {
-        } else {
-            if false {
-                while true {}
-            }
-            write!(f, "cool")?;
-        }
-        for i in 0..10 {
-            if false {
-            } else {
-                if false {
-                    while true {}
-                }
-                write!(f, "cool")?;
-            }
-        }
-        Ok(())
-    }
-}
-
-fn main() {
-    let debug_test = DebugTest;
-    println!("{:?}", debug_test);
-    let display_test = DisplayTest;
-    println!("{}", display_test);
-}
diff --git a/src/test/run-make-fulldeps/coverage/match_or_pattern.rs b/src/test/run-make-fulldeps/coverage/match_or_pattern.rs
deleted file mode 100644 (file)
index 4c6a8a9..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#![feature(or_patterns)]
-
-fn main() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-
-    let mut a: u8 = 0;
-    let mut b: u8 = 0;
-    if is_true {
-        a = 2;
-        b = 0;
-    }
-    match (a, b) {
-        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
-        // This test confirms a fix for Issue #79569.
-        (0 | 1, 2 | 3) => {}
-        _ => {}
-    }
-    if is_true {
-        a = 0;
-        b = 0;
-    }
-    match (a, b) {
-        (0 | 1, 2 | 3) => {}
-        _ => {}
-    }
-    if is_true {
-        a = 2;
-        b = 2;
-    }
-    match (a, b) {
-        (0 | 1, 2 | 3) => {}
-        _ => {}
-    }
-    if is_true {
-        a = 0;
-        b = 2;
-    }
-    match (a, b) {
-        (0 | 1, 2 | 3) => {}
-        _ => {}
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/nested_loops.rs b/src/test/run-make-fulldeps/coverage/nested_loops.rs
deleted file mode 100644 (file)
index 4c7c784..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-fn main() {
-    let is_true = std::env::args().len() == 1;
-    let mut countdown = 10;
-
-    'outer: while countdown > 0 {
-        let mut a = 100;
-        let mut b = 100;
-        for _ in 0..50 {
-            if a < 30 {
-                break;
-            }
-            a -= 5;
-            b -= 5;
-            if b < 90 {
-                a -= 10;
-                if is_true {
-                    break 'outer;
-                } else {
-                    a -= 2;
-                }
-            }
-        }
-        countdown -= 1;
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/no_cov_crate.rs b/src/test/run-make-fulldeps/coverage/no_cov_crate.rs
deleted file mode 100644 (file)
index 0bfbdda..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-// Enables `no_coverage` on the entire crate
-#![feature(no_coverage)]
-
-#[no_coverage]
-fn do_not_add_coverage_1() {
-    println!("called but not covered");
-}
-
-fn do_not_add_coverage_2() {
-    #![no_coverage]
-    println!("called but not covered");
-}
-
-#[no_coverage]
-fn do_not_add_coverage_not_called() {
-    println!("not called and not covered");
-}
-
-fn add_coverage_1() {
-    println!("called and covered");
-}
-
-fn add_coverage_2() {
-    println!("called and covered");
-}
-
-fn add_coverage_not_called() {
-    println!("not called but covered");
-}
-
-// FIXME: These test-cases illustrate confusing results of nested functions.
-// See https://github.com/rust-lang/rust/issues/93319
-mod nested_fns {
-    #[no_coverage]
-    pub fn outer_not_covered(is_true: bool) {
-        fn inner(is_true: bool) {
-            if is_true {
-                println!("called and covered");
-            } else {
-                println!("absolutely not covered");
-            }
-        }
-        println!("called but not covered");
-        inner(is_true);
-    }
-
-    pub fn outer(is_true: bool) {
-        println!("called and covered");
-        inner_not_covered(is_true);
-
-        #[no_coverage]
-        fn inner_not_covered(is_true: bool) {
-            if is_true {
-                println!("called but not covered");
-            } else {
-                println!("absolutely not covered");
-            }
-        }
-    }
-
-    pub fn outer_both_covered(is_true: bool) {
-        println!("called and covered");
-        inner(is_true);
-
-        fn inner(is_true: bool) {
-            if is_true {
-                println!("called and covered");
-            } else {
-                println!("absolutely not covered");
-            }
-        }
-    }
-}
-
-fn main() {
-    let is_true = std::env::args().len() == 1;
-
-    do_not_add_coverage_1();
-    do_not_add_coverage_2();
-    add_coverage_1();
-    add_coverage_2();
-
-    nested_fns::outer_not_covered(is_true);
-    nested_fns::outer(is_true);
-    nested_fns::outer_both_covered(is_true);
-}
diff --git a/src/test/run-make-fulldeps/coverage/overflow.rs b/src/test/run-make-fulldeps/coverage/overflow.rs
deleted file mode 100644 (file)
index e537b0e..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#![allow(unused_assignments)]
-// expect-exit-status-101
-
-fn might_overflow(to_add: u32) -> u32 {
-    if to_add > 5 {
-        println!("this will probably overflow");
-    }
-    let add_to = u32::MAX - 5;
-    println!("does {} + {} overflow?", add_to, to_add);
-    let result = to_add + add_to;
-    println!("continuing after overflow check");
-    result
-}
-
-fn main() -> Result<(),u8> {
-    let mut countdown = 10;
-    while countdown > 0 {
-        if countdown == 1 {
-            let result = might_overflow(10);
-            println!("Result: {}", result);
-        } else if countdown < 5 {
-            let result = might_overflow(1);
-            println!("Result: {}", result);
-        }
-        countdown -= 1;
-    }
-    Ok(())
-}
-
-// Notes:
-//   1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
-//      and similar tests `panic_unwind.rs`, abort.rs` and `try_error_result.rs`.
-//   2. This test confirms the coverage generated when a program passes or fails a
-//      compiler-generated `TerminatorKind::Assert` (based on an overflow check, in this case).
-//   3. Similar to how the coverage instrumentation handles `TerminatorKind::Call`,
-//      compiler-generated assertion failures are assumed to be a symptom of a program bug, not
-//      expected behavior. To simplify the coverage graphs and keep instrumented programs as
-//      small and fast as possible, `Assert` terminators are assumed to always succeed, and
-//      therefore are considered "non-branching" terminators. So, an `Assert` terminator does not
-//      get its own coverage counter.
-//   4. After an unhandled panic or failed Assert, coverage results may not always be intuitive.
-//      In this test, the final count for the statements after the `if` block in `might_overflow()`
-//      is 4, even though the lines after `to_add + add_to` were executed only 3 times. Depending
-//      on the MIR graph and the structure of the code, this count could have been 3 (which might
-//      have been valid for the overflowed add `+`, but should have been 4 for the lines before
-//      the overflow. The reason for this potential uncertainty is, a `CounterKind` is incremented
-//      via StatementKind::Counter at the end of the block, but (as in the case in this test),
-//      a CounterKind::Expression is always evaluated. In this case, the expression was based on
-//      a `Counter` incremented as part of the evaluation of the `if` expression, which was
-//      executed, and counted, 4 times, before reaching the overflow add.
-
-// If the program did not overflow, the coverage for `might_overflow()` would look like this:
-//
-//     4|       |fn might_overflow(to_add: u32) -> u32 {
-//     5|      4|    if to_add > 5 {
-//     6|      0|        println!("this will probably overflow");
-//     7|      4|    }
-//     8|      4|    let add_to = u32::MAX - 5;
-//     9|      4|    println!("does {} + {} overflow?", add_to, to_add);
-//    10|      4|    let result = to_add + add_to;
-//    11|      4|    println!("continuing after overflow check");
-//    12|      4|    result
-//    13|      4|}
diff --git a/src/test/run-make-fulldeps/coverage/panic_unwind.rs b/src/test/run-make-fulldeps/coverage/panic_unwind.rs
deleted file mode 100644 (file)
index 03128c2..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#![allow(unused_assignments)]
-// expect-exit-status-101
-
-fn might_panic(should_panic: bool) {
-    if should_panic {
-        println!("panicking...");
-        panic!("panics");
-    } else {
-        println!("Don't Panic");
-    }
-}
-
-fn main() -> Result<(), u8> {
-    let mut countdown = 10;
-    while countdown > 0 {
-        if countdown == 1 {
-            might_panic(true);
-        } else if countdown < 5 {
-            might_panic(false);
-        }
-        countdown -= 1;
-    }
-    Ok(())
-}
-
-// Notes:
-//   1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
-//      `try_error_result.rs`.
-//   2. Since the `panic_unwind.rs` test is allowed to unwind, it is also allowed to execute the
-//      normal program exit cleanup, including writing out the current values of the coverage
-//      counters.
diff --git a/src/test/run-make-fulldeps/coverage/partial_eq.rs b/src/test/run-make-fulldeps/coverage/partial_eq.rs
deleted file mode 100644 (file)
index 4ceaba9..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
-// structure of this test.
-
-#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Version {
-    major: usize,
-    minor: usize,
-    patch: usize,
-}
-
-impl Version {
-    pub fn new(major: usize, minor: usize, patch: usize) -> Self {
-        Self {
-            major,
-            minor,
-            patch,
-        }
-    }
-}
-
-fn main() {
-    let version_3_2_1 = Version::new(3, 2, 1);
-    let version_3_3_0 = Version::new(3, 3, 0);
-
-    println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0);
-}
-
-/*
-
-This test verifies a bug was fixed that otherwise generated this error:
-
-thread 'rustc' panicked at 'No counters provided the source_hash for function:
-    Instance {
-        def: Item(WithOptConstParam {
-            did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp),
-            const_param_did: None
-        }),
-        substs: []
-    }'
-The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage
-without a code region associated with any `Counter`. Code regions were associated with at least
-one expression, which is allowed, but the `function_source_hash` was only passed to the codegen
-(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the
-`function_source_hash` without a code region, if necessary.
-
-*/
diff --git a/src/test/run-make-fulldeps/coverage/simple_loop.rs b/src/test/run-make-fulldeps/coverage/simple_loop.rs
deleted file mode 100644 (file)
index 6f7f234..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#![allow(unused_assignments)]
-
-fn main() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-
-    let mut countdown = 0;
-
-    if
-        is_true
-    {
-        countdown
-        =
-            10
-        ;
-    }
-
-    loop
-    {
-        if
-            countdown
-                ==
-            0
-        {
-            break
-            ;
-        }
-        countdown
-        -=
-        1
-        ;
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/simple_match.rs b/src/test/run-make-fulldeps/coverage/simple_match.rs
deleted file mode 100644 (file)
index be99e59..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-fn main() {
-    // Initialize test constants in a way that cannot be determined at compile time, to ensure
-    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
-    // dependent conditions.
-    let is_true = std::env::args().len() == 1;
-
-    let mut countdown = 1;
-    if is_true {
-        countdown = 0;
-    }
-
-    for
-        _
-    in
-        0..2
-    {
-        let z
-        ;
-        match
-            countdown
-        {
-            x
-            if
-                x
-                    <
-                1
-            =>
-            {
-                z = countdown
-                ;
-                let y = countdown
-                ;
-                countdown = 10
-                ;
-            }
-            _
-            =>
-            {}
-        }
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/tight_inf_loop.rs b/src/test/run-make-fulldeps/coverage/tight_inf_loop.rs
deleted file mode 100644 (file)
index cef9902..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
-    if false {
-        loop {}
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/try_error_result.rs b/src/test/run-make-fulldeps/coverage/try_error_result.rs
deleted file mode 100644 (file)
index cd0acf7..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-#![allow(unused_assignments)]
-// expect-exit-status-1
-
-fn call(return_error: bool) -> Result<(),()> {
-    if return_error {
-        Err(())
-    } else {
-        Ok(())
-    }
-}
-
-fn test1() -> Result<(),()> {
-    let mut
-        countdown = 10
-    ;
-    for
-        _
-    in
-        0..10
-    {
-        countdown
-            -= 1
-        ;
-        if
-            countdown < 5
-        {
-            call(/*return_error=*/ true)?;
-            call(/*return_error=*/ false)?;
-        }
-        else
-        {
-            call(/*return_error=*/ false)?;
-        }
-    }
-    Ok(())
-}
-
-struct Thing1;
-impl Thing1 {
-    fn get_thing_2(&self, return_error: bool) -> Result<Thing2,()> {
-        if return_error {
-            Err(())
-        } else {
-            Ok(Thing2{})
-        }
-    }
-}
-
-struct Thing2;
-impl Thing2 {
-    fn call(&self, return_error: bool) -> Result<u32,()> {
-        if return_error {
-            Err(())
-        } else {
-            Ok(57)
-        }
-    }
-}
-
-fn test2() -> Result<(),()> {
-    let thing1 = Thing1{};
-    let mut
-        countdown = 10
-    ;
-    for
-        _
-    in
-        0..10
-    {
-        countdown
-            -= 1
-        ;
-        if
-            countdown < 5
-        {
-            thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
-            thing1
-                .
-                get_thing_2(/*return_error=*/ false)
-                ?
-                .
-                call(/*return_error=*/ true)
-                .
-                expect_err(
-                    "call should fail"
-                );
-            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ true)?;
-            assert_eq!(val, 57);
-            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ false)?;
-            assert_eq!(val, 57);
-        }
-        else
-        {
-            let val = thing1.get_thing_2(/*return_error=*/ false)?.call(/*return_error=*/ false)?;
-            assert_eq!(val, 57);
-            let val = thing1
-                .get_thing_2(/*return_error=*/ false)?
-                .call(/*return_error=*/ false)?;
-            assert_eq!(val, 57);
-            let val = thing1
-                .get_thing_2(/*return_error=*/ false)
-                ?
-                .call(/*return_error=*/ false)
-                ?
-                ;
-            assert_eq!(val, 57);
-        }
-    }
-    Ok(())
-}
-
-fn main() -> Result<(),()> {
-    test1().expect_err("test1 should fail");
-    test2()
-    ?
-    ;
-    Ok(())
-}
diff --git a/src/test/run-make-fulldeps/coverage/unused.rs b/src/test/run-make-fulldeps/coverage/unused.rs
deleted file mode 100644 (file)
index fb6113e..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-fn foo<T>(x: T) {
-    let mut i = 0;
-    while i < 10 {
-        i != 0 || i != 0;
-        i += 1;
-    }
-}
-
-fn unused_template_func<T>(x: T) {
-    let mut i = 0;
-    while i < 10 {
-        i != 0 || i != 0;
-        i += 1;
-    }
-}
-
-fn unused_func(mut a: u32) {
-    if a != 0 {
-        a += 1;
-    }
-}
-
-fn unused_func2(mut a: u32) {
-    if a != 0 {
-        a += 1;
-    }
-}
-
-fn unused_func3(mut a: u32) {
-    if a != 0 {
-        a += 1;
-    }
-}
-
-fn main() -> Result<(), u8> {
-    foo::<u32>(0);
-    foo::<f32>(0.0);
-    Ok(())
-}
diff --git a/src/test/run-make-fulldeps/coverage/unused_mod.rs b/src/test/run-make-fulldeps/coverage/unused_mod.rs
deleted file mode 100644 (file)
index 679b4e5..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#[path = "lib/unused_mod_helper.rs"]
-mod unused_module;
-
-fn main() {
-    println!("hello world!");
-}
diff --git a/src/test/run-make-fulldeps/coverage/uses_crate.rs b/src/test/run-make-fulldeps/coverage/uses_crate.rs
deleted file mode 100644 (file)
index 20cb05f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-extern crate used_crate;
-
-fn main() {
-    used_crate::used_function();
-    let some_vec = vec![1, 2, 3, 4];
-    used_crate::used_only_from_bin_crate_generic_function(&some_vec);
-    used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
-    used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
-    used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");
-}
diff --git a/src/test/run-make-fulldeps/coverage/uses_inline_crate.rs b/src/test/run-make-fulldeps/coverage/uses_inline_crate.rs
deleted file mode 100644 (file)
index a7fe853..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#![allow(unused_assignments, unused_variables)]
-
-// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-
-extern crate used_inline_crate;
-
-fn main() {
-    used_inline_crate::used_function();
-    used_inline_crate::used_inline_function();
-    let some_vec = vec![1, 2, 3, 4];
-    used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec);
-    used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
-    used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
-    used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
-        "interesting?",
-    );
-}
diff --git a/src/test/run-make-fulldeps/coverage/while.rs b/src/test/run-make-fulldeps/coverage/while.rs
deleted file mode 100644 (file)
index 781b90b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
-    let num = 9;
-    while num >= 10 {
-    }
-}
diff --git a/src/test/run-make-fulldeps/coverage/while_early_ret.rs b/src/test/run-make-fulldeps/coverage/while_early_ret.rs
deleted file mode 100644 (file)
index 1fcea9c..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#![allow(unused_assignments)]
-// expect-exit-status-1
-
-fn main() -> Result<(),u8> {
-    let mut countdown = 10;
-    while
-        countdown
-            >
-        0
-    {
-        if
-            countdown
-                <
-            5
-        {
-            return
-                if
-                    countdown
-                        >
-                    8
-                {
-                    Ok(())
-                }
-                else
-                {
-                    Err(1)
-                }
-                ;
-        }
-        countdown
-            -=
-        1
-        ;
-    }
-    Ok(())
-}
-
-// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and
-// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux
-// and MacOS. But on Windows (MSVC, at least), the call to `std::process::exit()` exits the program
-// without saving the InstrProf coverage counters. The use of `std::process:exit()` is not critical
-// to the coverage test for early returns, but this is a limitation that should be fixed.
diff --git a/src/test/run-make-fulldeps/coverage/yield.rs b/src/test/run-make-fulldeps/coverage/yield.rs
deleted file mode 100644 (file)
index ff76166..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#![feature(generators, generator_trait)]
-#![allow(unused_assignments)]
-
-use std::ops::{Generator, GeneratorState};
-use std::pin::Pin;
-
-fn main() {
-    let mut generator = || {
-        yield 1;
-        return "foo"
-    };
-
-    match Pin::new(&mut generator).resume(()) {
-        GeneratorState::Yielded(1) => {}
-        _ => panic!("unexpected value from resume"),
-    }
-    match Pin::new(&mut generator).resume(()) {
-        GeneratorState::Complete("foo") => {}
-        _ => panic!("unexpected value from resume"),
-    }
-
-    let mut generator = || {
-        yield 1;
-        yield 2;
-        yield 3;
-        return "foo"
-    };
-
-    match Pin::new(&mut generator).resume(()) {
-        GeneratorState::Yielded(1) => {}
-        _ => panic!("unexpected value from resume"),
-    }
-    match Pin::new(&mut generator).resume(()) {
-        GeneratorState::Yielded(2) => {}
-        _ => panic!("unexpected value from resume"),
-    }
-}
diff --git a/src/test/run-make/coverage-llvmir/Makefile b/src/test/run-make/coverage-llvmir/Makefile
new file mode 100644 (file)
index 0000000..fbe0a5c
--- /dev/null
@@ -0,0 +1,64 @@
+# needs-profiler-support
+
+# Rust coverage maps support LLVM Coverage Mapping Format versions 5 and 6,
+# corresponding with LLVM versions 12 and 13, respectively.
+# When upgrading LLVM versions, consider whether to enforce a minimum LLVM
+# version during testing, with an additional directive at the top of this file
+# that sets, for example: `min-llvm-version: 12.0`
+
+-include ../coverage/coverage_tools.mk
+
+BASEDIR=../coverage-llvmir
+
+ifeq ($(UNAME),Darwin)
+       INSTR_PROF_DATA_SUFFIX=,regular,live_support
+       DATA_SECTION_PREFIX=__DATA,
+       LLVM_COV_SECTION_PREFIX=__LLVM_COV,
+       COMDAT_IF_SUPPORTED=
+else
+       INSTR_PROF_DATA_SUFFIX=
+       DATA_SECTION_PREFIX=
+       LLVM_COV_SECTION_PREFIX=
+       COMDAT_IF_SUPPORTED=, comdat
+endif
+
+DEFINE_INTERNAL=define internal
+
+ifdef IS_WINDOWS
+       LLVM_FILECHECK_OPTIONS=\
+               -check-prefixes=CHECK,WINDOWS \
+               -DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \
+               -DCOMDAT_IF_SUPPORTED='$(COMDAT_IF_SUPPORTED)' \
+               -DINSTR_PROF_DATA='.lprfd$$M' \
+               -DINSTR_PROF_NAME='.lprfn$$M' \
+               -DINSTR_PROF_CNTS='.lprfc$$M' \
+               -DINSTR_PROF_VALS='.lprfv$$M' \
+               -DINSTR_PROF_VNODES='.lprfnd$$M' \
+               -DINSTR_PROF_COVMAP='.lcovmap$$M' \
+               -DINSTR_PROF_COVFUN='.lcovfun$$M' \
+               -DINSTR_PROF_ORDERFILE='.lorderfile$$M'
+else
+       LLVM_FILECHECK_OPTIONS=\
+               -check-prefixes=CHECK \
+               -DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \
+               -DCOMDAT_IF_SUPPORTED='$(COMDAT_IF_SUPPORTED)' \
+               -DINSTR_PROF_DATA='$(DATA_SECTION_PREFIX)__llvm_prf_data$(INSTR_PROF_DATA_SUFFIX)' \
+               -DINSTR_PROF_NAME='$(DATA_SECTION_PREFIX)__llvm_prf_names' \
+               -DINSTR_PROF_CNTS='$(DATA_SECTION_PREFIX)__llvm_prf_cnts' \
+               -DINSTR_PROF_VALS='$(DATA_SECTION_PREFIX)__llvm_prf_vals' \
+               -DINSTR_PROF_VNODES='$(DATA_SECTION_PREFIX)__llvm_prf_vnds' \
+               -DINSTR_PROF_COVMAP='$(LLVM_COV_SECTION_PREFIX)__llvm_covmap' \
+               -DINSTR_PROF_COVFUN='$(LLVM_COV_SECTION_PREFIX)__llvm_covfun' \
+               -DINSTR_PROF_ORDERFILE='$(DATA_SECTION_PREFIX)__llvm_orderfile'
+endif
+
+all: test_llvm_ir
+
+test_llvm_ir:
+       # Compile the test program with non-experimental coverage instrumentation, and generate LLVM IR
+       $(RUSTC) $(BASEDIR)/testprog.rs \
+                       -Cinstrument-coverage \
+                       --emit=llvm-ir
+
+       cat "$(TMPDIR)"/testprog.ll | \
+                       "$(LLVM_FILECHECK)" $(BASEDIR)/filecheck.testprog.txt $(LLVM_FILECHECK_OPTIONS)
diff --git a/src/test/run-make/coverage-llvmir/filecheck.testprog.txt b/src/test/run-make/coverage-llvmir/filecheck.testprog.txt
new file mode 100644 (file)
index 0000000..7a5f219
--- /dev/null
@@ -0,0 +1,50 @@
+# Check for metadata, variables, declarations, and function definitions injected
+# into LLVM IR when compiling with -Cinstrument-coverage.
+
+WINDOWS:      $__llvm_profile_runtime_user = comdat any
+
+CHECK:        @__covrec_{{[A-F0-9]+}}u = linkonce_odr hidden constant
+CHECK-SAME:   section "[[INSTR_PROF_COVFUN]]"[[COMDAT_IF_SUPPORTED]], align 8
+
+CHECK:        @__llvm_coverage_mapping = private constant
+CHECK-SAME:   section "[[INSTR_PROF_COVMAP]]", align 8
+
+WINDOWS:      @__llvm_profile_runtime = external global i32
+
+CHECK:        @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
+CHECK-SAME:   section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
+
+CHECK:        @__profd__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
+CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called
+CHECK-SAME:   section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
+
+CHECK:        @__profc__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
+CHECK-SAME:   section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
+
+CHECK:        @__profd__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
+CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog4main
+CHECK-SAME:   section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
+
+CHECK:        @__llvm_prf_nm = private constant
+CHECK-SAME:   section "[[INSTR_PROF_NAME]]", align 1
+
+CHECK:        @llvm.used = appending global
+CHECK-SAME:   @__llvm_coverage_mapping
+CHECK-SAME:   @__llvm_prf_nm
+CHECK-SAME:   section "llvm.metadata"
+
+CHECK:        [[DEFINE_INTERNAL]] { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} {
+CHECK-NEXT:   start:
+CHECK-NOT:    [[DEFINE_INTERNAL]]
+CHECK:        %pgocount = load i64, {{i64\*|ptr}}
+CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called,
+
+CHECK:        declare void @llvm.instrprof.increment({{i8\*|ptr}}, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]
+
+WINDOWS:      define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat {
+WINDOWS-NEXT: %1 = load i32, {{i32\*|ptr}} @__llvm_profile_runtime
+WINDOWS-NEXT: ret i32 %1
+WINDOWS-NEXT: }
+
+CHECK:        attributes #[[LLVM_INSTRPROF_INCREMENT_ATTR]] = { nounwind }
+WINDOWS:      attributes #[[LLVM_PROFILE_RUNTIME_USER_ATTR]] = { noinline }
diff --git a/src/test/run-make/coverage-llvmir/testprog.rs b/src/test/run-make/coverage-llvmir/testprog.rs
new file mode 100644 (file)
index 0000000..358c256
--- /dev/null
@@ -0,0 +1,38 @@
+pub fn will_be_called() -> &'static str {
+    let val = "called";
+    println!("{}", val);
+    val
+}
+
+pub fn will_not_be_called() -> bool {
+    println!("should not have been called");
+    false
+}
+
+pub fn print<T>(left: &str, value: T, right: &str)
+where
+    T: std::fmt::Display,
+{
+    println!("{}{}{}", left, value, right);
+}
+
+pub fn wrap_with<F, T>(inner: T, should_wrap: bool, wrapper: F)
+where
+    F: FnOnce(&T)
+{
+    if should_wrap {
+        wrapper(&inner)
+    }
+}
+
+fn main() {
+    let less = 1;
+    let more = 100;
+
+    if less < more {
+        wrap_with(will_be_called(), less < more, |inner| print(" ***", inner, "*** "));
+        wrap_with(will_be_called(), more < less, |inner| print(" ***", inner, "*** "));
+    } else {
+        wrap_with(will_not_be_called(), true, |inner| print("wrapped result is: ", inner, ""));
+    }
+}
diff --git a/src/test/run-make/coverage-reports/Makefile b/src/test/run-make/coverage-reports/Makefile
new file mode 100644 (file)
index 0000000..78723e7
--- /dev/null
@@ -0,0 +1,180 @@
+# needs-profiler-support
+# ignore-windows-gnu
+
+# Rust coverage maps support LLVM Coverage Mapping Format versions 5 and 6,
+# corresponding with LLVM versions 12 and 13, respectively.
+# When upgrading LLVM versions, consider whether to enforce a minimum LLVM
+# version during testing, with an additional directive at the top of this file
+# that sets, for example: `min-llvm-version: 12.0`
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
+
+-include ../coverage/coverage_tools.mk
+
+BASEDIR=../coverage-reports
+SOURCEDIR=../coverage
+
+# The `llvm-cov show` flag `--debug`, used to generate the `counters` output files, is only
+# enabled if LLVM assertions are enabled. This requires Rust config `llvm/optimize` and not
+# `llvm/release_debuginfo`. Note that some CI builds disable debug assertions (by setting
+# `NO_LLVM_ASSERTIONS=1`), so the tests must still pass even if the `--debug` flag is
+# not supported. (Note that `counters` files are only produced in the `$(TMPDIR)`
+# directory, for inspection and debugging support. They are *not* copied to `expected_*`
+# files when `--bless`ed.)
+LLVM_COV_DEBUG := $(shell \
+               "$(LLVM_BIN_DIR)"/llvm-cov show --debug 2>&1 | \
+               grep -q "Unknown command line argument '--debug'"; \
+               echo $$?)
+ifeq ($(LLVM_COV_DEBUG), 1)
+DEBUG_FLAG=--debug
+endif
+
+# FIXME(richkadel): I'm adding `--ignore-filename-regex=` line(s) for specific test(s) that produce
+# `llvm-cov` results for multiple files (for example `uses_crate.rs` and `used_crate/mod.rs`) as a
+# workaround for two problems causing tests to fail on Windows:
+#
+# 1. When multiple files appear in the `llvm-cov show` results, each file's coverage results can
+#    appear in different a different order. Whether this is random or, somehow, platform-specific,
+#    the Windows output flips the order of the files, compared to Linux. In the `uses_crate.rs`
+#    test, the only test-unique (interesting) results we care about are the results for only one
+#    of the two files, `mod/uses_crate.rs`, so the workaround is to ignore all but this one file.
+#    In the future, we may want a more sophisticated solution that splits apart `llvm-cov show`
+#    results into separate results files for each result (taking care not to create new file
+#    paths that might be too long for Windows MAX_PATH limits when creating these new sub-results,
+#    as well).
+# 2. When multiple files appear in the `llvm-cov show` results, the results for each file are
+#    prefixed with their filename, including platform-specific path separators (`\` for Windows,
+#    and `/` everywhere else). This could be filtered or normalized of course, but by ignoring
+#    coverage results for all but one of the file, the filenames are no longer included anyway.
+#    If this changes (if/when we decide to support `llvm-cov show` results for multiple files),
+#    the file path separator differences may need to be addressed.
+#
+# Since this is only a workaround, I decided to implement the override by adding an option for
+# each file to be ignored, using a `--ignore-filename-regex=` entry for each one, rather than
+# implement some more sophisticated solution with a new custom test directive in the test file
+# itself (similar to `expect-exit-status`) because that would add a lot of complexity and still
+# be a workaround, with the same result, with no benefit.
+#
+# Yes these `--ignore-filename-regex=` options are included in all invocations of `llvm-cov show`
+# for now, but it is effectively ignored for all tests that don't include this file anyway.
+#
+# (Note that it's also possible the `_counters.<test>.txt` and `<test>.json` files (if generated)
+# may order results from multiple files inconsistently, which might also have to be accomodated
+# if and when we allow `llvm-cov` to produce results for multiple files. Note, the path separators
+# appear to be normalized to `/` in those files, thankfully.)
+LLVM_COV_IGNORE_FILES=\
+       --ignore-filename-regex='(uses_crate.rs|uses_inline_crate.rs|unused_mod.rs)'
+
+all: $(patsubst $(SOURCEDIR)/lib/%.rs,%,$(wildcard $(SOURCEDIR)/lib/*.rs)) $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs))
+
+# Ensure there are no `expected` results for tests that may have been removed or renamed
+.PHONY: clear_expected_if_blessed
+clear_expected_if_blessed:
+ifdef RUSTC_BLESS_TEST
+       rm -f expected_*
+endif
+
+-include clear_expected_if_blessed
+
+%: $(SOURCEDIR)/lib/%.rs
+       # Compile the test library with coverage instrumentation
+       $(RUSTC) $(SOURCEDIR)/lib/$@.rs \
+                       $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/lib/$@.rs ) \
+                       --crate-type rlib -Cinstrument-coverage
+
+%: $(SOURCEDIR)/%.rs
+       # Compile the test program with coverage instrumentation
+       $(RUSTC) $(SOURCEDIR)/$@.rs \
+                       $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \
+                       -L "$(TMPDIR)" -Cinstrument-coverage
+
+       # Run it in order to generate some profiling data,
+       # with `LLVM_PROFILE_FILE=<profdata_file>` environment variable set to
+       # output the coverage stats for this run.
+       LLVM_PROFILE_FILE="$(TMPDIR)"/$@.profraw \
+                       $(call RUN,$@) || \
+                       ( \
+                               status=$$?; \
+                               grep -q "^\/\/ expect-exit-status-$$status" $(SOURCEDIR)/$@.rs || \
+                               ( >&2 echo "program exited with an unexpected exit status: $$status"; \
+                                       false \
+                               ) \
+                       )
+
+       # Run it through rustdoc as well to cover doctests.
+       # `%p` is the pid, and `%m` the binary signature. We suspect that the pid alone
+       # might result in overwritten files and failed tests, as rustdoc spawns each
+       # doctest as its own process, so make sure the filename is as unique as possible.
+       LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p-%m.profraw \
+                       $(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \
+                       $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \
+                       -L "$(TMPDIR)" -Cinstrument-coverage \
+                       -Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@
+
+       # Postprocess the profiling data so it can be used by the llvm-cov tool
+       "$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \
+                       "$(TMPDIR)"/$@*.profraw \
+                       -o "$(TMPDIR)"/$@.profdata
+
+       # Generate a coverage report using `llvm-cov show`.
+       "$(LLVM_BIN_DIR)"/llvm-cov show \
+                       $(DEBUG_FLAG) \
+                       $(LLVM_COV_IGNORE_FILES) \
+                       --compilation-dir=. \
+                       --Xdemangler="$(RUST_DEMANGLER)" \
+                       --show-line-counts-or-regions \
+                       --instr-profile="$(TMPDIR)"/$@.profdata \
+                       $(call BIN,"$(TMPDIR)"/$@) \
+                       $$( \
+                               for file in $(TMPDIR)/rustdoc-$@/*/rust_out; do \
+                               [ -x "$$file" ] && printf "%s %s " -object $$file; \
+                               done \
+                       ) \
+               2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \
+               | "$(PYTHON)" $(BASEDIR)/normalize_paths.py \
+               > "$(TMPDIR)"/actual_show_coverage.$@.txt || \
+       ( status=$$? ; \
+               >&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \
+               exit $$status \
+       )
+
+ifdef DEBUG_FLAG
+       # The first line (beginning with "Args:" contains hard-coded, build-specific
+       # file paths. Strip that line and keep the remaining lines with counter debug
+       # data.
+       tail -n +2 "$(TMPDIR)"/show_coverage_stderr.$@.txt \
+               > "$(TMPDIR)"/actual_show_coverage_counters.$@.txt
+endif
+
+ifdef RUSTC_BLESS_TEST
+       cp "$(TMPDIR)"/actual_show_coverage.$@.txt \
+                       expected_show_coverage.$@.txt
+else
+       # Compare the show coverage output (`--bless` refreshes `typical` files).
+       #
+       # FIXME(richkadel): None of the Rust test source samples have the
+       # `// ignore-llvm-cov-show-diffs` anymore. This directive exists to work around a limitation
+       # with `llvm-cov show`. When reporting coverage for multiple instantiations of a generic function,
+       # with different type substitutions, `llvm-cov show` prints these in a non-deterministic order,
+       # breaking the `diff` comparision.
+       #
+       # A partial workaround is implemented below, with `diff --ignore-matching-lines=RE`
+       # to ignore each line prefixing each generic instantiation coverage code region.
+       #
+       # This workaround only works if the coverage counts are identical across all reported
+       # instantiations. If there is no way to ensure this, you may need to apply the
+       # `// ignore-llvm-cov-show-diffs` directive, and check for differences using the
+       # `.json` files to validate that results have not changed. (Until then, the JSON
+       # files are redundant, so there is no need to generate `expected_*.json` files or
+       # compare actual JSON results.)
+
+       $(DIFF) --ignore-matching-lines='^  | .*::<.*>.*:$$' --ignore-matching-lines='^  | <.*>::.*:$$' \
+               expected_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \
+               ( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \
+                       >&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \
+               ) || \
+               ( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \
+                       false \
+               )
+endif
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.abort.txt b/src/test/run-make/coverage-reports/expected_show_coverage.abort.txt
new file mode 100644 (file)
index 0000000..00f46f4
--- /dev/null
@@ -0,0 +1,69 @@
+    1|       |#![feature(c_unwind)]
+    2|       |#![allow(unused_assignments)]
+    3|       |
+    4|     12|extern "C" fn might_abort(should_abort: bool) {
+    5|     12|    if should_abort {
+    6|      0|        println!("aborting...");
+    7|      0|        panic!("panics and aborts");
+    8|     12|    } else {
+    9|     12|        println!("Don't Panic");
+   10|     12|    }
+   11|     12|}
+   12|       |
+   13|      1|fn main() -> Result<(), u8> {
+   14|      1|    let mut countdown = 10;
+   15|     11|    while countdown > 0 {
+   16|     10|        if countdown < 5 {
+   17|      4|            might_abort(false);
+   18|      6|        }
+   19|       |        // See discussion (below the `Notes` section) on coverage results for the closing brace.
+   20|     10|        if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
+                                       ^4                     ^6
+   21|       |        // For the following example, the closing brace is the last character on the line.
+   22|       |        // This shows the character after the closing brace is highlighted, even if that next
+   23|       |        // character is a newline.
+   24|     10|        if countdown < 5 { might_abort(false); }
+                                       ^4                     ^6
+   25|     10|        countdown -= 1;
+   26|       |    }
+   27|      1|    Ok(())
+   28|      1|}
+   29|       |
+   30|       |// Notes:
+   31|       |//   1. Compare this program and its coverage results to those of the similar tests
+   32|       |//      `panic_unwind.rs` and `try_error_result.rs`.
+   33|       |//   2. This test confirms the coverage generated when a program includes `TerminatorKind::Abort`.
+   34|       |//   3. The test does not invoke the abort. By executing to a successful completion, the coverage
+   35|       |//      results show where the program did and did not execute.
+   36|       |//   4. If the program actually aborted, the coverage counters would not be saved (which "works as
+   37|       |//      intended"). Coverage results would show no executed coverage regions.
+   38|       |//   6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
+   39|       |//      (on Linux at least).
+   40|       |
+   41|       |/*
+   42|       |
+   43|       |Expect the following coverage results:
+   44|       |
+   45|       |```text
+   46|       |    16|     11|    while countdown > 0 {
+   47|       |    17|     10|        if countdown < 5 {
+   48|       |    18|      4|            might_abort(false);
+   49|       |    19|      6|        }
+   50|       |```
+   51|       |
+   52|       |This is actually correct.
+   53|       |
+   54|       |The condition `countdown < 5` executed 10 times (10 loop iterations).
+   55|       |
+   56|       |It evaluated to `true` 4 times, and executed the `might_abort()` call.
+   57|       |
+   58|       |It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
+   59|       |`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
+   60|       |closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
+   61|       |non-true condition.
+   62|       |
+   63|       |As another example of why this is important, say the condition was `countdown < 50`, which is always
+   64|       |`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
+   65|       |The closing brace would have a count of `0`, highlighting the missed coverage.
+   66|       |*/
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.assert.txt b/src/test/run-make/coverage-reports/expected_show_coverage.assert.txt
new file mode 100644 (file)
index 0000000..4056888
--- /dev/null
@@ -0,0 +1,34 @@
+    1|       |#![allow(unused_assignments)]
+    2|       |// expect-exit-status-101
+    3|       |
+    4|      4|fn might_fail_assert(one_plus_one: u32) {
+    5|      4|    println!("does 1 + 1 = {}?", one_plus_one);
+    6|      4|    assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
+                                                  ^1
+    7|      3|}
+    8|       |
+    9|      1|fn main() -> Result<(),u8> {
+   10|      1|    let mut countdown = 10;
+   11|     11|    while countdown > 0 {
+   12|     11|        if countdown == 1 {
+   13|      1|            might_fail_assert(3);
+   14|     10|        } else if countdown < 5 {
+   15|      3|            might_fail_assert(2);
+   16|      6|        }
+   17|     10|        countdown -= 1;
+   18|       |    }
+   19|      0|    Ok(())
+   20|      0|}
+   21|       |
+   22|       |// Notes:
+   23|       |//   1. Compare this program and its coverage results to those of the very similar test
+   24|       |//      `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
+   25|       |//   2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
+   26|       |//      related `assert_*!()` macro.
+   27|       |//   3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
+   28|       |//      conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
+   29|       |//      `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
+   30|       |//   4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
+   31|       |//      (and in many other coverage tests). The `Assert` terminator is typically generated by the
+   32|       |//      Rust compiler to check for runtime failures, such as numeric overflows.
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.async.txt b/src/test/run-make/coverage-reports/expected_show_coverage.async.txt
new file mode 100644 (file)
index 0000000..2f69adb
--- /dev/null
@@ -0,0 +1,139 @@
+    1|       |#![allow(unused_assignments, dead_code)]
+    2|       |
+    3|       |// compile-flags: --edition=2018 -C opt-level=1
+    4|       |
+    5|      1|async fn c(x: u8) -> u8 {
+    6|      1|    if x == 8 {
+    7|      1|        1
+    8|       |    } else {
+    9|      0|        0
+   10|       |    }
+   11|      1|}
+   12|       |
+   13|      0|async fn d() -> u8 { 1 }
+   14|       |
+   15|      0|async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
+   16|       |
+   17|      1|async fn f() -> u8 { 1 }
+   18|       |
+   19|      0|async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
+   20|       |
+   21|      1|pub async fn g(x: u8) {
+   22|      0|    match x {
+   23|      0|        y if e().await == y => (),
+   24|      0|        y if f().await == y => (),
+   25|      0|        _ => (),
+   26|       |    }
+   27|      0|}
+   28|       |
+   29|      1|async fn h(x: usize) { // The function signature is counted when called, but the body is not
+   30|      0|                       // executed (not awaited) so the open brace has a `0` count (at least when
+   31|      0|                       // displayed with `llvm-cov show` in color-mode).
+   32|      0|    match x {
+   33|      0|        y if foo().await[y] => (),
+   34|      0|        _ => (),
+   35|       |    }
+   36|      0|}
+   37|       |
+   38|      1|async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
+   39|      1|                    // (a) the function signature, counted when the function is called; and
+   40|      1|                    // (b) the open brace for the function body, counted once when the body is
+   41|      1|                    // executed asynchronously.
+   42|      1|    match x {
+   43|      1|        y if c(x).await == y + 1 => { d().await; }
+                      ^0       ^0                   ^0 ^0
+   44|      1|        y if f().await == y + 1 => (),
+                      ^0      ^0                 ^0
+   45|      1|        _ => (),
+   46|       |    }
+   47|      1|}
+   48|       |
+   49|      1|fn j(x: u8) {
+   50|      1|    // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`.
+   51|      1|    fn c(x: u8) -> u8 {
+   52|      1|        if x == 8 {
+   53|      1|            1 // This line appears covered, but the 1-character expression span covering the `1`
+                          ^0
+   54|      1|              // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
+   55|      1|              // `fn j()` executes the open brace for the funciton body, followed by the function's
+   56|      1|              // first executable statement, `match x`. Inner function declarations are not
+   57|      1|              // "visible" to the MIR for `j()`, so the code region counts all lines between the
+   58|      1|              // open brace and the first statement as executed, which is, in a sense, true.
+   59|      1|              // `llvm-cov show` overcomes this kind of situation by showing the actual counts
+   60|      1|              // of the enclosed coverages, (that is, the `1` expression was not executed, and
+   61|      1|              // accurately displays a `0`).
+   62|      1|        } else {
+   63|      1|            0
+   64|      1|        }
+   65|      1|    }
+   66|      1|    fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed
+                  ^0
+   67|      1|    fn f() -> u8 { 1 }
+   68|      1|    match x {
+   69|      1|        y if c(x) == y + 1 => { d(); }
+                      ^0                    ^0
+   70|      1|        y if f() == y + 1 => (),
+                      ^0                   ^0
+   71|      1|        _ => (),
+   72|       |    }
+   73|      1|}
+   74|       |
+   75|      0|fn k(x: u8) { // unused function
+   76|      0|    match x {
+   77|      0|        1 => (),
+   78|      0|        2 => (),
+   79|      0|        _ => (),
+   80|       |    }
+   81|      0|}
+   82|       |
+   83|      1|fn l(x: u8) {
+   84|      1|    match x {
+   85|      0|        1 => (),
+   86|      0|        2 => (),
+   87|      1|        _ => (),
+   88|       |    }
+   89|      1|}
+   90|       |
+   91|      1|async fn m(x: u8) -> u8 { x - 1 }
+                                      ^0
+   92|       |
+   93|      1|fn main() {
+   94|      1|    let _ = g(10);
+   95|      1|    let _ = h(9);
+   96|      1|    let mut future = Box::pin(i(8));
+   97|      1|    j(7);
+   98|      1|    l(6);
+   99|      1|    let _ = m(5);
+  100|      1|    executor::block_on(future.as_mut());
+  101|      1|}
+  102|       |
+  103|       |mod executor {
+  104|       |    use core::{
+  105|       |        future::Future,
+  106|       |        pin::Pin,
+  107|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+  108|       |    };
+  109|       |
+  110|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+  111|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+  112|      1|        use std::hint::unreachable_unchecked;
+  113|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+  114|      1|            |_| unsafe { unreachable_unchecked() }, // clone
+                              ^0
+  115|      1|            |_| unsafe { unreachable_unchecked() }, // wake
+                              ^0
+  116|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+                              ^0
+  117|      1|            |_| (),
+  118|      1|        );
+  119|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+  120|      1|        let mut context = Context::from_waker(&waker);
+  121|       |
+  122|       |        loop {
+  123|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+  124|      1|                break val;
+  125|      0|            }
+  126|       |        }
+  127|      1|    }
+  128|       |}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.async2.txt b/src/test/run-make/coverage-reports/expected_show_coverage.async2.txt
new file mode 100644 (file)
index 0000000..dc06a48
--- /dev/null
@@ -0,0 +1,116 @@
+    1|       |// compile-flags: --edition=2018
+    2|       |
+    3|       |use core::{
+    4|       |    future::Future,
+    5|       |    marker::Send,
+    6|       |    pin::Pin,
+    7|       |};
+    8|       |
+    9|      1|fn non_async_func() {
+   10|      1|    println!("non_async_func was covered");
+   11|      1|    let b = true;
+   12|      1|    if b {
+   13|      1|        println!("non_async_func println in block");
+   14|      1|    }
+                   ^0
+   15|      1|}
+   16|       |
+   17|       |
+   18|       |
+   19|       |
+   20|      1|async fn async_func() {
+   21|      1|    println!("async_func was covered");
+   22|      1|    let b = true;
+   23|      1|    if b {
+   24|      1|        println!("async_func println in block");
+   25|      1|    }
+                   ^0
+   26|      1|}
+   27|       |
+   28|       |
+   29|       |
+   30|       |
+   31|      1|async fn async_func_just_println() {
+   32|      1|    println!("async_func_just_println was covered");
+   33|      1|}
+   34|       |
+   35|      1|fn main() {
+   36|      1|    println!("codecovsample::main");
+   37|      1|
+   38|      1|    non_async_func();
+   39|      1|
+   40|      1|    executor::block_on(async_func());
+   41|      1|    executor::block_on(async_func_just_println());
+   42|      1|}
+   43|       |
+   44|       |mod executor {
+   45|       |    use core::{
+   46|       |        future::Future,
+   47|       |        pin::Pin,
+   48|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+   49|       |    };
+   50|       |
+   51|      2|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+   52|      2|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+   53|      2|        use std::hint::unreachable_unchecked;
+   54|      2|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+   55|      2|            |_| unsafe { unreachable_unchecked() }, // clone
+                              ^0
+   56|      2|            |_| unsafe { unreachable_unchecked() }, // wake
+                              ^0
+   57|      2|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+                              ^0
+   58|      2|            |_| (),
+   59|      2|        );
+   60|      2|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+   61|      2|        let mut context = Context::from_waker(&waker);
+   62|       |
+   63|       |        loop {
+   64|      2|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+   65|      2|                break val;
+   66|      0|            }
+   67|       |        }
+   68|      2|    }
+  ------------------
+  | async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func::{closure#0}>>:
+  |   51|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+  |   52|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+  |   53|      1|        use std::hint::unreachable_unchecked;
+  |   54|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+  |   55|      1|            |_| unsafe { unreachable_unchecked() }, // clone
+  |   56|      1|            |_| unsafe { unreachable_unchecked() }, // wake
+  |   57|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+  |   58|      1|            |_| (),
+  |   59|      1|        );
+  |   60|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+  |   61|      1|        let mut context = Context::from_waker(&waker);
+  |   62|       |
+  |   63|       |        loop {
+  |   64|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+  |   65|      1|                break val;
+  |   66|      0|            }
+  |   67|       |        }
+  |   68|      1|    }
+  ------------------
+  | async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func_just_println::{closure#0}>>:
+  |   51|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+  |   52|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+  |   53|      1|        use std::hint::unreachable_unchecked;
+  |   54|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+  |   55|      1|            |_| unsafe { unreachable_unchecked() }, // clone
+  |   56|      1|            |_| unsafe { unreachable_unchecked() }, // wake
+  |   57|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+  |   58|      1|            |_| (),
+  |   59|      1|        );
+  |   60|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+  |   61|      1|        let mut context = Context::from_waker(&waker);
+  |   62|       |
+  |   63|       |        loop {
+  |   64|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+  |   65|      1|                break val;
+  |   66|      0|            }
+  |   67|       |        }
+  |   68|      1|    }
+  ------------------
+   69|       |}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.closure.txt b/src/test/run-make/coverage-reports/expected_show_coverage.closure.txt
new file mode 100644 (file)
index 0000000..09ad276
--- /dev/null
@@ -0,0 +1,222 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |// compile-flags: -C opt-level=2 # fix described in rustc_middle/mir/mono.rs
+    3|      1|fn main() {
+    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      1|    // dependent conditions.
+    7|      1|    let is_true = std::env::args().len() == 1;
+    8|      1|    let is_false = ! is_true;
+    9|      1|
+   10|      1|    let mut some_string = Some(String::from("the string content"));
+   11|      1|    println!(
+   12|      1|        "The string or alt: {}"
+   13|      1|        ,
+   14|      1|        some_string
+   15|      1|            .
+   16|      1|            unwrap_or_else
+   17|      1|        (
+   18|      1|            ||
+   19|      0|            {
+   20|      0|                let mut countdown = 0;
+   21|      0|                if is_false {
+   22|      0|                    countdown = 10;
+   23|      0|                }
+   24|      0|                "alt string 1".to_owned()
+   25|      1|            }
+   26|      1|        )
+   27|      1|    );
+   28|      1|
+   29|      1|    some_string = Some(String::from("the string content"));
+   30|      1|    let
+   31|      1|        a
+   32|      1|    =
+   33|      1|        ||
+   34|      0|    {
+   35|      0|        let mut countdown = 0;
+   36|      0|        if is_false {
+   37|      0|            countdown = 10;
+   38|      0|        }
+   39|      0|        "alt string 2".to_owned()
+   40|       |    };
+   41|      1|    println!(
+   42|      1|        "The string or alt: {}"
+   43|      1|        ,
+   44|      1|        some_string
+   45|      1|            .
+   46|      1|            unwrap_or_else
+   47|      1|        (
+   48|      1|            a
+   49|      1|        )
+   50|      1|    );
+   51|      1|
+   52|      1|    some_string = None;
+   53|      1|    println!(
+   54|      1|        "The string or alt: {}"
+   55|      1|        ,
+   56|      1|        some_string
+   57|      1|            .
+   58|      1|            unwrap_or_else
+   59|      1|        (
+   60|      1|            ||
+   61|      1|            {
+   62|      1|                let mut countdown = 0;
+   63|      1|                if is_false {
+   64|      0|                    countdown = 10;
+   65|      1|                }
+   66|      1|                "alt string 3".to_owned()
+   67|      1|            }
+   68|      1|        )
+   69|      1|    );
+   70|      1|
+   71|      1|    some_string = None;
+   72|      1|    let
+   73|      1|        a
+   74|      1|    =
+   75|      1|        ||
+   76|      1|    {
+   77|      1|        let mut countdown = 0;
+   78|      1|        if is_false {
+   79|      0|            countdown = 10;
+   80|      1|        }
+   81|      1|        "alt string 4".to_owned()
+   82|       |    };
+   83|      1|    println!(
+   84|      1|        "The string or alt: {}"
+   85|      1|        ,
+   86|      1|        some_string
+   87|      1|            .
+   88|      1|            unwrap_or_else
+   89|      1|        (
+   90|      1|            a
+   91|      1|        )
+   92|      1|    );
+   93|      1|
+   94|      1|    let
+   95|      1|        quote_closure
+   96|      1|    =
+   97|      1|        |val|
+   98|      5|    {
+   99|      5|        let mut countdown = 0;
+  100|      5|        if is_false {
+  101|      0|            countdown = 10;
+  102|      5|        }
+  103|      5|        format!("'{}'", val)
+  104|       |    };
+  105|      1|    println!(
+  106|      1|        "Repeated, quoted string: {:?}"
+  107|      1|        ,
+  108|      1|        std::iter::repeat("repeat me")
+  109|      1|            .take(5)
+  110|      1|            .map
+  111|      1|        (
+  112|      1|            quote_closure
+  113|      1|        )
+  114|      1|            .collect::<Vec<_>>()
+  115|      1|    );
+  116|      1|
+  117|      1|    let
+  118|      1|        _unused_closure
+  119|       |    =
+  120|       |        |
+  121|       |            mut countdown
+  122|       |        |
+  123|      0|    {
+  124|      0|        if is_false {
+  125|      0|            countdown = 10;
+  126|      0|        }
+  127|      0|        "closure should be unused".to_owned()
+  128|       |    };
+  129|       |
+  130|      1|    let mut countdown = 10;
+  131|      1|    let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
+                                                                  ^0
+  132|       |
+  133|       |
+  134|      1|    let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
+  135|      1|    let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
+                                                                              ^0
+  136|      1|    let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
+                                                                        ^0
+  137|       |
+  138|       |
+  139|       |
+  140|       |
+  141|      1|    let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
+                                                                        ^0
+  142|       |
+  143|      1|    let _shortish_unused_closure = | _unused_arg: u8 | {
+  144|      0|        println!("not called")
+  145|      0|    };
+  146|       |
+  147|      1|    let _as_short_unused_closure = |
+  148|       |        _unused_arg: u8
+  149|      0|    | { println!("not called") };
+  150|       |
+  151|      1|    let _almost_as_short_unused_closure = |
+  152|       |        _unused_arg: u8
+  153|      0|    | { println!("not called") }
+  154|       |    ;
+  155|       |
+  156|       |
+  157|       |
+  158|       |
+  159|       |
+  160|      1|    let _short_unused_closure_line_break_no_block = | _unused_arg: u8 |
+  161|      0|println!("not called")
+  162|       |    ;
+  163|       |
+  164|      1|    let _short_unused_closure_line_break_no_block2 =
+  165|       |        | _unused_arg: u8 |
+  166|      0|            println!(
+  167|      0|                "not called"
+  168|      0|            )
+  169|       |    ;
+  170|       |
+  171|      1|    let short_used_not_covered_closure_line_break_no_block_embedded_branch =
+  172|       |        | _unused_arg: u8 |
+  173|      0|            println!(
+  174|      0|                "not called: {}",
+  175|      0|                if is_true { "check" } else { "me" }
+  176|       |            )
+  177|       |    ;
+  178|       |
+  179|      1|    let short_used_not_covered_closure_line_break_block_embedded_branch =
+  180|      1|        | _unused_arg: u8 |
+  181|      0|        {
+  182|      0|            println!(
+  183|      0|                "not called: {}",
+  184|      0|                if is_true { "check" } else { "me" }
+  185|       |            )
+  186|       |        }
+  187|       |    ;
+  188|       |
+  189|      1|    let short_used_covered_closure_line_break_no_block_embedded_branch =
+  190|      1|        | _unused_arg: u8 |
+  191|      1|            println!(
+  192|      1|                "not called: {}",
+  193|      1|                if is_true { "check" } else { "me" }
+                                                            ^0
+  194|       |            )
+  195|       |    ;
+  196|       |
+  197|      1|    let short_used_covered_closure_line_break_block_embedded_branch =
+  198|      1|        | _unused_arg: u8 |
+  199|      1|        {
+  200|      1|            println!(
+  201|      1|                "not called: {}",
+  202|      1|                if is_true { "check" } else { "me" }
+                                                            ^0
+  203|       |            )
+  204|       |        }
+  205|       |    ;
+  206|       |
+  207|      1|    if is_false {
+  208|      0|        short_used_not_covered_closure_macro(0);
+  209|      0|        short_used_not_covered_closure_line_break_no_block_embedded_branch(0);
+  210|      0|        short_used_not_covered_closure_line_break_block_embedded_branch(0);
+  211|      1|    }
+  212|      1|    short_used_covered_closure_macro(0);
+  213|      1|    short_used_covered_closure_line_break_no_block_embedded_branch(0);
+  214|      1|    short_used_covered_closure_line_break_block_embedded_branch(0);
+  215|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.closure_macro.txt b/src/test/run-make/coverage-reports/expected_show_coverage.closure_macro.txt
new file mode 100644 (file)
index 0000000..87f7014
--- /dev/null
@@ -0,0 +1,42 @@
+    1|       |// compile-flags: --edition=2018
+    2|       |#![feature(no_coverage)]
+    3|       |
+    4|       |macro_rules! bail {
+    5|       |    ($msg:literal $(,)?) => {
+    6|       |        if $msg.len() > 0 {
+    7|       |            println!("no msg");
+    8|       |        } else {
+    9|       |            println!($msg);
+   10|       |        }
+   11|       |        return Err(String::from($msg));
+   12|       |    };
+   13|       |}
+   14|       |
+   15|       |macro_rules! on_error {
+   16|       |    ($value:expr, $error_message:expr) => {
+   17|       |        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
+   18|       |            let message = format!($error_message, e);
+   19|       |            if message.len() > 0 {
+   20|       |                println!("{}", message);
+   21|       |                Ok(String::from("ok"))
+   22|       |            } else {
+   23|       |                bail!("error");
+   24|       |            }
+   25|       |        })
+   26|       |    };
+   27|       |}
+   28|       |
+   29|      1|fn load_configuration_files() -> Result<String, String> {
+   30|      1|    Ok(String::from("config"))
+   31|      1|}
+   32|       |
+   33|      1|pub fn main() -> Result<(), String> {
+   34|      1|    println!("Starting service");
+   35|      1|    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
+                                                                                                 ^0
+   36|       |
+   37|      1|    let startup_delay_duration = String::from("arg");
+   38|      1|    let _ = (config, startup_delay_duration);
+   39|      1|    Ok(())
+   40|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.closure_macro_async.txt b/src/test/run-make/coverage-reports/expected_show_coverage.closure_macro_async.txt
new file mode 100644 (file)
index 0000000..2b54181
--- /dev/null
@@ -0,0 +1,83 @@
+    1|       |// compile-flags: --edition=2018
+    2|       |#![feature(no_coverage)]
+    3|       |
+    4|       |macro_rules! bail {
+    5|       |    ($msg:literal $(,)?) => {
+    6|       |        if $msg.len() > 0 {
+    7|       |            println!("no msg");
+    8|       |        } else {
+    9|       |            println!($msg);
+   10|       |        }
+   11|       |        return Err(String::from($msg));
+   12|       |    };
+   13|       |}
+   14|       |
+   15|       |macro_rules! on_error {
+   16|       |    ($value:expr, $error_message:expr) => {
+   17|       |        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
+   18|       |            let message = format!($error_message, e);
+   19|       |            if message.len() > 0 {
+   20|       |                println!("{}", message);
+   21|       |                Ok(String::from("ok"))
+   22|       |            } else {
+   23|       |                bail!("error");
+   24|       |            }
+   25|       |        })
+   26|       |    };
+   27|       |}
+   28|       |
+   29|      1|fn load_configuration_files() -> Result<String, String> {
+   30|      1|    Ok(String::from("config"))
+   31|      1|}
+   32|       |
+   33|      1|pub async fn test() -> Result<(), String> {
+   34|      1|    println!("Starting service");
+   35|      1|    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
+                                                                                                 ^0
+   36|       |
+   37|      1|    let startup_delay_duration = String::from("arg");
+   38|      1|    let _ = (config, startup_delay_duration);
+   39|      1|    Ok(())
+   40|      1|}
+   41|       |
+   42|       |#[no_coverage]
+   43|       |fn main() {
+   44|       |    executor::block_on(test());
+   45|       |}
+   46|       |
+   47|       |mod executor {
+   48|       |    use core::{
+   49|       |        future::Future,
+   50|       |        pin::Pin,
+   51|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+   52|       |    };
+   53|       |
+   54|       |    #[no_coverage]
+   55|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+   56|       |        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+   57|       |        use std::hint::unreachable_unchecked;
+   58|       |        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+   59|       |
+   60|       |            #[no_coverage]
+   61|       |            |_| unsafe { unreachable_unchecked() }, // clone
+   62|       |
+   63|       |            #[no_coverage]
+   64|       |            |_| unsafe { unreachable_unchecked() }, // wake
+   65|       |
+   66|       |            #[no_coverage]
+   67|       |            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+   68|       |
+   69|       |            #[no_coverage]
+   70|       |            |_| (),
+   71|       |        );
+   72|       |        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+   73|       |        let mut context = Context::from_waker(&waker);
+   74|       |
+   75|       |        loop {
+   76|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+   77|       |                break val;
+   78|       |            }
+   79|       |        }
+   80|       |    }
+   81|       |}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.conditions.txt b/src/test/run-make/coverage-reports/expected_show_coverage.conditions.txt
new file mode 100644 (file)
index 0000000..2d8a98a
--- /dev/null
@@ -0,0 +1,94 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    let mut countdown = 0;
+    5|      1|    if true {
+    6|      1|        countdown = 10;
+    7|      1|    }
+                   ^0
+    8|       |
+    9|       |    const B: u32 = 100;
+   10|      1|    let x = if countdown > 7 {
+   11|      1|        countdown -= 4;
+   12|      1|        B
+   13|      0|    } else if countdown > 2 {
+   14|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
+   15|      0|            countdown = 0;
+   16|      0|        }
+   17|      0|        countdown -= 5;
+   18|      0|        countdown
+   19|       |    } else {
+   20|      0|        return;
+   21|       |    };
+   22|       |
+   23|      1|    let mut countdown = 0;
+   24|      1|    if true {
+   25|      1|        countdown = 10;
+   26|      1|    }
+                   ^0
+   27|       |
+   28|      1|    if countdown > 7 {
+   29|      1|        countdown -= 4;
+   30|      1|    } else if countdown > 2 {
+                            ^0
+   31|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
+   32|      0|            countdown = 0;
+   33|      0|        }
+   34|      0|        countdown -= 5;
+   35|       |    } else {
+   36|      0|        return;
+   37|       |    }
+   38|       |
+   39|      1|    if true {
+   40|      1|        let mut countdown = 0;
+   41|      1|        if true {
+   42|      1|            countdown = 10;
+   43|      1|        }
+                       ^0
+   44|       |
+   45|      1|        if countdown > 7 {
+   46|      1|            countdown -= 4;
+   47|      1|        }
+   48|      0|        else if countdown > 2 {
+   49|      0|            if countdown < 1 || countdown > 5 || countdown != 9 {
+   50|      0|                countdown = 0;
+   51|      0|            }
+   52|      0|            countdown -= 5;
+   53|       |        } else {
+   54|      0|            return;
+   55|       |        }
+   56|      0|    }
+   57|       |
+   58|       |
+   59|      1|    let mut countdown = 0;
+   60|      1|    if true {
+   61|      1|        countdown = 1;
+   62|      1|    }
+                   ^0
+   63|       |
+   64|      1|    let z = if countdown > 7 {
+                      ^0
+   65|      0|        countdown -= 4;
+   66|      1|    } else if countdown > 2 {
+   67|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
+   68|      0|            countdown = 0;
+   69|      0|        }
+   70|      0|        countdown -= 5;
+   71|       |    } else {
+   72|      1|        let should_be_reachable = countdown;
+   73|      1|        println!("reached");
+   74|      1|        return;
+   75|       |    };
+   76|       |
+   77|      0|    let w = if countdown > 7 {
+   78|      0|        countdown -= 4;
+   79|      0|    } else if countdown > 2 {
+   80|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
+   81|      0|            countdown = 0;
+   82|      0|        }
+   83|      0|        countdown -= 5;
+   84|       |    } else {
+   85|      0|        return;
+   86|       |    };
+   87|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.continue.txt b/src/test/run-make/coverage-reports/expected_show_coverage.continue.txt
new file mode 100644 (file)
index 0000000..1c64ead
--- /dev/null
@@ -0,0 +1,70 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    let is_true = std::env::args().len() == 1;
+    5|      1|
+    6|      1|    let mut x = 0;
+    7|     11|    for _ in 0..10 {
+    8|     10|        match is_true {
+    9|       |            true => {
+   10|     10|                continue;
+   11|       |            }
+   12|      0|            _ => {
+   13|      0|                x = 1;
+   14|      0|            }
+   15|      0|        }
+   16|      0|        x = 3;
+   17|       |    }
+   18|     11|    for _ in 0..10 {
+   19|     10|        match is_true {
+   20|      0|            false => {
+   21|      0|                x = 1;
+   22|      0|            }
+   23|       |            _ => {
+   24|     10|                continue;
+   25|       |            }
+   26|       |        }
+   27|      0|        x = 3;
+   28|       |    }
+   29|     11|    for _ in 0..10 {
+   30|     10|        match is_true {
+   31|     10|            true => {
+   32|     10|                x = 1;
+   33|     10|            }
+   34|       |            _ => {
+   35|      0|                continue;
+   36|       |            }
+   37|       |        }
+   38|     10|        x = 3;
+   39|       |    }
+   40|     11|    for _ in 0..10 {
+   41|     10|        if is_true {
+   42|     10|            continue;
+   43|      0|        }
+   44|      0|        x = 3;
+   45|       |    }
+   46|     11|    for _ in 0..10 {
+   47|     10|        match is_true {
+   48|      0|            false => {
+   49|      0|                x = 1;
+   50|      0|            }
+   51|     10|            _ => {
+   52|     10|                let _ = x;
+   53|     10|            }
+   54|       |        }
+   55|     10|        x = 3;
+   56|       |    }
+   57|      1|    for _ in 0..10 {
+   58|      1|        match is_true {
+   59|      0|            false => {
+   60|      0|                x = 1;
+   61|      0|            }
+   62|       |            _ => {
+   63|      1|                break;
+   64|       |            }
+   65|       |        }
+   66|      0|        x = 3;
+   67|       |    }
+   68|       |    let _ = x;
+   69|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.dead_code.txt b/src/test/run-make/coverage-reports/expected_show_coverage.dead_code.txt
new file mode 100644 (file)
index 0000000..09ff14c
--- /dev/null
@@ -0,0 +1,39 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |
+    3|      0|pub fn unused_pub_fn_not_in_library() {
+    4|      0|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      0|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      0|    // dependent conditions.
+    7|      0|    let is_true = std::env::args().len() == 1;
+    8|      0|
+    9|      0|    let mut countdown = 0;
+   10|      0|    if is_true {
+   11|      0|        countdown = 10;
+   12|      0|    }
+   13|      0|}
+   14|       |
+   15|      0|fn unused_fn() {
+   16|      0|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   17|      0|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   18|      0|    // dependent conditions.
+   19|      0|    let is_true = std::env::args().len() == 1;
+   20|      0|
+   21|      0|    let mut countdown = 0;
+   22|      0|    if is_true {
+   23|      0|        countdown = 10;
+   24|      0|    }
+   25|      0|}
+   26|       |
+   27|      1|fn main() {
+   28|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   29|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   30|      1|    // dependent conditions.
+   31|      1|    let is_true = std::env::args().len() == 1;
+   32|      1|
+   33|      1|    let mut countdown = 0;
+   34|      1|    if is_true {
+   35|      1|        countdown = 10;
+   36|      1|    }
+                   ^0
+   37|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt b/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt
new file mode 100644 (file)
index 0000000..7ae0e97
--- /dev/null
@@ -0,0 +1,121 @@
+../coverage/doctest.rs:
+    1|       |//! This test ensures that code from doctests is properly re-mapped.
+    2|       |//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
+    3|       |//!
+    4|       |//! Just some random code:
+    5|      1|//! ```
+    6|      1|//! if true {
+    7|       |//!     // this is executed!
+    8|      1|//!     assert_eq!(1, 1);
+    9|       |//! } else {
+   10|       |//!     // this is not!
+   11|      0|//!     assert_eq!(1, 2);
+   12|       |//! }
+   13|      1|//! ```
+   14|       |//!
+   15|       |//! doctest testing external code:
+   16|       |//! ```
+   17|      1|//! extern crate doctest_crate;
+   18|      1|//! doctest_crate::fn_run_in_doctests(1);
+   19|      1|//! ```
+   20|       |//!
+   21|       |//! doctest returning a result:
+   22|      1|//! ```
+   23|      2|//! #[derive(Debug, PartialEq)]
+                       ^1
+  ------------------
+  | Unexecuted instantiation: <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::ne
+  ------------------
+  | <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::eq:
+  |   23|      2|//! #[derive(Debug, PartialEq)]
+  ------------------
+   24|      1|//! struct SomeError {
+   25|      1|//!     msg: String,
+   26|      1|//! }
+   27|      1|//! let mut res = Err(SomeError { msg: String::from("a message") });
+   28|      1|//! if res.is_ok() {
+   29|      0|//!     res?;
+   30|       |//! } else {
+   31|      1|//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
+   32|      1|//!         println!("{:?}", res);
+   33|      1|//!     }
+                   ^0
+   34|      1|//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
+   35|      1|//!         res = Ok(1);
+   36|      1|//!     }
+                   ^0
+   37|      1|//!     res = Ok(0);
+   38|       |//! }
+   39|       |//! // need to be explicit because rustdoc cant infer the return type
+   40|      1|//! Ok::<(), SomeError>(())
+   41|      1|//! ```
+   42|       |//!
+   43|       |//! doctest with custom main:
+   44|       |//! ```
+   45|      1|//! fn some_func() {
+   46|      1|//!     println!("called some_func()");
+   47|      1|//! }
+   48|       |//!
+   49|      0|//! #[derive(Debug)]
+   50|       |//! struct SomeError;
+   51|       |//!
+   52|       |//! extern crate doctest_crate;
+   53|       |//!
+   54|      1|//! fn doctest_main() -> Result<(), SomeError> {
+   55|      1|//!     some_func();
+   56|      1|//!     doctest_crate::fn_run_in_doctests(2);
+   57|      1|//!     Ok(())
+   58|      1|//! }
+   59|       |//!
+   60|       |//! // this `main` is not shown as covered, as it clashes with all the other
+   61|       |//! // `main` functions that were automatically generated for doctests
+   62|       |//! fn main() -> Result<(), SomeError> {
+   63|       |//!     doctest_main()
+   64|       |//! }
+   65|       |//! ```
+   66|       |
+   67|       |/// doctest attached to fn testing external code:
+   68|       |/// ```
+   69|      1|/// extern crate doctest_crate;
+   70|      1|/// doctest_crate::fn_run_in_doctests(3);
+   71|      1|/// ```
+   72|       |///
+   73|      1|fn main() {
+   74|      1|    if true {
+   75|      1|        assert_eq!(1, 1);
+   76|       |    } else {
+   77|      0|        assert_eq!(1, 2);
+   78|       |    }
+   79|      1|}
+   80|       |
+   81|       |// FIXME(Swatinem): Fix known issue that coverage code region columns need to be offset by the
+   82|       |// doc comment line prefix (`///` or `//!`) and any additional indent (before or after the doc
+   83|       |// comment characters). This test produces `llvm-cov show` results demonstrating the problem.
+   84|       |//
+   85|       |// One of the above tests now includes: `derive(Debug, PartialEq)`, producing an `llvm-cov show`
+   86|       |// result with a distinct count for `Debug`, denoted by `^1`, but the caret points to the wrong
+   87|       |// column. Similarly, the `if` blocks without `else` blocks show `^0`, which should point at, or
+   88|       |// one character past, the `if` block's closing brace. In both cases, these are most likely off
+   89|       |// by the number of characters stripped from the beginning of each doc comment line: indent
+   90|       |// whitespace, if any, doc comment prefix (`//!` in this case) and (I assume) one space character
+   91|       |// (?). Note, when viewing `llvm-cov show` results in `--color` mode, the column offset errors are
+   92|       |// more pronounced, and show up in more places, with background color used to show some distinct
+   93|       |// code regions with different coverage counts.
+   94|       |//
+   95|       |// NOTE: Since the doc comment line prefix may vary, one possible solution is to replace each
+   96|       |// character stripped from the beginning of doc comment lines with a space. This will give coverage
+   97|       |// results the correct column offsets, and I think it should compile correctly, but I don't know
+   98|       |// what affect it might have on diagnostic messages from the compiler, and whether anyone would care
+   99|       |// if the indentation changed. I don't know if there is a more viable solution.
+
+../coverage/lib/doctest_crate.rs:
+    1|       |/// A function run only from within doctests
+    2|      3|pub fn fn_run_in_doctests(conditional: usize) {
+    3|      3|    match conditional {
+    4|      1|        1 => assert_eq!(1, 1), // this is run,
+    5|      1|        2 => assert_eq!(1, 1), // this,
+    6|      1|        3 => assert_eq!(1, 1), // and this too
+    7|      0|        _ => assert_eq!(1, 2), // however this is not
+    8|       |    }
+    9|      3|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.drop_trait.txt b/src/test/run-make/coverage-reports/expected_show_coverage.drop_trait.txt
new file mode 100644 (file)
index 0000000..fe6a9e9
--- /dev/null
@@ -0,0 +1,34 @@
+    1|       |#![allow(unused_assignments)]
+    2|       |// expect-exit-status-1
+    3|       |
+    4|       |struct Firework {
+    5|       |    strength: i32,
+    6|       |}
+    7|       |
+    8|       |impl Drop for Firework {
+    9|      2|    fn drop(&mut self) {
+   10|      2|        println!("BOOM times {}!!!", self.strength);
+   11|      2|    }
+   12|       |}
+   13|       |
+   14|      1|fn main() -> Result<(),u8> {
+   15|      1|    let _firecracker = Firework { strength: 1 };
+   16|      1|
+   17|      1|    let _tnt = Firework { strength: 100 };
+   18|      1|
+   19|      1|    if true {
+   20|      1|        println!("Exiting with error...");
+   21|      1|        return Err(1);
+   22|      0|    }
+   23|      0|
+   24|      0|    let _ = Firework { strength: 1000 };
+   25|      0|
+   26|      0|    Ok(())
+   27|      1|}
+   28|       |
+   29|       |// Expected program output:
+   30|       |//   Exiting with error...
+   31|       |//   BOOM times 100!!!
+   32|       |//   BOOM times 1!!!
+   33|       |//   Error: 1
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.generator.txt b/src/test/run-make/coverage-reports/expected_show_coverage.generator.txt
new file mode 100644 (file)
index 0000000..d70e12e
--- /dev/null
@@ -0,0 +1,32 @@
+    1|       |#![feature(generators, generator_trait)]
+    2|       |
+    3|       |use std::ops::{Generator, GeneratorState};
+    4|       |use std::pin::Pin;
+    5|       |
+    6|       |// The following implementation of a function called from a `yield` statement
+    7|       |// (apparently requiring the Result and the `String` type or constructor)
+    8|       |// creates conditions where the `generator::StateTransform` MIR transform will
+    9|       |// drop all `Counter` `Coverage` statements from a MIR. `simplify.rs` has logic
+   10|       |// to handle this condition, and still report dead block coverage.
+   11|      1|fn get_u32(val: bool) -> Result<u32, String> {
+   12|      1|    if val { Ok(1) } else { Err(String::from("some error")) }
+                                          ^0
+   13|      1|}
+   14|       |
+   15|      1|fn main() {
+   16|      1|    let is_true = std::env::args().len() == 1;
+   17|      1|    let mut generator = || {
+   18|      1|        yield get_u32(is_true);
+   19|      1|        return "foo";
+   20|       |    };
+   21|       |
+   22|      1|    match Pin::new(&mut generator).resume(()) {
+   23|      1|        GeneratorState::Yielded(Ok(1)) => {}
+   24|      0|        _ => panic!("unexpected return from resume"),
+   25|       |    }
+   26|      1|    match Pin::new(&mut generator).resume(()) {
+   27|      1|        GeneratorState::Complete("foo") => {}
+   28|      0|        _ => panic!("unexpected return from resume"),
+   29|       |    }
+   30|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.generics.txt b/src/test/run-make/coverage-reports/expected_show_coverage.generics.txt
new file mode 100644 (file)
index 0000000..48983ba
--- /dev/null
@@ -0,0 +1,71 @@
+    1|       |#![allow(unused_assignments)]
+    2|       |// expect-exit-status-1
+    3|       |
+    4|       |struct Firework<T> where T: Copy + std::fmt::Display {
+    5|       |    strength: T,
+    6|       |}
+    7|       |
+    8|       |impl<T> Firework<T> where T: Copy + std::fmt::Display {
+    9|       |    #[inline(always)]
+   10|      3|    fn set_strength(&mut self, new_strength: T) {
+   11|      3|        self.strength = new_strength;
+   12|      3|    }
+  ------------------
+  | <generics::Firework<i32>>::set_strength:
+  |   10|      1|    fn set_strength(&mut self, new_strength: T) {
+  |   11|      1|        self.strength = new_strength;
+  |   12|      1|    }
+  ------------------
+  | <generics::Firework<f64>>::set_strength:
+  |   10|      2|    fn set_strength(&mut self, new_strength: T) {
+  |   11|      2|        self.strength = new_strength;
+  |   12|      2|    }
+  ------------------
+   13|       |}
+   14|       |
+   15|       |impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
+   16|       |    #[inline(always)]
+   17|      2|    fn drop(&mut self) {
+   18|      2|        println!("BOOM times {}!!!", self.strength);
+   19|      2|    }
+  ------------------
+  | <generics::Firework<f64> as core::ops::drop::Drop>::drop:
+  |   17|      1|    fn drop(&mut self) {
+  |   18|      1|        println!("BOOM times {}!!!", self.strength);
+  |   19|      1|    }
+  ------------------
+  | <generics::Firework<i32> as core::ops::drop::Drop>::drop:
+  |   17|      1|    fn drop(&mut self) {
+  |   18|      1|        println!("BOOM times {}!!!", self.strength);
+  |   19|      1|    }
+  ------------------
+   20|       |}
+   21|       |
+   22|      1|fn main() -> Result<(),u8> {
+   23|      1|    let mut firecracker = Firework { strength: 1 };
+   24|      1|    firecracker.set_strength(2);
+   25|      1|
+   26|      1|    let mut tnt = Firework { strength: 100.1 };
+   27|      1|    tnt.set_strength(200.1);
+   28|      1|    tnt.set_strength(300.3);
+   29|      1|
+   30|      1|    if true {
+   31|      1|        println!("Exiting with error...");
+   32|      1|        return Err(1);
+   33|      0|    }
+   34|      0|
+   35|      0|
+   36|      0|
+   37|      0|
+   38|      0|
+   39|      0|    let _ = Firework { strength: 1000 };
+   40|      0|
+   41|      0|    Ok(())
+   42|      1|}
+   43|       |
+   44|       |// Expected program output:
+   45|       |//   Exiting with error...
+   46|       |//   BOOM times 100!!!
+   47|       |//   BOOM times 1!!!
+   48|       |//   Error: 1
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.if.txt b/src/test/run-make/coverage-reports/expected_show_coverage.if.txt
new file mode 100644 (file)
index 0000000..0c9eff2
--- /dev/null
@@ -0,0 +1,30 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      1|    // dependent conditions.
+    7|      1|    let
+    8|      1|    is_true
+    9|      1|    =
+   10|      1|        std::env::args().len()
+   11|      1|    ==
+   12|      1|        1
+   13|      1|    ;
+   14|      1|    let
+   15|      1|        mut
+   16|      1|    countdown
+   17|      1|    =
+   18|      1|        0
+   19|      1|    ;
+   20|      1|    if
+   21|      1|        is_true
+   22|      1|    {
+   23|      1|        countdown
+   24|      1|        =
+   25|      1|            10
+   26|      1|        ;
+   27|      1|    }
+                   ^0
+   28|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.if_else.txt b/src/test/run-make/coverage-reports/expected_show_coverage.if_else.txt
new file mode 100644 (file)
index 0000000..4285d31
--- /dev/null
@@ -0,0 +1,41 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      1|    // dependent conditions.
+    7|      1|    let is_true = std::env::args().len() == 1;
+    8|      1|
+    9|      1|    let mut countdown = 0;
+   10|      1|    if
+   11|      1|        is_true
+   12|      1|    {
+   13|      1|        countdown
+   14|      1|        =
+   15|      1|            10
+   16|      1|        ;
+   17|      1|    }
+   18|       |    else // Note coverage region difference without semicolon
+   19|       |    {
+   20|      0|        countdown
+   21|      0|        =
+   22|      0|            100
+   23|       |    }
+   24|       |
+   25|       |    if
+   26|      1|        is_true
+   27|      1|    {
+   28|      1|        countdown
+   29|      1|        =
+   30|      1|            10
+   31|      1|        ;
+   32|      1|    }
+   33|       |    else
+   34|      0|    {
+   35|      0|        countdown
+   36|      0|        =
+   37|      0|            100
+   38|      0|        ;
+   39|      0|    }
+   40|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.inline-dead.txt b/src/test/run-make/coverage-reports/expected_show_coverage.inline-dead.txt
new file mode 100644 (file)
index 0000000..effdef8
--- /dev/null
@@ -0,0 +1,28 @@
+    1|       |// Regression test for issue #98833.
+    2|       |// compile-flags: -Zinline-mir -Cdebug-assertions=off
+    3|       |
+    4|      1|fn main() {
+    5|      1|    println!("{}", live::<false>());
+    6|      1|
+    7|      1|    let f = |x: bool| {
+    8|       |        debug_assert!(
+    9|       |            x
+   10|       |        );
+   11|      1|    };
+   12|      1|    f(false);
+   13|      1|}
+   14|       |
+   15|       |#[inline]
+   16|      1|fn live<const B: bool>() -> u32 {
+   17|      1|    if B {
+   18|      0|        dead()
+   19|       |    } else {
+   20|      1|        0
+   21|       |    }
+   22|      1|}
+   23|       |
+   24|       |#[inline]
+   25|      0|fn dead() -> u32 {
+   26|      0|    42
+   27|      0|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.inline.txt b/src/test/run-make/coverage-reports/expected_show_coverage.inline.txt
new file mode 100644 (file)
index 0000000..6f5d154
--- /dev/null
@@ -0,0 +1,54 @@
+    1|       |// compile-flags: -Zinline-mir
+    2|       |
+    3|       |use std::fmt::Display;
+    4|       |
+    5|      1|fn main() {
+    6|      1|    permutations(&['a', 'b', 'c']);
+    7|      1|}
+    8|       |
+    9|       |#[inline(always)]
+   10|      1|fn permutations<T: Copy + Display>(xs: &[T]) {
+   11|      1|    let mut ys = xs.to_owned();
+   12|      1|    permutate(&mut ys, 0);
+   13|      1|}
+   14|       |
+   15|     16|fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
+   16|     16|    let n = length(xs);
+   17|     16|    if k == n {
+   18|      6|        display(xs);
+   19|     10|    } else if k < n {
+   20|     15|        for i in k..n {
+                               ^10
+   21|     15|            swap(xs, i, k);
+   22|     15|            permutate(xs, k + 1);
+   23|     15|            swap(xs, i, k);
+   24|     15|        }
+   25|      0|    } else {
+   26|      0|        error();
+   27|      0|    }
+   28|     16|}
+   29|       |
+   30|     16|fn length<T>(xs: &[T]) -> usize {
+   31|     16|    xs.len()
+   32|     16|}
+   33|       |
+   34|       |#[inline]
+   35|     30|fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
+   36|     30|    let t = xs[i];
+   37|     30|    xs[i] = xs[j];
+   38|     30|    xs[j] = t;
+   39|     30|}
+   40|       |
+   41|      6|fn display<T: Display>(xs: &[T]) {
+   42|     24|    for x in xs {
+                      ^18
+   43|     18|        print!("{}", x);
+   44|     18|    }
+   45|      6|    println!();
+   46|      6|}
+   47|       |
+   48|       |#[inline(always)]
+   49|      0|fn error() {
+   50|      0|    panic!("error");
+   51|      0|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.inner_items.txt b/src/test/run-make/coverage-reports/expected_show_coverage.inner_items.txt
new file mode 100644 (file)
index 0000000..883254a
--- /dev/null
@@ -0,0 +1,60 @@
+    1|       |#![allow(unused_assignments, unused_variables, dead_code)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      1|    // dependent conditions.
+    7|      1|    let is_true = std::env::args().len() == 1;
+    8|      1|
+    9|      1|    let mut countdown = 0;
+   10|      1|    if is_true {
+   11|      1|        countdown = 10;
+   12|      1|    }
+                   ^0
+   13|       |
+   14|       |    mod in_mod {
+   15|       |        const IN_MOD_CONST: u32 = 1000;
+   16|       |    }
+   17|       |
+   18|      3|    fn in_func(a: u32) {
+   19|      3|        let b = 1;
+   20|      3|        let c = a + b;
+   21|      3|        println!("c = {}", c)
+   22|      3|    }
+   23|       |
+   24|       |    struct InStruct {
+   25|       |        in_struct_field: u32,
+   26|       |    }
+   27|       |
+   28|       |    const IN_CONST: u32 = 1234;
+   29|       |
+   30|       |    trait InTrait {
+   31|       |        fn trait_func(&mut self, incr: u32);
+   32|       |
+   33|      1|        fn default_trait_func(&mut self) {
+   34|      1|            in_func(IN_CONST);
+   35|      1|            self.trait_func(IN_CONST);
+   36|      1|        }
+   37|       |    }
+   38|       |
+   39|       |    impl InTrait for InStruct {
+   40|      1|        fn trait_func(&mut self, incr: u32) {
+   41|      1|            self.in_struct_field += incr;
+   42|      1|            in_func(self.in_struct_field);
+   43|      1|        }
+   44|       |    }
+   45|       |
+   46|       |    type InType = String;
+   47|       |
+   48|      1|    if is_true {
+   49|      1|        in_func(countdown);
+   50|      1|    }
+                   ^0
+   51|       |
+   52|      1|    let mut val = InStruct {
+   53|      1|        in_struct_field: 101,
+   54|      1|    };
+   55|      1|
+   56|      1|    val.default_trait_func();
+   57|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt
new file mode 100644 (file)
index 0000000..de32c88
--- /dev/null
@@ -0,0 +1,22 @@
+    1|       |// Shows that rust-lang/rust/83601 is resolved
+    2|       |
+    3|      3|#[derive(Debug, PartialEq, Eq)]
+                              ^2
+  ------------------
+  | <issue_83601::Foo as core::cmp::PartialEq>::eq:
+  |    3|      2|#[derive(Debug, PartialEq, Eq)]
+  ------------------
+  | Unexecuted instantiation: <issue_83601::Foo as core::cmp::PartialEq>::ne
+  ------------------
+    4|       |struct Foo(u32);
+    5|       |
+    6|      1|fn main() {
+    7|      1|    let bar = Foo(1);
+    8|      1|    assert_eq!(bar, Foo(1));
+    9|      1|    let baz = Foo(0);
+   10|      1|    assert_ne!(baz, Foo(1));
+   11|      1|    println!("{:?}", Foo(1));
+   12|      1|    println!("{:?}", bar);
+   13|      1|    println!("{:?}", baz);
+   14|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt
new file mode 100644 (file)
index 0000000..f24f7c6
--- /dev/null
@@ -0,0 +1,195 @@
+    1|       |// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
+    2|       |
+    3|       |// expect-exit-status-101
+    4|     21|#[derive(PartialEq, Eq)]
+  ------------------
+  | <issue_84561::Foo as core::cmp::PartialEq>::eq:
+  |    4|     21|#[derive(PartialEq, Eq)]
+  ------------------
+  | Unexecuted instantiation: <issue_84561::Foo as core::cmp::PartialEq>::ne
+  ------------------
+    5|       |struct Foo(u32);
+    6|      1|fn test3() {
+    7|      1|    let is_true = std::env::args().len() == 1;
+    8|      1|    let bar = Foo(1);
+    9|      1|    assert_eq!(bar, Foo(1));
+   10|      1|    let baz = Foo(0);
+   11|      1|    assert_ne!(baz, Foo(1));
+   12|      1|    println!("{:?}", Foo(1));
+   13|      1|    println!("{:?}", bar);
+   14|      1|    println!("{:?}", baz);
+   15|      1|
+   16|      1|    assert_eq!(Foo(1), Foo(1));
+   17|      1|    assert_ne!(Foo(0), Foo(1));
+   18|      1|    assert_eq!(Foo(2), Foo(2));
+   19|      1|    let bar = Foo(0);
+   20|      1|    assert_ne!(bar, Foo(3));
+   21|      1|    assert_ne!(Foo(0), Foo(4));
+   22|      1|    assert_eq!(Foo(3), Foo(3), "with a message");
+                                             ^0
+   23|      1|    println!("{:?}", bar);
+   24|      1|    println!("{:?}", Foo(1));
+   25|      1|
+   26|      1|    assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
+                                             ^0                 ^0                      ^0
+   27|      1|    assert_ne!(
+   28|       |        Foo(0)
+   29|       |        ,
+   30|       |        Foo(5)
+   31|       |        ,
+   32|      0|        "{}"
+   33|      0|        ,
+   34|      0|        if
+   35|      0|        is_true
+   36|       |        {
+   37|      0|            "true message"
+   38|       |        } else {
+   39|      0|            "false message"
+   40|       |        }
+   41|       |    );
+   42|       |
+   43|      1|    let is_true = std::env::args().len() == 1;
+   44|      1|
+   45|      1|    assert_eq!(
+   46|      1|        Foo(1),
+   47|      1|        Foo(1)
+   48|      1|    );
+   49|      1|    assert_ne!(
+   50|      1|        Foo(0),
+   51|      1|        Foo(1)
+   52|      1|    );
+   53|      1|    assert_eq!(
+   54|      1|        Foo(2),
+   55|      1|        Foo(2)
+   56|      1|    );
+   57|      1|    let bar = Foo(1);
+   58|      1|    assert_ne!(
+   59|      1|        bar,
+   60|      1|        Foo(3)
+   61|      1|    );
+   62|      1|    if is_true {
+   63|      1|        assert_ne!(
+   64|      1|            Foo(0),
+   65|      1|            Foo(4)
+   66|      1|        );
+   67|       |    } else {
+   68|      0|        assert_eq!(
+   69|      0|            Foo(3),
+   70|      0|            Foo(3)
+   71|      0|        );
+   72|       |    }
+   73|      1|    if is_true {
+   74|      1|        assert_ne!(
+   75|       |            Foo(0),
+   76|       |            Foo(4),
+   77|      0|            "with a message"
+   78|       |        );
+   79|       |    } else {
+   80|      0|        assert_eq!(
+   81|       |            Foo(3),
+   82|       |            Foo(3),
+   83|      0|            "with a message"
+   84|       |        );
+   85|       |    }
+   86|      1|    assert_ne!(
+   87|      1|        if is_true {
+   88|      1|            Foo(0)
+   89|       |        } else {
+   90|      0|            Foo(1)
+   91|       |        },
+   92|       |        Foo(5)
+   93|       |    );
+   94|      1|    assert_ne!(
+   95|      1|        Foo(5),
+   96|      1|        if is_true {
+   97|      1|            Foo(0)
+   98|       |        } else {
+   99|      0|            Foo(1)
+  100|       |        }
+  101|       |    );
+  102|      1|    assert_ne!(
+  103|      1|        if is_true {
+  104|      1|            assert_eq!(
+  105|      1|                Foo(3),
+  106|      1|                Foo(3)
+  107|      1|            );
+  108|      1|            Foo(0)
+  109|       |        } else {
+  110|      0|            assert_ne!(
+  111|      0|                if is_true {
+  112|      0|                    Foo(0)
+  113|       |                } else {
+  114|      0|                    Foo(1)
+  115|       |                },
+  116|       |                Foo(5)
+  117|       |            );
+  118|      0|            Foo(1)
+  119|       |        },
+  120|       |        Foo(5),
+  121|      0|        "with a message"
+  122|       |    );
+  123|      1|    assert_eq!(
+  124|       |        Foo(1),
+  125|       |        Foo(3),
+  126|      1|        "this assert should fail"
+  127|       |    );
+  128|      0|    assert_eq!(
+  129|       |        Foo(3),
+  130|       |        Foo(3),
+  131|      0|        "this assert should not be reached"
+  132|       |    );
+  133|      0|}
+  134|       |
+  135|       |impl std::fmt::Debug for Foo {
+  136|       |    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+  137|      7|        write!(f, "try and succeed")?;
+                                                  ^0
+  138|      7|        Ok(())
+  139|      7|    }
+  140|       |}
+  141|       |
+  142|       |static mut DEBUG_LEVEL_ENABLED: bool = false;
+  143|       |
+  144|       |macro_rules! debug {
+  145|       |    ($($arg:tt)+) => (
+  146|       |        if unsafe { DEBUG_LEVEL_ENABLED } {
+  147|       |            println!($($arg)+);
+  148|       |        }
+  149|       |    );
+  150|       |}
+  151|       |
+  152|      1|fn test1() {
+  153|      1|    debug!("debug is enabled");
+                         ^0
+  154|      1|    debug!("debug is enabled");
+                         ^0
+  155|      1|    let _ = 0;
+  156|      1|    debug!("debug is enabled");
+                         ^0
+  157|      1|    unsafe {
+  158|      1|        DEBUG_LEVEL_ENABLED = true;
+  159|      1|    }
+  160|      1|    debug!("debug is enabled");
+  161|      1|}
+  162|       |
+  163|       |macro_rules! call_debug {
+  164|       |    ($($arg:tt)+) => (
+  165|      1|        fn call_print(s: &str) {
+  166|      1|            print!("{}", s);
+  167|      1|        }
+  168|       |
+  169|       |        call_print("called from call_debug: ");
+  170|       |        debug!($($arg)+);
+  171|       |    );
+  172|       |}
+  173|       |
+  174|      1|fn test2() {
+  175|      1|    call_debug!("debug is enabled");
+  176|      1|}
+  177|       |
+  178|      1|fn main() {
+  179|      1|    test1();
+  180|      1|    test2();
+  181|      1|    test3();
+  182|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.issue-85461.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-85461.txt
new file mode 100644 (file)
index 0000000..1aa4a22
--- /dev/null
@@ -0,0 +1,36 @@
+../coverage/issue-85461.rs:
+    1|       |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
+    2|       |
+    3|       |extern crate inline_always_with_dead_code;
+    4|       |
+    5|       |use inline_always_with_dead_code::{bar, baz};
+    6|       |
+    7|      1|fn main() {
+    8|      1|    bar::call_me();
+    9|      1|    baz::call_me();
+   10|      1|}
+
+../coverage/lib/inline_always_with_dead_code.rs:
+    1|       |// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
+    2|       |
+    3|       |#![allow(dead_code)]
+    4|       |
+    5|       |mod foo {
+    6|       |    #[inline(always)]
+    7|      2|    pub fn called() { }
+    8|       |
+    9|      0|    fn uncalled() { }
+   10|       |}
+   11|       |
+   12|       |pub mod bar {
+   13|      1|    pub fn call_me() {
+   14|      1|        super::foo::called();
+   15|      1|    }
+   16|       |}
+   17|       |
+   18|       |pub mod baz {
+   19|      1|    pub fn call_me() {
+   20|      1|        super::foo::called();
+   21|      1|    }
+   22|       |}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.issue-93054.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-93054.txt
new file mode 100644 (file)
index 0000000..a1655ad
--- /dev/null
@@ -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/coverage-reports/expected_show_coverage.lazy_boolean.txt b/src/test/run-make/coverage-reports/expected_show_coverage.lazy_boolean.txt
new file mode 100644 (file)
index 0000000..bd349df
--- /dev/null
@@ -0,0 +1,64 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      1|    // dependent conditions.
+    7|      1|    let is_true = std::env::args().len() == 1;
+    8|      1|
+    9|      1|    let (mut a, mut b, mut c) = (0, 0, 0);
+   10|      1|    if is_true {
+   11|      1|        a = 1;
+   12|      1|        b = 10;
+   13|      1|        c = 100;
+   14|      1|    }
+                   ^0
+   15|       |    let
+   16|      1|        somebool
+   17|       |        =
+   18|      1|            a < b
+   19|       |        ||
+   20|      0|            b < c
+   21|       |    ;
+   22|       |    let
+   23|      1|        somebool
+   24|       |        =
+   25|      1|            b < a
+   26|       |        ||
+   27|      1|            b < c
+   28|       |    ;
+   29|      1|    let somebool = a < b && b < c;
+   30|      1|    let somebool = b < a && b < c;
+                                          ^0
+   31|       |
+   32|       |    if
+   33|      1|        !
+   34|      1|        is_true
+   35|      0|    {
+   36|      0|        a = 2
+   37|      0|        ;
+   38|      1|    }
+   39|       |
+   40|       |    if
+   41|      1|        is_true
+   42|      1|    {
+   43|      1|        b = 30
+   44|      1|        ;
+   45|      1|    }
+   46|       |    else
+   47|      0|    {
+   48|      0|        c = 400
+   49|      0|        ;
+   50|      0|    }
+   51|       |
+   52|      1|    if !is_true {
+   53|      0|        a = 2;
+   54|      1|    }
+   55|       |
+   56|      1|    if is_true {
+   57|      1|        b = 30;
+   58|      1|    } else {
+   59|      0|        c = 400;
+   60|      0|    }
+   61|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.loop_break_value.txt b/src/test/run-make/coverage-reports/expected_show_coverage.loop_break_value.txt
new file mode 100644 (file)
index 0000000..022fe4c
--- /dev/null
@@ -0,0 +1,14 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    let result
+    5|      1|        =
+    6|      1|            loop
+    7|      1|        {
+    8|      1|            break
+    9|      1|            10
+   10|      1|            ;
+   11|      1|        }
+   12|      1|    ;
+   13|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.loops_branches.txt b/src/test/run-make/coverage-reports/expected_show_coverage.loops_branches.txt
new file mode 100644 (file)
index 0000000..b7ad79a
--- /dev/null
@@ -0,0 +1,68 @@
+    1|       |#![allow(unused_assignments, unused_variables, while_true)]
+    2|       |
+    3|       |// This test confirms that (1) unexecuted infinite loops are handled correctly by the
+    4|       |// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped.
+    5|       |
+    6|       |struct DebugTest;
+    7|       |
+    8|       |impl std::fmt::Debug for DebugTest {
+    9|      1|    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+   10|      1|        if true {
+   11|      1|            if false {
+   12|      0|                while true {
+   13|      0|                }
+   14|      1|            }
+   15|      1|            write!(f, "cool")?;
+                                           ^0
+   16|      0|        } else {
+   17|      0|        }
+   18|       |
+   19|     11|        for i in 0..10 {
+                          ^10
+   20|     10|            if true {
+   21|     10|                if false {
+   22|      0|                    while true {}
+   23|     10|                }
+   24|     10|                write!(f, "cool")?;
+                                               ^0
+   25|      0|            } else {
+   26|      0|            }
+   27|       |        }
+   28|      1|        Ok(())
+   29|      1|    }
+   30|       |}
+   31|       |
+   32|       |struct DisplayTest;
+   33|       |
+   34|       |impl std::fmt::Display for DisplayTest {
+   35|      1|    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+   36|      1|        if false {
+   37|      0|        } else {
+   38|      1|            if false {
+   39|      0|                while true {}
+   40|      1|            }
+   41|      1|            write!(f, "cool")?;
+                                           ^0
+   42|       |        }
+   43|     11|        for i in 0..10 {
+                          ^10
+   44|     10|            if false {
+   45|      0|            } else {
+   46|     10|                if false {
+   47|      0|                    while true {}
+   48|     10|                }
+   49|     10|                write!(f, "cool")?;
+                                               ^0
+   50|       |            }
+   51|       |        }
+   52|      1|        Ok(())
+   53|      1|    }
+   54|       |}
+   55|       |
+   56|      1|fn main() {
+   57|      1|    let debug_test = DebugTest;
+   58|      1|    println!("{:?}", debug_test);
+   59|      1|    let display_test = DisplayTest;
+   60|      1|    println!("{}", display_test);
+   61|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.match_or_pattern.txt b/src/test/run-make/coverage-reports/expected_show_coverage.match_or_pattern.txt
new file mode 100644 (file)
index 0000000..a0fccb2
--- /dev/null
@@ -0,0 +1,50 @@
+    1|       |#![feature(or_patterns)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      1|    // dependent conditions.
+    7|      1|    let is_true = std::env::args().len() == 1;
+    8|      1|
+    9|      1|    let mut a: u8 = 0;
+   10|      1|    let mut b: u8 = 0;
+   11|      1|    if is_true {
+   12|      1|        a = 2;
+   13|      1|        b = 0;
+   14|      1|    }
+                   ^0
+   15|      1|    match (a, b) {
+   16|       |        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
+   17|       |        // This test confirms a fix for Issue #79569.
+   18|      0|        (0 | 1, 2 | 3) => {}
+   19|      1|        _ => {}
+   20|       |    }
+   21|      1|    if is_true {
+   22|      1|        a = 0;
+   23|      1|        b = 0;
+   24|      1|    }
+                   ^0
+   25|      1|    match (a, b) {
+   26|      0|        (0 | 1, 2 | 3) => {}
+   27|      1|        _ => {}
+   28|       |    }
+   29|      1|    if is_true {
+   30|      1|        a = 2;
+   31|      1|        b = 2;
+   32|      1|    }
+                   ^0
+   33|      1|    match (a, b) {
+   34|      0|        (0 | 1, 2 | 3) => {}
+   35|      1|        _ => {}
+   36|       |    }
+   37|      1|    if is_true {
+   38|      1|        a = 0;
+   39|      1|        b = 2;
+   40|      1|    }
+                   ^0
+   41|      1|    match (a, b) {
+   42|      1|        (0 | 1, 2 | 3) => {}
+   43|      0|        _ => {}
+   44|       |    }
+   45|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.nested_loops.txt b/src/test/run-make/coverage-reports/expected_show_coverage.nested_loops.txt
new file mode 100644 (file)
index 0000000..0dbd6bc
--- /dev/null
@@ -0,0 +1,26 @@
+    1|      1|fn main() {
+    2|      1|    let is_true = std::env::args().len() == 1;
+    3|      1|    let mut countdown = 10;
+    4|       |
+    5|      1|    'outer: while countdown > 0 {
+    6|      1|        let mut a = 100;
+    7|      1|        let mut b = 100;
+    8|      3|        for _ in 0..50 {
+    9|      3|            if a < 30 {
+   10|      0|                break;
+   11|      3|            }
+   12|      3|            a -= 5;
+   13|      3|            b -= 5;
+   14|      3|            if b < 90 {
+   15|      1|                a -= 10;
+   16|      1|                if is_true {
+   17|      1|                    break 'outer;
+   18|      0|                } else {
+   19|      0|                    a -= 2;
+   20|      0|                }
+   21|      2|            }
+   22|       |        }
+   23|      0|        countdown -= 1;
+   24|       |    }
+   25|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.no_cov_crate.txt b/src/test/run-make/coverage-reports/expected_show_coverage.no_cov_crate.txt
new file mode 100644 (file)
index 0000000..83a9204
--- /dev/null
@@ -0,0 +1,87 @@
+    1|       |// Enables `no_coverage` on the entire crate
+    2|       |#![feature(no_coverage)]
+    3|       |
+    4|       |#[no_coverage]
+    5|       |fn do_not_add_coverage_1() {
+    6|       |    println!("called but not covered");
+    7|       |}
+    8|       |
+    9|       |fn do_not_add_coverage_2() {
+   10|       |    #![no_coverage]
+   11|       |    println!("called but not covered");
+   12|       |}
+   13|       |
+   14|       |#[no_coverage]
+   15|       |fn do_not_add_coverage_not_called() {
+   16|       |    println!("not called and not covered");
+   17|       |}
+   18|       |
+   19|      1|fn add_coverage_1() {
+   20|      1|    println!("called and covered");
+   21|      1|}
+   22|       |
+   23|      1|fn add_coverage_2() {
+   24|      1|    println!("called and covered");
+   25|      1|}
+   26|       |
+   27|      0|fn add_coverage_not_called() {
+   28|      0|    println!("not called but covered");
+   29|      0|}
+   30|       |
+   31|       |// FIXME: These test-cases illustrate confusing results of nested functions.
+   32|       |// See https://github.com/rust-lang/rust/issues/93319
+   33|       |mod nested_fns {
+   34|       |    #[no_coverage]
+   35|       |    pub fn outer_not_covered(is_true: bool) {
+   36|      1|        fn inner(is_true: bool) {
+   37|      1|            if is_true {
+   38|      1|                println!("called and covered");
+   39|      1|            } else {
+   40|      0|                println!("absolutely not covered");
+   41|      0|            }
+   42|      1|        }
+   43|       |        println!("called but not covered");
+   44|       |        inner(is_true);
+   45|       |    }
+   46|       |
+   47|      1|    pub fn outer(is_true: bool) {
+   48|      1|        println!("called and covered");
+   49|      1|        inner_not_covered(is_true);
+   50|      1|
+   51|      1|        #[no_coverage]
+   52|      1|        fn inner_not_covered(is_true: bool) {
+   53|      1|            if is_true {
+   54|      1|                println!("called but not covered");
+   55|      1|            } else {
+   56|      1|                println!("absolutely not covered");
+   57|      1|            }
+   58|      1|        }
+   59|      1|    }
+   60|       |
+   61|      1|    pub fn outer_both_covered(is_true: bool) {
+   62|      1|        println!("called and covered");
+   63|      1|        inner(is_true);
+   64|      1|
+   65|      1|        fn inner(is_true: bool) {
+   66|      1|            if is_true {
+   67|      1|                println!("called and covered");
+   68|      1|            } else {
+   69|      0|                println!("absolutely not covered");
+   70|      0|            }
+   71|      1|        }
+   72|      1|    }
+   73|       |}
+   74|       |
+   75|      1|fn main() {
+   76|      1|    let is_true = std::env::args().len() == 1;
+   77|      1|
+   78|      1|    do_not_add_coverage_1();
+   79|      1|    do_not_add_coverage_2();
+   80|      1|    add_coverage_1();
+   81|      1|    add_coverage_2();
+   82|      1|
+   83|      1|    nested_fns::outer_not_covered(is_true);
+   84|      1|    nested_fns::outer(is_true);
+   85|      1|    nested_fns::outer_both_covered(is_true);
+   86|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.overflow.txt b/src/test/run-make/coverage-reports/expected_show_coverage.overflow.txt
new file mode 100644 (file)
index 0000000..25e822b
--- /dev/null
@@ -0,0 +1,64 @@
+    1|       |#![allow(unused_assignments)]
+    2|       |// expect-exit-status-101
+    3|       |
+    4|      4|fn might_overflow(to_add: u32) -> u32 {
+    5|      4|    if to_add > 5 {
+    6|      1|        println!("this will probably overflow");
+    7|      3|    }
+    8|      4|    let add_to = u32::MAX - 5;
+    9|      4|    println!("does {} + {} overflow?", add_to, to_add);
+   10|      4|    let result = to_add + add_to;
+   11|      4|    println!("continuing after overflow check");
+   12|      4|    result
+   13|      4|}
+   14|       |
+   15|      1|fn main() -> Result<(),u8> {
+   16|      1|    let mut countdown = 10;
+   17|     11|    while countdown > 0 {
+   18|     11|        if countdown == 1 {
+   19|      1|            let result = might_overflow(10);
+   20|      1|            println!("Result: {}", result);
+   21|     10|        } else if countdown < 5 {
+   22|      3|            let result = might_overflow(1);
+   23|      3|            println!("Result: {}", result);
+   24|      6|        }
+   25|     10|        countdown -= 1;
+   26|       |    }
+   27|      0|    Ok(())
+   28|      0|}
+   29|       |
+   30|       |// Notes:
+   31|       |//   1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
+   32|       |//      and similar tests `panic_unwind.rs`, abort.rs` and `try_error_result.rs`.
+   33|       |//   2. This test confirms the coverage generated when a program passes or fails a
+   34|       |//      compiler-generated `TerminatorKind::Assert` (based on an overflow check, in this case).
+   35|       |//   3. Similar to how the coverage instrumentation handles `TerminatorKind::Call`,
+   36|       |//      compiler-generated assertion failures are assumed to be a symptom of a program bug, not
+   37|       |//      expected behavior. To simplify the coverage graphs and keep instrumented programs as
+   38|       |//      small and fast as possible, `Assert` terminators are assumed to always succeed, and
+   39|       |//      therefore are considered "non-branching" terminators. So, an `Assert` terminator does not
+   40|       |//      get its own coverage counter.
+   41|       |//   4. After an unhandled panic or failed Assert, coverage results may not always be intuitive.
+   42|       |//      In this test, the final count for the statements after the `if` block in `might_overflow()`
+   43|       |//      is 4, even though the lines after `to_add + add_to` were executed only 3 times. Depending
+   44|       |//      on the MIR graph and the structure of the code, this count could have been 3 (which might
+   45|       |//      have been valid for the overflowed add `+`, but should have been 4 for the lines before
+   46|       |//      the overflow. The reason for this potential uncertainty is, a `CounterKind` is incremented
+   47|       |//      via StatementKind::Counter at the end of the block, but (as in the case in this test),
+   48|       |//      a CounterKind::Expression is always evaluated. In this case, the expression was based on
+   49|       |//      a `Counter` incremented as part of the evaluation of the `if` expression, which was
+   50|       |//      executed, and counted, 4 times, before reaching the overflow add.
+   51|       |
+   52|       |// If the program did not overflow, the coverage for `might_overflow()` would look like this:
+   53|       |//
+   54|       |//     4|       |fn might_overflow(to_add: u32) -> u32 {
+   55|       |//     5|      4|    if to_add > 5 {
+   56|       |//     6|      0|        println!("this will probably overflow");
+   57|       |//     7|      4|    }
+   58|       |//     8|      4|    let add_to = u32::MAX - 5;
+   59|       |//     9|      4|    println!("does {} + {} overflow?", add_to, to_add);
+   60|       |//    10|      4|    let result = to_add + add_to;
+   61|       |//    11|      4|    println!("continuing after overflow check");
+   62|       |//    12|      4|    result
+   63|       |//    13|      4|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.panic_unwind.txt b/src/test/run-make/coverage-reports/expected_show_coverage.panic_unwind.txt
new file mode 100644 (file)
index 0000000..114507d
--- /dev/null
@@ -0,0 +1,32 @@
+    1|       |#![allow(unused_assignments)]
+    2|       |// expect-exit-status-101
+    3|       |
+    4|      4|fn might_panic(should_panic: bool) {
+    5|      4|    if should_panic {
+    6|      1|        println!("panicking...");
+    7|      1|        panic!("panics");
+    8|      3|    } else {
+    9|      3|        println!("Don't Panic");
+   10|      3|    }
+   11|      3|}
+   12|       |
+   13|      1|fn main() -> Result<(), u8> {
+   14|      1|    let mut countdown = 10;
+   15|     11|    while countdown > 0 {
+   16|     11|        if countdown == 1 {
+   17|      1|            might_panic(true);
+   18|     10|        } else if countdown < 5 {
+   19|      3|            might_panic(false);
+   20|      6|        }
+   21|     10|        countdown -= 1;
+   22|       |    }
+   23|      0|    Ok(())
+   24|      0|}
+   25|       |
+   26|       |// Notes:
+   27|       |//   1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
+   28|       |//      `try_error_result.rs`.
+   29|       |//   2. Since the `panic_unwind.rs` test is allowed to unwind, it is also allowed to execute the
+   30|       |//      normal program exit cleanup, including writing out the current values of the coverage
+   31|       |//      counters.
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt b/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt
new file mode 100644 (file)
index 0000000..fc26665
--- /dev/null
@@ -0,0 +1,53 @@
+    1|       |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
+    2|       |// structure of this test.
+    3|       |
+    4|      2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+                       ^0            ^0      ^0     ^1       ^1 ^0^0
+  ------------------
+  | Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::ne
+  ------------------
+  | Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::eq
+  ------------------
+    5|       |pub struct Version {
+    6|       |    major: usize,
+    7|       |    minor: usize,
+    8|       |    patch: usize,
+    9|       |}
+   10|       |
+   11|       |impl Version {
+   12|      2|    pub fn new(major: usize, minor: usize, patch: usize) -> Self {
+   13|      2|        Self {
+   14|      2|            major,
+   15|      2|            minor,
+   16|      2|            patch,
+   17|      2|        }
+   18|      2|    }
+   19|       |}
+   20|       |
+   21|      1|fn main() {
+   22|      1|    let version_3_2_1 = Version::new(3, 2, 1);
+   23|      1|    let version_3_3_0 = Version::new(3, 3, 0);
+   24|      1|
+   25|      1|    println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0);
+   26|      1|}
+   27|       |
+   28|       |/*
+   29|       |
+   30|       |This test verifies a bug was fixed that otherwise generated this error:
+   31|       |
+   32|       |thread 'rustc' panicked at 'No counters provided the source_hash for function:
+   33|       |    Instance {
+   34|       |        def: Item(WithOptConstParam {
+   35|       |            did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp),
+   36|       |            const_param_did: None
+   37|       |        }),
+   38|       |        substs: []
+   39|       |    }'
+   40|       |The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage
+   41|       |without a code region associated with any `Counter`. Code regions were associated with at least
+   42|       |one expression, which is allowed, but the `function_source_hash` was only passed to the codegen
+   43|       |(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the
+   44|       |`function_source_hash` without a code region, if necessary.
+   45|       |
+   46|       |*/
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.simple_loop.txt b/src/test/run-make/coverage-reports/expected_show_coverage.simple_loop.txt
new file mode 100644 (file)
index 0000000..feb83ba
--- /dev/null
@@ -0,0 +1,37 @@
+    1|       |#![allow(unused_assignments)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      1|    // dependent conditions.
+    7|      1|    let is_true = std::env::args().len() == 1;
+    8|      1|
+    9|      1|    let mut countdown = 0;
+   10|      1|
+   11|      1|    if
+   12|      1|        is_true
+   13|      1|    {
+   14|      1|        countdown
+   15|      1|        =
+   16|      1|            10
+   17|      1|        ;
+   18|      1|    }
+                   ^0
+   19|       |
+   20|       |    loop
+   21|       |    {
+   22|       |        if
+   23|     11|            countdown
+   24|     11|                ==
+   25|     11|            0
+   26|       |        {
+   27|      1|            break
+   28|       |            ;
+   29|     10|        }
+   30|     10|        countdown
+   31|     10|        -=
+   32|     10|        1
+   33|       |        ;
+   34|       |    }
+   35|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.simple_match.txt b/src/test/run-make/coverage-reports/expected_show_coverage.simple_match.txt
new file mode 100644 (file)
index 0000000..b929821
--- /dev/null
@@ -0,0 +1,45 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      1|    // dependent conditions.
+    7|      1|    let is_true = std::env::args().len() == 1;
+    8|      1|
+    9|      1|    let mut countdown = 1;
+   10|      1|    if is_true {
+   11|      1|        countdown = 0;
+   12|      1|    }
+                   ^0
+   13|       |
+   14|       |    for
+   15|       |        _
+   16|       |    in
+   17|      3|        0..2
+   18|       |    {
+   19|       |        let z
+   20|       |        ;
+   21|       |        match
+   22|      2|            countdown
+   23|       |        {
+   24|      1|            x
+   25|       |            if
+   26|      2|                x
+   27|      2|                    <
+   28|      2|                1
+   29|       |            =>
+   30|      1|            {
+   31|      1|                z = countdown
+   32|      1|                ;
+   33|      1|                let y = countdown
+   34|      1|                ;
+   35|      1|                countdown = 10
+   36|      1|                ;
+   37|      1|            }
+   38|       |            _
+   39|       |            =>
+   40|      1|            {}
+   41|       |        }
+   42|       |    }
+   43|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.tight_inf_loop.txt b/src/test/run-make/coverage-reports/expected_show_coverage.tight_inf_loop.txt
new file mode 100644 (file)
index 0000000..2d4c57f
--- /dev/null
@@ -0,0 +1,6 @@
+    1|      1|fn main() {
+    2|      1|    if false {
+    3|      0|        loop {}
+    4|      1|    }
+    5|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.try_error_result.txt b/src/test/run-make/coverage-reports/expected_show_coverage.try_error_result.txt
new file mode 100644 (file)
index 0000000..0ad0180
--- /dev/null
@@ -0,0 +1,125 @@
+    1|       |#![allow(unused_assignments)]
+    2|       |// expect-exit-status-1
+    3|       |
+    4|      6|fn call(return_error: bool) -> Result<(),()> {
+    5|      6|    if return_error {
+    6|      1|        Err(())
+    7|       |    } else {
+    8|      5|        Ok(())
+    9|       |    }
+   10|      6|}
+   11|       |
+   12|      1|fn test1() -> Result<(),()> {
+   13|      1|    let mut
+   14|      1|        countdown = 10
+   15|       |    ;
+   16|       |    for
+   17|       |        _
+   18|       |    in
+   19|      6|        0..10
+   20|       |    {
+   21|      6|        countdown
+   22|      6|            -= 1
+   23|      6|        ;
+   24|      6|        if
+   25|      6|            countdown < 5
+   26|       |        {
+   27|      1|            call(/*return_error=*/ true)?;
+   28|      0|            call(/*return_error=*/ false)?;
+   29|       |        }
+   30|       |        else
+   31|       |        {
+   32|      5|            call(/*return_error=*/ false)?;
+                                                       ^0
+   33|       |        }
+   34|       |    }
+   35|      0|    Ok(())
+   36|      1|}
+   37|       |
+   38|       |struct Thing1;
+   39|       |impl Thing1 {
+   40|     18|    fn get_thing_2(&self, return_error: bool) -> Result<Thing2,()> {
+   41|     18|        if return_error {
+   42|      1|            Err(())
+   43|       |        } else {
+   44|     17|            Ok(Thing2{})
+   45|       |        }
+   46|     18|    }
+   47|       |}
+   48|       |
+   49|       |struct Thing2;
+   50|       |impl Thing2 {
+   51|     17|    fn call(&self, return_error: bool) -> Result<u32,()> {
+   52|     17|        if return_error {
+   53|      2|            Err(())
+   54|       |        } else {
+   55|     15|            Ok(57)
+   56|       |        }
+   57|     17|    }
+   58|       |}
+   59|       |
+   60|      1|fn test2() -> Result<(),()> {
+   61|      1|    let thing1 = Thing1{};
+   62|      1|    let mut
+   63|      1|        countdown = 10
+   64|       |    ;
+   65|       |    for
+   66|       |        _
+   67|       |    in
+   68|      6|        0..10
+   69|       |    {
+   70|      6|        countdown
+   71|      6|            -= 1
+   72|      6|        ;
+   73|      6|        if
+   74|      6|            countdown < 5
+   75|       |        {
+   76|      1|            thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
+                                                            ^0
+   77|      1|            thing1
+   78|      1|                .
+   79|      1|                get_thing_2(/*return_error=*/ false)
+   80|      0|                ?
+   81|       |                .
+   82|      1|                call(/*return_error=*/ true)
+   83|      1|                .
+   84|      1|                expect_err(
+   85|      1|                    "call should fail"
+   86|      1|                );
+   87|      1|            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ true)?;
+                              ^0                                                ^0                          ^0
+   88|      0|            assert_eq!(val, 57);
+   89|      0|            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ false)?;
+   90|      0|            assert_eq!(val, 57);
+   91|       |        }
+   92|       |        else
+   93|       |        {
+   94|      5|            let val = thing1.get_thing_2(/*return_error=*/ false)?.call(/*return_error=*/ false)?;
+                                                                               ^0                             ^0
+   95|      5|            assert_eq!(val, 57);
+   96|      5|            let val = thing1
+   97|      5|                .get_thing_2(/*return_error=*/ false)?
+                                                                   ^0
+   98|      5|                .call(/*return_error=*/ false)?;
+                                                            ^0
+   99|      5|            assert_eq!(val, 57);
+  100|      5|            let val = thing1
+  101|      5|                .get_thing_2(/*return_error=*/ false)
+  102|      0|                ?
+  103|      5|                .call(/*return_error=*/ false)
+  104|      0|                ?
+  105|       |                ;
+  106|      5|            assert_eq!(val, 57);
+  107|       |        }
+  108|       |    }
+  109|      0|    Ok(())
+  110|      1|}
+  111|       |
+  112|      1|fn main() -> Result<(),()> {
+  113|      1|    test1().expect_err("test1 should fail");
+  114|      1|    test2()
+  115|      1|    ?
+  116|       |    ;
+  117|      0|    Ok(())
+  118|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.unused.txt b/src/test/run-make/coverage-reports/expected_show_coverage.unused.txt
new file mode 100644 (file)
index 0000000..15fcf21
--- /dev/null
@@ -0,0 +1,62 @@
+    1|      2|fn foo<T>(x: T) {
+    2|      2|    let mut i = 0;
+    3|     22|    while i < 10 {
+    4|     20|        i != 0 || i != 0;
+                                ^2
+    5|     20|        i += 1;
+    6|       |    }
+    7|      2|}
+  ------------------
+  | unused::foo::<f32>:
+  |    1|      1|fn foo<T>(x: T) {
+  |    2|      1|    let mut i = 0;
+  |    3|     11|    while i < 10 {
+  |    4|     10|        i != 0 || i != 0;
+  |                                ^1
+  |    5|     10|        i += 1;
+  |    6|       |    }
+  |    7|      1|}
+  ------------------
+  | unused::foo::<u32>:
+  |    1|      1|fn foo<T>(x: T) {
+  |    2|      1|    let mut i = 0;
+  |    3|     11|    while i < 10 {
+  |    4|     10|        i != 0 || i != 0;
+  |                                ^1
+  |    5|     10|        i += 1;
+  |    6|       |    }
+  |    7|      1|}
+  ------------------
+    8|       |
+    9|      0|fn unused_template_func<T>(x: T) {
+   10|      0|    let mut i = 0;
+   11|      0|    while i < 10 {
+   12|      0|        i != 0 || i != 0;
+   13|      0|        i += 1;
+   14|       |    }
+   15|      0|}
+   16|       |
+   17|      0|fn unused_func(mut a: u32) {
+   18|      0|    if a != 0 {
+   19|      0|        a += 1;
+   20|      0|    }
+   21|      0|}
+   22|       |
+   23|      0|fn unused_func2(mut a: u32) {
+   24|      0|    if a != 0 {
+   25|      0|        a += 1;
+   26|      0|    }
+   27|      0|}
+   28|       |
+   29|      0|fn unused_func3(mut a: u32) {
+   30|      0|    if a != 0 {
+   31|      0|        a += 1;
+   32|      0|    }
+   33|      0|}
+   34|       |
+   35|      1|fn main() -> Result<(), u8> {
+   36|      1|    foo::<u32>(0);
+   37|      1|    foo::<f32>(0.0);
+   38|      1|    Ok(())
+   39|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.unused_mod.txt b/src/test/run-make/coverage-reports/expected_show_coverage.unused_mod.txt
new file mode 100644 (file)
index 0000000..82d6fcc
--- /dev/null
@@ -0,0 +1,4 @@
+    1|      0|pub fn never_called_function() {
+    2|      0|    println!("I am never called");
+    3|      0|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make/coverage-reports/expected_show_coverage.uses_crate.txt
new file mode 100644 (file)
index 0000000..65eb100
--- /dev/null
@@ -0,0 +1,148 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
+    3|       |use std::fmt::Debug;
+    4|       |
+    5|      1|pub fn used_function() {
+    6|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    7|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    8|      1|    // dependent conditions.
+    9|      1|    let is_true = std::env::args().len() == 1;
+   10|      1|    let mut countdown = 0;
+   11|      1|    if is_true {
+   12|      1|        countdown = 10;
+   13|      1|    }
+                   ^0
+   14|      1|    use_this_lib_crate();
+   15|      1|}
+   16|       |
+   17|      2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+   18|      2|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+   19|      2|}
+  ------------------
+  | used_crate::used_only_from_bin_crate_generic_function::<&str>:
+  |   17|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+  |   18|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+  |   19|      1|}
+  ------------------
+  | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
+  |   17|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+  |   18|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+  |   19|      1|}
+  ------------------
+  | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
+  ------------------
+   20|       |// Expect for above function: `Unexecuted instantiation` (see below)
+   21|      2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+   22|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+   23|      2|}
+  ------------------
+  | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+  |   21|      1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   22|      1|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+  |   23|      1|}
+  ------------------
+  | used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
+  |   21|      1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   22|      1|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+  |   23|      1|}
+  ------------------
+   24|       |
+   25|      2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+   26|      2|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+   27|      2|}
+  ------------------
+  | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+  |   25|      1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   26|      1|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   27|      1|}
+  ------------------
+  | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   25|      1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   26|      1|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   27|      1|}
+  ------------------
+   28|       |
+   29|      2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+   30|      2|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+   31|      2|}
+  ------------------
+  | used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   29|      1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   30|      1|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   31|      1|}
+  ------------------
+  | used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   29|      1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   30|      1|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   31|      1|}
+  ------------------
+   32|       |
+   33|      0|pub fn unused_generic_function<T: Debug>(arg: T) {
+   34|      0|    println!("unused_generic_function with {:?}", arg);
+   35|      0|}
+   36|       |
+   37|      0|pub fn unused_function() {
+   38|      0|    let is_true = std::env::args().len() == 1;
+   39|      0|    let mut countdown = 2;
+   40|      0|    if !is_true {
+   41|      0|        countdown = 20;
+   42|      0|    }
+   43|      0|}
+   44|       |
+   45|      0|fn unused_private_function() {
+   46|      0|    let is_true = std::env::args().len() == 1;
+   47|      0|    let mut countdown = 2;
+   48|      0|    if !is_true {
+   49|      0|        countdown = 20;
+   50|      0|    }
+   51|      0|}
+   52|       |
+   53|      1|fn use_this_lib_crate() {
+   54|      1|    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
+   55|      1|    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+   56|      1|        "used from library used_crate.rs",
+   57|      1|    );
+   58|      1|    let some_vec = vec![5, 6, 7, 8];
+   59|      1|    used_only_from_this_lib_crate_generic_function(some_vec);
+   60|      1|    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
+   61|      1|}
+   62|       |
+   63|       |// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
+   64|       |// for example:
+   65|       |//
+   66|       |// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
+   67|       |//
+   68|       |// These notices appear when `llvm-cov` shows instantiations. This may be a
+   69|       |// default option, but it can be suppressed with:
+   70|       |//
+   71|       |// ```shell
+   72|       |// $ `llvm-cov show --show-instantiations=0 ...`
+   73|       |// ```
+   74|       |//
+   75|       |// The notice is triggered because the function is unused by the library itself,
+   76|       |// and when the library is compiled, a synthetic function is generated, so
+   77|       |// unused function coverage can be reported. Coverage can be skipped for unused
+   78|       |// generic functions with:
+   79|       |//
+   80|       |// ```shell
+   81|       |// $ `rustc -Zunstable-options -C instrument-coverage=except-unused-generics ...`
+   82|       |// ```
+   83|       |//
+   84|       |// Even though this function is used by `uses_crate.rs` (and
+   85|       |// counted), with substitutions for `T`, those instantiations are only generated
+   86|       |// when the generic function is actually used (from the binary, not from this
+   87|       |// library crate). So the test result shows coverage for all instantiated
+   88|       |// versions and their generic type substitutions, plus the `Unexecuted
+   89|       |// instantiation` message for the non-substituted version. This is valid, but
+   90|       |// unfortunately a little confusing.
+   91|       |//
+   92|       |// The library crate has its own coverage map, and the only way to show unused
+   93|       |// coverage of a generic function is to include the generic function in the
+   94|       |// coverage map, marked as an "unused function". If the library were used by
+   95|       |// another binary that never used this generic function, then it would be valid
+   96|       |// to show the unused generic, with unknown substitution (`_`).
+   97|       |//
+   98|       |// The alternative is to exclude all generics from being included in the "unused
+   99|       |// functions" list, which would then omit coverage results for
+  100|       |// `unused_generic_function<T>()`, below.
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt
new file mode 100644 (file)
index 0000000..dab31cb
--- /dev/null
@@ -0,0 +1,139 @@
+    1|       |#![allow(unused_assignments, unused_variables)]
+    2|       |
+    3|       |// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
+    4|       |
+    5|       |use std::fmt::Debug;
+    6|       |
+    7|      1|pub fn used_function() {
+    8|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    9|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   10|      1|    // dependent conditions.
+   11|      1|    let is_true = std::env::args().len() == 1;
+   12|      1|    let mut countdown = 0;
+   13|      1|    if is_true {
+   14|      1|        countdown = 10;
+   15|      1|    }
+                   ^0
+   16|      1|    use_this_lib_crate();
+   17|      1|}
+   18|       |
+   19|       |#[inline(always)]
+   20|      1|pub fn used_inline_function() {
+   21|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   22|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   23|      1|    // dependent conditions.
+   24|      1|    let is_true = std::env::args().len() == 1;
+   25|      1|    let mut countdown = 0;
+   26|      1|    if is_true {
+   27|      1|        countdown = 10;
+   28|      1|    }
+                   ^0
+   29|      1|    use_this_lib_crate();
+   30|      1|}
+   31|       |
+   32|       |
+   33|       |
+   34|       |
+   35|       |
+   36|       |
+   37|       |
+   38|       |#[inline(always)]
+   39|      2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+   40|      2|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+   41|      2|}
+  ------------------
+  | used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
+  |   39|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+  |   40|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+  |   41|      1|}
+  ------------------
+  | used_inline_crate::used_only_from_bin_crate_generic_function::<&str>:
+  |   39|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+  |   40|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+  |   41|      1|}
+  ------------------
+  | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_>
+  ------------------
+   42|       |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
+   43|       |
+   44|       |#[inline(always)]
+   45|      4|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+   46|      4|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+   47|      4|}
+  ------------------
+  | used_inline_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+  |   45|      2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   46|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+  |   47|      2|}
+  ------------------
+  | used_inline_crate::used_only_from_this_lib_crate_generic_function::<&str>:
+  |   45|      2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   46|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+  |   47|      2|}
+  ------------------
+   48|       |
+   49|       |#[inline(always)]
+   50|      3|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+   51|      3|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+   52|      3|}
+  ------------------
+  | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+  |   50|      1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   51|      1|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   52|      1|}
+  ------------------
+  | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   50|      2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   51|      2|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   52|      2|}
+  ------------------
+   53|       |
+   54|       |#[inline(always)]
+   55|      3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+   56|      3|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+   57|      3|}
+  ------------------
+  | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   55|      1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   56|      1|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   57|      1|}
+  ------------------
+  | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   55|      2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   56|      2|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   57|      2|}
+  ------------------
+   58|       |
+   59|       |#[inline(always)]
+   60|      0|pub fn unused_generic_function<T: Debug>(arg: T) {
+   61|      0|    println!("unused_generic_function with {:?}", arg);
+   62|      0|}
+   63|       |
+   64|       |#[inline(always)]
+   65|      0|pub fn unused_function() {
+   66|      0|    let is_true = std::env::args().len() == 1;
+   67|      0|    let mut countdown = 2;
+   68|      0|    if !is_true {
+   69|      0|        countdown = 20;
+   70|      0|    }
+   71|      0|}
+   72|       |
+   73|       |#[inline(always)]
+   74|      0|fn unused_private_function() {
+   75|      0|    let is_true = std::env::args().len() == 1;
+   76|      0|    let mut countdown = 2;
+   77|      0|    if !is_true {
+   78|      0|        countdown = 20;
+   79|      0|    }
+   80|      0|}
+   81|       |
+   82|      2|fn use_this_lib_crate() {
+   83|      2|    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
+   84|      2|    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+   85|      2|        "used from library used_crate.rs",
+   86|      2|    );
+   87|      2|    let some_vec = vec![5, 6, 7, 8];
+   88|      2|    used_only_from_this_lib_crate_generic_function(some_vec);
+   89|      2|    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
+   90|      2|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.while.txt b/src/test/run-make/coverage-reports/expected_show_coverage.while.txt
new file mode 100644 (file)
index 0000000..efa7d08
--- /dev/null
@@ -0,0 +1,6 @@
+    1|      1|fn main() {
+    2|      1|    let num = 9;
+    3|      1|    while num >= 10 {
+    4|      0|    }
+    5|      1|}
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.while_early_ret.txt b/src/test/run-make/coverage-reports/expected_show_coverage.while_early_ret.txt
new file mode 100644 (file)
index 0000000..d19afc0
--- /dev/null
@@ -0,0 +1,43 @@
+    1|       |#![allow(unused_assignments)]
+    2|       |// expect-exit-status-1
+    3|       |
+    4|      1|fn main() -> Result<(),u8> {
+    5|      1|    let mut countdown = 10;
+    6|       |    while
+    7|      7|        countdown
+    8|      7|            >
+    9|      7|        0
+   10|       |    {
+   11|       |        if
+   12|      7|            countdown
+   13|      7|                <
+   14|      7|            5
+   15|       |        {
+   16|       |            return
+   17|       |                if
+   18|      1|                    countdown
+   19|      1|                        >
+   20|      1|                    8
+   21|       |                {
+   22|      0|                    Ok(())
+   23|       |                }
+   24|       |                else
+   25|       |                {
+   26|      1|                    Err(1)
+   27|       |                }
+   28|       |                ;
+   29|      6|        }
+   30|      6|        countdown
+   31|      6|            -=
+   32|      6|        1
+   33|       |        ;
+   34|       |    }
+   35|      0|    Ok(())
+   36|      1|}
+   37|       |
+   38|       |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and
+   39|       |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux
+   40|       |// and MacOS. But on Windows (MSVC, at least), the call to `std::process::exit()` exits the program
+   41|       |// without saving the InstrProf coverage counters. The use of `std::process:exit()` is not critical
+   42|       |// to the coverage test for early returns, but this is a limitation that should be fixed.
+
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.yield.txt b/src/test/run-make/coverage-reports/expected_show_coverage.yield.txt
new file mode 100644 (file)
index 0000000..60a8d94
--- /dev/null
@@ -0,0 +1,38 @@
+    1|       |#![feature(generators, generator_trait)]
+    2|       |#![allow(unused_assignments)]
+    3|       |
+    4|       |use std::ops::{Generator, GeneratorState};
+    5|       |use std::pin::Pin;
+    6|       |
+    7|      1|fn main() {
+    8|      1|    let mut generator = || {
+    9|      1|        yield 1;
+   10|      1|        return "foo"
+   11|       |    };
+   12|       |
+   13|      1|    match Pin::new(&mut generator).resume(()) {
+   14|      1|        GeneratorState::Yielded(1) => {}
+   15|      0|        _ => panic!("unexpected value from resume"),
+   16|       |    }
+   17|      1|    match Pin::new(&mut generator).resume(()) {
+   18|      1|        GeneratorState::Complete("foo") => {}
+   19|      0|        _ => panic!("unexpected value from resume"),
+   20|       |    }
+   21|       |
+   22|      1|    let mut generator = || {
+   23|      1|        yield 1;
+   24|      1|        yield 2;
+   25|      0|        yield 3;
+   26|      0|        return "foo"
+   27|       |    };
+   28|       |
+   29|      1|    match Pin::new(&mut generator).resume(()) {
+   30|      1|        GeneratorState::Yielded(1) => {}
+   31|      0|        _ => panic!("unexpected value from resume"),
+   32|       |    }
+   33|      1|    match Pin::new(&mut generator).resume(()) {
+   34|      1|        GeneratorState::Yielded(2) => {}
+   35|      0|        _ => panic!("unexpected value from resume"),
+   36|       |    }
+   37|      1|}
+
diff --git a/src/test/run-make/coverage-reports/normalize_paths.py b/src/test/run-make/coverage-reports/normalize_paths.py
new file mode 100755 (executable)
index 0000000..e5777ad
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+
+from __future__ import print_function
+
+import sys
+
+# Normalize file paths in output
+for line in sys.stdin:
+    if line.startswith("..") and line.rstrip().endswith(".rs:"):
+        print(line.replace("\\", "/"), end='')
+    else:
+        print(line, end='')
diff --git a/src/test/run-make/coverage/WARNING_KEEP_NAMES_SHORT.txt b/src/test/run-make/coverage/WARNING_KEEP_NAMES_SHORT.txt
new file mode 100644 (file)
index 0000000..6a1403b
--- /dev/null
@@ -0,0 +1,10 @@
+IMPORTANT: The Rust test programs in this directory generate various output
+files in the `../coverage*` directories (`expected` and `actual` files).
+
+Microsoft Windows has a relatively short limit on file paths (not individual
+path components, but the entire path). The files generated by these
+`../coverage*` tests typically have file paths that include the program
+source file name plus function and type names (depending on the program).
+
+Keep the test file names short, and keep function names and other symbols
+short as well, to avoid hitting the Windows limits.
diff --git a/src/test/run-make/coverage/abort.rs b/src/test/run-make/coverage/abort.rs
new file mode 100644 (file)
index 0000000..3dac43d
--- /dev/null
@@ -0,0 +1,66 @@
+#![feature(c_unwind)]
+#![allow(unused_assignments)]
+
+extern "C" fn might_abort(should_abort: bool) {
+    if should_abort {
+        println!("aborting...");
+        panic!("panics and aborts");
+    } else {
+        println!("Don't Panic");
+    }
+}
+
+fn main() -> Result<(), u8> {
+    let mut countdown = 10;
+    while countdown > 0 {
+        if countdown < 5 {
+            might_abort(false);
+        }
+        // See discussion (below the `Notes` section) on coverage results for the closing brace.
+        if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
+        // For the following example, the closing brace is the last character on the line.
+        // This shows the character after the closing brace is highlighted, even if that next
+        // character is a newline.
+        if countdown < 5 { might_abort(false); }
+        countdown -= 1;
+    }
+    Ok(())
+}
+
+// Notes:
+//   1. Compare this program and its coverage results to those of the similar tests
+//      `panic_unwind.rs` and `try_error_result.rs`.
+//   2. This test confirms the coverage generated when a program includes `TerminatorKind::Abort`.
+//   3. The test does not invoke the abort. By executing to a successful completion, the coverage
+//      results show where the program did and did not execute.
+//   4. If the program actually aborted, the coverage counters would not be saved (which "works as
+//      intended"). Coverage results would show no executed coverage regions.
+//   6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
+//      (on Linux at least).
+
+/*
+
+Expect the following coverage results:
+
+```text
+    16|     11|    while countdown > 0 {
+    17|     10|        if countdown < 5 {
+    18|      4|            might_abort(false);
+    19|      6|        }
+```
+
+This is actually correct.
+
+The condition `countdown < 5` executed 10 times (10 loop iterations).
+
+It evaluated to `true` 4 times, and executed the `might_abort()` call.
+
+It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
+`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
+closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
+non-true condition.
+
+As another example of why this is important, say the condition was `countdown < 50`, which is always
+`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
+The closing brace would have a count of `0`, highlighting the missed coverage.
+*/
diff --git a/src/test/run-make/coverage/assert.rs b/src/test/run-make/coverage/assert.rs
new file mode 100644 (file)
index 0000000..c85f274
--- /dev/null
@@ -0,0 +1,32 @@
+#![allow(unused_assignments)]
+// expect-exit-status-101
+
+fn might_fail_assert(one_plus_one: u32) {
+    println!("does 1 + 1 = {}?", one_plus_one);
+    assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
+}
+
+fn main() -> Result<(),u8> {
+    let mut countdown = 10;
+    while countdown > 0 {
+        if countdown == 1 {
+            might_fail_assert(3);
+        } else if countdown < 5 {
+            might_fail_assert(2);
+        }
+        countdown -= 1;
+    }
+    Ok(())
+}
+
+// Notes:
+//   1. Compare this program and its coverage results to those of the very similar test
+//      `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
+//   2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
+//      related `assert_*!()` macro.
+//   3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
+//      conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
+//      `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
+//   4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
+//      (and in many other coverage tests). The `Assert` terminator is typically generated by the
+//      Rust compiler to check for runtime failures, such as numeric overflows.
diff --git a/src/test/run-make/coverage/async.rs b/src/test/run-make/coverage/async.rs
new file mode 100644 (file)
index 0000000..a6e3877
--- /dev/null
@@ -0,0 +1,128 @@
+#![allow(unused_assignments, dead_code)]
+
+// compile-flags: --edition=2018 -C opt-level=1
+
+async fn c(x: u8) -> u8 {
+    if x == 8 {
+        1
+    } else {
+        0
+    }
+}
+
+async fn d() -> u8 { 1 }
+
+async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
+
+async fn f() -> u8 { 1 }
+
+async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
+
+pub async fn g(x: u8) {
+    match x {
+        y if e().await == y => (),
+        y if f().await == y => (),
+        _ => (),
+    }
+}
+
+async fn h(x: usize) { // The function signature is counted when called, but the body is not
+                       // executed (not awaited) so the open brace has a `0` count (at least when
+                       // displayed with `llvm-cov show` in color-mode).
+    match x {
+        y if foo().await[y] => (),
+        _ => (),
+    }
+}
+
+async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
+                    // (a) the function signature, counted when the function is called; and
+                    // (b) the open brace for the function body, counted once when the body is
+                    // executed asynchronously.
+    match x {
+        y if c(x).await == y + 1 => { d().await; }
+        y if f().await == y + 1 => (),
+        _ => (),
+    }
+}
+
+fn j(x: u8) {
+    // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`.
+    fn c(x: u8) -> u8 {
+        if x == 8 {
+            1 // This line appears covered, but the 1-character expression span covering the `1`
+              // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
+              // `fn j()` executes the open brace for the funciton body, followed by the function's
+              // first executable statement, `match x`. Inner function declarations are not
+              // "visible" to the MIR for `j()`, so the code region counts all lines between the
+              // open brace and the first statement as executed, which is, in a sense, true.
+              // `llvm-cov show` overcomes this kind of situation by showing the actual counts
+              // of the enclosed coverages, (that is, the `1` expression was not executed, and
+              // accurately displays a `0`).
+        } else {
+            0
+        }
+    }
+    fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed
+    fn f() -> u8 { 1 }
+    match x {
+        y if c(x) == y + 1 => { d(); }
+        y if f() == y + 1 => (),
+        _ => (),
+    }
+}
+
+fn k(x: u8) { // unused function
+    match x {
+        1 => (),
+        2 => (),
+        _ => (),
+    }
+}
+
+fn l(x: u8) {
+    match x {
+        1 => (),
+        2 => (),
+        _ => (),
+    }
+}
+
+async fn m(x: u8) -> u8 { x - 1 }
+
+fn main() {
+    let _ = g(10);
+    let _ = h(9);
+    let mut future = Box::pin(i(8));
+    j(7);
+    l(6);
+    let _ = m(5);
+    executor::block_on(future.as_mut());
+}
+
+mod executor {
+    use core::{
+        future::Future,
+        pin::Pin,
+        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+    };
+
+    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+        use std::hint::unreachable_unchecked;
+        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+            |_| unsafe { unreachable_unchecked() }, // clone
+            |_| unsafe { unreachable_unchecked() }, // wake
+            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+            |_| (),
+        );
+        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+        let mut context = Context::from_waker(&waker);
+
+        loop {
+            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+                break val;
+            }
+        }
+    }
+}
diff --git a/src/test/run-make/coverage/async2.rs b/src/test/run-make/coverage/async2.rs
new file mode 100644 (file)
index 0000000..959d48c
--- /dev/null
@@ -0,0 +1,69 @@
+// compile-flags: --edition=2018
+
+use core::{
+    future::Future,
+    marker::Send,
+    pin::Pin,
+};
+
+fn non_async_func() {
+    println!("non_async_func was covered");
+    let b = true;
+    if b {
+        println!("non_async_func println in block");
+    }
+}
+
+
+
+
+async fn async_func() {
+    println!("async_func was covered");
+    let b = true;
+    if b {
+        println!("async_func println in block");
+    }
+}
+
+
+
+
+async fn async_func_just_println() {
+    println!("async_func_just_println was covered");
+}
+
+fn main() {
+    println!("codecovsample::main");
+
+    non_async_func();
+
+    executor::block_on(async_func());
+    executor::block_on(async_func_just_println());
+}
+
+mod executor {
+    use core::{
+        future::Future,
+        pin::Pin,
+        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+    };
+
+    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+        use std::hint::unreachable_unchecked;
+        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+            |_| unsafe { unreachable_unchecked() }, // clone
+            |_| unsafe { unreachable_unchecked() }, // wake
+            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+            |_| (),
+        );
+        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+        let mut context = Context::from_waker(&waker);
+
+        loop {
+            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+                break val;
+            }
+        }
+    }
+}
diff --git a/src/test/run-make/coverage/closure.rs b/src/test/run-make/coverage/closure.rs
new file mode 100644 (file)
index 0000000..32ec0bc
--- /dev/null
@@ -0,0 +1,215 @@
+#![allow(unused_assignments, unused_variables)]
+// compile-flags: -C opt-level=2 # fix described in rustc_middle/mir/mono.rs
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+    let is_false = ! is_true;
+
+    let mut some_string = Some(String::from("the string content"));
+    println!(
+        "The string or alt: {}"
+        ,
+        some_string
+            .
+            unwrap_or_else
+        (
+            ||
+            {
+                let mut countdown = 0;
+                if is_false {
+                    countdown = 10;
+                }
+                "alt string 1".to_owned()
+            }
+        )
+    );
+
+    some_string = Some(String::from("the string content"));
+    let
+        a
+    =
+        ||
+    {
+        let mut countdown = 0;
+        if is_false {
+            countdown = 10;
+        }
+        "alt string 2".to_owned()
+    };
+    println!(
+        "The string or alt: {}"
+        ,
+        some_string
+            .
+            unwrap_or_else
+        (
+            a
+        )
+    );
+
+    some_string = None;
+    println!(
+        "The string or alt: {}"
+        ,
+        some_string
+            .
+            unwrap_or_else
+        (
+            ||
+            {
+                let mut countdown = 0;
+                if is_false {
+                    countdown = 10;
+                }
+                "alt string 3".to_owned()
+            }
+        )
+    );
+
+    some_string = None;
+    let
+        a
+    =
+        ||
+    {
+        let mut countdown = 0;
+        if is_false {
+            countdown = 10;
+        }
+        "alt string 4".to_owned()
+    };
+    println!(
+        "The string or alt: {}"
+        ,
+        some_string
+            .
+            unwrap_or_else
+        (
+            a
+        )
+    );
+
+    let
+        quote_closure
+    =
+        |val|
+    {
+        let mut countdown = 0;
+        if is_false {
+            countdown = 10;
+        }
+        format!("'{}'", val)
+    };
+    println!(
+        "Repeated, quoted string: {:?}"
+        ,
+        std::iter::repeat("repeat me")
+            .take(5)
+            .map
+        (
+            quote_closure
+        )
+            .collect::<Vec<_>>()
+    );
+
+    let
+        _unused_closure
+    =
+        |
+            mut countdown
+        |
+    {
+        if is_false {
+            countdown = 10;
+        }
+        "closure should be unused".to_owned()
+    };
+
+    let mut countdown = 10;
+    let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
+
+
+    let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
+    let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
+    let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
+
+
+
+
+    let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
+
+    let _shortish_unused_closure = | _unused_arg: u8 | {
+        println!("not called")
+    };
+
+    let _as_short_unused_closure = |
+        _unused_arg: u8
+    | { println!("not called") };
+
+    let _almost_as_short_unused_closure = |
+        _unused_arg: u8
+    | { println!("not called") }
+    ;
+
+
+
+
+
+    let _short_unused_closure_line_break_no_block = | _unused_arg: u8 |
+println!("not called")
+    ;
+
+    let _short_unused_closure_line_break_no_block2 =
+        | _unused_arg: u8 |
+            println!(
+                "not called"
+            )
+    ;
+
+    let short_used_not_covered_closure_line_break_no_block_embedded_branch =
+        | _unused_arg: u8 |
+            println!(
+                "not called: {}",
+                if is_true { "check" } else { "me" }
+            )
+    ;
+
+    let short_used_not_covered_closure_line_break_block_embedded_branch =
+        | _unused_arg: u8 |
+        {
+            println!(
+                "not called: {}",
+                if is_true { "check" } else { "me" }
+            )
+        }
+    ;
+
+    let short_used_covered_closure_line_break_no_block_embedded_branch =
+        | _unused_arg: u8 |
+            println!(
+                "not called: {}",
+                if is_true { "check" } else { "me" }
+            )
+    ;
+
+    let short_used_covered_closure_line_break_block_embedded_branch =
+        | _unused_arg: u8 |
+        {
+            println!(
+                "not called: {}",
+                if is_true { "check" } else { "me" }
+            )
+        }
+    ;
+
+    if is_false {
+        short_used_not_covered_closure_macro(0);
+        short_used_not_covered_closure_line_break_no_block_embedded_branch(0);
+        short_used_not_covered_closure_line_break_block_embedded_branch(0);
+    }
+    short_used_covered_closure_macro(0);
+    short_used_covered_closure_line_break_no_block_embedded_branch(0);
+    short_used_covered_closure_line_break_block_embedded_branch(0);
+}
diff --git a/src/test/run-make/coverage/closure_macro.rs b/src/test/run-make/coverage/closure_macro.rs
new file mode 100644 (file)
index 0000000..5e3b00d
--- /dev/null
@@ -0,0 +1,40 @@
+// compile-flags: --edition=2018
+#![feature(no_coverage)]
+
+macro_rules! bail {
+    ($msg:literal $(,)?) => {
+        if $msg.len() > 0 {
+            println!("no msg");
+        } else {
+            println!($msg);
+        }
+        return Err(String::from($msg));
+    };
+}
+
+macro_rules! on_error {
+    ($value:expr, $error_message:expr) => {
+        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
+            let message = format!($error_message, e);
+            if message.len() > 0 {
+                println!("{}", message);
+                Ok(String::from("ok"))
+            } else {
+                bail!("error");
+            }
+        })
+    };
+}
+
+fn load_configuration_files() -> Result<String, String> {
+    Ok(String::from("config"))
+}
+
+pub fn main() -> Result<(), String> {
+    println!("Starting service");
+    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
+
+    let startup_delay_duration = String::from("arg");
+    let _ = (config, startup_delay_duration);
+    Ok(())
+}
diff --git a/src/test/run-make/coverage/closure_macro_async.rs b/src/test/run-make/coverage/closure_macro_async.rs
new file mode 100644 (file)
index 0000000..e3e89e9
--- /dev/null
@@ -0,0 +1,81 @@
+// compile-flags: --edition=2018
+#![feature(no_coverage)]
+
+macro_rules! bail {
+    ($msg:literal $(,)?) => {
+        if $msg.len() > 0 {
+            println!("no msg");
+        } else {
+            println!($msg);
+        }
+        return Err(String::from($msg));
+    };
+}
+
+macro_rules! on_error {
+    ($value:expr, $error_message:expr) => {
+        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
+            let message = format!($error_message, e);
+            if message.len() > 0 {
+                println!("{}", message);
+                Ok(String::from("ok"))
+            } else {
+                bail!("error");
+            }
+        })
+    };
+}
+
+fn load_configuration_files() -> Result<String, String> {
+    Ok(String::from("config"))
+}
+
+pub async fn test() -> Result<(), String> {
+    println!("Starting service");
+    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
+
+    let startup_delay_duration = String::from("arg");
+    let _ = (config, startup_delay_duration);
+    Ok(())
+}
+
+#[no_coverage]
+fn main() {
+    executor::block_on(test());
+}
+
+mod executor {
+    use core::{
+        future::Future,
+        pin::Pin,
+        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+    };
+
+    #[no_coverage]
+    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+        use std::hint::unreachable_unchecked;
+        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+
+            #[no_coverage]
+            |_| unsafe { unreachable_unchecked() }, // clone
+
+            #[no_coverage]
+            |_| unsafe { unreachable_unchecked() }, // wake
+
+            #[no_coverage]
+            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+
+            #[no_coverage]
+            |_| (),
+        );
+        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+        let mut context = Context::from_waker(&waker);
+
+        loop {
+            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+                break val;
+            }
+        }
+    }
+}
diff --git a/src/test/run-make/coverage/compiletest-ignore-dir b/src/test/run-make/coverage/compiletest-ignore-dir
new file mode 100644 (file)
index 0000000..b533b27
--- /dev/null
@@ -0,0 +1,3 @@
+# Directory "coverage" supports the tests at prefix ../coverage-*
+
+# Use ./x.py [options] test src/test/run-make/coverage to run all related tests.
diff --git a/src/test/run-make/coverage/conditions.rs b/src/test/run-make/coverage/conditions.rs
new file mode 100644 (file)
index 0000000..057599d
--- /dev/null
@@ -0,0 +1,87 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    let mut countdown = 0;
+    if true {
+        countdown = 10;
+    }
+
+    const B: u32 = 100;
+    let x = if countdown > 7 {
+        countdown -= 4;
+        B
+    } else if countdown > 2 {
+        if countdown < 1 || countdown > 5 || countdown != 9 {
+            countdown = 0;
+        }
+        countdown -= 5;
+        countdown
+    } else {
+        return;
+    };
+
+    let mut countdown = 0;
+    if true {
+        countdown = 10;
+    }
+
+    if countdown > 7 {
+        countdown -= 4;
+    } else if countdown > 2 {
+        if countdown < 1 || countdown > 5 || countdown != 9 {
+            countdown = 0;
+        }
+        countdown -= 5;
+    } else {
+        return;
+    }
+
+    if true {
+        let mut countdown = 0;
+        if true {
+            countdown = 10;
+        }
+
+        if countdown > 7 {
+            countdown -= 4;
+        }
+        else if countdown > 2 {
+            if countdown < 1 || countdown > 5 || countdown != 9 {
+                countdown = 0;
+            }
+            countdown -= 5;
+        } else {
+            return;
+        }
+    }
+
+
+    let mut countdown = 0;
+    if true {
+        countdown = 1;
+    }
+
+    let z = if countdown > 7 {
+        countdown -= 4;
+    } else if countdown > 2 {
+        if countdown < 1 || countdown > 5 || countdown != 9 {
+            countdown = 0;
+        }
+        countdown -= 5;
+    } else {
+        let should_be_reachable = countdown;
+        println!("reached");
+        return;
+    };
+
+    let w = if countdown > 7 {
+        countdown -= 4;
+    } else if countdown > 2 {
+        if countdown < 1 || countdown > 5 || countdown != 9 {
+            countdown = 0;
+        }
+        countdown -= 5;
+    } else {
+        return;
+    };
+}
diff --git a/src/test/run-make/coverage/continue.rs b/src/test/run-make/coverage/continue.rs
new file mode 100644 (file)
index 0000000..624aa98
--- /dev/null
@@ -0,0 +1,69 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    let is_true = std::env::args().len() == 1;
+
+    let mut x = 0;
+    for _ in 0..10 {
+        match is_true {
+            true => {
+                continue;
+            }
+            _ => {
+                x = 1;
+            }
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        match is_true {
+            false => {
+                x = 1;
+            }
+            _ => {
+                continue;
+            }
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        match is_true {
+            true => {
+                x = 1;
+            }
+            _ => {
+                continue;
+            }
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        if is_true {
+            continue;
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        match is_true {
+            false => {
+                x = 1;
+            }
+            _ => {
+                let _ = x;
+            }
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        match is_true {
+            false => {
+                x = 1;
+            }
+            _ => {
+                break;
+            }
+        }
+        x = 3;
+    }
+    let _ = x;
+}
diff --git a/src/test/run-make/coverage/coverage_tools.mk b/src/test/run-make/coverage/coverage_tools.mk
new file mode 100644 (file)
index 0000000..a578e08
--- /dev/null
@@ -0,0 +1,6 @@
+# Common Makefile include for Rust `run-make/coverage-* tests. Include this
+# file with the line:
+#
+# -include ../coverage/coverage_tools.mk
+
+-include ../tools.mk
diff --git a/src/test/run-make/coverage/dead_code.rs b/src/test/run-make/coverage/dead_code.rs
new file mode 100644 (file)
index 0000000..a1285df
--- /dev/null
@@ -0,0 +1,37 @@
+#![allow(unused_assignments, unused_variables)]
+
+pub fn unused_pub_fn_not_in_library() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+}
+
+fn unused_fn() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+}
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+}
diff --git a/src/test/run-make/coverage/doctest.rs b/src/test/run-make/coverage/doctest.rs
new file mode 100644 (file)
index 0000000..ec04ea5
--- /dev/null
@@ -0,0 +1,99 @@
+//! This test ensures that code from doctests is properly re-mapped.
+//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
+//!
+//! Just some random code:
+//! ```
+//! if true {
+//!     // this is executed!
+//!     assert_eq!(1, 1);
+//! } else {
+//!     // this is not!
+//!     assert_eq!(1, 2);
+//! }
+//! ```
+//!
+//! doctest testing external code:
+//! ```
+//! extern crate doctest_crate;
+//! doctest_crate::fn_run_in_doctests(1);
+//! ```
+//!
+//! doctest returning a result:
+//! ```
+//! #[derive(Debug, PartialEq)]
+//! struct SomeError {
+//!     msg: String,
+//! }
+//! let mut res = Err(SomeError { msg: String::from("a message") });
+//! if res.is_ok() {
+//!     res?;
+//! } else {
+//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
+//!         println!("{:?}", res);
+//!     }
+//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
+//!         res = Ok(1);
+//!     }
+//!     res = Ok(0);
+//! }
+//! // need to be explicit because rustdoc cant infer the return type
+//! Ok::<(), SomeError>(())
+//! ```
+//!
+//! doctest with custom main:
+//! ```
+//! fn some_func() {
+//!     println!("called some_func()");
+//! }
+//!
+//! #[derive(Debug)]
+//! struct SomeError;
+//!
+//! extern crate doctest_crate;
+//!
+//! fn doctest_main() -> Result<(), SomeError> {
+//!     some_func();
+//!     doctest_crate::fn_run_in_doctests(2);
+//!     Ok(())
+//! }
+//!
+//! // this `main` is not shown as covered, as it clashes with all the other
+//! // `main` functions that were automatically generated for doctests
+//! fn main() -> Result<(), SomeError> {
+//!     doctest_main()
+//! }
+//! ```
+
+/// doctest attached to fn testing external code:
+/// ```
+/// extern crate doctest_crate;
+/// doctest_crate::fn_run_in_doctests(3);
+/// ```
+///
+fn main() {
+    if true {
+        assert_eq!(1, 1);
+    } else {
+        assert_eq!(1, 2);
+    }
+}
+
+// FIXME(Swatinem): Fix known issue that coverage code region columns need to be offset by the
+// doc comment line prefix (`///` or `//!`) and any additional indent (before or after the doc
+// comment characters). This test produces `llvm-cov show` results demonstrating the problem.
+//
+// One of the above tests now includes: `derive(Debug, PartialEq)`, producing an `llvm-cov show`
+// result with a distinct count for `Debug`, denoted by `^1`, but the caret points to the wrong
+// column. Similarly, the `if` blocks without `else` blocks show `^0`, which should point at, or
+// one character past, the `if` block's closing brace. In both cases, these are most likely off
+// by the number of characters stripped from the beginning of each doc comment line: indent
+// whitespace, if any, doc comment prefix (`//!` in this case) and (I assume) one space character
+// (?). Note, when viewing `llvm-cov show` results in `--color` mode, the column offset errors are
+// more pronounced, and show up in more places, with background color used to show some distinct
+// code regions with different coverage counts.
+//
+// NOTE: Since the doc comment line prefix may vary, one possible solution is to replace each
+// character stripped from the beginning of doc comment lines with a space. This will give coverage
+// results the correct column offsets, and I think it should compile correctly, but I don't know
+// what affect it might have on diagnostic messages from the compiler, and whether anyone would care
+// if the indentation changed. I don't know if there is a more viable solution.
diff --git a/src/test/run-make/coverage/drop_trait.rs b/src/test/run-make/coverage/drop_trait.rs
new file mode 100644 (file)
index 0000000..d15bfc0
--- /dev/null
@@ -0,0 +1,33 @@
+#![allow(unused_assignments)]
+// expect-exit-status-1
+
+struct Firework {
+    strength: i32,
+}
+
+impl Drop for Firework {
+    fn drop(&mut self) {
+        println!("BOOM times {}!!!", self.strength);
+    }
+}
+
+fn main() -> Result<(),u8> {
+    let _firecracker = Firework { strength: 1 };
+
+    let _tnt = Firework { strength: 100 };
+
+    if true {
+        println!("Exiting with error...");
+        return Err(1);
+    }
+
+    let _ = Firework { strength: 1000 };
+
+    Ok(())
+}
+
+// Expected program output:
+//   Exiting with error...
+//   BOOM times 100!!!
+//   BOOM times 1!!!
+//   Error: 1
diff --git a/src/test/run-make/coverage/generator.rs b/src/test/run-make/coverage/generator.rs
new file mode 100644 (file)
index 0000000..4319991
--- /dev/null
@@ -0,0 +1,30 @@
+#![feature(generators, generator_trait)]
+
+use std::ops::{Generator, GeneratorState};
+use std::pin::Pin;
+
+// The following implementation of a function called from a `yield` statement
+// (apparently requiring the Result and the `String` type or constructor)
+// creates conditions where the `generator::StateTransform` MIR transform will
+// drop all `Counter` `Coverage` statements from a MIR. `simplify.rs` has logic
+// to handle this condition, and still report dead block coverage.
+fn get_u32(val: bool) -> Result<u32, String> {
+    if val { Ok(1) } else { Err(String::from("some error")) }
+}
+
+fn main() {
+    let is_true = std::env::args().len() == 1;
+    let mut generator = || {
+        yield get_u32(is_true);
+        return "foo";
+    };
+
+    match Pin::new(&mut generator).resume(()) {
+        GeneratorState::Yielded(Ok(1)) => {}
+        _ => panic!("unexpected return from resume"),
+    }
+    match Pin::new(&mut generator).resume(()) {
+        GeneratorState::Complete("foo") => {}
+        _ => panic!("unexpected return from resume"),
+    }
+}
diff --git a/src/test/run-make/coverage/generics.rs b/src/test/run-make/coverage/generics.rs
new file mode 100644 (file)
index 0000000..18b3886
--- /dev/null
@@ -0,0 +1,48 @@
+#![allow(unused_assignments)]
+// expect-exit-status-1
+
+struct Firework<T> where T: Copy + std::fmt::Display {
+    strength: T,
+}
+
+impl<T> Firework<T> where T: Copy + std::fmt::Display {
+    #[inline(always)]
+    fn set_strength(&mut self, new_strength: T) {
+        self.strength = new_strength;
+    }
+}
+
+impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
+    #[inline(always)]
+    fn drop(&mut self) {
+        println!("BOOM times {}!!!", self.strength);
+    }
+}
+
+fn main() -> Result<(),u8> {
+    let mut firecracker = Firework { strength: 1 };
+    firecracker.set_strength(2);
+
+    let mut tnt = Firework { strength: 100.1 };
+    tnt.set_strength(200.1);
+    tnt.set_strength(300.3);
+
+    if true {
+        println!("Exiting with error...");
+        return Err(1);
+    }
+
+
+
+
+
+    let _ = Firework { strength: 1000 };
+
+    Ok(())
+}
+
+// Expected program output:
+//   Exiting with error...
+//   BOOM times 100!!!
+//   BOOM times 1!!!
+//   Error: 1
diff --git a/src/test/run-make/coverage/if.rs b/src/test/run-make/coverage/if.rs
new file mode 100644 (file)
index 0000000..8ad5042
--- /dev/null
@@ -0,0 +1,28 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let
+    is_true
+    =
+        std::env::args().len()
+    ==
+        1
+    ;
+    let
+        mut
+    countdown
+    =
+        0
+    ;
+    if
+        is_true
+    {
+        countdown
+        =
+            10
+        ;
+    }
+}
diff --git a/src/test/run-make/coverage/if_else.rs b/src/test/run-make/coverage/if_else.rs
new file mode 100644 (file)
index 0000000..3244e1e
--- /dev/null
@@ -0,0 +1,40 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if
+        is_true
+    {
+        countdown
+        =
+            10
+        ;
+    }
+    else // Note coverage region difference without semicolon
+    {
+        countdown
+        =
+            100
+    }
+
+    if
+        is_true
+    {
+        countdown
+        =
+            10
+        ;
+    }
+    else
+    {
+        countdown
+        =
+            100
+        ;
+    }
+}
diff --git a/src/test/run-make/coverage/inline-dead.rs b/src/test/run-make/coverage/inline-dead.rs
new file mode 100644 (file)
index 0000000..854fa06
--- /dev/null
@@ -0,0 +1,27 @@
+// Regression test for issue #98833.
+// compile-flags: -Zinline-mir -Cdebug-assertions=off
+
+fn main() {
+    println!("{}", live::<false>());
+
+    let f = |x: bool| {
+        debug_assert!(
+            x
+        );
+    };
+    f(false);
+}
+
+#[inline]
+fn live<const B: bool>() -> u32 {
+    if B {
+        dead()
+    } else {
+        0
+    }
+}
+
+#[inline]
+fn dead() -> u32 {
+    42
+}
diff --git a/src/test/run-make/coverage/inline.rs b/src/test/run-make/coverage/inline.rs
new file mode 100644 (file)
index 0000000..9cfab9d
--- /dev/null
@@ -0,0 +1,51 @@
+// compile-flags: -Zinline-mir
+
+use std::fmt::Display;
+
+fn main() {
+    permutations(&['a', 'b', 'c']);
+}
+
+#[inline(always)]
+fn permutations<T: Copy + Display>(xs: &[T]) {
+    let mut ys = xs.to_owned();
+    permutate(&mut ys, 0);
+}
+
+fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
+    let n = length(xs);
+    if k == n {
+        display(xs);
+    } else if k < n {
+        for i in k..n {
+            swap(xs, i, k);
+            permutate(xs, k + 1);
+            swap(xs, i, k);
+        }
+    } else {
+        error();
+    }
+}
+
+fn length<T>(xs: &[T]) -> usize {
+    xs.len()
+}
+
+#[inline]
+fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
+    let t = xs[i];
+    xs[i] = xs[j];
+    xs[j] = t;
+}
+
+fn display<T: Display>(xs: &[T]) {
+    for x in xs {
+        print!("{}", x);
+    }
+    println!();
+}
+
+#[inline(always)]
+fn error() {
+    panic!("error");
+}
diff --git a/src/test/run-make/coverage/inner_items.rs b/src/test/run-make/coverage/inner_items.rs
new file mode 100644 (file)
index 0000000..bcb62b3
--- /dev/null
@@ -0,0 +1,57 @@
+#![allow(unused_assignments, unused_variables, dead_code)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+
+    mod in_mod {
+        const IN_MOD_CONST: u32 = 1000;
+    }
+
+    fn in_func(a: u32) {
+        let b = 1;
+        let c = a + b;
+        println!("c = {}", c)
+    }
+
+    struct InStruct {
+        in_struct_field: u32,
+    }
+
+    const IN_CONST: u32 = 1234;
+
+    trait InTrait {
+        fn trait_func(&mut self, incr: u32);
+
+        fn default_trait_func(&mut self) {
+            in_func(IN_CONST);
+            self.trait_func(IN_CONST);
+        }
+    }
+
+    impl InTrait for InStruct {
+        fn trait_func(&mut self, incr: u32) {
+            self.in_struct_field += incr;
+            in_func(self.in_struct_field);
+        }
+    }
+
+    type InType = String;
+
+    if is_true {
+        in_func(countdown);
+    }
+
+    let mut val = InStruct {
+        in_struct_field: 101,
+    };
+
+    val.default_trait_func();
+}
diff --git a/src/test/run-make/coverage/issue-83601.rs b/src/test/run-make/coverage/issue-83601.rs
new file mode 100644 (file)
index 0000000..0b72a81
--- /dev/null
@@ -0,0 +1,14 @@
+// Shows that rust-lang/rust/83601 is resolved
+
+#[derive(Debug, PartialEq, Eq)]
+struct Foo(u32);
+
+fn main() {
+    let bar = Foo(1);
+    assert_eq!(bar, Foo(1));
+    let baz = Foo(0);
+    assert_ne!(baz, Foo(1));
+    println!("{:?}", Foo(1));
+    println!("{:?}", bar);
+    println!("{:?}", baz);
+}
diff --git a/src/test/run-make/coverage/issue-84561.rs b/src/test/run-make/coverage/issue-84561.rs
new file mode 100644 (file)
index 0000000..b39a289
--- /dev/null
@@ -0,0 +1,182 @@
+// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
+
+// expect-exit-status-101
+#[derive(PartialEq, Eq)]
+struct Foo(u32);
+fn test3() {
+    let is_true = std::env::args().len() == 1;
+    let bar = Foo(1);
+    assert_eq!(bar, Foo(1));
+    let baz = Foo(0);
+    assert_ne!(baz, Foo(1));
+    println!("{:?}", Foo(1));
+    println!("{:?}", bar);
+    println!("{:?}", baz);
+
+    assert_eq!(Foo(1), Foo(1));
+    assert_ne!(Foo(0), Foo(1));
+    assert_eq!(Foo(2), Foo(2));
+    let bar = Foo(0);
+    assert_ne!(bar, Foo(3));
+    assert_ne!(Foo(0), Foo(4));
+    assert_eq!(Foo(3), Foo(3), "with a message");
+    println!("{:?}", bar);
+    println!("{:?}", Foo(1));
+
+    assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
+    assert_ne!(
+        Foo(0)
+        ,
+        Foo(5)
+        ,
+        "{}"
+        ,
+        if
+        is_true
+        {
+            "true message"
+        } else {
+            "false message"
+        }
+    );
+
+    let is_true = std::env::args().len() == 1;
+
+    assert_eq!(
+        Foo(1),
+        Foo(1)
+    );
+    assert_ne!(
+        Foo(0),
+        Foo(1)
+    );
+    assert_eq!(
+        Foo(2),
+        Foo(2)
+    );
+    let bar = Foo(1);
+    assert_ne!(
+        bar,
+        Foo(3)
+    );
+    if is_true {
+        assert_ne!(
+            Foo(0),
+            Foo(4)
+        );
+    } else {
+        assert_eq!(
+            Foo(3),
+            Foo(3)
+        );
+    }
+    if is_true {
+        assert_ne!(
+            Foo(0),
+            Foo(4),
+            "with a message"
+        );
+    } else {
+        assert_eq!(
+            Foo(3),
+            Foo(3),
+            "with a message"
+        );
+    }
+    assert_ne!(
+        if is_true {
+            Foo(0)
+        } else {
+            Foo(1)
+        },
+        Foo(5)
+    );
+    assert_ne!(
+        Foo(5),
+        if is_true {
+            Foo(0)
+        } else {
+            Foo(1)
+        }
+    );
+    assert_ne!(
+        if is_true {
+            assert_eq!(
+                Foo(3),
+                Foo(3)
+            );
+            Foo(0)
+        } else {
+            assert_ne!(
+                if is_true {
+                    Foo(0)
+                } else {
+                    Foo(1)
+                },
+                Foo(5)
+            );
+            Foo(1)
+        },
+        Foo(5),
+        "with a message"
+    );
+    assert_eq!(
+        Foo(1),
+        Foo(3),
+        "this assert should fail"
+    );
+    assert_eq!(
+        Foo(3),
+        Foo(3),
+        "this assert should not be reached"
+    );
+}
+
+impl std::fmt::Debug for Foo {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        write!(f, "try and succeed")?;
+        Ok(())
+    }
+}
+
+static mut DEBUG_LEVEL_ENABLED: bool = false;
+
+macro_rules! debug {
+    ($($arg:tt)+) => (
+        if unsafe { DEBUG_LEVEL_ENABLED } {
+            println!($($arg)+);
+        }
+    );
+}
+
+fn test1() {
+    debug!("debug is enabled");
+    debug!("debug is enabled");
+    let _ = 0;
+    debug!("debug is enabled");
+    unsafe {
+        DEBUG_LEVEL_ENABLED = true;
+    }
+    debug!("debug is enabled");
+}
+
+macro_rules! call_debug {
+    ($($arg:tt)+) => (
+        fn call_print(s: &str) {
+            print!("{}", s);
+        }
+
+        call_print("called from call_debug: ");
+        debug!($($arg)+);
+    );
+}
+
+fn test2() {
+    call_debug!("debug is enabled");
+}
+
+fn main() {
+    test1();
+    test2();
+    test3();
+}
diff --git a/src/test/run-make/coverage/issue-85461.rs b/src/test/run-make/coverage/issue-85461.rs
new file mode 100644 (file)
index 0000000..a1b9ebb
--- /dev/null
@@ -0,0 +1,10 @@
+// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
+
+extern crate inline_always_with_dead_code;
+
+use inline_always_with_dead_code::{bar, baz};
+
+fn main() {
+    bar::call_me();
+    baz::call_me();
+}
diff --git a/src/test/run-make/coverage/issue-93054.rs b/src/test/run-make/coverage/issue-93054.rs
new file mode 100644 (file)
index 0000000..c160b3d
--- /dev/null
@@ -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() { }
diff --git a/src/test/run-make/coverage/lazy_boolean.rs b/src/test/run-make/coverage/lazy_boolean.rs
new file mode 100644 (file)
index 0000000..bb6219e
--- /dev/null
@@ -0,0 +1,61 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let (mut a, mut b, mut c) = (0, 0, 0);
+    if is_true {
+        a = 1;
+        b = 10;
+        c = 100;
+    }
+    let
+        somebool
+        =
+            a < b
+        ||
+            b < c
+    ;
+    let
+        somebool
+        =
+            b < a
+        ||
+            b < c
+    ;
+    let somebool = a < b && b < c;
+    let somebool = b < a && b < c;
+
+    if
+        !
+        is_true
+    {
+        a = 2
+        ;
+    }
+
+    if
+        is_true
+    {
+        b = 30
+        ;
+    }
+    else
+    {
+        c = 400
+        ;
+    }
+
+    if !is_true {
+        a = 2;
+    }
+
+    if is_true {
+        b = 30;
+    } else {
+        c = 400;
+    }
+}
diff --git a/src/test/run-make/coverage/lib/doctest_crate.rs b/src/test/run-make/coverage/lib/doctest_crate.rs
new file mode 100644 (file)
index 0000000..c321014
--- /dev/null
@@ -0,0 +1,9 @@
+/// A function run only from within doctests
+pub fn fn_run_in_doctests(conditional: usize) {
+    match conditional {
+        1 => assert_eq!(1, 1), // this is run,
+        2 => assert_eq!(1, 1), // this,
+        3 => assert_eq!(1, 1), // and this too
+        _ => assert_eq!(1, 2), // however this is not
+    }
+}
diff --git a/src/test/run-make/coverage/lib/inline_always_with_dead_code.rs b/src/test/run-make/coverage/lib/inline_always_with_dead_code.rs
new file mode 100644 (file)
index 0000000..2b21dee
--- /dev/null
@@ -0,0 +1,22 @@
+// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
+
+#![allow(dead_code)]
+
+mod foo {
+    #[inline(always)]
+    pub fn called() { }
+
+    fn uncalled() { }
+}
+
+pub mod bar {
+    pub fn call_me() {
+        super::foo::called();
+    }
+}
+
+pub mod baz {
+    pub fn call_me() {
+        super::foo::called();
+    }
+}
diff --git a/src/test/run-make/coverage/lib/unused_mod_helper.rs b/src/test/run-make/coverage/lib/unused_mod_helper.rs
new file mode 100644 (file)
index 0000000..ae1cc15
--- /dev/null
@@ -0,0 +1,3 @@
+pub fn never_called_function() {
+    println!("I am never called");
+}
diff --git a/src/test/run-make/coverage/lib/used_crate.rs b/src/test/run-make/coverage/lib/used_crate.rs
new file mode 100644 (file)
index 0000000..8b8b1f7
--- /dev/null
@@ -0,0 +1,100 @@
+#![allow(unused_assignments, unused_variables)]
+// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
+use std::fmt::Debug;
+
+pub fn used_function() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+    use_this_lib_crate();
+}
+
+pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+}
+// Expect for above function: `Unexecuted instantiation` (see below)
+pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+}
+
+pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+}
+
+pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+}
+
+pub fn unused_generic_function<T: Debug>(arg: T) {
+    println!("unused_generic_function with {:?}", arg);
+}
+
+pub fn unused_function() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 2;
+    if !is_true {
+        countdown = 20;
+    }
+}
+
+fn unused_private_function() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 2;
+    if !is_true {
+        countdown = 20;
+    }
+}
+
+fn use_this_lib_crate() {
+    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
+    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+        "used from library used_crate.rs",
+    );
+    let some_vec = vec![5, 6, 7, 8];
+    used_only_from_this_lib_crate_generic_function(some_vec);
+    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
+}
+
+// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
+// for example:
+//
+// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
+//
+// These notices appear when `llvm-cov` shows instantiations. This may be a
+// default option, but it can be suppressed with:
+//
+// ```shell
+// $ `llvm-cov show --show-instantiations=0 ...`
+// ```
+//
+// The notice is triggered because the function is unused by the library itself,
+// and when the library is compiled, a synthetic function is generated, so
+// unused function coverage can be reported. Coverage can be skipped for unused
+// generic functions with:
+//
+// ```shell
+// $ `rustc -Zunstable-options -C instrument-coverage=except-unused-generics ...`
+// ```
+//
+// Even though this function is used by `uses_crate.rs` (and
+// counted), with substitutions for `T`, those instantiations are only generated
+// when the generic function is actually used (from the binary, not from this
+// library crate). So the test result shows coverage for all instantiated
+// versions and their generic type substitutions, plus the `Unexecuted
+// instantiation` message for the non-substituted version. This is valid, but
+// unfortunately a little confusing.
+//
+// The library crate has its own coverage map, and the only way to show unused
+// coverage of a generic function is to include the generic function in the
+// coverage map, marked as an "unused function". If the library were used by
+// another binary that never used this generic function, then it would be valid
+// to show the unused generic, with unknown substitution (`_`).
+//
+// The alternative is to exclude all generics from being included in the "unused
+// functions" list, which would then omit coverage results for
+// `unused_generic_function<T>()`, below.
diff --git a/src/test/run-make/coverage/lib/used_inline_crate.rs b/src/test/run-make/coverage/lib/used_inline_crate.rs
new file mode 100644 (file)
index 0000000..4a05275
--- /dev/null
@@ -0,0 +1,90 @@
+#![allow(unused_assignments, unused_variables)]
+
+// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
+
+use std::fmt::Debug;
+
+pub fn used_function() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+    use_this_lib_crate();
+}
+
+#[inline(always)]
+pub fn used_inline_function() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+    use_this_lib_crate();
+}
+
+
+
+
+
+
+
+#[inline(always)]
+pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+}
+// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
+
+#[inline(always)]
+pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+}
+
+#[inline(always)]
+pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+}
+
+#[inline(always)]
+pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+}
+
+#[inline(always)]
+pub fn unused_generic_function<T: Debug>(arg: T) {
+    println!("unused_generic_function with {:?}", arg);
+}
+
+#[inline(always)]
+pub fn unused_function() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 2;
+    if !is_true {
+        countdown = 20;
+    }
+}
+
+#[inline(always)]
+fn unused_private_function() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 2;
+    if !is_true {
+        countdown = 20;
+    }
+}
+
+fn use_this_lib_crate() {
+    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
+    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+        "used from library used_crate.rs",
+    );
+    let some_vec = vec![5, 6, 7, 8];
+    used_only_from_this_lib_crate_generic_function(some_vec);
+    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
+}
diff --git a/src/test/run-make/coverage/loop_break_value.rs b/src/test/run-make/coverage/loop_break_value.rs
new file mode 100644 (file)
index 0000000..dbc4fad
--- /dev/null
@@ -0,0 +1,13 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    let result
+        =
+            loop
+        {
+            break
+            10
+            ;
+        }
+    ;
+}
diff --git a/src/test/run-make/coverage/loops_branches.rs b/src/test/run-make/coverage/loops_branches.rs
new file mode 100644 (file)
index 0000000..7116ce4
--- /dev/null
@@ -0,0 +1,61 @@
+#![allow(unused_assignments, unused_variables, while_true)]
+
+// This test confirms that (1) unexecuted infinite loops are handled correctly by the
+// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped.
+
+struct DebugTest;
+
+impl std::fmt::Debug for DebugTest {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        if true {
+            if false {
+                while true {
+                }
+            }
+            write!(f, "cool")?;
+        } else {
+        }
+
+        for i in 0..10 {
+            if true {
+                if false {
+                    while true {}
+                }
+                write!(f, "cool")?;
+            } else {
+            }
+        }
+        Ok(())
+    }
+}
+
+struct DisplayTest;
+
+impl std::fmt::Display for DisplayTest {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        if false {
+        } else {
+            if false {
+                while true {}
+            }
+            write!(f, "cool")?;
+        }
+        for i in 0..10 {
+            if false {
+            } else {
+                if false {
+                    while true {}
+                }
+                write!(f, "cool")?;
+            }
+        }
+        Ok(())
+    }
+}
+
+fn main() {
+    let debug_test = DebugTest;
+    println!("{:?}", debug_test);
+    let display_test = DisplayTest;
+    println!("{}", display_test);
+}
diff --git a/src/test/run-make/coverage/match_or_pattern.rs b/src/test/run-make/coverage/match_or_pattern.rs
new file mode 100644 (file)
index 0000000..4c6a8a9
--- /dev/null
@@ -0,0 +1,45 @@
+#![feature(or_patterns)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut a: u8 = 0;
+    let mut b: u8 = 0;
+    if is_true {
+        a = 2;
+        b = 0;
+    }
+    match (a, b) {
+        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
+        // This test confirms a fix for Issue #79569.
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+    if is_true {
+        a = 0;
+        b = 0;
+    }
+    match (a, b) {
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+    if is_true {
+        a = 2;
+        b = 2;
+    }
+    match (a, b) {
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+    if is_true {
+        a = 0;
+        b = 2;
+    }
+    match (a, b) {
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+}
diff --git a/src/test/run-make/coverage/nested_loops.rs b/src/test/run-make/coverage/nested_loops.rs
new file mode 100644 (file)
index 0000000..4c7c784
--- /dev/null
@@ -0,0 +1,25 @@
+fn main() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 10;
+
+    'outer: while countdown > 0 {
+        let mut a = 100;
+        let mut b = 100;
+        for _ in 0..50 {
+            if a < 30 {
+                break;
+            }
+            a -= 5;
+            b -= 5;
+            if b < 90 {
+                a -= 10;
+                if is_true {
+                    break 'outer;
+                } else {
+                    a -= 2;
+                }
+            }
+        }
+        countdown -= 1;
+    }
+}
diff --git a/src/test/run-make/coverage/no_cov_crate.rs b/src/test/run-make/coverage/no_cov_crate.rs
new file mode 100644 (file)
index 0000000..0bfbdda
--- /dev/null
@@ -0,0 +1,86 @@
+// Enables `no_coverage` on the entire crate
+#![feature(no_coverage)]
+
+#[no_coverage]
+fn do_not_add_coverage_1() {
+    println!("called but not covered");
+}
+
+fn do_not_add_coverage_2() {
+    #![no_coverage]
+    println!("called but not covered");
+}
+
+#[no_coverage]
+fn do_not_add_coverage_not_called() {
+    println!("not called and not covered");
+}
+
+fn add_coverage_1() {
+    println!("called and covered");
+}
+
+fn add_coverage_2() {
+    println!("called and covered");
+}
+
+fn add_coverage_not_called() {
+    println!("not called but covered");
+}
+
+// FIXME: These test-cases illustrate confusing results of nested functions.
+// See https://github.com/rust-lang/rust/issues/93319
+mod nested_fns {
+    #[no_coverage]
+    pub fn outer_not_covered(is_true: bool) {
+        fn inner(is_true: bool) {
+            if is_true {
+                println!("called and covered");
+            } else {
+                println!("absolutely not covered");
+            }
+        }
+        println!("called but not covered");
+        inner(is_true);
+    }
+
+    pub fn outer(is_true: bool) {
+        println!("called and covered");
+        inner_not_covered(is_true);
+
+        #[no_coverage]
+        fn inner_not_covered(is_true: bool) {
+            if is_true {
+                println!("called but not covered");
+            } else {
+                println!("absolutely not covered");
+            }
+        }
+    }
+
+    pub fn outer_both_covered(is_true: bool) {
+        println!("called and covered");
+        inner(is_true);
+
+        fn inner(is_true: bool) {
+            if is_true {
+                println!("called and covered");
+            } else {
+                println!("absolutely not covered");
+            }
+        }
+    }
+}
+
+fn main() {
+    let is_true = std::env::args().len() == 1;
+
+    do_not_add_coverage_1();
+    do_not_add_coverage_2();
+    add_coverage_1();
+    add_coverage_2();
+
+    nested_fns::outer_not_covered(is_true);
+    nested_fns::outer(is_true);
+    nested_fns::outer_both_covered(is_true);
+}
diff --git a/src/test/run-make/coverage/overflow.rs b/src/test/run-make/coverage/overflow.rs
new file mode 100644 (file)
index 0000000..e537b0e
--- /dev/null
@@ -0,0 +1,63 @@
+#![allow(unused_assignments)]
+// expect-exit-status-101
+
+fn might_overflow(to_add: u32) -> u32 {
+    if to_add > 5 {
+        println!("this will probably overflow");
+    }
+    let add_to = u32::MAX - 5;
+    println!("does {} + {} overflow?", add_to, to_add);
+    let result = to_add + add_to;
+    println!("continuing after overflow check");
+    result
+}
+
+fn main() -> Result<(),u8> {
+    let mut countdown = 10;
+    while countdown > 0 {
+        if countdown == 1 {
+            let result = might_overflow(10);
+            println!("Result: {}", result);
+        } else if countdown < 5 {
+            let result = might_overflow(1);
+            println!("Result: {}", result);
+        }
+        countdown -= 1;
+    }
+    Ok(())
+}
+
+// Notes:
+//   1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
+//      and similar tests `panic_unwind.rs`, abort.rs` and `try_error_result.rs`.
+//   2. This test confirms the coverage generated when a program passes or fails a
+//      compiler-generated `TerminatorKind::Assert` (based on an overflow check, in this case).
+//   3. Similar to how the coverage instrumentation handles `TerminatorKind::Call`,
+//      compiler-generated assertion failures are assumed to be a symptom of a program bug, not
+//      expected behavior. To simplify the coverage graphs and keep instrumented programs as
+//      small and fast as possible, `Assert` terminators are assumed to always succeed, and
+//      therefore are considered "non-branching" terminators. So, an `Assert` terminator does not
+//      get its own coverage counter.
+//   4. After an unhandled panic or failed Assert, coverage results may not always be intuitive.
+//      In this test, the final count for the statements after the `if` block in `might_overflow()`
+//      is 4, even though the lines after `to_add + add_to` were executed only 3 times. Depending
+//      on the MIR graph and the structure of the code, this count could have been 3 (which might
+//      have been valid for the overflowed add `+`, but should have been 4 for the lines before
+//      the overflow. The reason for this potential uncertainty is, a `CounterKind` is incremented
+//      via StatementKind::Counter at the end of the block, but (as in the case in this test),
+//      a CounterKind::Expression is always evaluated. In this case, the expression was based on
+//      a `Counter` incremented as part of the evaluation of the `if` expression, which was
+//      executed, and counted, 4 times, before reaching the overflow add.
+
+// If the program did not overflow, the coverage for `might_overflow()` would look like this:
+//
+//     4|       |fn might_overflow(to_add: u32) -> u32 {
+//     5|      4|    if to_add > 5 {
+//     6|      0|        println!("this will probably overflow");
+//     7|      4|    }
+//     8|      4|    let add_to = u32::MAX - 5;
+//     9|      4|    println!("does {} + {} overflow?", add_to, to_add);
+//    10|      4|    let result = to_add + add_to;
+//    11|      4|    println!("continuing after overflow check");
+//    12|      4|    result
+//    13|      4|}
diff --git a/src/test/run-make/coverage/panic_unwind.rs b/src/test/run-make/coverage/panic_unwind.rs
new file mode 100644 (file)
index 0000000..03128c2
--- /dev/null
@@ -0,0 +1,31 @@
+#![allow(unused_assignments)]
+// expect-exit-status-101
+
+fn might_panic(should_panic: bool) {
+    if should_panic {
+        println!("panicking...");
+        panic!("panics");
+    } else {
+        println!("Don't Panic");
+    }
+}
+
+fn main() -> Result<(), u8> {
+    let mut countdown = 10;
+    while countdown > 0 {
+        if countdown == 1 {
+            might_panic(true);
+        } else if countdown < 5 {
+            might_panic(false);
+        }
+        countdown -= 1;
+    }
+    Ok(())
+}
+
+// Notes:
+//   1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
+//      `try_error_result.rs`.
+//   2. Since the `panic_unwind.rs` test is allowed to unwind, it is also allowed to execute the
+//      normal program exit cleanup, including writing out the current values of the coverage
+//      counters.
diff --git a/src/test/run-make/coverage/partial_eq.rs b/src/test/run-make/coverage/partial_eq.rs
new file mode 100644 (file)
index 0000000..4ceaba9
--- /dev/null
@@ -0,0 +1,46 @@
+// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
+// structure of this test.
+
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Version {
+    major: usize,
+    minor: usize,
+    patch: usize,
+}
+
+impl Version {
+    pub fn new(major: usize, minor: usize, patch: usize) -> Self {
+        Self {
+            major,
+            minor,
+            patch,
+        }
+    }
+}
+
+fn main() {
+    let version_3_2_1 = Version::new(3, 2, 1);
+    let version_3_3_0 = Version::new(3, 3, 0);
+
+    println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0);
+}
+
+/*
+
+This test verifies a bug was fixed that otherwise generated this error:
+
+thread 'rustc' panicked at 'No counters provided the source_hash for function:
+    Instance {
+        def: Item(WithOptConstParam {
+            did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp),
+            const_param_did: None
+        }),
+        substs: []
+    }'
+The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage
+without a code region associated with any `Counter`. Code regions were associated with at least
+one expression, which is allowed, but the `function_source_hash` was only passed to the codegen
+(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the
+`function_source_hash` without a code region, if necessary.
+
+*/
diff --git a/src/test/run-make/coverage/simple_loop.rs b/src/test/run-make/coverage/simple_loop.rs
new file mode 100644 (file)
index 0000000..6f7f234
--- /dev/null
@@ -0,0 +1,35 @@
+#![allow(unused_assignments)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+
+    if
+        is_true
+    {
+        countdown
+        =
+            10
+        ;
+    }
+
+    loop
+    {
+        if
+            countdown
+                ==
+            0
+        {
+            break
+            ;
+        }
+        countdown
+        -=
+        1
+        ;
+    }
+}
diff --git a/src/test/run-make/coverage/simple_match.rs b/src/test/run-make/coverage/simple_match.rs
new file mode 100644 (file)
index 0000000..be99e59
--- /dev/null
@@ -0,0 +1,43 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 1;
+    if is_true {
+        countdown = 0;
+    }
+
+    for
+        _
+    in
+        0..2
+    {
+        let z
+        ;
+        match
+            countdown
+        {
+            x
+            if
+                x
+                    <
+                1
+            =>
+            {
+                z = countdown
+                ;
+                let y = countdown
+                ;
+                countdown = 10
+                ;
+            }
+            _
+            =>
+            {}
+        }
+    }
+}
diff --git a/src/test/run-make/coverage/tight_inf_loop.rs b/src/test/run-make/coverage/tight_inf_loop.rs
new file mode 100644 (file)
index 0000000..cef9902
--- /dev/null
@@ -0,0 +1,5 @@
+fn main() {
+    if false {
+        loop {}
+    }
+}
diff --git a/src/test/run-make/coverage/try_error_result.rs b/src/test/run-make/coverage/try_error_result.rs
new file mode 100644 (file)
index 0000000..cd0acf7
--- /dev/null
@@ -0,0 +1,118 @@
+#![allow(unused_assignments)]
+// expect-exit-status-1
+
+fn call(return_error: bool) -> Result<(),()> {
+    if return_error {
+        Err(())
+    } else {
+        Ok(())
+    }
+}
+
+fn test1() -> Result<(),()> {
+    let mut
+        countdown = 10
+    ;
+    for
+        _
+    in
+        0..10
+    {
+        countdown
+            -= 1
+        ;
+        if
+            countdown < 5
+        {
+            call(/*return_error=*/ true)?;
+            call(/*return_error=*/ false)?;
+        }
+        else
+        {
+            call(/*return_error=*/ false)?;
+        }
+    }
+    Ok(())
+}
+
+struct Thing1;
+impl Thing1 {
+    fn get_thing_2(&self, return_error: bool) -> Result<Thing2,()> {
+        if return_error {
+            Err(())
+        } else {
+            Ok(Thing2{})
+        }
+    }
+}
+
+struct Thing2;
+impl Thing2 {
+    fn call(&self, return_error: bool) -> Result<u32,()> {
+        if return_error {
+            Err(())
+        } else {
+            Ok(57)
+        }
+    }
+}
+
+fn test2() -> Result<(),()> {
+    let thing1 = Thing1{};
+    let mut
+        countdown = 10
+    ;
+    for
+        _
+    in
+        0..10
+    {
+        countdown
+            -= 1
+        ;
+        if
+            countdown < 5
+        {
+            thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
+            thing1
+                .
+                get_thing_2(/*return_error=*/ false)
+                ?
+                .
+                call(/*return_error=*/ true)
+                .
+                expect_err(
+                    "call should fail"
+                );
+            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ true)?;
+            assert_eq!(val, 57);
+            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ false)?;
+            assert_eq!(val, 57);
+        }
+        else
+        {
+            let val = thing1.get_thing_2(/*return_error=*/ false)?.call(/*return_error=*/ false)?;
+            assert_eq!(val, 57);
+            let val = thing1
+                .get_thing_2(/*return_error=*/ false)?
+                .call(/*return_error=*/ false)?;
+            assert_eq!(val, 57);
+            let val = thing1
+                .get_thing_2(/*return_error=*/ false)
+                ?
+                .call(/*return_error=*/ false)
+                ?
+                ;
+            assert_eq!(val, 57);
+        }
+    }
+    Ok(())
+}
+
+fn main() -> Result<(),()> {
+    test1().expect_err("test1 should fail");
+    test2()
+    ?
+    ;
+    Ok(())
+}
diff --git a/src/test/run-make/coverage/unused.rs b/src/test/run-make/coverage/unused.rs
new file mode 100644 (file)
index 0000000..fb6113e
--- /dev/null
@@ -0,0 +1,39 @@
+fn foo<T>(x: T) {
+    let mut i = 0;
+    while i < 10 {
+        i != 0 || i != 0;
+        i += 1;
+    }
+}
+
+fn unused_template_func<T>(x: T) {
+    let mut i = 0;
+    while i < 10 {
+        i != 0 || i != 0;
+        i += 1;
+    }
+}
+
+fn unused_func(mut a: u32) {
+    if a != 0 {
+        a += 1;
+    }
+}
+
+fn unused_func2(mut a: u32) {
+    if a != 0 {
+        a += 1;
+    }
+}
+
+fn unused_func3(mut a: u32) {
+    if a != 0 {
+        a += 1;
+    }
+}
+
+fn main() -> Result<(), u8> {
+    foo::<u32>(0);
+    foo::<f32>(0.0);
+    Ok(())
+}
diff --git a/src/test/run-make/coverage/unused_mod.rs b/src/test/run-make/coverage/unused_mod.rs
new file mode 100644 (file)
index 0000000..679b4e5
--- /dev/null
@@ -0,0 +1,6 @@
+#[path = "lib/unused_mod_helper.rs"]
+mod unused_module;
+
+fn main() {
+    println!("hello world!");
+}
diff --git a/src/test/run-make/coverage/uses_crate.rs b/src/test/run-make/coverage/uses_crate.rs
new file mode 100644 (file)
index 0000000..20cb05f
--- /dev/null
@@ -0,0 +1,12 @@
+#![allow(unused_assignments, unused_variables)]
+// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
+extern crate used_crate;
+
+fn main() {
+    used_crate::used_function();
+    let some_vec = vec![1, 2, 3, 4];
+    used_crate::used_only_from_bin_crate_generic_function(&some_vec);
+    used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
+    used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
+    used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");
+}
diff --git a/src/test/run-make/coverage/uses_inline_crate.rs b/src/test/run-make/coverage/uses_inline_crate.rs
new file mode 100644 (file)
index 0000000..a7fe853
--- /dev/null
@@ -0,0 +1,17 @@
+#![allow(unused_assignments, unused_variables)]
+
+// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
+
+extern crate used_inline_crate;
+
+fn main() {
+    used_inline_crate::used_function();
+    used_inline_crate::used_inline_function();
+    let some_vec = vec![1, 2, 3, 4];
+    used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec);
+    used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
+    used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
+    used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+        "interesting?",
+    );
+}
diff --git a/src/test/run-make/coverage/while.rs b/src/test/run-make/coverage/while.rs
new file mode 100644 (file)
index 0000000..781b90b
--- /dev/null
@@ -0,0 +1,5 @@
+fn main() {
+    let num = 9;
+    while num >= 10 {
+    }
+}
diff --git a/src/test/run-make/coverage/while_early_ret.rs b/src/test/run-make/coverage/while_early_ret.rs
new file mode 100644 (file)
index 0000000..1fcea9c
--- /dev/null
@@ -0,0 +1,42 @@
+#![allow(unused_assignments)]
+// expect-exit-status-1
+
+fn main() -> Result<(),u8> {
+    let mut countdown = 10;
+    while
+        countdown
+            >
+        0
+    {
+        if
+            countdown
+                <
+            5
+        {
+            return
+                if
+                    countdown
+                        >
+                    8
+                {
+                    Ok(())
+                }
+                else
+                {
+                    Err(1)
+                }
+                ;
+        }
+        countdown
+            -=
+        1
+        ;
+    }
+    Ok(())
+}
+
+// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and
+// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux
+// and MacOS. But on Windows (MSVC, at least), the call to `std::process::exit()` exits the program
+// without saving the InstrProf coverage counters. The use of `std::process:exit()` is not critical
+// to the coverage test for early returns, but this is a limitation that should be fixed.
diff --git a/src/test/run-make/coverage/yield.rs b/src/test/run-make/coverage/yield.rs
new file mode 100644 (file)
index 0000000..ff76166
--- /dev/null
@@ -0,0 +1,37 @@
+#![feature(generators, generator_trait)]
+#![allow(unused_assignments)]
+
+use std::ops::{Generator, GeneratorState};
+use std::pin::Pin;
+
+fn main() {
+    let mut generator = || {
+        yield 1;
+        return "foo"
+    };
+
+    match Pin::new(&mut generator).resume(()) {
+        GeneratorState::Yielded(1) => {}
+        _ => panic!("unexpected value from resume"),
+    }
+    match Pin::new(&mut generator).resume(()) {
+        GeneratorState::Complete("foo") => {}
+        _ => panic!("unexpected value from resume"),
+    }
+
+    let mut generator = || {
+        yield 1;
+        yield 2;
+        yield 3;
+        return "foo"
+    };
+
+    match Pin::new(&mut generator).resume(()) {
+        GeneratorState::Yielded(1) => {}
+        _ => panic!("unexpected value from resume"),
+    }
+    match Pin::new(&mut generator).resume(()) {
+        GeneratorState::Yielded(2) => {}
+        _ => panic!("unexpected value from resume"),
+    }
+}