Change:
When compiling a testcase (e.g. the last snippet in on the current nightly, or any of the other examples in that issue on older compilers) with (or Cargo which does that by default), only the initial run will ICE. Subsequent runs will succeed without an ICE, in the absence of any regular errors. However, changing the relevant code (e.g. adding a space) can cause the query that calls to be recomputed and bring the ICE back. IIUC, incremental compilation stores diagnostics and replays them on subsequent runs, but that appears to not apply to ICEs. cc
It looks like without incremental we output artifacts (like ). Do we do this in case of errors too? It seems bad to produce artifacts after an ICE.
Nominating and proposing P-high (mostly because of potential annoyance factor). This should possibly also be labeled I-unsound under the assumption that under the general case of this issue, we might produce artifacts under subsequent runs that may produce UB traces. (However, it is probable that the user will notice the ICE at some other point in time and therefore discard the artifact.)
The current expected behavior of the compiler is to not save any incremental state if an error occurs. may slip through the cracks here.
In that case, it seems to me like it's a matter of recording the fact that we did a (which we already do, ) and then have this mean "there was an error" in terms of "should we save incremental state?".
Yep, the following check should also take into account: While we are at it, we could also add a similar check to and , as not to waste time producing values that will then be discarded anyway:
I'd like to start contributing to rustc and I wanted to ask if this is a good issue to start on (I have read the rustc book)
Sure, this is a decently good issue to start on and should be pretty interesting in terms of learning the infrastructure. If you get stuck, need help, and want to talk synchronously you can hop into https://rust- and we'll try to help out.
fixes this issue. It would still be good to have a test case for it.
I have started to write the code making this test possible, I'll open a PR shortly

Discussion:
pub fn has_errors(&self) -> bool { self.diagnostic().has_errors() } <ins> pub fn has_errors_or_delayed_span_bugs(&self) -> bool { self.diagnostic().has_errors_or_delayed_span_bugs() } </ins> pub fn abort_if_errors(&self) { self.diagnostic().abort_if_errors(); }

pub fn has_errors(&self) -> bool { self.inner.borrow().has_errors() } <ins> pub fn has_errors_or_delayed_span_bugs(&self) -> bool { self.inner.borrow().has_errors_or_delayed_span_bugs() } </ins> pub fn print_error_count(&self, registry: &Registry) { self.inner.borrow_mut().print_error_count(registry)

fn has_errors(&self) -> bool { self.err_count() > 0 } <ins> fn has_errors_or_delayed_span_bugs(&self) -> bool { self.has_errors() || !self.delayed_span_bugs.is_empty() } </ins> fn abort_if_errors_and_should_abort(&mut self) { self.emit_stashed_diagnostics();

let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone(); <del> if sess.has_errors() { </del> <ins> if sess.has_errors_or_delayed_span_bugs() { </ins> // If there have been any errors during compilation, we don't want to // publish this session directory. Rather, we'll just delete it.

if sess.opts.incremental.is_none() { return; } <ins> // This is going to be deleted in finalize_session_directory, so let's not create it if sess.has_errors_or_delayed_span_bugs() { return; } </ins> let query_cache_path = query_cache_path(sess); let dep_graph_path = dep_graph_path(sess);

if sess.opts.incremental.is_none() { return; } <ins> // This is going to be deleted in finalize_session_directory, so let's not create it if sess.has_errors_or_delayed_span_bugs() { return; } </ins> debug!("save_work_product_index()"); dep_graph.assert_ignored();