|
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