fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>(
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    drop_impl_did: DefId,
    dtor_predicates: &ty::GenericPredicates<'tcx>,
    self_type_did: DefId,
    self_to_impl_substs: &Substs<'tcx>)
    -> Result<(), ErrorReported>
{
    let mut result = Ok(());

    // Here is an example, analogous to that from
    // `compare_impl_method`.
    //
    // Consider a struct type:
    //
    //     struct Type<'c, 'b:'c, 'a> {
    //         x: &'a Contents            // (contents are irrelevant;
    //         y: &'c Cell<&'b Contents>, //  only the bounds matter for our purposes.)
    //     }
    //
    // and a Drop impl:
    //
    //     impl<'z, 'y:'z, 'x:'y> Drop for P<'z, 'y, 'x> {
    //         fn drop(&mut self) { self.y.set(self.x); } // (only legal if 'x: 'y)
    //     }
    //
    // We start out with self_to_impl_substs, that maps the generic
    // parameters of Type to that of the Drop impl.
    //
    //     self_to_impl_substs = {'c => 'z, 'b => 'y, 'a => 'x}
    //
    // Applying this to the predicates (i.e. assumptions) provided by the item
    // definition yields the instantiated assumptions:
    //
    //     ['y : 'z]
    //
    // We then check all of the predicates of the Drop impl:
    //
    //     ['y:'z, 'x:'y]
    //
    // and ensure each is in the list of instantiated
    // assumptions. Here, `'y:'z` is present, but `'x:'y` is
    // absent. So we report an error that the Drop impl injected a
    // predicate that is not present on the struct definition.

    let self_type_node_id = tcx.hir.as_local_node_id(self_type_did).unwrap();

    let drop_impl_span = tcx.def_span(drop_impl_did);

    // We can assume the predicates attached to struct/enum definition
    // hold.
    let generic_assumptions = tcx.predicates_of(self_type_did);

    let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs);
    let assumptions_in_impl_context = assumptions_in_impl_context.predicates;

    // An earlier version of this code attempted to do this checking
    // via the traits::fulfill machinery. However, it ran into trouble
    // since the fulfill machinery merely turns outlives-predicates
    // 'a:'b and T:'b into region inference constraints. It is simpler
    // just to look for all the predicates directly.

    assert_eq!(dtor_predicates.parent, None);
    for predicate in &dtor_predicates.predicates {
        // (We do not need to worry about deep analysis of type
        // expressions etc because the Drop impls are already forced
        // to take on a structure that is roughly an alpha-renaming of
        // the generic parameters of the item definition.)

        // This path now just checks *all* predicates via the direct
        // lookup, rather than using fulfill machinery.
        //
        // However, it may be more efficient in the future to batch
        // the analysis together via the fulfill , rather than the
        // repeated `contains` calls.

        if !assumptions_in_impl_context.contains(&predicate) {
            let item_span = tcx.hir.span(self_type_node_id);
            struct_span_err!(tcx.sess, drop_impl_span, E0367,
                             "The requirement `{}` is added only by the Drop impl.", predicate)
                .span_note(item_span,
                           "The same requirement must be part of \
                            the struct/enum definition")
                .emit();
            result = Err(ErrorReported);
        }
    }

    result
}
/// Confirms that every predicate imposed by dtor_predicates is
/// implied by assuming the predicates attached to self_type_did.
Confirms that every predicate imposed by dtor_predicates is
implied by assuming the predicates attached to self_type_did.
Confirms that every predicate imposed by dtor_predicates is implied by assuming the predicates attached to self_type_did .
fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>(
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    drop_impl_did: DefId,
    dtor_predicates: &ty::GenericPredicates<'tcx>,
    self_type_did: DefId,
    self_to_impl_substs: &Substs<'tcx>)
    -> Result<(), ErrorReported>
{
    let mut result = Ok(());
    // Here is an example, analogous to that from
    // `compare_impl_method`.
    //
    // Consider a struct type:
    //
    //     struct Type<'c, 'b:'c, 'a> {
    //         x: &'a Contents            // (contents are irrelevant;
    //         y: &'c Cell<&'b Contents>, //  only the bounds matter for our purposes.)
    //     }
    //
    // and a Drop impl:
    //
    //     impl<'z, 'y:'z, 'x:'y> Drop for P<'z, 'y, 'x> {
    //         fn drop(&mut self) { self.y.set(self.x); } // (only legal if 'x: 'y)
    //     }
    //
    // We start out with self_to_impl_substs, that maps the generic
    // parameters of Type to that of the Drop impl.
    //
    //     self_to_impl_substs = {'c => 'z, 'b => 'y, 'a => 'x}
    //
    // Applying this to the predicates (i.e. assumptions) provided by the item
    // definition yields the instantiated assumptions:
    //
    //     ['y : 'z]
    //
    // We then check all of the predicates of the Drop impl:
    //
    //     ['y:'z, 'x:'y]
    //
    // and ensure each is in the list of instantiated
    // assumptions. Here, `'y:'z` is present, but `'x:'y` is
    // absent. So we report an error that the Drop impl injected a
    // predicate that is not present on the struct definition.
    let self_type_node_id = tcx.hir.as_local_node_id(self_type_did).unwrap();
    let drop_impl_span = tcx.def_span(drop_impl_did);
    // We can assume the predicates attached to struct/enum definition
    // hold.
    let generic_assumptions = tcx.predicates_of(self_type_did);
    let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs);
    let assumptions_in_impl_context = assumptions_in_impl_context.predicates;
    // An earlier version of this code attempted to do this checking
    // via the traits::fulfill machinery. However, it ran into trouble
    // since the fulfill machinery merely turns outlives-predicates
    // 'a:'b and T:'b into region inference constraints. It is simpler
    // just to look for all the predicates directly.
    assert_eq!(dtor_predicates.parent, None);
    for predicate in &dtor_predicates.predicates {
        // (We do not need to worry about deep analysis of type
        // expressions etc because the Drop impls are already forced
        // to take on a structure that is roughly an alpha-renaming of
        // the generic parameters of the item definition.)
        // This path now just checks *all* predicates via the direct
        // lookup, rather than using fulfill machinery.
        //
        // However, it may be more efficient in the future to batch
        // the analysis together via the fulfill , rather than the
        // repeated `contains` calls.
        if !assumptions_in_impl_context.contains(&predicate) {
            let item_span = tcx.hir.span(self_type_node_id);
            struct_span_err!(tcx.sess, drop_impl_span, E0367,
                             "The requirement `{}` is added only by the Drop impl.", predicate)
                .span_note(item_span,
                           "The same requirement must be part of \
                            the struct/enum definition")
                .emit();
            result = Err(ErrorReported);
        }
    }
    result
}
fn ensure_drop_predicates_are_implied_by_item_defn < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , drop_impl_did : DefId , dtor_predicates : & ty :: GenericPredicates < ' tcx > , self_type_did : DefId , self_to_impl_substs : & Substs < ' tcx > ) -> Result < ( ) , ErrorReported > { let mut result = Ok ( ( ) ) ; // Here is an example, analogous to that from // `compare_impl_method`. // // Consider a struct type: // //     struct Type<'c, 'b:'c, 'a> { //         x: &'a Contents            // (contents are irrelevant; //         y: &'c Cell<&'b Contents>, //  only the bounds matter for our purposes.) //     } // // and a Drop impl: // //     impl<'z, 'y:'z, 'x:'y> Drop for P<'z, 'y, 'x> { //         fn drop(&mut self) { self.y.set(self.x); } // (only legal if 'x: 'y) //     } // // We start out with self_to_impl_substs, that maps the generic // parameters of Type to that of the Drop impl. // //     self_to_impl_substs = {'c => 'z, 'b => 'y, 'a => 'x} // // Applying this to the predicates (i.e. assumptions) provided by the item // definition yields the instantiated assumptions: // //     ['y : 'z] // // We then check all of the predicates of the Drop impl: // //     ['y:'z, 'x:'y] // // and ensure each is in the list of instantiated // assumptions. Here, `'y:'z` is present, but `'x:'y` is // absent. So we report an error that the Drop impl injected a // predicate that is not present on the struct definition. let self_type_node_id = tcx . hir . as_local_node_id ( self_type_did ) . unwrap ( ) ; let drop_impl_span = tcx . def_span ( drop_impl_did ) ; // We can assume the predicates attached to struct/enum definition // hold. let generic_assumptions = tcx . predicates_of ( self_type_did ) ; let assumptions_in_impl_context = generic_assumptions . instantiate ( tcx , & self_to_impl_substs ) ; let assumptions_in_impl_context = assumptions_in_impl_context . predicates ; // An earlier version of this code attempted to do this checking // via the traits::fulfill machinery. However, it ran into trouble // since the fulfill machinery merely turns outlives-predicates // 'a:'b and T:'b into region inference constraints. It is simpler // just to look for all the predicates directly. assert_eq ! ( dtor_predicates parent None ) ; for predicate in & dtor_predicates . predicates { // (We do not need to worry about deep analysis of type // expressions etc because the Drop impls are already forced // to take on a structure that is roughly an alpha-renaming of // the generic parameters of the item definition.) // This path now just checks *all* predicates via the direct // lookup, rather than using fulfill machinery. // // However, it may be more efficient in the future to batch // the analysis together via the fulfill , rather than the // repeated `contains` calls. if ! assumptions_in_impl_context . contains ( & predicate ) { let item_span = tcx . hir . span ( self_type_node_id ) ; struct_span_err ! ( tcx sess drop_impl_span E0367 " " predicate ) . span_note ( item_span , " \
 " ) . emit ( ) ; result = Err ( ErrorReported ) ; } } result }
Confirms that every predicate imposed by dtor_predicates is
implied by assuming the predicates attached to self_type_did.
Confirms that every predicate imposed by dtor_predicates is implied by assuming the predicates attached to self_type_did .
tcx
TyCtxt<'a, 'tcx, 'tcx>
drop_impl_did
DefId
dtor_predicates
&ty::GenericPredicates<'tcx>
self_type_did
DefId
self_to_impl_substs
&Substs<'tcx>
tcx
TyCtxt<'a, 'tcx, 'tcx>
drop_impl_did
DefId
dtor_predicates
&ty::GenericPredicates<'tcx>
self_type_did
DefId
self_to_impl_substs
&Substs<'tcx>