Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/borrow_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> {
mir::BorrowKind::Mut {
kind: mir::MutBorrowKind::Default | mir::MutBorrowKind::TwoPhaseBorrow,
} => "mut ",
mir::BorrowKind::Pinned(mir::Mutability::Not) => "pin const ",
mir::BorrowKind::Pinned(mir::Mutability::Mut) => "pin mut ",
mir::BorrowKind::Pinned(mir::Mutability::Not, _) => "pin const ",
mir::BorrowKind::Pinned(mir::Mutability::Mut, _) => "pin mut ",
};
write!(w, "&{:?} {}{:?}", self.region, kind, self.borrowed_place)
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,9 +757,10 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Pins<'_, 'tcx> {
mir::StatementKind::Assign(box (lhs, rhs)) => {
self.kill_pins_on_place(state, *lhs);

// Check if this is a pinned borrow
if let mir::Rvalue::Ref(_, mir::BorrowKind::Pinned(_), place) = rhs {
// Generate the pin
// Only user-written `&pin` borrows create long-lived pin facts.
if let mir::Rvalue::Ref(_, mir::BorrowKind::Pinned(_, kind), place) = rhs
&& matches!(*kind, mir::PinBorrowKind::Persistent)
{
self.gen_pins_on_place(state, *place);
}
}
Expand Down
26 changes: 14 additions & 12 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1773,9 +1773,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
(
BorrowKind::Shared
| BorrowKind::Fake(FakeBorrowKind::Deep)
| BorrowKind::Pinned(mir::Mutability::Not),
| BorrowKind::Pinned(mir::Mutability::Not, _),
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
| BorrowKind::Pinned(mir::Mutability::Mut),
| BorrowKind::Pinned(mir::Mutability::Mut, _),
) => {
first_borrow_desc = "mutable ";
let mut err = self.cannot_reborrow_already_borrowed(
Expand All @@ -1800,10 +1800,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}
(
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
| BorrowKind::Pinned(mir::Mutability::Mut),
| BorrowKind::Pinned(mir::Mutability::Mut, _),
BorrowKind::Shared
| BorrowKind::Fake(FakeBorrowKind::Deep)
| BorrowKind::Pinned(mir::Mutability::Not),
| BorrowKind::Pinned(mir::Mutability::Not, _),
) => {
first_borrow_desc = "immutable ";
let mut err = self.cannot_reborrow_already_borrowed(
Expand Down Expand Up @@ -1835,9 +1835,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {

(
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
| BorrowKind::Pinned(mir::Mutability::Mut),
| BorrowKind::Pinned(mir::Mutability::Mut, _),
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
| BorrowKind::Pinned(mir::Mutability::Mut),
| BorrowKind::Pinned(mir::Mutability::Mut, _),
) => {
first_borrow_desc = "first ";
let mut err = self.cannot_mutably_borrow_multiply(
Expand Down Expand Up @@ -1877,7 +1877,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}

(
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut),
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut, _),
BorrowKind::Fake(FakeBorrowKind::Shallow),
) => {
if let Some(immutable_section_description) =
Expand Down Expand Up @@ -1944,7 +1944,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
(
BorrowKind::Shared
| BorrowKind::Fake(FakeBorrowKind::Deep)
| BorrowKind::Pinned(mir::Mutability::Not),
| BorrowKind::Pinned(mir::Mutability::Not, _),
BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture },
) => {
first_borrow_desc = "first ";
Expand All @@ -1962,7 +1962,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}

(
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut),
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut, _),
BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture },
) => {
first_borrow_desc = "first ";
Expand All @@ -1982,15 +1982,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
(
BorrowKind::Shared
| BorrowKind::Fake(FakeBorrowKind::Deep)
| BorrowKind::Pinned(mir::Mutability::Not),
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(mir::Mutability::Not),
| BorrowKind::Pinned(mir::Mutability::Not, _),
BorrowKind::Shared
| BorrowKind::Fake(_)
| BorrowKind::Pinned(mir::Mutability::Not, _),
)
| (
BorrowKind::Fake(FakeBorrowKind::Shallow),
BorrowKind::Mut { .. }
| BorrowKind::Shared
| BorrowKind::Fake(_)
| BorrowKind::Pinned(_),
| BorrowKind::Pinned(..),
) => {
unreachable!()
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -869,11 +869,13 @@ impl UseSpans<'_> {
| rustc_middle::mir::BorrowKind::Fake(_)
| rustc_middle::mir::BorrowKind::Pinned(
rustc_middle::mir::Mutability::Not,
_,
) => CaptureVarKind::Immut { kind_span: capture_kind_span },

rustc_middle::mir::BorrowKind::Mut { .. }
| rustc_middle::mir::BorrowKind::Pinned(
rustc_middle::mir::Mutability::Mut,
_,
) => CaptureVarKind::Mut { kind_span: capture_kind_span },
},
None => CaptureVarKind::Move { kind_span: capture_kind_span },
Expand Down
47 changes: 28 additions & 19 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1328,16 +1328,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {

(
Read(_),
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not),
BorrowKind::Shared
| BorrowKind::Fake(_)
| BorrowKind::Pinned(Mutability::Not, _),
)
| (
Read(ReadKind::Borrow(BorrowKind::Fake(FakeBorrowKind::Shallow))),
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut),
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _),
) => ControlFlow::Continue(()),

(
Reservation(_),
BorrowKind::Fake(_) | BorrowKind::Shared | BorrowKind::Pinned(Mutability::Not),
BorrowKind::Fake(_)
| BorrowKind::Shared
| BorrowKind::Pinned(Mutability::Not, _),
) => {
// This used to be a future compatibility warning (to be
// disallowed on NLL). See rust-lang/rust#56254
Expand All @@ -1350,13 +1354,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
}

// Ignore the expired borrow (pinnedness never conflicts with a read)
(Read(_), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut))
(Read(_), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _))
if !borrows_in_scope.contains(borrow_index) =>
{
ControlFlow::Continue(())
}

