Skip to content

Commit 122d1be

Browse files
P8L1frank-king
authored andcommitted
Fix pin ergonomics borrowck for transient pinned borrows
1 parent 05b9a73 commit 122d1be

21 files changed

Lines changed: 220 additions & 72 deletions

File tree

compiler/rustc_borrowck/src/borrow_set.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> {
124124
mir::BorrowKind::Mut {
125125
kind: mir::MutBorrowKind::Default | mir::MutBorrowKind::TwoPhaseBorrow,
126126
} => "mut ",
127-
mir::BorrowKind::Pinned(mir::Mutability::Not) => "pin const ",
128-
mir::BorrowKind::Pinned(mir::Mutability::Mut) => "pin mut ",
127+
mir::BorrowKind::Pinned(mir::Mutability::Not, _) => "pin const ",
128+
mir::BorrowKind::Pinned(mir::Mutability::Mut, _) => "pin mut ",
129129
};
130130
write!(w, "&{:?} {}{:?}", self.region, kind, self.borrowed_place)
131131
}

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -757,9 +757,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Pins<'_, 'tcx> {
757757
mir::StatementKind::Assign(box (lhs, rhs)) => {
758758
self.kill_pins_on_place(state, *lhs);
759759

760-
// Check if this is a pinned borrow
761-
if let mir::Rvalue::Ref(_, mir::BorrowKind::Pinned(_), place) = rhs {
762-
// Generate the pin
760+
// Only user-written `&pin` borrows create long-lived pin facts.
761+
if let mir::Rvalue::Ref(_, mir::BorrowKind::Pinned(_, kind), place) = rhs
762+
&& matches!(*kind, mir::PinBorrowKind::Persistent)
763+
{
763764
self.gen_pins_on_place(state, *place);
764765
}
765766
}

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,9 +1773,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
17731773
(
17741774
BorrowKind::Shared
17751775
| BorrowKind::Fake(FakeBorrowKind::Deep)
1776-
| BorrowKind::Pinned(mir::Mutability::Not),
1776+
| BorrowKind::Pinned(mir::Mutability::Not, _),
17771777
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
1778-
| BorrowKind::Pinned(mir::Mutability::Mut),
1778+
| BorrowKind::Pinned(mir::Mutability::Mut, _),
17791779
) => {
17801780
first_borrow_desc = "mutable ";
17811781
let mut err = self.cannot_reborrow_already_borrowed(
@@ -1800,10 +1800,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
18001800
}
18011801
(
18021802
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
1803-
| BorrowKind::Pinned(mir::Mutability::Mut),
1803+
| BorrowKind::Pinned(mir::Mutability::Mut, _),
18041804
BorrowKind::Shared
18051805
| BorrowKind::Fake(FakeBorrowKind::Deep)
1806-
| BorrowKind::Pinned(mir::Mutability::Not),
1806+
| BorrowKind::Pinned(mir::Mutability::Not, _),
18071807
) => {
18081808
first_borrow_desc = "immutable ";
18091809
let mut err = self.cannot_reborrow_already_borrowed(
@@ -1835,9 +1835,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
18351835

18361836
(
18371837
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
1838-
| BorrowKind::Pinned(mir::Mutability::Mut),
1838+
| BorrowKind::Pinned(mir::Mutability::Mut, _),
18391839
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
1840-
| BorrowKind::Pinned(mir::Mutability::Mut),
1840+
| BorrowKind::Pinned(mir::Mutability::Mut, _),
18411841
) => {
18421842
first_borrow_desc = "first ";
18431843
let mut err = self.cannot_mutably_borrow_multiply(
@@ -1877,7 +1877,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
18771877
}
18781878

18791879
(
1880-
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut),
1880+
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut, _),
18811881
BorrowKind::Fake(FakeBorrowKind::Shallow),
18821882
) => {
18831883
if let Some(immutable_section_description) =
@@ -1944,7 +1944,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
19441944
(
19451945
BorrowKind::Shared
19461946
| BorrowKind::Fake(FakeBorrowKind::Deep)
1947-
| BorrowKind::Pinned(mir::Mutability::Not),
1947+
| BorrowKind::Pinned(mir::Mutability::Not, _),
19481948
BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture },
19491949
) => {
19501950
first_borrow_desc = "first ";
@@ -1962,7 +1962,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
19621962
}
19631963

19641964
(
1965-
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut),
1965+
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut, _),
19661966
BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture },
19671967
) => {
19681968
first_borrow_desc = "first ";
@@ -1982,15 +1982,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
19821982
(
19831983
BorrowKind::Shared
19841984
| BorrowKind::Fake(FakeBorrowKind::Deep)
1985-
| BorrowKind::Pinned(mir::Mutability::Not),
1986-
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(mir::Mutability::Not),
1985+
| BorrowKind::Pinned(mir::Mutability::Not, _),
1986+
BorrowKind::Shared
1987+
| BorrowKind::Fake(_)
1988+
| BorrowKind::Pinned(mir::Mutability::Not, _),
19871989
)
19881990
| (
19891991
BorrowKind::Fake(FakeBorrowKind::Shallow),
19901992
BorrowKind::Mut { .. }
19911993
| BorrowKind::Shared
19921994
| BorrowKind::Fake(_)
1993-
| BorrowKind::Pinned(_),
1995+
| BorrowKind::Pinned(..),
19941996
) => {
19951997
unreachable!()
19961998
}

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,11 +869,13 @@ impl UseSpans<'_> {
869869
| rustc_middle::mir::BorrowKind::Fake(_)
870870
| rustc_middle::mir::BorrowKind::Pinned(
871871
rustc_middle::mir::Mutability::Not,
872+
_,
872873
) => CaptureVarKind::Immut { kind_span: capture_kind_span },
873874

874875
rustc_middle::mir::BorrowKind::Mut { .. }
875876
| rustc_middle::mir::BorrowKind::Pinned(
876877
rustc_middle::mir::Mutability::Mut,
878+
_,
877879
) => CaptureVarKind::Mut { kind_span: capture_kind_span },
878880
},
879881
None => CaptureVarKind::Move { kind_span: capture_kind_span },

compiler/rustc_borrowck/src/lib.rs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,16 +1328,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
13281328

13291329
(
13301330
Read(_),
1331-
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not),
1331+
BorrowKind::Shared
1332+
| BorrowKind::Fake(_)
1333+
| BorrowKind::Pinned(Mutability::Not, _),
13321334
)
13331335
| (
13341336
Read(ReadKind::Borrow(BorrowKind::Fake(FakeBorrowKind::Shallow))),
1335-
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut),
1337+
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _),
13361338
) => ControlFlow::Continue(()),
13371339

