Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --code from glacier <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Reduced from another code sample: `
- Thanks for the ICE report, and the reduced code sample! - The reduced sample produces a couple of MIR that make it to PreCodegen, one of which is: And you can see that there are two different counters with ID "1". Most likely, is merging one MIR into another, or something like that, combining counters from different "functions". The output (shown above in this issue) shows the new warning that I recently : Until seeing this post, I wasn't aware that might also break coverage altogether (and cause an ICE). I don't believe we should be trying to support this option combination. I can replace the warning with an error (and update the message to say they are incompatible, or something like that). For this type of problem, I think the failed assertion is still valid (the MIR is invalid), and it is better to fail on the option combination, rather than try to gracefully recover somehow. WDYT?
Yeah it looks like was inlined which is where one of the counters came from. Is there anyway we could the MIR inliner to support handling coverage statements? For example, could we renumber the counter ids so they are unique again? If that is infeasible, we should probably just have the inline pass disable itself if code coverage is enabled. Yeah, I agree! It seems like it will be easier for us to diagnose the ICE than to try to figure out why coverage data is missing or behaving incorrectly.
Update: The solution implemented by is different from what we initially agreed on. More detail can be found in the PR discussion, but to be more future-proof, we didn't want to disable everything at the same that enables inlining. That means 2 is allowed with , but the pass is disabled, regardless of the level. If inlining is ever moved to 1 (the default), inlining will still be disabled. If a non-default is specified, a warning is generated to inform the developer that inlining is not enabled by that change. (The warning will not be displayed if inlining is moved to the default (1) level in the future.) As noted in the PR discussion, I don't believe it's worth trying to hack around the LLVM instrprof expectation that each function actually be an LLVM function. Source-based coverage is not meant for production code, so disabling inlining seems like a much better way to address the problem; and now that it only affects the inlining part, it still allows for other optimizations, which is an improvement (in addition to preventing the ICE). Lastly, I would stress that there may (or may not) still be other compiler flags and/or other optimizations that are found to be incompatible with LLVM Instrprof coverage, as implemented. But the test in this issue does now work, with 2 enabled.

Discussion:
return; } <ins> if tcx.sess.opts.debugging_opts.instrument_coverage { // Since `Inline` happens after `InstrumentCoverage`, the function-specific coverage // counters can be invalidated, such as by merging coverage counter statements from // a pre-inlined function into a different function. This kind of change is invalid, // so inlining must be skipped. Note: This check is performed here so inlining can // be disabled without preventing other optimizations (regardless of `mir_opt_level`). return; } </ins> if inline(tcx, body) { debug!("running simplify cfg on {:?}", body.source); CfgSimplifier::new(body).simplify();

} if debugging_opts.mir_opt_level > 1 { <ins> // Functions inlined during MIR transform can, at best, make it impossible to // effectively cover inlined functions, and, at worst, break coverage map generation // during LLVM codegen. For example, function counter IDs are only unique within a // function. Inlining after these counters are injected can produce duplicate counters, // resulting in an invalid coverage map (and ICE); so this option combination is not // allowed. </ins> early_warn( error_format, &format!( <del> "`-Z mir-opt-level={}` (any level > 1) enables function inlining, which  limits the effectiveness of `-Z instrument-coverage`.", </del> <ins> "`-Z mir-opt-level={}` (or any level > 1) enables function inlining, which  is incompatible with `-Z instrument-coverage`. Inlining will be disabled.", </ins> debugging_opts.mir_opt_level, ), );

20|       |//! 21|       |//! doctest returning a result: 22|      1|//! ``` <del> 23|      1|//! #[derive(Debug)] 24|      1|//! struct SomeError; 25|      1|//! let mut res = Err(SomeError); 26|      1|//! if res.is_ok() { 27|      0|//!   res?; 28|      1|//! } else { 29|      1|//!   res = Ok(0); 30|      1|//! } 31|       |//! // need to be explicit because rustdoc cant infer the return type 32|      1|//! Ok::<(), SomeError>(()) 33|      1|//! ``` 34|       |//! 35|       |//! doctest with custom main: 36|       |//! ``` 37|       |//! #[derive(Debug)] 38|       |//! struct SomeError; 39|       |//! 40|       |//! extern crate doctest_crate; 41|       |//! 42|      1|//! fn doctest_main() -> Result<(), SomeError> { 43|      1|//!     doctest_crate::fn_run_in_doctests(2); 44|      1|//!     Ok(()) 45|      1|//! } 46|       |//! 47|       |//! // this `main` is not shown as covered, as it clashes with all the other 48|       |//! // `main` functions that were automatically generated for doctests 49|       |//! fn main() -> Result<(), SomeError> { 50|       |//!     doctest_main() 51|       |//! } 52|       |//! ``` 53|       | 54|       |/// doctest attached to fn testing external code: 55|       |/// ``` 56|      1|/// extern crate doctest_crate; 57|      1|/// doctest_crate::fn_run_in_doctests(3); 58|      1|/// ``` 59|       |/// 60|      1|fn main() { 61|      1|    if true { 62|      1|        assert_eq!(1, 1); 63|       |    } else { 64|       |        assert_eq!(1, 2); 65|       |    } 66|      1|} </del> <ins> 23|      2|//! #[derive(Debug, PartialEq)] ^1 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|       |//! #[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|       |        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. </ins> ../coverage/lib/doctest_crate.rs: 1|       |/// A function run only from within doctests

