use std::ops::Deref;
use rustc_errors::DiagCtxtHandle;
use rustc_infer::infer::InferCtxt;
use rustc_infer::traits::PredicateObligation;
use rustc_macros::extension;
use rustc_middle::bug;
use rustc_middle::ty::{self, Ty};
use crate::error_reporting::infer::sub_relations;
pub mod infer;
pub mod traits;
pub struct TypeErrCtxt<'a, 'tcx> {
pub infcx: &'a InferCtxt<'tcx>,
pub sub_relations: std::cell::RefCell<sub_relations::SubRelations>,
pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
pub fallback_has_occurred: bool,
pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
pub autoderef_steps:
Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, Vec<PredicateObligation<'tcx>>)> + 'a>,
}
#[extension(pub trait InferCtxtErrorExt<'tcx>)]
impl<'tcx> InferCtxt<'tcx> {
fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
TypeErrCtxt {
infcx: self,
sub_relations: Default::default(),
typeck_results: None,
fallback_has_occurred: false,
normalize_fn_sig: Box::new(|fn_sig| fn_sig),
autoderef_steps: Box::new(|ty| {
debug_assert!(false, "shouldn't be using autoderef_steps outside of typeck");
vec![(ty, vec![])]
}),
}
}
}
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'a> {
self.infcx.dcx()
}
#[deprecated(note = "you already have a `TypeErrCtxt`")]
#[allow(unused)]
pub fn err_ctxt(&self) -> ! {
bug!("called `err_ctxt` on `TypeErrCtxt`. Try removing the call");
}
}
impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx> {
type Target = InferCtxt<'tcx>;
fn deref(&self) -> &InferCtxt<'tcx> {
self.infcx
}
}