diff options
Diffstat (limited to 'compiler/rustc_middle/src/util/bug.rs')
-rw-r--r-- | compiler/rustc_middle/src/util/bug.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs new file mode 100644 index 000000000..fd7045d6a --- /dev/null +++ b/compiler/rustc_middle/src/util/bug.rs @@ -0,0 +1,54 @@ +// These functions are used by macro expansion for bug! and span_bug! + +use crate::ty::{tls, TyCtxt}; +use rustc_errors::MultiSpan; +use rustc_span::Span; +use std::fmt; +use std::panic::{panic_any, Location}; + +#[cold] +#[inline(never)] +#[track_caller] +pub fn bug_fmt(args: fmt::Arguments<'_>) -> ! { + // this wrapper mostly exists so I don't have to write a fully + // qualified path of None::<Span> inside the bug!() macro definition + opt_span_bug_fmt(None::<Span>, args, Location::caller()); +} + +#[cold] +#[inline(never)] +#[track_caller] +pub fn span_bug_fmt<S: Into<MultiSpan>>(span: S, args: fmt::Arguments<'_>) -> ! { + opt_span_bug_fmt(Some(span), args, Location::caller()); +} + +#[track_caller] +fn opt_span_bug_fmt<S: Into<MultiSpan>>( + span: Option<S>, + args: fmt::Arguments<'_>, + location: &Location<'_>, +) -> ! { + tls::with_opt(move |tcx| { + let msg = format!("{}: {}", location, args); + match (tcx, span) { + (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg), + (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 +/// `delay_span_bug`, so what is the point of this? It exists to help us test `delay_span_bug`'s +/// interactions with the query system and incremental. +pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: rustc_hir::def_id::DefId) { + tcx.sess.delay_span_bug( + tcx.def_span(key), + "delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]", + ); +} + +pub fn provide(providers: &mut crate::ty::query::Providers) { + *providers = crate::ty::query::Providers { trigger_delay_span_bug, ..*providers }; +} |