Skip to content

Commit c1160a8

Browse files
committed
treat ref-to-raw cast like a reborrow: do a special kind of retag
1 parent c9bb68f commit c1160a8

File tree

22 files changed

+76
-128
lines changed

22 files changed

+76
-128
lines changed

src/librustc/ich/impls_mir.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,13 @@ impl_stable_hash_for!(impl<'gcx> for enum mir::StatementKind<'gcx> [ mir::Statem
200200
SetDiscriminant { place, variant_index },
201201
StorageLive(place),
202202
StorageDead(place),
203-
EscapeToRaw(place),
204-
Retag { fn_entry, two_phase, place },
203+
Retag(retag_kind, place),
205204
AscribeUserType(place, variance, c_ty),
206205
Nop,
207206
InlineAsm { asm, outputs, inputs },
208207
});
209208

209+
impl_stable_hash_for!(enum mir::RetagKind { FnEntry, TwoPhase, Raw, Default });
210210
impl_stable_hash_for!(enum mir::FakeReadCause { ForMatchGuard, ForMatchedPlace, ForLet });
211211

212212
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Place<'gcx> {

src/librustc/mir/mod.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -1774,23 +1774,7 @@ pub enum StatementKind<'tcx> {
17741774
/// by miri and only generated when "-Z mir-emit-retag" is passed.
17751775
/// See <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/>
17761776
/// for more details.
1777-
Retag {
1778-
/// `fn_entry` indicates whether this is the initial retag that happens in the
1779-
/// function prolog.
1780-
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
1785-
place: Place<'tcx>,
1786-
},
1787-
1788-
/// Escape the given reference to a raw pointer, so that it can be accessed
1789-
/// without precise provenance tracking. These statements are currently only interpreted
1790-
/// by miri and only generated when "-Z mir-emit-retag" is passed.
1791-
/// See <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/>
1792-
/// for more details.
1793-
EscapeToRaw(Operand<'tcx>),
1777+
Retag(RetagKind, Place<'tcx>),
17941778

17951779
/// Encodes a user's type ascription. These need to be preserved
17961780
/// intact so that NLL can respect them. For example:
@@ -1810,6 +1794,19 @@ pub enum StatementKind<'tcx> {
18101794
Nop,
18111795
}
18121796

1797+
/// `RetagKind` describes what kind of retag is to be performed.
1798+
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq)]
1799+
pub enum RetagKind {
1800+
/// The initial retag when entering a function
1801+
FnEntry,
1802+
/// Retag preparing for a two-phase borrow
1803+
TwoPhase,
1804+
/// Retagging raw pointers
1805+
Raw,
1806+
/// A "normal" retag
1807+
Default,
1808+
}
1809+
18131810
/// The `FakeReadCause` describes the type of pattern why a `FakeRead` statement exists.
18141811
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
18151812
pub enum FakeReadCause {
@@ -1845,13 +1842,16 @@ impl<'tcx> Debug for Statement<'tcx> {
18451842
match self.kind {
18461843
Assign(ref place, ref rv) => write!(fmt, "{:?} = {:?}", place, rv),
18471844
FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, 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 { "" },
1845+
Retag(ref kind, ref place) =>
1846+
write!(fmt, "Retag({}{:?})",
1847+
match kind {
1848+
RetagKind::FnEntry => "[fn entry] ",
1849+
RetagKind::TwoPhase => "[2phase] ",
1850+
RetagKind::Raw => "[raw] ",
1851+
RetagKind::Default => "",
1852+
},
18521853
place,
18531854
),
1854-
EscapeToRaw(ref place) => write!(fmt, "EscapeToRaw({:?})", place),
18551855
StorageLive(ref place) => write!(fmt, "StorageLive({:?})", place),
18561856
StorageDead(ref place) => write!(fmt, "StorageDead({:?})", place),
18571857
SetDiscriminant {
@@ -2965,6 +2965,7 @@ CloneTypeFoldableAndLiftImpls! {
29652965
SourceInfo,
29662966
UpvarDecl,
29672967
FakeReadCause,
2968+
RetagKind,
29682969
SourceScope,
29692970
SourceScopeData,
29702971
SourceScopeLocalData,
@@ -3031,8 +3032,7 @@ EnumTypeFoldableImpl! {
30313032
(StatementKind::StorageLive)(a),
30323033
(StatementKind::StorageDead)(a),
30333034
(StatementKind::InlineAsm) { asm, outputs, inputs },
3034-
(StatementKind::Retag) { fn_entry, two_phase, place },
3035-
(StatementKind::EscapeToRaw)(place),
3035+
(StatementKind::Retag)(kind, place),
30363036
(StatementKind::AscribeUserType)(a, v, b),
30373037
(StatementKind::Nop),
30383038
}

src/librustc/mir/visit.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,10 @@ macro_rules! make_mir_visitor {
153153
}
154154

155155
fn visit_retag(&mut self,
156-
fn_entry: & $($mutability)* bool,
157-
two_phase: & $($mutability)* bool,
156+
kind: & $($mutability)* RetagKind,
158157
place: & $($mutability)* Place<'tcx>,
159158
location: Location) {
160-
self.super_retag(fn_entry, two_phase, place, location);
159+
self.super_retag(kind, place, location);
161160
}
162161

163162
fn visit_place(&mut self,
@@ -385,9 +384,6 @@ macro_rules! make_mir_visitor {
385384
location
386385
);
387386
}
388-
StatementKind::EscapeToRaw(ref $($mutability)* op) => {
389-
self.visit_operand(op, location);
390-
}
391387
StatementKind::StorageLive(ref $($mutability)* local) => {
392388
self.visit_local(
393389
local,
@@ -417,10 +413,9 @@ macro_rules! make_mir_visitor {
417413
self.visit_operand(input, location);
418414
}
419415
}
420-
StatementKind::Retag { ref $($mutability)* fn_entry,
421-
ref $($mutability)* two_phase,
422-
ref $($mutability)* place } => {
423-
self.visit_retag(fn_entry, two_phase, place, location);
416+
StatementKind::Retag ( ref $($mutability)* kind,
417+
ref $($mutability)* place ) => {
418+
self.visit_retag(kind, place, location);
424419
}
425420
StatementKind::AscribeUserType(
426421
ref $($mutability)* place,
@@ -725,8 +720,7 @@ macro_rules! make_mir_visitor {
725720
}
726721

727722
fn super_retag(&mut self,
728-
_fn_entry: & $($mutability)* bool,
729-
_two_phase: & $($mutability)* bool,
723+
_kind: & $($mutability)* RetagKind,
730724
place: & $($mutability)* Place<'tcx>,
731725
location: Location) {
732726
self.visit_place(

src/librustc_codegen_ssa/mir/statement.rs

-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
106106
}
107107
mir::StatementKind::FakeRead(..) |
108108
mir::StatementKind::Retag { .. } |
109-
mir::StatementKind::EscapeToRaw { .. } |
110109
mir::StatementKind::AscribeUserType(..) |
111110
mir::StatementKind::Nop => bx,
112111
}

src/librustc_mir/borrow_check/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,6 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
590590
StatementKind::Nop
591591
| StatementKind::AscribeUserType(..)
592592
| StatementKind::Retag { .. }
593-
| StatementKind::EscapeToRaw { .. }
594593
| StatementKind::StorageLive(..) => {
595594
// `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant
596595
// to borrow check.

src/librustc_mir/borrow_check/nll/invalidation.rs

-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
135135
StatementKind::Nop |
136136
StatementKind::AscribeUserType(..) |
137137
StatementKind::Retag { .. } |
138-
StatementKind::EscapeToRaw { .. } |
139138
StatementKind::StorageLive(..) => {
140139
// `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant
141140
// to borrow check.

src/librustc_mir/borrow_check/nll/type_check/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13161316
| StatementKind::StorageDead(..)
13171317
| StatementKind::InlineAsm { .. }
13181318
| StatementKind::Retag { .. }
1319-
| StatementKind::EscapeToRaw { .. }
13201319
| StatementKind::Nop => {}
13211320
}
13221321
}

src/librustc_mir/dataflow/impls/borrows.rs

-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
300300
mir::StatementKind::SetDiscriminant { .. } |
301301
mir::StatementKind::StorageLive(..) |
302302
mir::StatementKind::Retag { .. } |
303-
mir::StatementKind::EscapeToRaw { .. } |
304303
mir::StatementKind::AscribeUserType(..) |
305304
mir::StatementKind::Nop => {}
306305

src/librustc_mir/dataflow/move_paths/builder.rs

-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,6 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
302302
"SetDiscriminant should not exist during borrowck");
303303
}
304304
StatementKind::Retag { .. } |
305-
StatementKind::EscapeToRaw { .. } |
306305
StatementKind::AscribeUserType(..) |
307306
StatementKind::Nop => {}
308307
}

src/librustc_mir/interpret/cast.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -44,34 +44,28 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
4444
}
4545

4646
Misc => {
47-
let src_layout = src.layout;
4847
let src = self.read_immediate(src)?;
4948

50-
// There are no casts to references
51-
assert!(!dest.layout.ty.is_region_ptr());
52-
// Hence we make all casts erase the tag
53-
let src = src.erase_tag().with_default_tag();
54-
55-
if self.type_is_fat_ptr(src_layout.ty) {
56-
match (src, self.type_is_fat_ptr(dest.layout.ty)) {
49+
if self.type_is_fat_ptr(src.layout.ty) {
50+
match (*src, self.type_is_fat_ptr(dest.layout.ty)) {
5751
// pointers to extern types
5852
(Immediate::Scalar(_),_) |
5953
// slices and trait objects to other slices/trait objects
6054
(Immediate::ScalarPair(..), true) => {
6155
// No change to immediate
62-
self.write_immediate(src, dest)?;
56+
self.write_immediate(*src, dest)?;
6357
}
6458
// slices and trait objects to thin pointers (dropping the metadata)
6559
(Immediate::ScalarPair(data, _), false) => {
6660
self.write_scalar(data, dest)?;
6761
}
6862
}
6963
} else {
70-
match src_layout.variants {
64+
match src.layout.variants {
7165
layout::Variants::Single { index } => {
72-
if let Some(def) = src_layout.ty.ty_adt_def() {
66+
if let Some(def) = src.layout.ty.ty_adt_def() {
7367
// Cast from a univariant enum
74-
assert!(src_layout.is_zst());
68+
assert!(src.layout.is_zst());
7569
let discr_val = def
7670
.discriminant_for_variant(*self.tcx, index)
7771
.val;
@@ -84,7 +78,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
8478
layout::Variants::NicheFilling { .. } => {},
8579
}
8680

87-
let dest_val = self.cast_scalar(src.to_scalar()?, src_layout, dest.layout)?;
81+
let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?;
8882
self.write_scalar(dest_val, dest)?;
8983
}
9084
}

src/librustc_mir/interpret/machine.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -203,22 +203,12 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
203203
#[inline]
204204
fn retag(
205205
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
206-
_fn_entry: bool,
207-
_two_phase: bool,
206+
_kind: mir::RetagKind,
208207
_place: PlaceTy<'tcx, Self::PointerTag>,
209208
) -> EvalResult<'tcx> {
210209
Ok(())
211210
}
212211

213-
/// Execute an escape-to-raw operation
214-
#[inline]
215-
fn escape_to_raw(
216-
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
217-
_ptr: OpTy<'tcx, Self::PointerTag>,
218-
) -> EvalResult<'tcx> {
219-
Ok(())
220-
}
221-
222212
/// Called immediately before a new stack frame got pushed
223213
fn stack_push(
224214
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,

src/librustc_mir/interpret/step.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -119,13 +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, two_phase, ref place } => {
122+
Retag(kind, ref place) => {
123123
let dest = self.eval_place(place)?;
124-
M::retag(self, fn_entry, two_phase, dest)?;
125-
}
126-
EscapeToRaw(ref op) => {
127-
let op = self.eval_operand(op, None)?;
128-
M::escape_to_raw(self, op)?;
124+
M::retag(self, kind, dest)?;
129125
}
130126

131127
// Statements we do not track.

src/librustc_mir/shim.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -226,20 +226,11 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
226226
// The first argument (index 0), but add 1 for the return value.
227227
let dropee_ptr = Place::Local(Local::new(1+0));
228228
if tcx.sess.opts.debugging_opts.mir_emit_retag {
229-
// Function arguments should be retagged
229+
// Function arguments should be retagged, and we make this one raw.
230230
mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
231231
source_info,
232-
kind: StatementKind::Retag {
233-
fn_entry: true,
234-
two_phase: false,
235-
place: dropee_ptr.clone(),
236-
},
232+
kind: StatementKind::Retag(RetagKind::Raw, dropee_ptr.clone()),
237233
});
238-
// We use raw ptr operations, better prepare the alias tracking for that
239-
mir.basic_blocks_mut()[START_BLOCK].statements.insert(1, Statement {
240-
source_info,
241-
kind: StatementKind::EscapeToRaw(Operand::Copy(dropee_ptr.clone())),
242-
})
243234
}
244235
let patch = {
245236
let param_env = tcx.param_env(def_id).with_reveal_all();

0 commit comments

Comments
 (0)