13381340
(
13391341
Reservation(_),
1340-
BorrowKind::Fake(_) | BorrowKind::Shared | BorrowKind::Pinned(Mutability::Not),
1342+
BorrowKind::Fake(_)
1343+
| BorrowKind::Shared
1344+
| BorrowKind::Pinned(Mutability::Not, _),
13411345
) => {
13421346
// This used to be a future compatibility warning (to be
13431347
// disallowed on NLL). See rust-lang/rust#56254
@@ -1350,13 +1354,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
13501354
}
13511355

13521356
// Ignore the expired borrow (pinnedness never conflicts with a read)
1353-
(Read(_), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut))
1357+
(Read(_), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _))
13541358
if !borrows_in_scope.contains(borrow_index) =>
13551359
{
13561360
ControlFlow::Continue(())
13571361
}
13581362

1359-
(Read(kind), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut)) => {
1363+
(Read(kind), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _)) => {
13601364
// Reading from mere reservations of mutable-borrows is OK.
13611365
if !is_active(this.dominators(), borrow, location) {
13621366
assert!(borrow.kind.is_two_phase_borrow());
@@ -1393,7 +1397,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
13931397
ControlFlow::Continue(())
13941398
}
13951399
// Mutable (pinned) borrow doesn't conflict with an expired borrow
1396-
WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut)) => {
1400+
WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut, _)) => {
13971401
ControlFlow::Continue(())
13981402
}
13991403
// Mutable (but non-pinned) borrow conflicts with an earlier pinned borrow
@@ -1550,12 +1554,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
15501554
BorrowKind::Fake(FakeBorrowKind::Shallow) => {
15511555
(Shallow(Some(ArtificialField::FakeBorrow)), Read(ReadKind::Borrow(bk)))
15521556
}
1553-
BorrowKind::Pinned(Mutability::Not) => {
1554-
(Shallow(None), Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Not))))
1555-
}
1556-
BorrowKind::Pinned(Mutability::Mut) => (
1557+
BorrowKind::Pinned(Mutability::Not, pin_kind) => (
1558+
Shallow(None),
1559+
Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Not, pin_kind))),
1560+
),
1561+
BorrowKind::Pinned(Mutability::Mut, pin_kind) => (
15571562
Shallow(None),
1558-
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut))),
1563+
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(
1564+
Mutability::Mut,
1565+
pin_kind,
1566+
))),
15591567
),
15601568
BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep) => {
15611569
(Deep, Read(ReadKind::Borrow(bk)))
@@ -1922,9 +1930,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
19221930

19231931
// only mutable borrows should be 2-phase
19241932
assert!(match borrow.kind {
1925-
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not) =>
1926-
false,
1927-
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut) => true,
1933+
BorrowKind::Shared
1934+
| BorrowKind::Fake(_)
1935+
| BorrowKind::Pinned(Mutability::Not, _) => false,
1936+
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _) => true,
19281937
});
19291938

