/// Returns whether a borrow of this place is invalidated when the function
/// exits
Returns whether a borrow of this place is invalidated when the function
exits
Returns whether a borrow of this place is invalidated when the function exits
fn check_for_invalidation_at_exit(
        &mut self,
        context: Context,
        borrow: &BorrowData<'tcx>,
        span: Span,
    ) {
        debug!("check_for_invalidation_at_exit({:?})", borrow);
        let place = &borrow.borrowed_place;
        let root_place = self.prefixes(place, PrefixSet::All).last().unwrap();
        // FIXME(nll-rfc#40): do more precise destructor tracking here. For now
        // we just know that all locals are dropped at function exit (otherwise
        // we'll have a memory leak) and assume that all statics have a destructor.
        //
        // FIXME: allow thread-locals to borrow other thread locals?
        let (might_be_alive, will_be_dropped) = match root_place {
            Place::Promoted(_) => (true, false),
            Place::Static(_) => {
                // Thread-locals might be dropped after the function exits, but
                // "true" statics will never be.
                let is_thread_local = self.is_place_thread_local(&root_place);
                (true, is_thread_local)
            }
            Place::Local(_) => {
                // Locals are always dropped at function exit, and if they
                // have a destructor it would've been called already.
                (false, self.locals_are_invalidated_at_exit)
            }
            Place::Projection(..) => {
                bug!("root of {:?} is a projection ({:?})?", place, root_place)
            }
        };
        if !will_be_dropped {
            debug!(
                "place_is_invalidated_at_exit({:?}) - won't be dropped",
                place
            );
            return;
        }
        // FIXME: replace this with a proper borrow_conflicts_with_place when
        // that is merged.
        let sd = if might_be_alive { Deep } else { Shallow(None) };
        if places_conflict::places_conflict(self.tcx, self.mir, place, root_place, sd) {
            debug!("check_for_invalidation_at_exit({:?}): INVALID", place);
            // FIXME: should be talking about the region lifetime instead
            // of just a span here.
            let span = self.tcx.sess.source_map().end_point(span);
            self.report_borrowed_value_does_not_live_long_enough(
                context,
                borrow,
                (place, span),
                None,
            )
        }
    }
fn check_for_invalidation_at_exit ( & mut self , context : Context , borrow : & BorrowData < ' tcx > , span : Span , ) { debug ! ( " " borrow ) ; let place = & borrow . borrowed_place ; let root_place = self . prefixes ( place , PrefixSet :: All ) . last ( ) . unwrap ( ) ; // FIXME(nll-rfc#40): do more precise destructor tracking here. For now // we just know that all locals are dropped at function exit (otherwise // we'll have a memory leak) and assume that all statics have a destructor. // // FIXME: allow thread-locals to borrow other thread locals? let ( might_be_alive , will_be_dropped ) = match root_place { Place :: Promoted ( _ ) => ( true , false ) , Place :: Static ( _ ) => { // Thread-locals might be dropped after the function exits, but // "true" statics will never be. let is_thread_local = self . is_place_thread_local ( & root_place ) ; ( true , is_thread_local ) } Place :: Local ( _ ) => { // Locals are always dropped at function exit, and if they // have a destructor it would've been called already. ( false , self . locals_are_invalidated_at_exit ) } Place :: Projection ( .. ) => { bug ! ( " " place root_place ) } } ; if ! will_be_dropped { debug ! ( " " place ) ; return ; } // FIXME: replace this with a proper borrow_conflicts_with_place when // that is merged. let sd = if might_be_alive { Deep } else { Shallow ( None ) } ; if places_conflict :: places_conflict ( self . tcx , self . mir , place , root_place , sd ) { debug ! ( " " place ) ; // FIXME: should be talking about the region lifetime instead // of just a span here. let span = self . tcx . sess . source_map ( ) . end_point ( span ) ; self . report_borrowed_value_does_not_live_long_enough ( context , borrow , ( place , span ) , None , ) } }
Returns whether a borrow of this place is invalidated when the function
exits
Returns whether a borrow of this place is invalidated when the function exits
&mut self
context
Context
borrow
&BorrowData<'tcx>
span
Span