@@ -1274,6 +1274,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
12741274 }
12751275 }
12761276
1277+ fn pinned_borrows < ' s > (
1278+ & self ,
1279+ state : & ' s BorrowckDomain ,
1280+ ) -> Option < & ' s MixedBitSet < BorrowIndex > > {
1281+ // FIXME(pin_ergonomics): borrowck behaviors depend on a safe trait
1282+ // which should not contain any safety invariants.
1283+ // if place
1284+ // .ty(self.body, self.infcx.tcx)
1285+ // .ty
1286+ // .is_unpin(self.infcx.tcx, self.body.typing_env(self.infcx.tcx))
1287+ // {
1288+ // None
1289+ // } else {
1290+ Some ( & state. pinned_borrows )
1291+ // }
1292+ }
1293+
12771294 #[ instrument( level = "debug" , skip( self , state) ) ]
12781295 fn check_access_for_conflict (
12791296 & mut self ,
@@ -1286,7 +1303,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
12861303 let mut error_reported = false ;
12871304
12881305 let borrows_in_scope = self . borrows_in_scope ( location, state) ;
1289- let pinned_borrows = & state . pinned_borrows ;
1306+ let pinned_borrows = self . pinned_borrows ( state ) ;
12901307
12911308 each_borrow_involving_path (
12921309 self ,
@@ -1295,7 +1312,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
12951312 ( sd, place_span. 0 ) ,
12961313 self . borrow_set ,
12971314 |borrow_index| {
1298- borrows_in_scope. contains ( borrow_index) || pinned_borrows. contains ( borrow_index)
1315+ borrows_in_scope. contains ( borrow_index)
1316+ || pinned_borrows. is_some_and ( |p| p. contains ( borrow_index) )
12991317 } ,
13001318 |this, borrow_index, borrow| match ( rw, borrow. kind ) {
13011319 // Obviously an activation is compatible with its own
@@ -1333,6 +1351,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
13331351 ControlFlow :: Continue ( ( ) )
13341352 }
13351353
1354+ // Ignore the expired borrow (pinnedness never conflicts with a read)
1355+ ( Read ( _) , BorrowKind :: Mut { .. } ) if !borrows_in_scope. contains ( borrow_index) => {
1356+ ControlFlow :: Continue ( ( ) )
1357+ }
1358+
13361359 ( Read ( kind) , BorrowKind :: Mut { .. } ) => {
13371360 // Reading from mere reservations of mutable-borrows is OK.
13381361 if !is_active ( this. dominators ( ) , borrow, location) {
@@ -1356,19 +1379,44 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
13561379 ControlFlow :: Break ( ( ) )
13571380 }
13581381
1359- ( Reservation ( kind) | Activation ( kind, _) | Write ( kind) , _) => {
1360- if pinned_borrows. contains ( borrow_index)
1361- && !borrows_in_scope. contains ( borrow_index)
1362- {
1363- // drop or write to the place is allowed after pinning
1364- if matches ! (
1365- kind,
1366- WriteKind :: StorageDeadOrDrop | WriteKind :: Mutate | WriteKind :: Replace
1367- ) {
1368- return ControlFlow :: Continue ( ( ) ) ;
1382+ // Handle the expired borrows (only pinned borrows)
1383+ ( Reservation ( kind) | Activation ( kind, _) | Write ( kind) , _)
1384+ if !borrows_in_scope. contains ( borrow_index) =>
1385+ {
1386+ debug_assert ! (
1387+ pinned_borrows. is_none_or( |p| p. contains( borrow_index) ) ,
1388+ "unexpected expired but non-pinned borrow {borrow_index:?}: {borrow:?}" ,
1389+ ) ;
1390+ match kind {
1391+ // Pinnedness doesn't conflict with a drop or write
1392+ WriteKind :: StorageDeadOrDrop | WriteKind :: Mutate | WriteKind :: Replace => {
1393+ ControlFlow :: Continue ( ( ) )
1394+ }
1395+ // Mutable (pinned) borrow doesn't conflict with an expired borrow
1396+ WriteKind :: MutableBorrow ( _)
1397+ if self
1398+ . borrow_set
1399+ . location_map
1400+ . get ( & location)
1401+ . is_none_or ( |b| b. pinnedness . is_pinned ( ) ) =>
1402+ {
1403+ ControlFlow :: Continue ( ( ) )
1404+ }
1405+ // Mutable (but non-pinned) borrow conflicts with an earlier pinned borrow
1406+ WriteKind :: MutableBorrow ( _) => {
1407+ this. report_mutably_borrow_after_pinned ( location, place_span, borrow) ;
1408+ error_reported = true ;
1409+ ControlFlow :: Break ( ( ) )
1410+ }
1411+ WriteKind :: Move => {
1412+ this. report_move_after_pinned ( location, place_span, borrow) ;
1413+ error_reported = true ;
1414+ ControlFlow :: Break ( ( ) )
13691415 }
13701416 }
1417+ }
13711418
1419+ ( Reservation ( kind) | Activation ( kind, _) | Write ( kind) , _) => {
13721420 match rw {
13731421 Reservation ( ..) => {
13741422 debug ! (
@@ -1391,15 +1439,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
13911439 error_reported = true ;
13921440 match kind {
13931441 WriteKind :: MutableBorrow ( bk) => {
1394- if pinned_borrows. contains ( borrow_index) {
1395- this. report_mutably_borrow_after_pinned (
1396- location, place_span, borrow,
1397- ) ;
1398- } else {
1399- let err = this
1400- . report_conflicting_borrow ( location, place_span, bk, borrow) ;
1401- this. buffer_error ( err) ;
1402- }
1442+ let err =
1443+ this. report_conflicting_borrow ( location, place_span, bk, borrow) ;
1444+ this. buffer_error ( err) ;
14031445 }
14041446 WriteKind :: StorageDeadOrDrop => this
14051447 . report_borrowed_value_does_not_live_long_enough (
@@ -1412,11 +1454,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
14121454 this. report_illegal_mutation_of_borrowed ( location, place_span, borrow)
14131455 }
14141456 WriteKind :: Move => {
1415- if pinned_borrows. contains ( borrow_index) {
1416- this. report_move_after_pinned ( location, place_span, borrow) ;
1417- } else {
1418- this. report_move_out_while_borrowed ( location, place_span, borrow)
1419- }
1457+ this. report_move_out_while_borrowed ( location, place_span, borrow)
14201458 }
14211459 WriteKind :: Replace => {
14221460 this. report_illegal_mutation_of_borrowed ( location, place_span, borrow)
0 commit comments