Skip to content

Commit c5fdddc

Browse files
committed
don't rely on locals_are_invalidated_at_exit
1 parent 2c65469 commit c5fdddc

File tree

1 file changed

+24
-32
lines changed
  • compiler/rustc_borrowck/src

1 file changed

+24
-32
lines changed

Diff for: compiler/rustc_borrowck/src/lib.rs

+24-32
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use std::cell::RefCell;
2222
use std::marker::PhantomData;
2323
use std::ops::{ControlFlow, Deref};
2424

25+
use borrow_set::LocalsStateAtExit;
2526
use root_cx::BorrowCheckRootCtxt;
2627
use rustc_abi::FieldIdx;
2728
use 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

Comments
 (0)