pub fn implied_bounds<'a, 'gcx, 'tcx>(
    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
    body_id: ast::NodeId,
    ty: Ty<'tcx>,
    span: Span)
    -> Vec<ImpliedBound<'tcx>>
{
    // Sometimes when we ask what it takes for T: WF, we get back that
    // U: WF is required; in that case, we push U onto this stack and
    // process it next. Currently (at least) these resulting
    // predicates are always guaranteed to be a subset of the original
    // type, so we need not fear non-termination.
    let mut wf_types = vec![ty];

    let mut implied_bounds = vec![];

    while let Some(ty) = wf_types.pop() {
        // Compute the obligations for `ty` to be well-formed. If `ty` is
        // an unresolved inference variable, just substituted an empty set
        // -- because the return type here is going to be things we *add*
        // to the environment, it's always ok for this set to be smaller
        // than the ultimate set. (Note: normally there won't be
        // unresolved inference variables here anyway, but there might be
        // during typeck under some circumstances.)
        let obligations = obligations(infcx, body_id, ty, span).unwrap_or(vec![]);

        // From the full set of obligations, just filter down to the
        // region relationships.
        implied_bounds.extend(
            obligations
            .into_iter()
            .flat_map(|obligation| {
                assert!(!obligation.has_escaping_regions());
                match obligation.predicate {
                    ty::Predicate::Trait(..) |
                    ty::Predicate::Equate(..) |
                    ty::Predicate::Subtype(..) |
                    ty::Predicate::Projection(..) |
                    ty::Predicate::ClosureKind(..) |
                    ty::Predicate::ObjectSafe(..) =>
                        vec![],

                    ty::Predicate::WellFormed(subty) => {
                        wf_types.push(subty);
                        vec![]
                    }

                    ty::Predicate::RegionOutlives(ref data) =>
                        match infcx.tcx.no_late_bound_regions(data) {
                            None =>
                                vec![],
                            Some(ty::OutlivesPredicate(r_a, r_b)) =>
                                vec![ImpliedBound::RegionSubRegion(r_b, r_a)],
                        },

                    ty::Predicate::TypeOutlives(ref data) =>
                        match infcx.tcx.no_late_bound_regions(data) {
                            None => vec![],
                            Some(ty::OutlivesPredicate(ty_a, r_b)) => {
                                let ty_a = infcx.resolve_type_vars_if_possible(&ty_a);
                                let components = infcx.tcx.outlives_components(ty_a);
                                implied_bounds_from_components(r_b, components)
                            }
                        },
                }}));
    }

    implied_bounds
}
/// Compute the implied bounds that a callee/impl can assume based on
/// the fact that caller/projector has ensured that `ty` is WF.  See
/// the `ImpliedBound` type for more details.
Compute the implied bounds that a callee/impl can assume based on
the fact that caller/projector has ensured that `ty` is WF.  See
the `ImpliedBound` type for more details.
Compute the implied bounds that a callee / impl can assume based on the fact that caller / projector has ensured that ` ty ` is WF . See the ` ImpliedBound ` type for more details .
pub fn implied_bounds<'a, 'gcx, 'tcx>(
    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
    body_id: ast::NodeId,
    ty: Ty<'tcx>,
    span: Span)
    -> Vec<ImpliedBound<'tcx>>
{
    // Sometimes when we ask what it takes for T: WF, we get back that
    // U: WF is required; in that case, we push U onto this stack and
    // process it next. Currently (at least) these resulting
    // predicates are always guaranteed to be a subset of the original
    // type, so we need not fear non-termination.
    let mut wf_types = vec![ty];
    let mut implied_bounds = vec![];
    while let Some(ty) = wf_types.pop() {
        // Compute the obligations for `ty` to be well-formed. If `ty` is
        // an unresolved inference variable, just substituted an empty set
        // -- because the return type here is going to be things we *add*
        // to the environment, it's always ok for this set to be smaller
        // than the ultimate set. (Note: normally there won't be
        // unresolved inference variables here anyway, but there might be
        // during typeck under some circumstances.)
        let obligations = obligations(infcx, body_id, ty, span).unwrap_or(vec![]);
        // From the full set of obligations, just filter down to the
        // region relationships.
        implied_bounds.extend(
            obligations
            .into_iter()
            .flat_map(|obligation| {
                assert!(!obligation.has_escaping_regions());
                match obligation.predicate {
                    ty::Predicate::Trait(..) |
                    ty::Predicate::Equate(..) |
                    ty::Predicate::Subtype(..) |
                    ty::Predicate::Projection(..) |
                    ty::Predicate::ClosureKind(..) |
                    ty::Predicate::ObjectSafe(..) =>
                        vec![],
                    ty::Predicate::WellFormed(subty) => {
                        wf_types.push(subty);
                        vec![]
                    }
                    ty::Predicate::RegionOutlives(ref data) =>
                        match infcx.tcx.no_late_bound_regions(data) {
                            None =>
                                vec![],
                            Some(ty::OutlivesPredicate(r_a, r_b)) =>
                                vec![ImpliedBound::RegionSubRegion(r_b, r_a)],
                        },
                    ty::Predicate::TypeOutlives(ref data) =>
                        match infcx.tcx.no_late_bound_regions(data) {
                            None => vec![],
                            Some(ty::OutlivesPredicate(ty_a, r_b)) => {
                                let ty_a = infcx.resolve_type_vars_if_possible(&ty_a);
                                let components = infcx.tcx.outlives_components(ty_a);
                                implied_bounds_from_components(r_b, components)
                            }
                        },
                }}));
    }
    implied_bounds
}
pub fn implied_bounds < ' a , ' gcx , ' tcx > ( infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > , body_id : ast :: NodeId , ty : Ty < ' tcx > , span : Span ) -> Vec < ImpliedBound < ' tcx > > { // Sometimes when we ask what it takes for T: WF, we get back that // U: WF is required; in that case, we push U onto this stack and // process it next. Currently (at least) these resulting // predicates are always guaranteed to be a subset of the original // type, so we need not fear non-termination. let mut wf_types = vec ! [ ty ] ; let mut implied_bounds = vec ! [ ] ; while let Some ( ty ) = wf_types . pop ( ) { // Compute the obligations for `ty` to be well-formed. If `ty` is // an unresolved inference variable, just substituted an empty set // -- because the return type here is going to be things we *add* // to the environment, it's always ok for this set to be smaller // than the ultimate set. (Note: normally there won't be // unresolved inference variables here anyway, but there might be // during typeck under some circumstances.) let obligations = obligations ( infcx , body_id , ty , span ) . unwrap_or ( vec ! [ ] ) ; // From the full set of obligations, just filter down to the // region relationships. implied_bounds . extend ( obligations . into_iter ( ) . flat_map ( | obligation | { assert ! ( obligation has_escaping_regions ( ) ) ; match obligation . predicate { ty :: Predicate :: Trait ( .. ) | ty :: Predicate :: Equate ( .. ) | ty :: Predicate :: Subtype ( .. ) | ty :: Predicate :: Projection ( .. ) | ty :: Predicate :: ClosureKind ( .. ) | ty :: Predicate :: ObjectSafe ( .. ) => vec ! [ ] , ty :: Predicate :: WellFormed ( subty ) => { wf_types . push ( subty ) ; vec ! [ ] } ty :: Predicate :: RegionOutlives ( ref data ) => match infcx . tcx . no_late_bound_regions ( data ) { None => vec ! [ ] , Some ( ty :: OutlivesPredicate ( r_a , r_b ) ) => vec ! [ ImpliedBound RegionSubRegion ( r_b r_a ) ] , } , ty :: Predicate :: TypeOutlives ( ref data ) => match infcx . tcx . no_late_bound_regions ( data ) { None => vec ! [ ] , Some ( ty :: OutlivesPredicate ( ty_a , r_b ) ) => { let ty_a = infcx . resolve_type_vars_if_possible ( & ty_a ) ; let components = infcx . tcx . outlives_components ( ty_a ) ; implied_bounds_from_components ( r_b , components ) } } , } } ) ) ; } implied_bounds }
Compute the implied bounds that a callee/impl can assume based on
the fact that caller/projector has ensured that `ty` is WF.
Compute the implied bounds that a callee / impl can assume based on the fact that caller / projector has ensured that ` ty ` is WF .
infcx
&'a InferCtxt<'a, 'gcx, 'tcx>
body_id
ast::NodeId
ty
Ty<'tcx>
span
Span
infcx
&'a InferCtxt<'a, 'gcx, 'tcx>
body_id
ast::NodeId
ty
Ty<'tcx>
span
Span