Skip to content

Commit

Permalink
add Self type into whereclause
Browse files Browse the repository at this point in the history
  • Loading branch information
csmoe committed Nov 14, 2021
1 parent 6bb470e commit c6a4dbe
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 44 deletions.
41 changes: 15 additions & 26 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<TraitRef<'tcx>> 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()`
Expand Down Expand Up @@ -1532,6 +1525,16 @@ pub struct ExistentialProjection<'tcx> {
pub ty: Ty<'tcx>,
}

impl From<ty::ProjectionPredicate<'tcx>> 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> {
Expand Down Expand Up @@ -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> {
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_middle/src/ty/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_trait_selection/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand All @@ -299,9 +298,7 @@ pub fn get_vtable_index_of_object_method<N>(
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.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, _)| {
Expand All @@ -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()
})
});

Expand Down

0 comments on commit c6a4dbe

Please sign in to comment.