@@ -548,14 +548,13 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
548
548
549
549
if self . place_is_invalidated_at_exit ( & borrow. place ) {
550
550
debug ! ( "borrow conflicts at exit {:?}" , borrow) ;
551
- let borrow_span = self . mir . source_info ( borrow. location ) . span ;
552
551
// FIXME: should be talking about the region lifetime instead
553
552
// of just a span here.
554
553
let end_span = domain. opt_region_end_span ( & borrow. region ) ;
555
554
556
555
self . report_borrowed_value_does_not_live_long_enough (
557
556
ContextKind :: StorageDead . new ( loc) ,
558
- ( & borrow. place , borrow_span ) ,
557
+ ( & borrow. place , end_span . unwrap_or ( span ) ) ,
559
558
end_span,
560
559
)
561
560
}
@@ -958,7 +957,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
958
957
959
958
/// Returns whether a borrow of this place is invalidated when the function
960
959
/// 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 {
962
961
debug ! ( "place_is_invalidated_at_exit({:?})" , place) ;
963
962
let root_place = self . prefixes ( place, PrefixSet :: All ) . last ( ) . unwrap ( ) ;
964
963
@@ -967,7 +966,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
967
966
// we'll have a memory leak) and assume that all statics have a destructor.
968
967
//
969
968
// 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 {
971
970
Place :: Static ( statik) => {
972
971
// Thread-locals might be dropped after the function exits, but
973
972
// "true" statics will never be.
@@ -976,12 +975,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
976
975
. iter ( )
977
976
. any ( |attr| attr. check_name ( "thread_local" ) ) ;
978
977
979
- ( true , is_thread_local)
978
+ ( true , is_thread_local, None )
980
979
}
981
- Place :: Local ( _ ) => {
980
+ Place :: Local ( local ) => {
982
981
// Locals are always dropped at function exit, and if they
983
982
// 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 ) )
985
984
}
986
985
Place :: Projection ( ..) => {
987
986
bug ! ( "root of {:?} is a projection ({:?})?" , place, root_place)
@@ -1004,8 +1003,19 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1004
1003
PrefixSet :: Shallow
1005
1004
} ;
1006
1005
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
1009
1019
}
1010
1020
}
1011
1021
0 commit comments