(Read(kind), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut)) => {
(Read(kind), BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _)) => {
// Reading from mere reservations of mutable-borrows is OK.
if !is_active(this.dominators(), borrow, location) {
assert!(borrow.kind.is_two_phase_borrow());
Expand Down Expand Up @@ -1393,7 +1397,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
ControlFlow::Continue(())
}
// Mutable (pinned) borrow doesn't conflict with an expired borrow
WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut)) => {
WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut, _)) => {
ControlFlow::Continue(())
}
// Mutable (but non-pinned) borrow conflicts with an earlier pinned borrow
Expand Down Expand Up @@ -1550,12 +1554,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
BorrowKind::Fake(FakeBorrowKind::Shallow) => {
(Shallow(Some(ArtificialField::FakeBorrow)), Read(ReadKind::Borrow(bk)))
}
BorrowKind::Pinned(Mutability::Not) => {
(Shallow(None), Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Not))))
}
BorrowKind::Pinned(Mutability::Mut) => (
BorrowKind::Pinned(Mutability::Not, pin_kind) => (
Shallow(None),
Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Not, pin_kind))),
),
BorrowKind::Pinned(Mutability::Mut, pin_kind) => (
Shallow(None),
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut))),
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(
Mutability::Mut,
pin_kind,
))),
),
BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep) => {
(Deep, Read(ReadKind::Borrow(bk)))
Expand Down Expand Up @@ -1922,9 +1930,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {

// only mutable borrows should be 2-phase
assert!(match borrow.kind {
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not) =>
false,
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut) => true,
BorrowKind::Shared
| BorrowKind::Fake(_)
| BorrowKind::Pinned(Mutability::Not, _) => false,
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _) => true,
});

self.access_place(
Expand Down Expand Up @@ -2501,7 +2510,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
| WriteKind::StorageDeadOrDrop
| WriteKind::MutableBorrow(BorrowKind::Shared)
| WriteKind::MutableBorrow(BorrowKind::Fake(_))
| WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut)),
| WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut, _)),
) => {
if self.is_mutable(place.as_ref(), is_local_mutation_allowed).is_err()
&& !self.has_buffered_diags()
Expand Down Expand Up @@ -2529,18 +2538,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
BorrowKind::Mut { .. }
| BorrowKind::Shared
| BorrowKind::Fake(_)
| BorrowKind::Pinned(Mutability::Not),
| BorrowKind::Pinned(Mutability::Not, _),
)
| ReadKind::Copy,
) => {
// Access authorized
return false;
}
Reservation(WriteKind::MutableBorrow(BorrowKind::Pinned(_))) => {
Reservation(WriteKind::MutableBorrow(BorrowKind::Pinned(..))) => {
span_bug!(span, "invalid reservation with a pinned borrow kind: {:?}", kind);
}
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Not)))
| Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Mut))) => {
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Not, _)))
| Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Mut, _))) => {
span_bug!(
span,
"invalid read with a pinned mutable borrow kind or write with an immutable pinned borrow kind: {:?}",
Expand Down
28 changes: 17 additions & 11 deletions compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,17 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep) => {
(Deep, Read(ReadKind::Borrow(bk)))
}
BorrowKind::Pinned(Mutability::Not) => {
(Deep, Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Not))))
}
BorrowKind::Pinned(Mutability::Mut) => {
(Deep, Write(WriteKind::MutableBorrow(BorrowKind::Pinned(Mutability::Mut))))
}
BorrowKind::Pinned(Mutability::Not, pin_kind) => (
Deep,
Read(ReadKind::Borrow(BorrowKind::Pinned(Mutability::Not, pin_kind))),
),
BorrowKind::Pinned(Mutability::Mut, pin_kind) => (
Deep,
Write(WriteKind::MutableBorrow(BorrowKind::Pinned(
Mutability::Mut,
pin_kind,
))),
),
BorrowKind::Mut { .. } => {
let wk = WriteKind::MutableBorrow(bk);
if bk.is_two_phase_borrow() {
Expand Down Expand Up @@ -383,7 +388,7 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
Read(_),
BorrowKind::Fake(_)
| BorrowKind::Shared
| BorrowKind::Pinned(Mutability::Not),
| BorrowKind::Pinned(Mutability::Not, _),
)
| (
Read(ReadKind::Borrow(BorrowKind::Fake(FakeBorrowKind::Shallow))),
Expand All @@ -392,7 +397,7 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
// Reads don't invalidate shared or shallow borrows
}

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

// only mutable borrows should be 2-phase
assert!(match borrow.kind {
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not) =>
false,
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut) => true,
BorrowKind::Shared
| BorrowKind::Fake(_)
| BorrowKind::Pinned(Mutability::Not, _) => false,
BorrowKind::Mut { .. } | BorrowKind::Pinned(Mutability::Mut, _) => true,
});

