Auto merge of #79945 - jackh726:existential_trait_ref, r=nikomatsakis
Move binder for dyn to each list item This essentially changes `ty::Binder<&'tcx List<ExistentialTraitRef>>` to `&'tcx List<ty::Binder<ExistentialTraitRef>>`. This is a first step in moving the `dyn Trait` representation closer to Chalk, which we've talked about in `@rust-lang/wg-traits.` r? `@nikomatsakis`
This commit is contained in:
commit
eb4fc71dc9
26 changed files with 315 additions and 262 deletions
|
@ -219,8 +219,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
if let ty::Dynamic(traits, _) = self_ty.kind() {
|
||||
for t in traits.skip_binder() {
|
||||
if let ty::ExistentialPredicate::Trait(trait_ref) = t {
|
||||
for t in traits.iter() {
|
||||
if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() {
|
||||
flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -551,8 +551,9 @@ fn object_ty_for_trait<'tcx>(
|
|||
|
||||
let trait_ref = ty::TraitRef::identity(tcx, trait_def_id);
|
||||
|
||||
let trait_predicate =
|
||||
ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref));
|
||||
let trait_predicate = ty::Binder::dummy(ty::ExistentialPredicate::Trait(
|
||||
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref),
|
||||
));
|
||||
|
||||
let mut associated_types = traits::supertraits(tcx, ty::Binder::dummy(trait_ref))
|
||||
.flat_map(|super_trait_ref| {
|
||||
|
@ -569,24 +570,19 @@ fn object_ty_for_trait<'tcx>(
|
|||
let projection_predicates = associated_types.into_iter().map(|(super_trait_ref, item)| {
|
||||
// We *can* get bound lifetimes here in cases like
|
||||
// `trait MyTrait: for<'s> OtherTrait<&'s T, Output=bool>`.
|
||||
//
|
||||
// binder moved to (*)...
|
||||
let super_trait_ref = super_trait_ref.skip_binder();
|
||||
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
|
||||
ty: tcx.mk_projection(item.def_id, super_trait_ref.substs),
|
||||
item_def_id: item.def_id,
|
||||
substs: super_trait_ref.substs,
|
||||
super_trait_ref.map_bound(|super_trait_ref| {
|
||||
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
|
||||
ty: tcx.mk_projection(item.def_id, super_trait_ref.substs),
|
||||
item_def_id: item.def_id,
|
||||
substs: super_trait_ref.substs,
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
let existential_predicates =
|
||||
tcx.mk_existential_predicates(iter::once(trait_predicate).chain(projection_predicates));
|
||||
let existential_predicates = tcx
|
||||
.mk_poly_existential_predicates(iter::once(trait_predicate).chain(projection_predicates));
|
||||
|
||||
let object_ty = tcx.mk_dynamic(
|
||||
// (*) ... binder re-introduced here
|
||||
ty::Binder::bind(existential_predicates),
|
||||
lifetime,
|
||||
);
|
||||
let object_ty = tcx.mk_dynamic(existential_predicates, lifetime);
|
||||
|
||||
debug!("object_ty_for_trait: object_ty=`{}`", object_ty);
|
||||
|
||||
|
|
|
@ -375,24 +375,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
|
||||
let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref);
|
||||
let data = match *self_ty.kind() {
|
||||
ty::Dynamic(data, ..) => {
|
||||
self.infcx
|
||||
.replace_bound_vars_with_fresh_vars(
|
||||
obligation.cause.span,
|
||||
HigherRankedType,
|
||||
data,
|
||||
)
|
||||
.0
|
||||
}
|
||||
ty::Dynamic(data, ..) => data,
|
||||
_ => span_bug!(obligation.cause.span, "object candidate with non-object"),
|
||||
};
|
||||
|
||||
let object_trait_ref = data
|
||||
.principal()
|
||||
.unwrap_or_else(|| {
|
||||
span_bug!(obligation.cause.span, "object candidate with no principal")
|
||||
})
|
||||
.with_self_ty(self.tcx(), self_ty);
|
||||
let object_trait_ref = data.principal().unwrap_or_else(|| {
|
||||
span_bug!(obligation.cause.span, "object candidate with no principal")
|
||||
});
|
||||
let object_trait_ref = self
|
||||
.infcx
|
||||
.replace_bound_vars_with_fresh_vars(
|
||||
obligation.cause.span,
|
||||
HigherRankedType,
|
||||
object_trait_ref,
|
||||
)
|
||||
.0;
|
||||
let object_trait_ref = object_trait_ref.with_self_ty(self.tcx(), self_ty);
|
||||
|
||||
let mut nested = vec![];
|
||||
|
||||
|
@ -711,15 +709,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
|
||||
(&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
|
||||
// See `assemble_candidates_for_unsizing` for more info.
|
||||
let existential_predicates = data_a.map_bound(|data_a| {
|
||||
let iter = data_a
|
||||
.principal()
|
||||
.map(ty::ExistentialPredicate::Trait)
|
||||
.into_iter()
|
||||
.chain(data_a.projection_bounds().map(ty::ExistentialPredicate::Projection))
|
||||
.chain(data_b.auto_traits().map(ty::ExistentialPredicate::AutoTrait));
|
||||
tcx.mk_existential_predicates(iter)
|
||||
});
|
||||
let iter = data_a
|
||||
.principal()
|
||||
.map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
|
||||
.into_iter()
|
||||
.chain(
|
||||
data_a
|
||||
.projection_bounds()
|
||||
.map(|b| b.map_bound(ty::ExistentialPredicate::Projection)),
|
||||
)
|
||||
.chain(
|
||||
data_b
|
||||
.auto_traits()
|
||||
.map(ty::ExistentialPredicate::AutoTrait)
|
||||
.map(ty::Binder::dummy),
|
||||
);
|
||||
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
|
||||
let source_trait = tcx.mk_dynamic(existential_predicates, r_b);
|
||||
|
||||
// Require that the traits involved in this upcast are **equal**;
|
||||
|
|
|
@ -706,7 +706,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
fn from_object_ty(
|
||||
&mut self,
|
||||
ty: Ty<'tcx>,
|
||||
data: ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
|
||||
data: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
region: ty::Region<'tcx>,
|
||||
) {
|
||||
// Imagine a type like this:
|
||||
|
@ -769,7 +769,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
/// `infer::required_region_bounds`, see that for more information.
|
||||
pub fn object_region_bounds<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
existential_predicates: ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
|
||||
existential_predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Vec<ty::Region<'tcx>> {
|
||||
// Since we don't actually *know* the self type for an object,
|
||||
// this "open(err)" serves as a kind of dummy standin -- basically
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue