Skip to content

Commit 77a6a61

Browse files
committed
Auto merge of #56307 - RalfJung:stacked-borrows-2-phase, r=oli-obk
Stacked borrows: Support 2 phase borrows Some infrastructure needed for Stacked Borrows to be able to handle 2-phase-borros. r? @oli-obk
2 parents 1839c14 + e6c8e9d commit 77a6a61

File tree

11 files changed

+86
-60
lines changed

11 files changed

+86
-60
lines changed

src/librustc/ich/impls_mir.rs

+12-45
Original file line numberDiff line numberDiff line change
@@ -193,51 +193,18 @@ for mir::TerminatorKind<'gcx> {
193193

194194
impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
195195

196-
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
197-
for mir::StatementKind<'gcx> {
198-
fn hash_stable<W: StableHasherResult>(&self,
199-
hcx: &mut StableHashingContext<'a>,
200-
hasher: &mut StableHasher<W>) {
201-
mem::discriminant(self).hash_stable(hcx, hasher);
202-
203-
match *self {
204-
mir::StatementKind::Assign(ref place, ref rvalue) => {
205-
place.hash_stable(hcx, hasher);
206-
rvalue.hash_stable(hcx, hasher);
207-
}
208-
mir::StatementKind::FakeRead(ref cause, ref place) => {
209-
cause.hash_stable(hcx, hasher);
210-
place.hash_stable(hcx, hasher);
211-
}
212-
mir::StatementKind::SetDiscriminant { ref place, variant_index } => {
213-
place.hash_stable(hcx, hasher);
214-
variant_index.hash_stable(hcx, hasher);
215-
}
216-
mir::StatementKind::StorageLive(ref place) |
217-
mir::StatementKind::StorageDead(ref place) => {
218-
place.hash_stable(hcx, hasher);
219-
}
220-
mir::StatementKind::EscapeToRaw(ref place) => {
221-
place.hash_stable(hcx, hasher);
222-
}
223-
mir::StatementKind::Retag { fn_entry, ref place } => {
224-
fn_entry.hash_stable(hcx, hasher);
225-
place.hash_stable(hcx, hasher);
226-
}
227-
mir::StatementKind::AscribeUserType(ref place, ref variance, ref c_ty) => {
228-
place.hash_stable(hcx, hasher);
229-
variance.hash_stable(hcx, hasher);
230-
c_ty.hash_stable(hcx, hasher);
231-
}
232-
mir::StatementKind::Nop => {}
233-
mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
234-
asm.hash_stable(hcx, hasher);
235-
outputs.hash_stable(hcx, hasher);
236-
inputs.hash_stable(hcx, hasher);
237-
}
238-
}
239-
}
240-
}
196+
impl_stable_hash_for!(impl<'gcx> for enum mir::StatementKind<'gcx> [ mir::StatementKind ] {
197+
Assign(place, rvalue),
198+
FakeRead(cause, place),
199+
SetDiscriminant { place, variant_index },
200+
StorageLive(place),
201+
StorageDead(place),
202+
EscapeToRaw(place),
203+
Retag { fn_entry, two_phase, place },
204+
AscribeUserType(place, variance, c_ty),
205+
Nop,
206+
InlineAsm { asm, outputs, inputs },
207+
});
241208

242209
impl_stable_hash_for!(enum mir::FakeReadCause { ForMatchGuard, ForMatchedPlace, ForLet });
243210

src/librustc/mir/interpret/value.rs

+8
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ impl<'tcx, Tag> Scalar<Tag> {
138138
}
139139
}
140140

