diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 09dbfaa57d248..c6b9197d0e986 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -2,7 +2,7 @@ use crate::callee::{self, DeferredCallResolution}; use crate::errors::CtorIsPrivate; use crate::method::{self, MethodCallee, SelfSource}; use crate::rvalue_scopes; -use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, RawTy}; +use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey}; @@ -373,14 +373,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn handle_raw_ty(&self, span: Span, ty: Ty<'tcx>) -> RawTy<'tcx> { - RawTy { raw: ty, normalized: self.normalize(span, ty) } - } - - pub fn to_ty(&self, ast_t: &hir::Ty<'tcx>) -> RawTy<'tcx> { + pub fn to_ty(&self, ast_t: &hir::Ty<'tcx>) -> LoweredTy<'tcx> { let t = self.astconv().ast_ty_to_ty(ast_t); self.register_wf_obligation(t.into(), ast_t.span, traits::WellFormed(None)); - self.handle_raw_ty(ast_t.span, t) + LoweredTy::from_raw(self, ast_t.span, t) } pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { @@ -396,7 +392,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty.normalized } - pub(super) fn user_args_for_adt(ty: RawTy<'tcx>) -> UserArgs<'tcx> { + pub(super) fn user_args_for_adt(ty: LoweredTy<'tcx>) -> UserArgs<'tcx> { match (ty.raw.kind(), ty.normalized.kind()) { (ty::Adt(_, args), _) => UserArgs { args, user_self_ty: None }, (_, ty::Adt(adt, args)) => UserArgs { @@ -801,7 +797,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id: hir::HirId, span: Span, args: Option<&'tcx [hir::Expr<'tcx>]>, - ) -> (Res, Option>, &'tcx [hir::PathSegment<'tcx>]) { + ) -> (Res, Option>, &'tcx [hir::PathSegment<'tcx>]) { debug!( "resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span @@ -825,7 +821,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We manually call `register_wf_obligation` in the success path // below. let ty = self.astconv().ast_ty_to_ty_in_path(qself); - (self.handle_raw_ty(span, ty), qself, segment) + (LoweredTy::from_raw(self, span, ty), qself, segment) } QPath::LangItem(..) => { bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`") @@ -1074,7 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn instantiate_value_path( &self, segments: &'tcx [hir::PathSegment<'tcx>], - self_ty: Option>, + self_ty: Option>, res: Res, span: Span, hir_id: hir::HirId, @@ -1201,8 +1197,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { path_segs.last().is_some_and(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self); let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res { - let ty = - self.handle_raw_ty(span, tcx.at(span).type_of(impl_def_id).instantiate_identity()); + let ty = LoweredTy::from_raw( + self, + span, + tcx.at(span).type_of(impl_def_id).instantiate_identity(), + ); match ty.normalized.ty_adt_def() { Some(adt_def) if adt_def.has_ctor() => { let (ctor_kind, ctor_def_id) = adt_def.non_enum_variant().ctor.unwrap(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 136ed1a709e94..6a77450f075bf 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -6,7 +6,7 @@ use crate::method::MethodCallee; use crate::TupleArgumentsFlag::*; use crate::{errors, Expectation::*}; use crate::{ - struct_span_code_err, BreakableCtxt, Diverges, Expectation, FnCtxt, Needs, RawTy, + struct_span_code_err, BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy, Needs, TupleArgumentsFlag, }; use itertools::Itertools; @@ -1792,12 +1792,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { qpath: &QPath<'tcx>, path_span: Span, hir_id: hir::HirId, - ) -> (Res, RawTy<'tcx>) { + ) -> (Res, LoweredTy<'tcx>) { match *qpath { QPath::Resolved(ref maybe_qself, path) => { let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself).raw); let ty = self.astconv().res_to_ty(self_ty, path, hir_id, true); - (path.res, self.handle_raw_ty(path_span, ty)) + (path.res, LoweredTy::from_raw(self, path_span, ty)) } QPath::TypeRelative(qself, segment) => { let ty = self.to_ty(qself); @@ -1808,7 +1808,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = result .map(|(ty, _, _)| ty) .unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar)); - let ty = self.handle_raw_ty(path_span, ty); + let ty = LoweredTy::from_raw(self, path_span, ty); let result = result.map(|(_, kind, def_id)| (kind, def_id)); // Write back the new resolution. @@ -1818,7 +1818,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } QPath::LangItem(lang_item, span) => { let (res, ty) = self.resolve_lang_item_path(lang_item, span, hir_id); - (res, self.handle_raw_ty(path_span, ty)) + (res, LoweredTy::from_raw(self, path_span, ty)) } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index f65e9b698ab2a..18f547be2a71c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -353,14 +353,22 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { } } -/// Represents a user-provided type in the raw form (never normalized). +/// The `ty` representation of a user-provided type. Depending on the use-site +/// we want to either use the unnormalized or the normalized form of this type. /// /// 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 struct LoweredTy<'tcx> { + /// The unnormalized type provided by the user. pub raw: Ty<'tcx>, /// The normalized form of `raw`, stored here for efficiency. pub normalized: Ty<'tcx>, } + +impl<'tcx> LoweredTy<'tcx> { + pub fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> { + LoweredTy { raw, normalized: fcx.normalize(span, raw) } + } +} diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 80467ca9381e3..bdd7c382903f2 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -49,7 +49,7 @@ use crate::check::check_fn; use crate::coercion::DynamicCoerceMany; use crate::diverges::Diverges; use crate::expectation::Expectation; -use crate::fn_ctxt::RawTy; +use crate::fn_ctxt::LoweredTy; use crate::gather_locals::GatherLocalsVisitor; use rustc_data_structures::unord::UnordSet; use rustc_errors::{struct_span_code_err, ErrorGuaranteed}; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 73fc0ee499e6e..e31eeab4c4a47 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1,5 +1,5 @@ use crate::gather_locals::DeclOrigin; -use crate::{errors, FnCtxt, RawTy}; +use crate::{errors, FnCtxt, LoweredTy}; use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{ @@ -891,7 +891,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat: &Pat<'tcx>, qpath: &hir::QPath<'_>, - path_resolution: (Res, Option>, &'tcx [hir::PathSegment<'tcx>]), + path_resolution: (Res, Option>, &'tcx [hir::PathSegment<'tcx>]), expected: Ty<'tcx>, ti: TopInfo<'tcx>, ) -> Ty<'tcx> {