diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 38a298d81dda..b660187945cd 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -597,6 +597,14 @@ impl<'a, 'gcx> HashStable> for mir::UserTypeAnnotation< mir::UserTypeAnnotation::Ty(ref ty) => { ty.hash_stable(hcx, hasher); } + mir::UserTypeAnnotation::FnDef(ref def_id, ref substs) => { + def_id.hash_stable(hcx, hasher); + substs.hash_stable(hcx, hasher); + } + mir::UserTypeAnnotation::AdtDef(ref def_id, ref substs) => { + def_id.hash_stable(hcx, hasher); + substs.hash_stable(hcx, hasher); + } } } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index eb4aa7ece49a..278a9bba1780 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -37,7 +37,7 @@ use syntax::ast::{self, Name}; use syntax::symbol::InternedString; use syntax_pos::{Span, DUMMY_SP}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use ty::subst::{Subst, Substs}; +use ty::subst::{CanonicalSubsts, Subst, Substs}; use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt}; use util::ppaux; @@ -2413,11 +2413,15 @@ pub struct Constant<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum UserTypeAnnotation<'tcx> { Ty(CanonicalTy<'tcx>), + FnDef(DefId, CanonicalSubsts<'tcx>), + AdtDef(&'tcx AdtDef, CanonicalSubsts<'tcx>), } EnumTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for UserTypeAnnotation<'tcx> { (UserTypeAnnotation::Ty)(ty), + (UserTypeAnnotation::FnDef)(def, substs), + (UserTypeAnnotation::AdtDef)(def, substs), } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs index 35d0b96b88a9..21dabd0c1bdb 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs @@ -71,9 +71,21 @@ pub(super) fn relate_type_and_user_type<'tcx>( a, v, user_ty, locations ); - let (b, _values) = match user_ty { + let b = match user_ty { UserTypeAnnotation::Ty(canonical_ty) => { - infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_ty) + let (ty, _) = + infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_ty); + ty + } + UserTypeAnnotation::FnDef(def_id, canonical_substs) => { + let (substs, _) = + infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_substs); + infcx.tcx.mk_fn_def(def_id, substs) + } + UserTypeAnnotation::AdtDef(adt_def, canonical_substs) => { + let (substs, _) = + infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_substs); + infcx.tcx.mk_adt(adt_def, substs) } }; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 4dc43a533cfc..984abb039265 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -295,13 +295,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let substs = cx.tables().node_substs(fun.hir_id); let user_ty = cx.tables().user_substs(fun.hir_id) - .map(|user_substs| { - UserTypeAnnotation::Ty(user_substs.unchecked_map(|user_substs| { - // Here, we just pair an `AdtDef` with the - // `user_substs`, so no new types etc are introduced. - cx.tcx().mk_adt(adt_def, user_substs) - })) - }); + .map(|user_substs| UserTypeAnnotation::AdtDef(adt_def, user_substs)); let field_refs = args.iter() .enumerate() @@ -774,14 +768,7 @@ fn user_substs_applied_to_def( Def::Method(_) | Def::StructCtor(_, CtorKind::Fn) | Def::VariantCtor(_, CtorKind::Fn) => - Some( - UserTypeAnnotation::Ty(cx.tables().user_substs(hir_id)?.unchecked_map(|user_substs| { - // Here, we just pair a `DefId` with the - // `user_substs`, so no new types etc are introduced. - cx.tcx().mk_fn_def(def.def_id(), user_substs) - }), - ) - ), + Some(UserTypeAnnotation::FnDef(def.def_id(), cx.tables().user_substs(hir_id)?)), Def::Const(_def_id) | Def::AssociatedConst(_def_id) => diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir/hair/util.rs index 46a957f453cb..71cbac6b7c88 100644 --- a/src/librustc_mir/hair/util.rs +++ b/src/librustc_mir/hair/util.rs @@ -23,13 +23,7 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { adt_def: &'tcx AdtDef, ) -> Option> { let user_substs = self.tables().user_substs(hir_id)?; - Some(UserTypeAnnotation::Ty(user_substs.unchecked_map( - |user_substs| { - // Here, we just pair an `AdtDef` with the - // `user_substs`, so no new types etc are introduced. - self.tcx().mk_adt(adt_def, user_substs) - }, - ))) + Some(UserTypeAnnotation::AdtDef(adt_def, user_substs)) } /// Looks up the type associated with this hir-id and applies the @@ -41,21 +35,8 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { ) -> Option> { let user_substs = self.tables().user_substs(hir_id)?; match &self.tables().node_id_to_type(hir_id).sty { - ty::Adt(adt_def, _) => Some(UserTypeAnnotation::Ty(user_substs.unchecked_map( - |user_substs| { - // Ok to call `unchecked_map` because we just pair an - // `AdtDef` with the `user_substs`, so no new types - // etc are introduced. - self.tcx().mk_adt(adt_def, user_substs) - }, - ))), - ty::FnDef(def_id, _) => Some(UserTypeAnnotation::Ty(user_substs.unchecked_map( - |user_substs| { - // Here, we just pair a `DefId` with the - // `user_substs`, so no new types etc are introduced. - self.tcx().mk_fn_def(*def_id, user_substs) - }, - ))), + ty::Adt(adt_def, _) => Some(UserTypeAnnotation::AdtDef(adt_def, user_substs)), + ty::FnDef(def_id, _) => Some(UserTypeAnnotation::FnDef(*def_id, user_substs)), sty => bug!( "sty: {:?} should not have user-substs {:?} recorded ", sty,