19301939
self.access_place(
@@ -2501,7 +2510,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
25012510
| WriteKind::StorageDeadOrDrop
25022511
| WriteKind::MutableBorrow(BorrowKind::Shared)
25032512
| WriteKind::MutableBorrow(BorrowKind::Fake(_))
2504-
| WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut)),
2513+
| WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut, _)),
25052514
) => {
25062515
if self.is_mutable(place.as_ref(), is_local_mutation_allowed).is_err()
25072516
&& !self.has_buffered_diags()
@@ -2529,18 +2538,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
25292538
BorrowKind::Mut { .. }
25302539
| BorrowKind::Shared
25312540
| BorrowKind::Fake(_)
2532-
| BorrowKind::Pinned(Mutability::Not),
2541+
| BorrowKind::Pinned(Mutability::Not, _),
25332542
)
25342543
| ReadKind::Copy,
25352544
) => {
25362545
// Access authorized
25372546
return false;
25382547
}
2539-
Reservation(WriteKind::MutableBorrow(BorrowKind::Pinned(_))) => {
2548+
Reservation(WriteKind::MutableBorrow(BorrowKind::Pinned(..))) => {
25402549
span_bug!(span, "invalid reservation with a pinned borrow kind: {:?}", kind);
25412550
}
2542-
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Not)))
2543-
| Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Mut))) => {
2551+
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Not, _)))
2552+
| Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Mut, _))) => {
25442553
span_bug!(
25452554
span,
25462555
"invalid read with a pinned mutable borrow kind or write with an immutable pinned borrow kind: {:?}",

compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,17 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
262262
BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep) => {
263263
(Deep, Read(ReadKind::Borrow(bk)))
264264
}
265-
BorrowKind::Pinned(Mutability::Not) => {
266-
(Deep, Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Not))))
267-
}
268-
BorrowKind::Pinned(Mutability::Mut) => {
269-
(Deep, Write(WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut))))
270-
}
265+
BorrowKind::Pinned(Mutability::Not, pin_kind) => (
266+
Deep,
267+
Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Not, pin_kind))),
268+
),
269+
BorrowKind::Pinned(Mutability::Mut, pin_kind) => (
270+
Deep,
271+
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(
272+
Mutability::Mut,
273+
pin_kind,
274+
))),
275+
),
271276
BorrowKind::Mut { .. } => {
272277
let wk = WriteKind::MutableBorrow(bk);
273278
if bk.is_two_phase_borrow() {
@@ -383,7 +388,7 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
383388
Read(_),
384389
BorrowKind::Fake(_)
385390
| BorrowKind::Shared
386-
| BorrowKind::Pinned(Mutability::Not),
391+
| BorrowKind::Pinned(Mutability::Not, _),
387392
)
388393
| (
389394
Read(ReadKind::Borrow(BorrowKind::Fake(FakeBorrowKind::Shallow))),
@@ -392,7 +397,7 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
392397
// Reads don't invalidate shared or shallow borrows
393398
}
394399

395-
(Read(_), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut)) => {
400+
(Read(_), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _)) => {
396401
// Reading from mere reservations of mutable-borrows is OK.
397402
if !is_active(this.dominators, borrow, location) {
398403
// If the borrow isn't active yet, reads don't invalidate it
@@ -433,9 +438,10 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
433438

434439
// only mutable borrows should be 2-phase
435440
assert!(match borrow.kind {
436-
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not) =>
437-
false,
438-
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut) => true,
441+
BorrowKind::Shared
442+
| BorrowKind::Fake(_)
443+
| BorrowKind::Pinned(Mutability::Not, _) => false,
444+
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _) => true,
439445
});
440446

