Skip to content

Commit 46c66aa

Browse files
committed
WIP: implement borrowck
1 parent ecd5952 commit 46c66aa

24 files changed

Lines changed: 199 additions & 247 deletions

File tree

compiler/rustc_borrowck/src/borrow_set.rs

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::fmt;
22
use std::ops::Index;
33

4-
use rustc_abi::FieldIdx;
54
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
65
use rustc_index::bit_set::DenseBitSet;
76
use rustc_middle::mir::visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor};
@@ -70,19 +69,6 @@ pub enum TwoPhaseActivation {
7069
ActivatedAt(Location),
7170
}
7271

73-
/// Location where a place is pinned, if a borrowed place is pinned.
74-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
75-
pub(crate) enum Pinnedness<'tcx> {
76-
Not,
77-
Pinned { to: mir::Place<'tcx>, at: Location },
78-
}
79-
80-
impl<'tcx> Pinnedness<'tcx> {
81-
pub(crate) fn is_pinned(&self) -> bool {
82-
matches!(self, Self::Pinned { .. })
83-
}
84-
}
85-
8672
#[derive(Debug, Clone)]
8773
pub struct BorrowData<'tcx> {
8874
/// Location where the borrow reservation starts.
@@ -98,8 +84,6 @@ pub struct BorrowData<'tcx> {
9884
pub(crate) borrowed_place: mir::Place<'tcx>,
9985
/// Place to which the borrow was stored
10086
pub(crate) assigned_place: mir::Place<'tcx>,
101-
/// Place and location to the pinning statement, if the borrowed place is pinned.
102-
pub(crate) pinnedness: Pinnedness<'tcx>,
10387
}
10488

10589
// These methods are public to support borrowck consumers.
@@ -140,6 +124,8 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> {
140124
mir::BorrowKind::Mut {
141125
kind: mir::MutBorrowKind::Default | mir::MutBorrowKind::TwoPhaseBorrow,
142126
} => "mut ",
127+
mir::BorrowKind::Pinned(mir::Mutability::Not) => "pin const ",
128+
mir::BorrowKind::Pinned(mir::Mutability::Mut) => "pin mut ",
143129
};
144130
write!(w, "&{:?} {}{:?}", self.region, kind, self.borrowed_place)
145131
}
@@ -276,7 +262,6 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
276262
activation_location,
277263
borrowed_place,
278264
assigned_place: *assigned_place,
279-
pinnedness: Pinnedness::Not,
280265
};
281266

282267
let idx = if !kind.is_two_phase_borrow() {
@@ -317,40 +302,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
317302
idx
318303
};
319304

320-
if let Some((pinned_place, successor)) =
321-
succeeded_by_pin(self.tcx, self.body, location, *assigned_place)
322-
{
323-
self.location_map[&location].pinnedness =
324-
Pinnedness::Pinned { to: pinned_place, at: successor };
325-
}
326-
327305
self.local_map.entry(borrowed_place.local).or_default().insert(idx);
328306
}
329307