141+
#[inline]
142+
pub fn with_tag(self, new_tag: Tag) -> Self {
143+
match self {
144+
Scalar::Ptr(ptr) => Scalar::Ptr(Pointer { tag: new_tag, ..ptr }),
145+
Scalar::Bits { bits, size } => Scalar::Bits { bits, size },
146+
}
147+
}
148+
141149
#[inline]
142150
pub fn ptr_null(cx: &impl HasDataLayout) -> Self {
143151
Scalar::Bits {

src/librustc/mir/mod.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,10 @@ pub enum StatementKind<'tcx> {
17781778
/// `fn_entry` indicates whether this is the initial retag that happens in the
17791779
/// function prolog.
17801780
fn_entry: bool,
1781+
/// `two_phase` indicates whether this is just the reservation action of
1782+
/// a two-phase borrow.
1783+
two_phase: bool,
1784+
/// The place to retag
17811785
place: Place<'tcx>,
17821786
},
17831787

@@ -1841,8 +1845,12 @@ impl<'tcx> Debug for Statement<'tcx> {
18411845
match self.kind {
18421846
Assign(ref place, ref rv) => write!(fmt, "{:?} = {:?}", place, rv),
18431847
FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place),
1844-
Retag { fn_entry, ref place } =>
1845-
write!(fmt, "Retag({}{:?})", if fn_entry { "[fn entry] " } else { "" }, place),
1848+
Retag { fn_entry, two_phase, ref place } =>
1849+
write!(fmt, "Retag({}{}{:?})",
1850+
if fn_entry { "[fn entry] " } else { "" },
1851+
if two_phase { "[2phase] " } else { "" },
1852+
place,
1853+
),
18461854
EscapeToRaw(ref place) => write!(fmt, "EscapeToRaw({:?})", place),
18471855
StorageLive(ref place) => write!(fmt, "StorageLive({:?})", place),
18481856
StorageDead(ref place) => write!(fmt, "StorageDead({:?})", place),
@@ -3019,7 +3027,7 @@ EnumTypeFoldableImpl! {
30193027
(StatementKind::StorageLive)(a),
30203028
(StatementKind::StorageDead)(a),
30213029
(StatementKind::InlineAsm) { asm, outputs, inputs },
3022-
(StatementKind::Retag) { fn_entry, place },
3030+
(StatementKind::Retag) { fn_entry, two_phase, place },
30233031
(StatementKind::EscapeToRaw)(place),
30243032
(StatementKind::AscribeUserType)(a, v, b),
30253033
(StatementKind::Nop),

src/librustc/mir/visit.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,10 @@ macro_rules! make_mir_visitor {
154154

155155
fn visit_retag(&mut self,
156156
fn_entry: & $($mutability)* bool,
157+
two_phase: & $($mutability)* bool,
157158
place: & $($mutability)* Place<'tcx>,
158159
location: Location) {
159-
self.super_retag(fn_entry, place, location);
160+
self.super_retag(fn_entry, two_phase, place, location);
160161
}
161162

162163
fn visit_place(&mut self,
@@ -417,8 +418,9 @@ macro_rules! make_mir_visitor {
417418
}
418419
}
419420
StatementKind::Retag { ref $($mutability)* fn_entry,
421+
ref $($mutability)* two_phase,
420422
ref $($mutability)* place } => {
421-
self.visit_retag(fn_entry, place, location);
423+
self.visit_retag(fn_entry, two_phase, place, location);
422424
}
423425
StatementKind::AscribeUserType(
424426
ref $($mutability)* place,
@@ -724,6 +726,7 @@ macro_rules! make_mir_visitor {
724726

725727
fn super_retag(&mut self,
726728
_fn_entry: & $($mutability)* bool,
729+
_two_phase: & $($mutability)* bool,
727730
place: & $($mutability)* Place<'tcx>,
728731
location: Location) {
729732
self.visit_place(

src/librustc_mir/interpret/machine.rs

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
204204
fn retag(
205205
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
206206
_fn_entry: bool,
207+
_two_phase: bool,
207208
_place: PlaceTy<'tcx, Self::PointerTag>,
208209
) -> EvalResult<'tcx> {
209210
Ok(())

src/librustc_mir/interpret/place.rs

+20
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ impl<Tag> MemPlace<Tag> {
115115
}
116116
}
117117

118+
#[inline]
119+
pub fn with_tag(self, new_tag: Tag) -> Self
120+
{
121+
MemPlace {
122+
ptr: self.ptr.with_tag(new_tag),
123+
align: self.align,
124+
meta: self.meta,
125+
}
126+
}
127+
118128
#[inline(always)]
119129
pub fn from_scalar_ptr(ptr: Scalar<Tag>, align: Align) -> Self {
120130
MemPlace {
@@ -187,6 +197,16 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
187197
}
188198
}
189199

200+
#[inline]
201+
pub fn with_tag(self, new_tag: Tag) -> Self
202+
{
203+
MPlaceTy {
204+
mplace: self.mplace.with_tag(new_tag),
205+
layout: self.layout,
206+
}
207+
}
208+
209+
#[inline]
190210
pub fn offset(
191211
self,
192212
offset: Size,

src/librustc_mir/interpret/step.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
119119
FakeRead(..) => {}
120120

121121
// Stacked Borrows.
122-
Retag { fn_entry, ref place } => {
122+
Retag { fn_entry, two_phase, ref place } => {
123123
let dest = self.eval_place(place)?;
124-
M::retag(self, fn_entry, dest)?;
124+
M::retag(self, fn_entry, two_phase, dest)?;
125125
}
126126
EscapeToRaw(ref op) => {
127127
let op = self.eval_operand(op, None)?;

src/librustc_mir/shim.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,11 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
229229
// Function arguments should be retagged
230230
mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
231231
source_info,
232-
kind: StatementKind::Retag { fn_entry: true, place: dropee_ptr.clone() },
232+
kind: StatementKind::Retag {
233+
fn_entry: true,
234+
two_phase: false,
235+
place: dropee_ptr.clone(),
236+
},
233237
});
234238
// We use raw ptr operations, better prepare the alias tracking for that
235239
mir.basic_blocks_mut()[START_BLOCK].statements.insert(1, Statement {

src/librustc_mir/transform/add_retag.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ impl MirPass for AddRetag {
118118
basic_blocks[START_BLOCK].statements.splice(0..0,
119119
places.into_iter().map(|place| Statement {
120120
source_info,
121-
kind: StatementKind::Retag { fn_entry: true, place },
121+
kind: StatementKind::Retag { fn_entry: true, two_phase: false, place },
122122
})
123123
);
124124
}
@@ -154,7 +154,7 @@ impl MirPass for AddRetag {
154154
for (source_info, dest_place, dest_block) in returns {
155155
basic_blocks[dest_block].statements.insert(0, Statement {
156156
source_info,
157-
kind: StatementKind::Retag { fn_entry: false, place: dest_place },
157+
kind: StatementKind::Retag { fn_entry: false, two_phase: false, place: dest_place },
158158
});
159159
}
160160

@@ -191,12 +191,21 @@ impl MirPass for AddRetag {
191191
// Assignments of reference or ptr type are the ones where we may have
192192
// to update tags. This includes `x = &[mut] ...` and hence
193193
// we also retag after taking a reference!
194-
StatementKind::Assign(ref place, _) if needs_retag(place) => {
194+
StatementKind::Assign(ref place, box ref rvalue) if needs_retag(place) => {
195+
let two_phase = match rvalue {
196+
Rvalue::Ref(_, borrow_kind, _) =>
197+
borrow_kind.allows_two_phase_borrow(),
198+
_ => false
199+
};
195200
// Insert a retag after the assignment.
196201
let source_info = block_data.statements[i].source_info;
197202
block_data.statements.insert(i+1, Statement {
198203
source_info,
199-
kind: StatementKind::Retag { fn_entry: false, place: place.clone() },
204+
kind: StatementKind::Retag {
205+
fn_entry: false,
206+
two_phase,
207+
place: place.clone(),
208+
},
200209
});
201210
}
202211
// Do nothing for the rest

src/librustc_mir/transform/inline.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -707,8 +707,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
707707
self.in_cleanup_block = false;
708708
}
709709

710-
fn visit_retag(&mut self, fn_entry: &mut bool, place: &mut Place<'tcx>, loc: Location) {
711-
self.super_retag(fn_entry, place, loc);
710+
fn visit_retag(
711+
&mut self,
712+
fn_entry: &mut bool,
713+
two_phase: &mut bool,
714+
place: &mut Place<'tcx>,
715+
loc: Location,
716+
) {
717+
self.super_retag(fn_entry, two_phase, place, loc);
712718

713719
// We have to patch all inlined retags to be aware that they are no longer
714720
// happening on function entry.

src/tools/miri

Submodule miri updated from 8d2bc97 to 61f2076

0 commit comments

Comments
 (0)