fn associated_type_projection_predicates(
    tcx: TyCtxt<'_>,
    assoc_item_def_id: DefId,
) -> &'_ ty::List<ty::Predicate<'_>> {
    let generic_trait_bounds = tcx.predicates_of(assoc_item_def_id);
    // We include predicates from the trait as well to handle
    // `where Self::X: Trait`.
    let item_bounds = generic_trait_bounds.instantiate_identity(tcx);
    let item_predicates = util::elaborate_predicates(tcx, item_bounds.predicates.into_iter());

    let assoc_item_ty = ty::ProjectionTy {
        item_def_id: assoc_item_def_id,
        substs: InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
    };

    let predicates = item_predicates.filter_map(|obligation| {
        let pred = obligation.predicate;
        match pred.kind() {
            ty::PredicateKind::Trait(tr, _) => {
                if let ty::Projection(p) = tr.skip_binder().self_ty().kind {
                    if p == assoc_item_ty {
                        return Some(pred);
                    }
                }
            }
            ty::PredicateKind::Projection(proj) => {
                if let ty::Projection(p) = proj.skip_binder().projection_ty.self_ty().kind {
                    if p == assoc_item_ty {
                        return Some(pred);
                    }
                }
            }
            ty::PredicateKind::TypeOutlives(outlives) => {
                if let ty::Projection(p) = outlives.skip_binder().0.kind {
                    if p == assoc_item_ty {
                        return Some(pred);
                    }
                }
            }
            _ => {}
        }
        None
    });

    let result = tcx.mk_predicates(predicates);
    debug!(
        "associated_type_projection_predicates({}) = {:?}",
        tcx.def_path_str(assoc_item_def_id),
        result
    );
    result
}
/// For associated types we allow bounds written on the associated type
/// (`type X: Trait`) to be used as candidates. We also allow the same bounds
/// when desugared as bounds on the trait `where Self::X: Trait`.
///
/// Note that this filtering is done with the items identity substs to
/// simplify checking that these bounds are met in impls. This means that
/// a bound such as `for<'b> <Self as X<'b>>::U: Clone` can't be used, as in
/// `hr-associated-type-bound-1.rs`.
For associated types we allow bounds written on the associated type
(`type X: Trait`) to be used as candidates. We also allow the same bounds
when desugared as bounds on the trait `where Self::X: Trait`.

Note that this filtering is done with the items identity substs to
simplify checking that these bounds are met in impls.
For associated types we allow bounds written on the associated type ( ` type X : Trait ` ) to be used as candidates . We also allow the same bounds when desugared as bounds on the trait ` where Self :: X : Trait ` . Note that this filtering is done with the items identity substs to simplify checking that these bounds are met in impls .
fn associated_type_projection_predicates(
    tcx: TyCtxt<'_>,
    assoc_item_def_id: DefId,
) -> &'_ ty::List<ty::Predicate<'_>> {
    let generic_trait_bounds = tcx.predicates_of(assoc_item_def_id);
    // We include predicates from the trait as well to handle
    // `where Self::X: Trait`.
    let item_bounds = generic_trait_bounds.instantiate_identity(tcx);
    let item_predicates = util::elaborate_predicates(tcx, item_bounds.predicates.into_iter());
    let assoc_item_ty = ty::ProjectionTy {
        item_def_id: assoc_item_def_id,
        substs: InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
    };
    let predicates = item_predicates.filter_map(|obligation| {
        let pred = obligation.predicate;
        match pred.kind() {
            ty::PredicateKind::Trait(tr, _) => {
                if let ty::Projection(p) = tr.skip_binder().self_ty().kind {
                    if p == assoc_item_ty {
                        return Some(pred);
                    }
                }
            }
            ty::PredicateKind::Projection(proj) => {
                if let ty::Projection(p) = proj.skip_binder().projection_ty.self_ty().kind {
                    if p == assoc_item_ty {
                        return Some(pred);
                    }
                }
            }
            ty::PredicateKind::TypeOutlives(outlives) => {
                if let ty::Projection(p) = outlives.skip_binder().0.kind {
                    if p == assoc_item_ty {
                        return Some(pred);
                    }
                }
            }
            _ => {}
        }
        None
    });
    let result = tcx.mk_predicates(predicates);
    debug!(
        "associated_type_projection_predicates({}) = {:?}",
        tcx.def_path_str(assoc_item_def_id),
        result
    );
    result
}
fn associated_type_projection_predicates ( tcx : TyCtxt < ' _ > , assoc_item_def_id : DefId , ) -> & ' _ ty :: List < ty :: Predicate < ' _ > > { let generic_trait_bounds = tcx . predicates_of ( assoc_item_def_id ) ; // We include predicates from the trait as well to handle // `where Self::X: Trait`. let item_bounds = generic_trait_bounds . instantiate_identity ( tcx ) ; let item_predicates = util :: elaborate_predicates ( tcx , item_bounds . predicates . into_iter ( ) ) ; let assoc_item_ty = ty :: ProjectionTy { item_def_id : assoc_item_def_id , substs : InternalSubsts :: identity_for_item ( tcx , assoc_item_def_id ) , } ; let predicates = item_predicates . filter_map ( | obligation | { let pred = obligation . predicate ; match pred . kind ( ) { ty :: PredicateKind :: Trait ( tr , _ ) => { if let ty :: Projection ( p ) = tr . skip_binder ( ) . self_ty ( ) . kind { if p == assoc_item_ty { return Some ( pred ) ; } } } ty :: PredicateKind :: Projection ( proj ) => { if let ty :: Projection ( p ) = proj . skip_binder ( ) . projection_ty . self_ty ( ) . kind { if p == assoc_item_ty { return Some ( pred ) ; } } } ty :: PredicateKind :: TypeOutlives ( outlives ) => { if let ty :: Projection ( p ) = outlives . skip_binder ( ) . 0 . kind { if p == assoc_item_ty { return Some ( pred ) ; } } } _ => { } } None } ) ; let result = tcx . mk_predicates ( predicates ) ; debug ! ( " " tcx def_path_str ( assoc_item_def_id ) result ) ; result }
For associated types we allow bounds written on the associated type
(`type X: Trait`) to be used as candidates.
For associated types we allow bounds written on the associated type ( ` type X : Trait ` ) to be used as candidates .
tcx
TyCtxt<'_>
assoc_item_def_id
DefId
tcx
TyCtxt<'_>
assoc_item_def_id
DefId