rustc_span/macros.rs
1use std::fmt;
2use std::panic::Location;
3
4use rustc_data_structures::AtomicRef;
5
6use crate::Span;
7
8/// A macro for triggering an ICE.
9/// Calling `bug` instead of panicking will result in a nicer error message and should
10/// therefore be preferred over `panic`/`unreachable` or others.
11///
12/// If you have a span available, you should use [`span_bug`] instead.
13///
14/// If the bug should only be emitted when compilation didn't fail,
15/// [`DiagCtxtHandle::span_delayed_bug`] may be useful.
16///
17/// [`DiagCtxtHandle::span_delayed_bug`]: ../../rustc_errors/struct.DiagCtxtHandle.html#method.span_delayed_bug
18/// [`span_bug`]: crate::span_bug
19pub macro bug {
20 () => (
21 bug!("impossible case reached")
22 ),
23 ($($arg:tt)+) => (
24 bug_impl(None, std::format_args!($($arg)+), Location::caller())
25 ),
26}
27
28/// A macro for triggering an ICE with a span.
29/// Calling `span_bug!` instead of panicking will result in a nicer error message and point
30/// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger
31/// ICEs.
32///
33/// If the bug should only be emitted when compilation didn't fail,
34/// [`DiagCtxtHandle::span_delayed_bug`] may be useful.
35///
36/// [`DiagCtxtHandle::span_delayed_bug`]: ../../rustc_errors/struct.DiagCtxtHandle.html#method.span_delayed_bug
37pub macro span_bug($span:expr, $($arg:tt)+){
38 bug_impl(Some($span), std::format_args!($($arg)+), Location::caller())
39}
40
41#[cold]
42#[track_caller]
43pub fn bug_impl(span: Option<Span>, args: fmt::Arguments<'_>, location: &Location<'_>) -> ! {
44 (*EMIT_BUG_DIAGNOSTIC)(span, args, location);
45 panic!("{args}")
46}
47
48pub static EMIT_BUG_DIAGNOSTIC: AtomicRef<fn(Option<Span>, fmt::Arguments<'_>, &Location<'_>)> =
49 AtomicRef::new(&(default_emit_diagnostic as _));
50
51fn default_emit_diagnostic(_: Option<Span>, _: fmt::Arguments<'_>, _: &Location<'_>) {}