self.access_place(
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}
}

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

Rvalue::Ref(
_,
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not),
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(Mutability::Not, _),
place,
)
| Rvalue::RawPtr(RawPtrKind::Const, place) => {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/check_consts/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ where

fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
match kind {
mir::BorrowKind::Mut { .. } | mir::BorrowKind::Pinned(mir::Mutability::Mut) => true,
mir::BorrowKind::Mut { .. } | mir::BorrowKind::Pinned(mir::Mutability::Mut, _) => true,
mir::BorrowKind::Shared
| mir::BorrowKind::Fake(_)
| mir::BorrowKind::Pinned(mir::Mutability::Not) => {
| mir::BorrowKind::Pinned(mir::Mutability::Not, _) => {
self.shared_borrow_allows_mutation(place)
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1117,8 +1117,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
BorrowKind::Fake(FakeBorrowKind::Deep) => "fake ",
BorrowKind::Fake(FakeBorrowKind::Shallow) => "fake shallow ",
BorrowKind::Mut { .. } => "mut ",
BorrowKind::Pinned(Mutability::Not) => "pin ",
BorrowKind::Pinned(Mutability::Mut) => "pin mut ",
BorrowKind::Pinned(Mutability::Not, _) => "pin ",
BorrowKind::Pinned(Mutability::Mut, _) => "pin mut ",
};

// When printing regions, add trailing space if necessary.
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/mir/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ impl BorrowKind {
match *self {
BorrowKind::Shared | BorrowKind::Fake(_) => Mutability::Not,
BorrowKind::Mut { .. } => Mutability::Mut,
BorrowKind::Pinned(mutability) => mutability,
BorrowKind::Pinned(mutability, _) => mutability,
}
}

Expand All @@ -849,7 +849,7 @@ impl BorrowKind {
BorrowKind::Shared
| BorrowKind::Fake(_)
| BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::ClosureCapture }
| BorrowKind::Pinned(_) => false,
| BorrowKind::Pinned(..) => false,
BorrowKind::Mut { kind: MutBorrowKind::TwoPhaseBorrow } => true,
}
}
Expand All @@ -862,7 +862,7 @@ impl BorrowKind {
// We have no type corresponding to a shallow borrow, so use
// `&` as an approximation.
BorrowKind::Fake(_) => hir::Mutability::Not,
BorrowKind::Pinned(mutability) => mutability,
BorrowKind::Pinned(mutability, _) => mutability,
}
}
}
Expand Down
18 changes: 16 additions & 2 deletions compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,22 @@ pub enum BorrowKind {
/// Data is mutable and not aliasable.
Mut { kind: MutBorrowKind },

/// Data is pinned and cannot be moved or mutably borrowed until dropped or reassigned.
Pinned(Mutability),
/// Data is pinned.
Pinned(Mutability, PinBorrowKind),
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable)]
pub enum PinBorrowKind {
/// A user-written `&pin` borrow.
///
/// The borrowed place stays pinned after this borrow ends, until reassignment.
Persistent,
/// A compiler-generated pinned borrow used for adjustments or coercions.
///
/// This remains a normal borrow while live, but does not create a persistent
/// pin fact after it ends.
Transient,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
Expand Down
Loading