rustc_trait_selection/error_reporting/
mod.rs1use std::ops::Deref;
2
3use 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};
9
10use crate::error_reporting::infer::sub_relations;
11
12pub mod infer;
13pub mod traits;
14
15pub struct TypeErrCtxt<'a, 'tcx> {
23    pub infcx: &'a InferCtxt<'tcx>,
24    pub sub_relations: std::cell::RefCell<sub_relations::SubRelations>,
25
26    pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
27    pub fallback_has_occurred: bool,
28
29    pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
30
31    pub autoderef_steps: Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, PredicateObligations<'tcx>)> + 'a>,
32}
33
34#[extension(pub trait InferCtxtErrorExt<'tcx>)]
35impl<'tcx> InferCtxt<'tcx> {
36    fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
39        TypeErrCtxt {
40            infcx: self,
41            sub_relations: Default::default(),
42            typeck_results: None,
43            fallback_has_occurred: false,
44            normalize_fn_sig: Box::new(|fn_sig| fn_sig),
45            autoderef_steps: Box::new(|ty| {
46                debug_assert!(false, "shouldn't be using autoderef_steps outside of typeck");
47                vec![(ty, PredicateObligations::new())]
48            }),
49        }
50    }
51}
52
53impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
54    pub fn dcx(&self) -> DiagCtxtHandle<'a> {
55        self.infcx.dcx()
56    }
57
58    #[deprecated(note = "you already have a `TypeErrCtxt`")]
61    #[allow(unused)]
62    pub fn err_ctxt(&self) -> ! {
63        bug!("called `err_ctxt` on `TypeErrCtxt`. Try removing the call");
64    }
65}
66
67impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx> {
68    type Target = InferCtxt<'tcx>;
69    fn deref(&self) -> &InferCtxt<'tcx> {
70        self.infcx
71    }
72}