|
8 | 8 | //! - not reference the erased type `Self` except for in this receiver;
|
9 | 9 | //! - not have generic type parameters.
|
10 | 10 |
|
11 |
| -use super::elaborate_predicates; |
| 11 | +use super::{elaborate_predicates, elaborate_trait_ref}; |
12 | 12 |
|
13 | 13 | use crate::infer::TyCtxtInferExt;
|
14 | 14 | use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
@@ -567,51 +567,37 @@ fn receiver_for_self_ty<'tcx>(
|
567 | 567 | /// Creates the object type for the current trait. For example,
|
568 | 568 | /// if the current trait is `Deref`, then this will be
|
569 | 569 | /// `dyn Deref<Target = Self::Target> + 'static`.
|
| 570 | +#[instrument(level = "trace", skip(tcx), ret)] |
570 | 571 | fn object_ty_for_trait<'tcx>(
|
571 | 572 | tcx: TyCtxt<'tcx>,
|
572 | 573 | trait_def_id: DefId,
|
573 | 574 | lifetime: ty::Region<'tcx>,
|
574 | 575 | ) -> Ty<'tcx> {
|
575 |
| - debug!("object_ty_for_trait: trait_def_id={:?}", trait_def_id); |
576 |
| - |
577 | 576 | let trait_ref = ty::TraitRef::identity(tcx, trait_def_id);
|
| 577 | + debug!(?trait_ref); |
578 | 578 |
|
579 | 579 | let trait_predicate = trait_ref.map_bound(|trait_ref| {
|
580 | 580 | ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref))
|
581 | 581 | });
|
| 582 | + debug!(?trait_predicate); |
582 | 583 |
|
583 |
| - let mut associated_types = traits::supertraits(tcx, trait_ref) |
584 |
| - .flat_map(|super_trait_ref| { |
585 |
| - tcx.associated_items(super_trait_ref.def_id()) |
586 |
| - .in_definition_order() |
587 |
| - .map(move |item| (super_trait_ref, item)) |
588 |
| - }) |
589 |
| - .filter(|(_, item)| item.kind == ty::AssocKind::Type) |
590 |
| - .collect::<Vec<_>>(); |
591 |
| - |
592 |
| - // existential predicates need to be in a specific order |
593 |
| - associated_types.sort_by_cached_key(|(_, item)| tcx.def_path_hash(item.def_id)); |
594 |
| - |
595 |
| - let projection_predicates = associated_types.into_iter().map(|(super_trait_ref, item)| { |
596 |
| - // We *can* get bound lifetimes here in cases like |
597 |
| - // `trait MyTrait: for<'s> OtherTrait<&'s T, Output=bool>`. |
598 |
| - super_trait_ref.map_bound(|super_trait_ref| { |
| 584 | + let elaborated_predicates = elaborate_trait_ref(tcx, trait_ref).filter_map(|obligation| { |
| 585 | + debug!(?obligation); |
| 586 | + let pred = obligation.predicate.to_opt_poly_projection_pred()?; |
| 587 | + Some(pred.map_bound(|p| { |
599 | 588 | ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
|
600 |
| - term: tcx.mk_projection(item.def_id, super_trait_ref.substs).into(), |
601 |
| - item_def_id: item.def_id, |
602 |
| - substs: super_trait_ref.substs, |
| 589 | + item_def_id: p.projection_ty.item_def_id, |
| 590 | + substs: p.projection_ty.substs, |
| 591 | + term: p.term, |
603 | 592 | })
|
604 |
| - }) |
| 593 | + })) |
605 | 594 | });
|
606 | 595 |
|
607 | 596 | let existential_predicates = tcx
|
608 |
| - .mk_poly_existential_predicates(iter::once(trait_predicate).chain(projection_predicates)); |
609 |
| - |
610 |
| - let object_ty = tcx.mk_dynamic(existential_predicates, lifetime, ty::Dyn); |
611 |
| - |
612 |
| - debug!("object_ty_for_trait: object_ty=`{}`", object_ty); |
| 597 | + .mk_poly_existential_predicates(iter::once(trait_predicate).chain(elaborated_predicates)); |
| 598 | + debug!(?existential_predicates); |
613 | 599 |
|
614 |
| - object_ty |
| 600 | + tcx.mk_dynamic(existential_predicates, lifetime, ty::Dyn) |
615 | 601 | }
|
616 | 602 |
|
617 | 603 | /// Checks the method's receiver (the `self` argument) can be dispatched on when `Self` is a
|
|
0 commit comments