pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>(
    rcx: &mut RegionCtxt<'a, 'gcx, 'tcx>,
    ty: Ty<'tcx>,
    span: Span,
    body_id: ast::NodeId,
    scope: region::Scope)
    -> Result<(), ErrorReported>
{
    debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}",
           ty, scope);


    let parent_scope = match rcx.region_scope_tree.opt_encl_scope(scope) {
        Some(parent_scope) => parent_scope,
        // If no enclosing scope, then it must be the root scope
        // which cannot be outlived.
        None => return Ok(())
    };
    let parent_scope = rcx.tcx.mk_region(ty::ReScope(parent_scope));
    let origin = || infer::SubregionOrigin::SafeDestructor(span);
    let cause = &ObligationCause::misc(span, body_id);
    let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty);
    debug!("dropck_outlives = {:#?}", infer_ok);
    let kinds = rcx.fcx.register_infer_ok_obligations(infer_ok);
    for kind in kinds {
        match kind.unpack() {
            UnpackedKind::Lifetime(r) => rcx.sub_regions(origin(), parent_scope, r),
            UnpackedKind::Type(ty) => rcx.type_must_outlive(origin(), ty, parent_scope),
        }
    }
    Ok(())
}
/// check_safety_of_destructor_if_necessary confirms that the type
/// expression `typ` conforms to the "Drop Check Rule" from the Sound
/// Generic Drop (RFC 769).
///
/// ----
///
/// The simplified (*) Drop Check Rule is the following:
///
/// Let `v` be some value (either temporary or named) and 'a be some
/// lifetime (scope). If the type of `v` owns data of type `D`, where
///
/// * (1.) `D` has a lifetime- or type-parametric Drop implementation,
///        (where that `Drop` implementation does not opt-out of
///         this check via the `unsafe_destructor_blind_to_params`
///         attribute), and
/// * (2.) the structure of `D` can reach a reference of type `&'a _`,
///
/// then 'a must strictly outlive the scope of v.
///
/// ----
///
/// This function is meant to by applied to the type for every
/// expression in the program.
///
/// ----
///
/// (*) The qualifier "simplified" is attached to the above
/// definition of the Drop Check Rule, because it is a simplification
/// of the original Drop Check rule, which attempted to prove that
/// some `Drop` implementations could not possibly access data even if
/// it was technically reachable, due to parametricity.
///
/// However, (1.) parametricity on its own turned out to be a
/// necessary but insufficient condition, and (2.)  future changes to
/// the language are expected to make it impossible to ensure that a
/// `Drop` implementation is actually parametric with respect to any
/// particular type parameter. (In particular, impl specialization is
/// expected to break the needed parametricity property beyond
/// repair.)
///
/// Therefore we have scaled back Drop-Check to a more conservative
/// rule that does not attempt to deduce whether a `Drop`
/// implementation could not possible access data of a given lifetime;
/// instead Drop-Check now simply assumes that if a destructor has
/// access (direct or indirect) to a lifetime parameter, then that
/// lifetime must be forced to outlive that destructor's dynamic
/// extent. We then provide the `unsafe_destructor_blind_to_params`
/// attribute as a way for destructor implementations to opt-out of
/// this conservative assumption (and thus assume the obligation of
/// ensuring that they do not access data nor invoke methods of
/// values that have been previously dropped).
///
check_safety_of_destructor_if_necessary confirms that the type
expression `typ` conforms to the "Drop Check Rule" from the Sound
Generic Drop (RFC 769).



The simplified (*) Drop Check Rule is the following.

Let `v` be some value (either temporary or named) and 'a be some
lifetime (scope). If the type of `v` owns data of type `D`, where



then 'a must strictly outlive the scope of v.



This function is meant to by applied to the type for every
expression in the program.



(*) The qualifier "simplified" is attached to the above
definition of the Drop Check Rule, because it is a simplification
of the original Drop Check rule, which attempted to prove that
some `Drop` implementations could not possibly access data even if
it was technically reachable, due to parametricity.

However, (1.) parametricity on its own turned out to be a
necessary but insufficient condition, and (2.)  future changes to
the language are expected to make it impossible to ensure that a
`Drop` implementation is actually parametric with respect to any
particular type parameter. (In particular, impl specialization is
expected to break the needed parametricity property beyond
repair.)

