diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b03352d5fec..9ed31d9419c 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -973,6 +973,7 @@ impl Handler { self.inner.borrow_mut().span_bug(span, msg) } + /// For documentation on this, see `Session::delay_span_bug`. #[track_caller] pub fn delay_span_bug( &self, @@ -1518,6 +1519,7 @@ impl HandlerInner { self.emit_diagnostic(diag.set_span(sp)); } + /// For documentation on this, see `Session::delay_span_bug`. #[track_caller] fn delay_span_bug( &mut self, diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 01fe72de612..5ca4d260179 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -1,3 +1,13 @@ +/// A macro for triggering an ICE. +/// Calling `bug` instead of panicking will result in a nicer error message and should +/// therefore be prefered over `panic`/`unreachable` or others. +/// +/// If you have a span available, you should use [`span_bug`] instead. +/// +/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful. +/// +/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug +/// [`span_bug`]: crate::span_bug #[macro_export] macro_rules! bug { () => ( $crate::bug!("impossible case reached") ); @@ -8,6 +18,14 @@ macro_rules! bug { }); } +/// A macro for triggering an ICE with a span. +/// Calling `span_bug!` instead of panicking will result in a nicer error message and point +/// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger +/// ICEs. +/// +/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful. +/// +/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug #[macro_export] macro_rules! span_bug { ($span:expr, $msg:expr) => ({ $crate::util::bug::span_bug_fmt($span, ::std::format_args!($msg)) }); diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index fd7045d6a03..b73ae593905 100644 --- a/compiler/rustc_middle/src/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs @@ -35,8 +35,7 @@ fn opt_span_bug_fmt>( (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg), (None, _) => panic_any(msg), } - }); - unreachable!(); + }) } /// A query to trigger a `delay_span_bug`. Clearly, if one has a `tcx` one can already trigger a diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 4a3d29414d6..1b2e8d9dc70 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -590,7 +590,19 @@ impl Session { pub fn warn(&self, msg: impl Into) { self.diagnostic().warn(msg) } - /// Delay a span_bug() call until abort_if_errors() + + /// Ensures that compilation cannot succeed. + /// + /// If this function has been called but no errors have been emitted and + /// compilation succeeds, it will cause an internal compiler error (ICE). + /// + /// This can be used in code paths that should never run on successful compilations. + /// For example, it can be used to create an [`ErrorGuaranteed`] + /// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission directly). + /// + /// If no span is available, use [`DUMMY_SP`]. + /// + /// [`DUMMY_SP`]: rustc_span::DUMMY_SP #[track_caller] pub fn delay_span_bug>( &self,