Skip to content

Commit cbcae7f

Browse files
committed
improve conflict error reporting
1 parent f8c35d9 commit cbcae7f

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

src/librustc_mir/borrow_check/mod.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -548,14 +548,13 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
548548

549549
if self.place_is_invalidated_at_exit(&borrow.place) {
550550
debug!("borrow conflicts at exit {:?}", borrow);
551-
let borrow_span = self.mir.source_info(borrow.location).span;
552551
// FIXME: should be talking about the region lifetime instead
553552
// of just a span here.
554553
let end_span = domain.opt_region_end_span(&borrow.region);
555554

556555
self.report_borrowed_value_does_not_live_long_enough(
557556
ContextKind::StorageDead.new(loc),
558-
(&borrow.place, borrow_span),
557+
(&borrow.place, end_span.unwrap_or(span)),
559558
end_span,
560559
)
561560
}
@@ -958,7 +957,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
958957

959958
/// Returns whether a borrow of this place is invalidated when the function
960959
/// exits
961-
fn place_is_invalidated_at_exit(&self, place: &Place<'tcx>) -> bool {
960+
fn place_is_invalidated_at_exit(&mut self, place: &Place<'tcx>) -> bool {
962961
debug!("place_is_invalidated_at_exit({:?})", place);
963962
let root_place = self.prefixes(place, PrefixSet::All).last().unwrap();
964963

@@ -967,7 +966,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
967966
// we'll have a memory leak) and assume that all statics have a destructor.
968967
//
969968
// FIXME: allow thread-locals to borrow other thread locals?x
970-
let (might_be_alive, will_be_dropped) = match root_place {
969+
let (might_be_alive, will_be_dropped, local) = match root_place {
971970
Place::Static(statik) => {
972971
// Thread-locals might be dropped after the function exits, but
973972
// "true" statics will never be.
@@ -976,12 +975,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
976975
.iter()
977976
.any(|attr| attr.check_name("thread_local"));
978977

979-
(true, is_thread_local)
978+
(true, is_thread_local, None)
980979
}
981-
Place::Local(_) => {
980+
Place::Local(local) => {
982981
// Locals are always dropped at function exit, and if they
983982
// have a destructor it would've been called already.
984-
(false, self.locals_are_invalidated_at_exit)
983+
(false, self.locals_are_invalidated_at_exit, Some(*local))
985984
}
986985
Place::Projection(..) => {
987986
bug!("root of {:?} is a projection ({:?})?", place, root_place)
@@ -1004,8 +1003,19 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
10041003
PrefixSet::Shallow
10051004
};
10061005

1007-
self.prefixes(place, prefix_set)
1008-
.any(|prefix| prefix == root_place)
1006+
let result =
1007+
self.prefixes(place, prefix_set).any(|prefix| prefix == root_place);
1008+
1009+
if result {
1010+
if let Some(local) = local {
1011+
if let Some(_) = self.storage_dead_or_drop_error_reported.replace(local) {
1012+
debug!("place_is_invalidated_at_exit({:?}) - suppressed", place);
1013+
return false;
1014+
}
1015+
}
1016+
}
1017+
1018+
result
10091019
}
10101020
}
10111021

src/test/compile-fail/borrowck/borrowck-local-borrow-outlives-fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
fn cplusplus_mode(x: isize) -> &'static isize {
1515
&x //[ast]~ ERROR `x` does not live long enough
16-
//[mir]~^ ERROR borrowed value does not live long enough
1716
}
17+
//[mir]~^ ERROR borrowed value does not live long enough
1818

1919
fn main() {}

src/test/compile-fail/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
fn cplusplus_mode_exceptionally_unsafe(x: &mut Option<&'static mut isize>) {
1515
let mut z = (0, 0);
1616
*x = Some(&mut z.1); //[ast]~ ERROR [E0597]
17-
//[mir]~^ ERROR [E0597]
1817
panic!("catch me for a dangling pointer!")
1918
}
19+
//[mir]~^ ERROR [E0597]
2020

2121
fn main() {
2222
cplusplus_mode_exceptionally_unsafe(&mut None);

0 commit comments

Comments
 (0)