330-
// Whether the current statement is followed by a
331-
// `pinned_place = Pin::<&[mut] T> { pointer: move assigned_place }` statement.
332-
fn succeeded_by_pin<'tcx>(
333-
tcx: TyCtxt<'tcx>,
334-
body: &mir::Body<'tcx>,
335-
location: mir::Location,
336-
assigned_place: mir::Place<'tcx>,
337-
) -> Option<(mir::Place<'tcx>, mir::Location)> {
338-
let successor = location.successor_within_block();
339-
let stmt =
340-
body.basic_blocks[successor.block].statements.get(successor.statement_index)?;
341-
if let mir::StatementKind::Assign(box (pinned_place, ref rvalue)) = stmt.kind
342-
&& let mir::Rvalue::Aggregate(box agg_kind, operands) = rvalue
343-
&& let mir::AggregateKind::Adt(adt_did, _, args, _, _) = agg_kind
344-
&& tcx.adt_def(*adt_did).is_pin()
345-
&& args.type_at(0).is_ref()
346-
&& let mir::Operand::Move(place) = operands[FieldIdx::ZERO]
347-
&& place == assigned_place
348-
{
349-
return Some((pinned_place, successor));
350-
}
351-
None
352-
}
353-
354308
self.super_assign(assigned_place, rvalue, location)
355309
}
356310

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ use rustc_mir_dataflow::impls::{
1414
use rustc_mir_dataflow::{Analysis, GenKill, JoinSemiLattice};
1515
use tracing::debug;
1616

17-
use crate::{
18-
BorrowSet, PinSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, places_conflict,
19-
};
17+
use crate::{BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, places_conflict};
2018

2119
// This analysis is different to most others. Its results aren't computed with
2220
// `iterate_to_fixpoint`, but are instead composed from the results of three sub-analyses that are
@@ -208,7 +206,6 @@ pub(crate) struct Pins<'a, 'tcx> {
208206
tcx: TyCtxt<'tcx>,
209207
body: &'a Body<'tcx>,
210208
borrow_set: &'a BorrowSet<'tcx>,
211-
pin_set: &'a PinSet,
212209
}
213210

214211
struct OutOfScopePrecomputer<'a, 'tcx> {
@@ -655,9 +652,21 @@ impl<'a, 'tcx> Pins<'a, 'tcx> {
655652
tcx: TyCtxt<'tcx>,
656653
body: &'a Body<'tcx>,
657654
borrow_set: &'a BorrowSet<'tcx>,
658-
pin_set: &'a PinSet,
659655
) -> Self {
660-
Pins { tcx, body, borrow_set, pin_set }
656+
Pins { tcx, body, borrow_set }
657+
}
658+
659+
fn gen_pins_on_place(&self, state: &mut <Self as Analysis<'tcx>>::Domain, place: Place<'tcx>) {
660+
self.borrow_set
661+
.local_map
662+
.get(&place.local)
663+
.into_iter()
664+
.flat_map(|bs| bs.iter())
665+
.copied()
666+
.filter(|&index| self.borrow_set[index].borrowed_place == place)
667+
.for_each(|index| {
668+
state.gen_(index);
669+
});
661670
}
662671

663672
/// Kill any pins whose original pinned place conflicts with `place`.
@@ -742,29 +751,16 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Pins<'_, 'tcx> {
742751
&self,
743752
state: &mut Self::Domain,
744753
stmt: &mir::Statement<'tcx>,
745-
location: Location,
754+
_location: Location,
746755
) {
747756
match &stmt.kind {
748757
mir::StatementKind::Assign(box (lhs, rhs)) => {
749758
self.kill_pins_on_place(state, *lhs);
750759

751-
// Check if this is a Pin aggregate creation
752-
if let mir::Rvalue::Aggregate(box agg_kind, _) = rhs
753-
&& let mir::AggregateKind::Adt(adt_did, _, args, _, _) = agg_kind
754-
&& self.tcx.adt_def(*adt_did).is_pin()
755-
&& args.type_at(0).is_ref()
756-
{
760+
// Check if this is a pinned borrow
761+
if let mir::Rvalue::Ref(_, mir::BorrowKind::Pinned(_), place) = rhs {
757762
// Generate the pin
758-
for index in self
759-
.pin_set
760-
.pin_location_map
761-
.get(&location)
762-
.into_iter()
763-
.flat_map(|bs| bs.iter())
764-
.copied()
765-
{
766-
state.gen_(index);
767-
}
763+
self.gen_pins_on_place(state, *place);
768764
}
769765
}
770766

compiler/rustc_borrowck/src/def_use.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@ pub(crate) fn categorize(context: PlaceContext) -> Option<DefUse> {
5656
PlaceContext::NonUse(NonUseContext::AscribeUserTy(_)) |
5757

5858
PlaceContext::MutatingUse(MutatingUseContext::RawBorrow) |
59+
PlaceContext::MutatingUse(MutatingUseContext::PinnedBorrow) |
5960
PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow) |
6061
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) |
6162
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
6263
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) |
63-
PlaceContext::MutatingUse(MutatingUseContext::Retag) =>
64+
PlaceContext::MutatingUse(MutatingUseContext::Retag) |
65+
PlaceContext::NonMutatingUse(NonMutatingUseContext::PinnedBorrow) =>
6466
Some(DefUse::Use),
6567

6668
///////////////////////////////////////////////////////////////////////////

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,8 +1771,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
17711771
let first_borrow_desc;
17721772
let mut err = match (gen_borrow_kind, issued_borrow.kind) {
17731773
(
1774-
BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep),
1775-
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
1774+
BorrowKind::Shared
1775+
| BorrowKind::Fake(FakeBorrowKind::Deep)
1776+
| BorrowKind::Pinned(mir::Mutability::Not),
1777+
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
1778+
| BorrowKind::Pinned(mir::Mutability::Mut),
17761779
) => {
17771780
first_borrow_desc = "mutable ";
17781781
let mut err = self.cannot_reborrow_already_borrowed(
@@ -1796,8 +1799,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
17961799
err
17971800
}
17981801
(
1799-
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
1800-
BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep),
1802+
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
1803+
| BorrowKind::Pinned(mir::Mutability::Mut),
1804+
BorrowKind::Shared
1805+
| BorrowKind::Fake(FakeBorrowKind::Deep)
1806+
| BorrowKind::Pinned(mir::Mutability::Not),
18011807
) => {
18021808
first_borrow_desc = "immutable ";
18031809
let mut err = self.cannot_reborrow_already_borrowed(
@@ -1828,8 +1834,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
18281834
}
18291835

18301836
(
1831-
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
1832-
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
1837+
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
1838+
| BorrowKind::Pinned(mir::Mutability::Mut),
1839+
BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow }
1840+
| BorrowKind::Pinned(mir::Mutability::Mut),
18331841
) => {
18341842
first_borrow_desc = "first ";
18351843
let mut err = self.cannot_mutably_borrow_multiply(
@@ -1868,7 +1876,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
18681876
self.cannot_uniquely_borrow_by_two_closures(span, &desc_place, issued_span, None)
18691877
}
18701878

1871-
(BorrowKind::Mut { .. }, BorrowKind::Fake(FakeBorrowKind::Shallow)) => {
1879+
(
1880+
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut),
1881+
BorrowKind::Fake(FakeBorrowKind::Shallow),
1882+
) => {
18721883
if let Some(immutable_section_description) =
18731884
self.classify_immutable_section(issued_borrow.assigned_place)
18741885
{
@@ -1931,7 +1942,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
19311942
}
19321943

19331944
(
1934-
BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep),
1945+
BorrowKind::Shared
1946+
| BorrowKind::Fake(FakeBorrowKind::Deep)
1947+
| BorrowKind::Pinned(mir::Mutability::Not),
19351948
BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture },
19361949
) => {
19371950
first_borrow_desc = "first ";
@@ -1948,7 +1961,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
19481961
)
19491962
}
19501963

1951-
(BorrowKind::Mut { .. }, BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }) => {
1964+
(
1965+
BorrowKind::Mut { .. } | BorrowKind::Pinned(mir::Mutability::Mut),
1966+
BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture },
1967+
) => {
19521968
first_borrow_desc = "first ";
19531969
self.cannot_reborrow_already_uniquely_borrowed(
19541970
span,
@@ -1964,12 +1980,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
19641980
}
19651981

19661982
(
1967-
BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep),
1968-
BorrowKind::Shared | BorrowKind::Fake(_),
1983+
BorrowKind::Shared
1984+
| BorrowKind::Fake(FakeBorrowKind::Deep)
1985+
| BorrowKind::Pinned(mir::Mutability::Not),
1986+
BorrowKind::Shared | BorrowKind::Fake(_) | BorrowKind::Pinned(mir::Mutability::Not),
19691987
)
19701988
| (
19711989
BorrowKind::Fake(FakeBorrowKind::Shallow),
1972-
BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Fake(_),
1990+
BorrowKind::Mut { .. }
1991+
| BorrowKind::Shared
1992+
| BorrowKind::Fake(_)
1993+
| BorrowKind::Pinned(_),
19731994
) => {
19741995
unreachable!()
19751996
}

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -866,13 +866,15 @@ impl UseSpans<'_> {
866866
err.subdiagnostic(match kind {
867867
Some(kd) => match kd {
868868
rustc_middle::mir::BorrowKind::Shared
869-
| rustc_middle::mir::BorrowKind::Fake(_) => {
870-
CaptureVarKind::Immut { kind_span: capture_kind_span }
871-
}
872-
873-
rustc_middle::mir::BorrowKind::Mut { .. } => {
874-
CaptureVarKind::Mut { kind_span: capture_kind_span }
875-
}
869+
| rustc_middle::mir::BorrowKind::Fake(_)
870+
| rustc_middle::mir::BorrowKind::Pinned(
871+
rustc_middle::mir::Mutability::Not,
872+
) => CaptureVarKind::Immut { kind_span: capture_kind_span },
873+
874+
rustc_middle::mir::BorrowKind::Mut { .. }
875+
| rustc_middle::mir::BorrowKind::Pinned(
876+
rustc_middle::mir::Mutability::Mut,
877+
) => CaptureVarKind::Mut { kind_span: capture_kind_span },
876878
},
877879
None => CaptureVarKind::Move { kind_span: capture_kind_span },
878880
});

0 commit comments

Comments
 (0)