1use std::ops::Deref;
23use rustc_errors::DiagCtxtHandle;
4use rustc_infer::infer::InferCtxt;
5use rustc_infer::traits::PredicateObligations;
6use rustc_macros::extension;
7use rustc_middle::bug;
8use rustc_middle::ty::{self, Ty};
910pub mod infer;
11pub mod traits;
1213/// A helper for building type related errors. The `typeck_results`
14/// field is only populated during an in-progress typeck.
15/// Get an instance by calling `InferCtxt::err_ctxt` or `FnCtxt::err_ctxt`.
16///
17/// You must only create this if you intend to actually emit an error (or
18/// perhaps a warning, though preferably not.) It provides a lot of utility
19/// methods which should not be used during the happy path.
20pub struct TypeErrCtxt<'a, 'tcx> {
21pub infcx: &'a InferCtxt<'tcx>,
2223pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
24pub diverging_fallback_has_occurred: bool,
2526pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
2728pub autoderef_steps: Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, PredicateObligations<'tcx>)> + 'a>,
29}
3031impl<'tcx> InferCtxtErrorExt<'tcx> for InferCtxt<'tcx> {
#[doc = " Creates a `TypeErrCtxt` for emitting various inference errors."]
#[doc = " During typeck, use `FnCtxt::err_ctxt` instead."]
fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
TypeErrCtxt {
infcx: self,
typeck_results: None,
diverging_fallback_has_occurred: false,
normalize_fn_sig: Box::new(|fn_sig| fn_sig),
autoderef_steps: Box::new(|ty|
{
if true {
if !false {
{
::core::panicking::panic_fmt(format_args!("shouldn\'t be using autoderef_steps outside of typeck"));
}
};
};
<[_]>::into_vec(::alloc::boxed::box_new([(ty,
PredicateObligations::new())]))
}),
}
}
}#[extension(pub trait InferCtxtErrorExt<'tcx>)]32impl<'tcx> InferCtxt<'tcx> {
33/// Creates a `TypeErrCtxt` for emitting various inference errors.
34 /// During typeck, use `FnCtxt::err_ctxt` instead.
35fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
36TypeErrCtxt {
37 infcx: self,
38 typeck_results: None,
39 diverging_fallback_has_occurred: false,
40 normalize_fn_sig: Box::new(|fn_sig| fn_sig),
41 autoderef_steps: Box::new(|ty| {
42debug_assert!(false, "shouldn't be using autoderef_steps outside of typeck");
43vec![(ty, PredicateObligations::new())]
44 }),
45 }
46 }
47}
4849impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
50pub fn dcx(&self) -> DiagCtxtHandle<'a> {
51self.infcx.dcx()
52 }
5354/// This is just to avoid a potential footgun of accidentally
55 /// dropping `typeck_results` by calling `InferCtxt::err_ctxt`
56#[deprecated(note = "you already have a `TypeErrCtxt`")]
57 #[allow(unused)]
58pub fn err_ctxt(&self) -> ! {
59::rustc_middle::util::bug::bug_fmt(format_args!("called `err_ctxt` on `TypeErrCtxt`. Try removing the call"));bug!("called `err_ctxt` on `TypeErrCtxt`. Try removing the call");
60 }
61}
6263impl<'tcx> Dereffor TypeErrCtxt<'_, 'tcx> {
64type Target = InferCtxt<'tcx>;
65fn deref(&self) -> &InferCtxt<'tcx> {
66self.infcx
67 }
68}