From c6a4dbe3a87dcfff214fa59f2b4ade806bf4290f Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 7 Oct 2021 18:59:14 +0800 Subject: [PATCH] add Self type into whereclause --- compiler/rustc_middle/src/ty/sty.rs | 41 +++++++------------ compiler/rustc_middle/src/ty/vtable.rs | 4 +- .../rustc_trait_selection/src/traits/mod.rs | 3 +- .../src/traits/object_safety.rs | 4 +- .../src/traits/select/confirmation.rs | 5 +-- .../rustc_trait_selection/src/traits/util.rs | 7 +--- compiler/rustc_typeck/src/astconv/mod.rs | 4 +- 7 files changed, 24 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 3acbe94a4f3f6..57d406d0e2c88 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -963,20 +963,13 @@ pub struct ExistentialTraitRef<'tcx> { pub substs: SubstsRef<'tcx>, } -impl<'tcx> ExistentialTraitRef<'tcx> { - pub fn erase_self_ty( - tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, - ) -> ty::ExistentialTraitRef<'tcx> { - // Assert there is a Self. - trait_ref.substs.type_at(0); - - ty::ExistentialTraitRef { - def_id: trait_ref.def_id, - substs: tcx.intern_substs(&trait_ref.substs[1..]), - } +impl From> for ExistentialTraitRef<'tcx> { + fn from(trait_ref: TraitRef<'tcx>) -> Self { + Self { def_id: trait_ref.def_id, substs: trait_ref.substs } } +} +impl<'tcx> ExistentialTraitRef<'tcx> { /// Object types don't have a self type specified. Therefore, when /// we convert the principal trait-ref into a normal trait-ref, /// you must give *some* self type. A common choice is `mk_err()` @@ -1532,6 +1525,16 @@ pub struct ExistentialProjection<'tcx> { pub ty: Ty<'tcx>, } +impl From> for ExistentialProjection<'tcx> { + fn from(projection_predicate: ty::ProjectionPredicate<'tcx>) -> Self { + Self { + item_def_id: projection_predicate.projection_ty.item_def_id, + substs: projection_predicate.projection_ty.substs, + ty: projection_predicate.ty, + } + } +} + pub type PolyExistentialProjection<'tcx> = Binder<'tcx, ExistentialProjection<'tcx>>; impl<'tcx> ExistentialProjection<'tcx> { @@ -1562,20 +1565,6 @@ impl<'tcx> ExistentialProjection<'tcx> { ty: self.ty, } } - - pub fn erase_self_ty( - tcx: TyCtxt<'tcx>, - projection_predicate: ty::ProjectionPredicate<'tcx>, - ) -> Self { - // Assert there is a Self. - projection_predicate.projection_ty.substs.type_at(0); - - Self { - item_def_id: projection_predicate.projection_ty.item_def_id, - substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]), - ty: projection_predicate.ty, - } - } } impl<'tcx> PolyExistentialProjection<'tcx> { diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index f766cad2b3d21..7e69740a071c3 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -76,7 +76,6 @@ pub(super) fn vtable_allocation_provider<'tcx>( // No need to do any alignment checks on the memory accesses below, because we know the // allocation is correctly aligned as we created it above. Also we're only offsetting by // multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`. - for (idx, entry) in vtable_entries.iter().enumerate() { let idx: u64 = u64::try_from(idx).unwrap(); let scalar = match entry { @@ -97,8 +96,7 @@ pub(super) fn vtable_allocation_provider<'tcx>( ScalarMaybeUninit::from_pointer(fn_ptr, &tcx) } VtblEntry::TraitVPtr(trait_ref) => { - let super_trait_ref = trait_ref - .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + let super_trait_ref = trait_ref.map_bound(|trait_ref| trait_ref.into()); let supertrait_alloc_id = tcx.vtable_allocation((ty, Some(super_trait_ref))); let vptr = Pointer::from(supertrait_alloc_id); ScalarMaybeUninit::from_pointer(vptr, &tcx) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index d4a586b0124a2..f7dd7d10576e1 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -675,8 +675,7 @@ fn vtable_entries<'tcx>( entries.extend(COMMON_VTABLE_ENTRIES); } VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { - let existential_trait_ref = trait_ref - .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + let existential_trait_ref = trait_ref.map_bound(|trait_ref| trait_ref.into()); // Lookup the shape of vtable for the trait. let own_existential_entries = diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index ddd47b0a58533..19f8cac9361e0 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -554,9 +554,7 @@ fn object_ty_for_trait<'tcx>( let trait_ref = ty::TraitRef::identity(tcx, trait_def_id); - let trait_predicate = trait_ref.map_bound(|trait_ref| { - ty::WhereClause::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)) - }); + let trait_predicate = trait_ref.map_bound(|trait_ref| ty::WhereClause::Trait(trait_ref.into())); let mut associated_types = traits::supertraits(tcx, trait_ref) .flat_map(|super_trait_ref| { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index c405f8cbc6712..3b66082c15a47 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -736,9 +736,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { source_trait_ref = principal_a.with_self_ty(tcx, source); upcast_trait_ref = util::supertraits(tcx, source_trait_ref).nth(idx).unwrap(); assert_eq!(data_b.principal_def_id(), Some(upcast_trait_ref.def_id())); - let existential_predicate = upcast_trait_ref.map_bound(|trait_ref| { - ty::WhereClause::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)) - }); + let existential_predicate = upcast_trait_ref + .map_bound(|trait_ref| ty::WhereClause::Trait(trait_ref.into())); let iter = Some(existential_predicate) .into_iter() .chain( diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index ed49abbbedc92..d8f6ab33ba2ca 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -285,8 +285,7 @@ pub fn upcast_choices( /// that come from `trait_ref`, excluding its supertraits. Used in /// computing the vtable base for an upcast trait of a trait object. pub fn count_own_vtable_entries(tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> usize { - let existential_trait_ref = - trait_ref.map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + let existential_trait_ref = trait_ref.map_bound(|trait_ref| trait_ref.into()); let existential_trait_ref = tcx.erase_regions(existential_trait_ref); tcx.own_existential_vtable_entries(existential_trait_ref).len() } @@ -299,9 +298,7 @@ pub fn get_vtable_index_of_object_method( object: &super::ImplSourceObjectData<'tcx, N>, method_def_id: DefId, ) -> usize { - let existential_trait_ref = object - .upcast_trait_ref - .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + let existential_trait_ref = object.upcast_trait_ref.map_bound(|trait_ref| trait_ref.into()); let existential_trait_ref = tcx.erase_regions(existential_trait_ref); // Count number of methods preceding the one we are selecting and // add them to the total offset. diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 9633849e90ca2..a972e486369e7 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1458,7 +1458,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ), ); } - ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) + trait_ref.into() }) }); let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| { @@ -1469,7 +1469,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &format!("trait_ref_to_existential called on {:?} with non-dummy Self", b), ); } - ty::ExistentialProjection::erase_self_ty(tcx, b) + b.into() }) });