@@ -22,6 +22,7 @@ use std::cell::RefCell;
2222use std:: marker:: PhantomData ;
2323use std:: ops:: { ControlFlow , Deref } ;
2424
25+ use borrow_set:: LocalsStateAtExit ;
2526use root_cx:: BorrowCheckRootCtxt ;
2627use rustc_abi:: FieldIdx ;
2728use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
@@ -382,7 +383,6 @@ fn do_mir_borrowck<'tcx>(
382383 location_table : & location_table,
383384 movable_coroutine,
384385 fn_self_span_reported : Default :: default ( ) ,
385- locals_are_invalidated_at_exit,
386386 access_place_error_reported : Default :: default ( ) ,
387387 reservation_error_reported : Default :: default ( ) ,
388388 uninitialized_error_reported : Default :: default ( ) ,
@@ -441,7 +441,6 @@ fn do_mir_borrowck<'tcx>(
441441 move_data : & move_data,
442442 location_table : & location_table,
443443 movable_coroutine,
444- locals_are_invalidated_at_exit,
445444 fn_self_span_reported : Default :: default ( ) ,
446445 access_place_error_reported : Default :: default ( ) ,
447446 reservation_error_reported : Default :: default ( ) ,
@@ -643,13 +642,6 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
643642 location_table : & ' a PoloniusLocationTable ,
644643
645644 movable_coroutine : bool ,
646- /// This keeps track of whether local variables are free-ed when the function
647- /// exits even without a `StorageDead`, which appears to be the case for
648- /// constants.
649- ///
650- /// I'm not sure this is the right approach - @eddyb could you try and
651- /// figure this out?
652- locals_are_invalidated_at_exit : bool ,
653645 /// This field keeps track of when borrow errors are reported in the access_place function
654646 /// so that there is no duplicate reporting. This field cannot also be used for the conflicting
655647 /// borrow errors that is handled by the `reservation_error_reported` field as the inclusion
@@ -925,13 +917,20 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<
925917 | TerminatorKind :: Return
926918 | TerminatorKind :: TailCall { .. }
927919 | TerminatorKind :: CoroutineDrop => {
928- // Returning from the function implicitly kills storage for all locals and statics.
929- // Often, the storage will already have been killed by an explicit
930- // StorageDead, but we don't always emit those (notably on unwind paths),
931- // so this "extra check" serves as a kind of backup.
932- for i in state. borrows . iter ( ) {
933- let borrow = & self . borrow_set [ i] ;
934- self . check_for_invalidation_at_exit ( loc, borrow, span) ;
920+ match self . borrow_set . locals_state_at_exit ( ) {
921+ LocalsStateAtExit :: AllAreInvalidated => {
922+ // Returning from the function implicitly kills storage for all locals and statics.
923+ // Often, the storage will already have been killed by an explicit
924+ // StorageDead, but we don't always emit those (notably on unwind paths),
925+ // so this "extra check" serves as a kind of backup.
926+ for i in state. borrows . iter ( ) {
927+ let borrow = & self . borrow_set [ i] ;
928+ self . check_for_invalidation_at_exit ( loc, borrow, span) ;
929+ }
930+ }
931+ // If we do not implicitly invalidate all locals on exit,
932+ // we check for conflicts when dropping or moving this local.
933+ LocalsStateAtExit :: SomeAreInvalidated { has_storage_dead_or_moved : _ } => { }
935934 }
936935 }
937936
@@ -1703,22 +1702,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
17031702 // we'll have a memory leak) and assume that all statics have a destructor.
17041703 //
17051704 // FIXME: allow thread-locals to borrow other thread locals?
1706-
1707- let ( might_be_alive, will_be_dropped) =
1708- if self . body . local_decls [ root_place. local ] . is_ref_to_thread_local ( ) {
1709- // Thread-locals might be dropped after the function exits
1710- // We have to dereference the outer reference because
1711- // borrows don't conflict behind shared references.
1712- root_place. projection = TyCtxtConsts :: DEREF_PROJECTION ;
1713- ( true , true )
1714- } else {
1715- ( false , self . locals_are_invalidated_at_exit )
1716- } ;
1717-
1718- if !will_be_dropped {
1719- debug ! ( "place_is_invalidated_at_exit({:?}) - won't be dropped" , place) ;
1720- return ;
1721- }
1705+ let might_be_alive = if self . body . local_decls [ root_place. local ] . is_ref_to_thread_local ( ) {
1706+ // Thread-locals might be dropped after the function exits
1707+ // We have to dereference the outer reference because
1708+ // borrows don't conflict behind shared references.
1709+ root_place. projection = TyCtxtConsts :: DEREF_PROJECTION ;
1710+ true
1711+ } else {
1712+ false
1713+ } ;
17221714
17231715 let sd = if might_be_alive { Deep } else { Shallow ( None ) } ;
17241716
0 commit comments