summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs')
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs45
1 files changed, 34 insertions, 11 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 30b59da78..428fde642 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -17,11 +17,10 @@ use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{self, Const, Ty, TyCtxt};
+use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitable};
use rustc_session::Session;
use rustc_span::symbol::Ident;
-use rustc_span::{self, Span};
+use rustc_span::{self, Span, DUMMY_SP};
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
use std::cell::{Cell, RefCell};
@@ -176,6 +175,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn_sig
})
}),
+ autoderef_steps: Box::new(|ty| {
+ let mut autoderef = self.autoderef(DUMMY_SP, ty).silence_errors();
+ let mut steps = vec![];
+ while let Some((ty, _)) = autoderef.next() {
+ steps.push((ty, autoderef.current_obligations()));
+ }
+ steps
+ }),
}
}
@@ -287,8 +294,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
poly_trait_ref,
);
- let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
- self,
+ let item_substs = self.astconv().create_substs_for_associated_item(
span,
item_def_id,
item_segment,
@@ -298,11 +304,14 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
self.tcx().mk_projection(item_def_id, item_substs)
}
- fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
- if ty.has_escaping_bound_vars() {
- ty // FIXME: normalization and escaping regions
- } else {
- self.normalize(span, ty)
+ fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
+ match ty.kind() {
+ ty::Adt(adt_def, _) => Some(*adt_def),
+ // FIXME(#104767): Should we handle bound regions here?
+ ty::Alias(ty::Projection, _) if !ty.has_escaping_bound_vars() => {
+ self.normalize(span, ty).ty_adt_def()
+ }
+ _ => None,
}
}
@@ -310,7 +319,21 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
self.infcx.set_tainted_by_errors(e)
}
- fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
+ fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
+ // FIXME: normalization and escaping regions
+ let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty };
self.write_ty(hir_id, ty)
}
}
+
+/// Represents a user-provided type in the raw form (never normalized).
+///
+/// This is a bridge between the interface of `AstConv`, which outputs a raw `Ty`,
+/// and the API in this module, which expect `Ty` to be fully normalized.
+#[derive(Clone, Copy, Debug)]
+pub struct RawTy<'tcx> {
+ pub raw: Ty<'tcx>,
+
+ /// The normalized form of `raw`, stored here for efficiency.
+ pub normalized: Ty<'tcx>,
+}