</style> </head> <body> <del> <div class="code" style="counter-reset: line 59"><span class="line"><span><span class="code even" style="--layer: 1"><span class="annotation">@0⦊</span>fn main() <span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0">{</span></span> <span class="line"><span class="code" style="--layer: 0">    if </span><span><span class="code even" style="--layer: 1" title="61:8-61:12: @0[1]: _1 = const true 61:8-61:12: @0[2]: FakeRead(ForMatchedPlace, _1)"><span class="annotation">@0⦊</span>true<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0"> {</span></span> <span class="line"><span class="code" style="--layer: 0">        </span><span><span class="code odd" style="--layer: 1" title="62:9-62:26: @5[0]: _2 = const ()"><span class="annotation">@5⦊</span></span></span><span class="code even" style="--layer: 2" title="62:9-62:26: @6[5]: _75 = const main::promoted[3] 62:9-62:26: @6[6]: _18 = &amp;(*_75) 62:9-62:26: @6[7]: _17 = &amp;(*_18) 62:9-62:26: @6[8]: _16 = move _17 as &amp;[&amp;str] (Pointer(Unsize)) 62:9-62:26: @6[17]: _26 = &amp;(*_8) 62:9-62:26: @6[18]: _25 = &amp;_26 62:9-62:26: @6[21]: _28 = &amp;(*_9) 62:9-62:26: @6[22]: _27 = &amp;_28 62:9-62:26: @6[23]: _24 = (move _25, move _27) 62:9-62:26: @6[26]: FakeRead(ForMatchedPlace, _24) 62:9-62:26: @6[28]: _29 = (_24.0: &amp;&amp;i32) 62:9-62:26: @6[30]: _30 = (_24.1: &amp;&amp;i32) 62:9-62:26: @6[33]: _32 = &amp;(*_29) 62:9-62:26: @6[35]: _33 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer)) 62:9-62:26: @6.Call: _31 = ArgumentV1::new::&lt;&amp;i32&gt;(move _32, move _33) -&gt; [return: bb7, unwind: bb17] 62:9-62:26: @7[4]: _35 = &amp;(*_30) 62:9-62:26: @7[6]: _36 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer)) 62:9-62:26: @7.Call: _34 = ArgumentV1::new::&lt;&amp;i32&gt;(move _35, move _36) -&gt; [return: bb8, unwind: bb17] 62:9-62:26: @8[2]: _23 = [move _31, move _34] 62:9-62:26: @8[7]: _22 = &amp;_23 62:9-62:26: @8[8]: _21 = &amp;(*_22) 62:9-62:26: @8[9]: _20 = move _21 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize)) 62:9-62:26: @8.Call: _15 = Arguments::new_v1(move _16, move _20) -&gt; [return: bb9, unwind: bb17] 62:9-62:26: @9.Call: core::panicking::panic_fmt(move _15) -&gt; bb17"><span class="annotation">@4,6,7,8,9⦊</span>assert_eq!(1, 1);<span class="annotation">⦉@4,6,7,8,9</span></span><span><span class="code odd" style="--layer: 1" title="62:9-62:26: @5[0]: _2 = const ()"><span class="annotation">⦉@5</span></span></span><span class="code" style="--layer: 0"></span></span> </del> <ins> <div class="code" style="counter-reset: line 72"><span class="line"><span><span class="code even" style="--layer: 1"><span class="annotation">@0⦊</span>fn main() <span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0">{</span></span> <span class="line"><span class="code" style="--layer: 0">    if </span><span><span class="code even" style="--layer: 1" title="74:8-74:12: @0[1]: _1 = const true 74:8-74:12: @0[2]: FakeRead(ForMatchedPlace, _1)"><span class="annotation">@0⦊</span>true<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0"> {</span></span> <span class="line"><span class="code" style="--layer: 0">        </span><span><span class="code odd" style="--layer: 1" title="75:9-75:26: @5[0]: _2 = const ()"><span class="annotation">@5⦊</span></span></span><span class="code even" style="--layer: 2" title="75:9-75:26: @6[5]: _75 = const main::promoted[3] 75:9-75:26: @6[6]: _18 = &amp;(*_75) 75:9-75:26: @6[7]: _17 = &amp;(*_18) 75:9-75:26: @6[8]: _16 = move _17 as &amp;[&amp;str] (Pointer(Unsize)) 75:9-75:26: @6[17]: _26 = &amp;(*_8) 75:9-75:26: @6[18]: _25 = &amp;_26 75:9-75:26: @6[21]: _28 = &amp;(*_9) 75:9-75:26: @6[22]: _27 = &amp;_28 75:9-75:26: @6[23]: _24 = (move _25, move _27) 75:9-75:26: @6[26]: FakeRead(ForMatchedPlace, _24) 75:9-75:26: @6[28]: _29 = (_24.0: &amp;&amp;i32) 75:9-75:26: @6[30]: _30 = (_24.1: &amp;&amp;i32) 75:9-75:26: @6[33]: _32 = &amp;(*_29) 75:9-75:26: @6[35]: _33 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer)) 75:9-75:26: @6.Call: _31 = ArgumentV1::new::&lt;&amp;i32&gt;(move _32, move _33) -&gt; [return: bb7, unwind: bb17] 75:9-75:26: @7[4]: _35 = &amp;(*_30) 75:9-75:26: @7[6]: _36 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer)) 75:9-75:26: @7.Call: _34 = ArgumentV1::new::&lt;&amp;i32&gt;(move _35, move _36) -&gt; [return: bb8, unwind: bb17] 75:9-75:26: @8[2]: _23 = [move _31, move _34] 75:9-75:26: @8[7]: _22 = &amp;_23 75:9-75:26: @8[8]: _21 = &amp;(*_22) 75:9-75:26: @8[9]: _20 = move _21 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize)) 75:9-75:26: @8.Call: _15 = Arguments::new_v1(move _16, move _20) -&gt; [return: bb9, unwind: bb17] 75:9-75:26: @9.Call: core::panicking::panic_fmt(move _15) -&gt; bb17"><span class="annotation">@4,6,7,8,9⦊</span>assert_eq!(1, 1);<span class="annotation">⦉@4,6,7,8,9</span></span><span><span class="code odd" style="--layer: 1" title="75:9-75:26: @5[0]: _2 = const ()"><span class="annotation">⦉@5</span></span></span><span class="code" style="--layer: 0"></span></span> </ins> <span class="line"><span class="code" style="--layer: 0">    } else {</span></span> <del> <span class="line"><span class="code" style="--layer: 0">        </span><span><span class="code even" style="--layer: 1" title="64:9-64:26: @11[0]: _37 = const ()"><span class="annotation">@11⦊</span></span></span><span class="code even" style="--layer: 2" title="64:9-64:26: @12[5]: _72 = const main::promoted[0] 64:9-64:26: @12[6]: _53 = &amp;(*_72) 64:9-64:26: @12[7]: _52 = &amp;(*_53) 64:9-64:26: @12[8]: _51 = move _52 as &amp;[&amp;str] (Pointer(Unsize)) 64:9-64:26: @12[17]: _61 = &amp;(*_43) 64:9-64:26: @12[18]: _60 = &amp;_61 64:9-64:26: @12[21]: _63 = &amp;(*_44) 64:9-64:26: @12[22]: _62 = &amp;_63 64:9-64:26: @12[23]: _59 = (move _60, move _62) 64:9-64:26: @12[26]: FakeRead(ForMatchedPlace, _59) 64:9-64:26: @12[28]: _64 = (_59.0: &amp;&amp;i32) 64:9-64:26: @12[30]: _65 = (_59.1: &amp;&amp;i32) 64:9-64:26: @12[33]: _67 = &amp;(*_64) 64:9-64:26: @12[35]: _68 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer)) 64:9-64:26: @12.Call: _66 = ArgumentV1::new::&lt;&amp;i32&gt;(move _67, move _68) -&gt; [return: bb13, unwind: bb17] 64:9-64:26: @13[4]: _70 = &amp;(*_65) 64:9-64:26: @13[6]: _71 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer)) 64:9-64:26: @13.Call: _69 = ArgumentV1::new::&lt;&amp;i32&gt;(move _70, move _71) -&gt; [return: bb14, unwind: bb17] 64:9-64:26: @14[2]: _58 = [move _66, move _69] 64:9-64:26: @14[7]: _57 = &amp;_58 64:9-64:26: @14[8]: _56 = &amp;(*_57) 64:9-64:26: @14[9]: _55 = move _56 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize)) 64:9-64:26: @14.Call: _50 = Arguments::new_v1(move _51, move _55) -&gt; [return: bb15, unwind: bb17] 64:9-64:26: @15.Call: core::panicking::panic_fmt(move _50) -&gt; bb17"><span class="annotation">@10,12,13,14,15⦊</span>assert_eq!(1, 2);<span class="annotation">⦉@10,12,13,14,15</span></span><span><span class="code even" style="--layer: 1" title="64:9-64:26: @11[0]: _37 = const ()"><span class="annotation">⦉@11</span></span></span><span class="code" style="--layer: 0"></span></span> </del> <ins> <span class="line"><span class="code" style="--layer: 0">        </span><span><span class="code even" style="--layer: 1" title="77:9-77:26: @11[0]: _37 = const ()"><span class="annotation">@11⦊</span></span></span><span class="code even" style="--layer: 2" title="77:9-77:26: @12[5]: _72 = const main::promoted[0] 77:9-77:26: @12[6]: _53 = &amp;(*_72) 77:9-77:26: @12[7]: _52 = &amp;(*_53) 77:9-77:26: @12[8]: _51 = move _52 as &amp;[&amp;str] (Pointer(Unsize)) 77:9-77:26: @12[17]: _61 = &amp;(*_43) 77:9-77:26: @12[18]: _60 = &amp;_61 77:9-77:26: @12[21]: _63 = &amp;(*_44) 77:9-77:26: @12[22]: _62 = &amp;_63 77:9-77:26: @12[23]: _59 = (move _60, move _62) 77:9-77:26: @12[26]: FakeRead(ForMatchedPlace, _59) 77:9-77:26: @12[28]: _64 = (_59.0: &amp;&amp;i32) 77:9-77:26: @12[30]: _65 = (_59.1: &amp;&amp;i32) 77:9-77:26: @12[33]: _67 = &amp;(*_64) 77:9-77:26: @12[35]: _68 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer)) 77:9-77:26: @12.Call: _66 = ArgumentV1::new::&lt;&amp;i32&gt;(move _67, move _68) -&gt; [return: bb13, unwind: bb17] 77:9-77:26: @13[4]: _70 = &amp;(*_65) 77:9-77:26: @13[6]: _71 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer)) 77:9-77:26: @13.Call: _69 = ArgumentV1::new::&lt;&amp;i32&gt;(move _70, move _71) -&gt; [return: bb14, unwind: bb17] 77:9-77:26: @14[2]: _58 = [move _66, move _69] 77:9-77:26: @14[7]: _57 = &amp;_58 77:9-77:26: @14[8]: _56 = &amp;(*_57) 77:9-77:26: @14[9]: _55 = move _56 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize)) 77:9-77:26: @14.Call: _50 = Arguments::new_v1(move _51, move _55) -&gt; [return: bb15, unwind: bb17] 77:9-77:26: @15.Call: core::panicking::panic_fmt(move _50) -&gt; bb17"><span class="annotation">@10,12,13,14,15⦊</span>assert_eq!(1, 2);<span class="annotation">⦉@10,12,13,14,15</span></span><span><span class="code even" style="--layer: 1" title="77:9-77:26: @11[0]: _37 = const ()"><span class="annotation">⦉@11</span></span></span><span class="code" style="--layer: 0"></span></span> </ins> <span class="line"><span class="code" style="--layer: 0">    }</span></span> <del> <span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="66:2-66:2: @16.Return: return"><span class="annotation">@16⦊</span>‸<span class="annotation">⦉@16</span></span></span></span></div> </del> <ins> <span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="79:2-79:2: @16.Return: return"><span class="annotation">@16⦊</span>‸<span class="annotation">⦉@16</span></span></span></span></div> </ins> </body> </html>

//! //! doctest returning a result: //! ``` <del> //! #[derive(Debug)] //! struct SomeError; //! let mut res = Err(SomeError); </del> <ins> //! #[derive(Debug, PartialEq)] //! struct SomeError { //!     msg: String, //! } //! let mut res = Err(SomeError { msg: String::from("a message") }); </ins> //! if res.is_ok() { <del> //!   res?; </del> <ins> //!     res?; </ins> //! } else { <del> //!   res = Ok(0); </del> <ins> //!     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); </ins> //! } //! // need to be explicit because rustdoc cant infer the return type //! Ok::<(), SomeError>(())

//! //! doctest with custom main: //! ``` <ins> //! fn some_func() { //!     println!("called some_func()"); //! } //! </ins> //! #[derive(Debug)] //! struct SomeError; //! //! extern crate doctest_crate; //! //! fn doctest_main() -> Result<(), SomeError> { <ins> //!     some_func(); </ins> //!     doctest_crate::fn_run_in_doctests(2); //!     Ok(()) //! }

assert_eq!(1, 2); } } <ins> // 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. </ins>

<ins> // Ensures -Zmir-opt-level=2 (specifically, inlining) is not allowed with -Zinstrument-coverage. // Regression test for issue #80060. // // needs-profiler-support // build-pass // compile-flags: -Zmir-opt-level=2 -Zinstrument-coverage #[inline(never)] fn foo() {} pub fn baz() { bar(); } #[inline(always)] fn bar() { foo(); } fn main() { bar(); } </ins>

<ins> warning: `-Z mir-opt-level=2` (or any level > 1) enables function inlining, which is incompatible with `-Z instrument-coverage`. Inlining will be disabled. </ins>