441447
self.access_place(

compiler/rustc_const_eval/src/check_consts/check.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
582582
}
583583
}
584584

585-
Rvalue::Ref(_, BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut), place)
585+
Rvalue::Ref(
586+
_,
587+
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _),
588+
place,
589+
)
586590
| Rvalue::RawPtr(RawPtrKind::Mut, place) => {
587591
// Inside mutable statics, we allow arbitrary mutable references.
588592
// We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
@@ -598,7 +602,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
598602

599603
Rvalue::Ref(
600604
_,
601-
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not),
605+
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not, _),
602606
place,
603607
)
604608
| Rvalue::RawPtr(RawPtrKind::Const, place) => {

compiler/rustc_const_eval/src/check_consts/resolver.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ where
103103

104104
fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
105105
match kind {
106-
mir::BorrowKind::Mut { .. } | mir::BorrowKind::Pinned(mir::Mutability::Mut) => true,
106+
mir::BorrowKind::Mut { .. } | mir::BorrowKind::Pinned(mir::Mutability::Mut, _) => true,
107107
mir::BorrowKind::Shared
108108
| mir::BorrowKind::Fake(_)
109-
| mir::BorrowKind::Pinned(mir::Mutability::Not) => {
109+
| mir::BorrowKind::Pinned(mir::Mutability::Not, _) => {
110110
self.shared_borrow_allows_mutation(place)
111111
}
112112
}

compiler/rustc_middle/src/mir/pretty.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,8 +1117,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
11171117
BorrowKind::Fake(FakeBorrowKind::Deep) => "fake ",
11181118
BorrowKind::Fake(FakeBorrowKind::Shallow) => "fake shallow ",
11191119
BorrowKind::Mut { .. } => "mut ",
1120-
BorrowKind::Pinned(Mutability::Not) => "pin ",
1121-
BorrowKind::Pinned(Mutability::Mut) => "pin mut ",
1120+
BorrowKind::Pinned(Mutability::Not, _) => "pin ",
1121+
BorrowKind::Pinned(Mutability::Mut, _) => "pin mut ",
11221122
};
11231123

11241124
// When printing regions, add trailing space if necessary.

compiler/rustc_middle/src/mir/statement.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ impl BorrowKind {
838838
match *self {
839839
BorrowKind::Shared | BorrowKind::Fake(_) => Mutability::Not,
840840
BorrowKind::Mut { .. } => Mutability::Mut,
841-
BorrowKind::Pinned(mutability) => mutability,
841+
BorrowKind::Pinned(mutability, _) => mutability,
842842
}
843843
}
844844

@@ -849,7 +849,7 @@ impl BorrowKind {
849849
BorrowKind::Shared
850850
| BorrowKind::Fake(_)
851851
| BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::ClosureCapture }
852-
| BorrowKind::Pinned(_) => false,
852+
| BorrowKind::Pinned(..) => false,
853853
BorrowKind::Mut { kind: MutBorrowKind::TwoPhaseBorrow } => true,
854854
}
855855
}
@@ -862,7 +862,7 @@ impl BorrowKind {
862862
// We have no type corresponding to a shallow borrow, so use
863863
// `&` as an approximation.
864864
BorrowKind::Fake(_) => hir::Mutability::Not,
865-
BorrowKind::Pinned(mutability) => mutability,
865+
BorrowKind::Pinned(mutability, _) => mutability,
866866
}
867867
}
868868
}

0 commit comments

Comments
 (0)