Therefore we have scaled back Drop-Check to a more conservative
rule that does not attempt to deduce whether a `Drop`
implementation could not possible access data of a given lifetime;
instead Drop-Check now simply assumes that if a destructor has
access (direct or indirect) to a lifetime parameter, then that
lifetime must be forced to outlive that destructor's dynamic
extent. We then provide the `unsafe_destructor_blind_to_params`
attribute as a way for destructor implementations to opt-out of
this conservative assumption (and thus assume the obligation of
ensuring that they do not access data nor invoke methods of
values that have been previously dropped).
check_safety_of_destructor_if_necessary confirms that the type expression ` typ ` conforms to the " Drop Check Rule " from the Sound Generic Drop ( RFC 769 ) . The simplified ( * ) Drop Check Rule is the following . Let ` v ` be some value ( either temporary or named ) and ' a be some lifetime ( scope ) . If the type of ` v ` owns data of type ` D ` where then ' a must strictly outlive the scope of v . This function is meant to by applied to the type for every expression in the program . ( * ) The qualifier " simplified " is attached to the above definition of the Drop Check Rule because it is a simplification of the original Drop Check rule which attempted to prove that some ` Drop ` implementations could not possibly access data even if it was technically reachable due to parametricity . However ( 1 . ) parametricity on its own turned out to be a necessary but insufficient condition and ( 2 . ) future changes to the language are expected to make it impossible to ensure that a ` Drop ` implementation is actually parametric with respect to any particular type parameter . ( In particular impl specialization is expected to break the needed parametricity property beyond repair . ) Therefore we have scaled back Drop - Check to a more conservative rule that does not attempt to deduce whether a ` Drop ` implementation could not possible access data of a given lifetime ; instead Drop - Check now simply assumes that if a destructor has access ( direct or indirect ) to a lifetime parameter then that lifetime must be forced to outlive that destructor ' s dynamic extent . We then provide the ` unsafe_destructor_blind_to_params ` attribute as a way for destructor implementations to opt - out of this conservative assumption ( and thus assume the obligation of ensuring that they do not access data nor invoke methods of values that have been previously dropped ) .
pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>(
    rcx: &mut RegionCtxt<'a, 'gcx, 'tcx>,
    ty: Ty<'tcx>,
    span: Span,
    body_id: ast::NodeId,
    scope: region::Scope)
    -> Result<(), ErrorReported>
{
    debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}",
           ty, scope);
    let parent_scope = match rcx.region_scope_tree.opt_encl_scope(scope) {
        Some(parent_scope) => parent_scope,
        // If no enclosing scope, then it must be the root scope
        // which cannot be outlived.
        None => return Ok(())
    };
    let parent_scope = rcx.tcx.mk_region(ty::ReScope(parent_scope));
    let origin = || infer::SubregionOrigin::SafeDestructor(span);
    let cause = &ObligationCause::misc(span, body_id);
    let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty);
    debug!("dropck_outlives = {:#?}", infer_ok);
    let kinds = rcx.fcx.register_infer_ok_obligations(infer_ok);
    for kind in kinds {
        match kind.unpack() {
            UnpackedKind::Lifetime(r) => rcx.sub_regions(origin(), parent_scope, r),
            UnpackedKind::Type(ty) => rcx.type_must_outlive(origin(), ty, parent_scope),
        }
    }
    Ok(())
}
pub fn check_safety_of_destructor_if_necessary < ' a , ' gcx , ' tcx > ( rcx : & mut RegionCtxt < ' a , ' gcx , ' tcx > , ty : Ty < ' tcx > , span : Span , body_id : ast :: NodeId , scope : region :: Scope ) -> Result < ( ) , ErrorReported > { debug ! ( " " ty scope ) ; let parent_scope = match rcx . region_scope_tree . opt_encl_scope ( scope ) { Some ( parent_scope ) => parent_scope , // If no enclosing scope, then it must be the root scope // which cannot be outlived. None => return Ok ( ( ) ) } ; let parent_scope = rcx . tcx . mk_region ( ty :: ReScope ( parent_scope ) ) ; let origin = | | infer :: SubregionOrigin :: SafeDestructor ( span ) ; let cause = & ObligationCause :: misc ( span , body_id ) ; let infer_ok = rcx . infcx . at ( cause , rcx . fcx . param_env ) . dropck_outlives ( ty ) ; debug ! ( " " infer_ok ) ; let kinds = rcx . fcx . register_infer_ok_obligations ( infer_ok ) ; for kind in kinds { match kind . unpack ( ) { UnpackedKind :: Lifetime ( r ) => rcx . sub_regions ( origin ( ) , parent_scope , r ) , UnpackedKind :: Type ( ty ) => rcx . type_must_outlive ( origin ( ) , ty , parent_scope ) , } } Ok ( ( ) ) }
check_safety_of_destructor_if_necessary confirms that the type
expression `typ` conforms to the "Drop Check Rule" from the Sound
Generic Drop (RFC 769).
check_safety_of_destructor_if_necessary confirms that the type expression ` typ ` conforms to the " Drop Check Rule " from the Sound Generic Drop ( RFC 769 ) .
rcx
&mut RegionCtxt<'a, 'gcx, 'tcx>
ty
Ty<'tcx>
span
Span
body_id
ast::NodeId
scope
region::Scope
rcx
&mut RegionCtxt<'a, 'gcx, 'tcx>
ty
Ty<'tcx>
span
Span
body_id
ast::NodeId
scope
region::Scope