Change:
//! //! 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(()) //! }

Discussion:
<!-- 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.