@@ -22,6 +22,7 @@ use std::cell::RefCell;
22
22
use std:: marker:: PhantomData ;
23
23
use std:: ops:: { ControlFlow , Deref } ;
24
24
25
+ use borrow_set:: LocalsStateAtExit ;
25
26
use root_cx:: BorrowCheckRootCtxt ;
26
27
use rustc_abi:: FieldIdx ;
27
28
use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
@@ -382,7 +383,6 @@ fn do_mir_borrowck<'tcx>(
382
383
location_table : & location_table,
383
384
movable_coroutine,
384
385
fn_self_span_reported : Default :: default ( ) ,
385
- locals_are_invalidated_at_exit,
386
386
access_place_error_reported : Default :: default ( ) ,
387
387
reservation_error_reported : Default :: default ( ) ,
388
388
uninitialized_error_reported : Default :: default ( ) ,
@@ -441,7 +441,6 @@ fn do_mir_borrowck<'tcx>(
441
441
move_data : & move_data,
442
442
location_table : & location_table,
443
443
movable_coroutine,
444
- locals_are_invalidated_at_exit,
445
444
fn_self_span_reported : Default :: default ( ) ,
446
445
access_place_error_reported : Default :: default ( ) ,
447
446
reservation_error_reported : Default :: default ( ) ,
@@ -643,13 +642,6 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
643
642
location_table : & ' a PoloniusLocationTable ,
644
643
645
644
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 ,
653
645
/// This field keeps track of when borrow errors are reported in the access_place function
654
646
/// so that there is no duplicate reporting. This field cannot also be used for the conflicting
655
647
/// 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<
925
917
| TerminatorKind :: Return
926
918
| TerminatorKind :: TailCall { .. }
927
919
| 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 : _ } => { }
935
934
}
936
935
}
937
936
@@ -1703,22 +1702,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
1703
1702
// we'll have a memory leak) and assume that all statics have a destructor.
1704
1703
//
1705
1704
// 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
+ } ;
1722
1714
1723
1715
let sd = if might_be_alive { Deep } else { Shallow ( None ) } ;
1724
1716
0 commit comments