Skip to content

Commit 048900c

Browse files
committed
make (de)reference hooks more consistent
1 parent 1982f18 commit 048900c

File tree

4 files changed

+45
-19
lines changed

4 files changed

+45
-19
lines changed

src/librustc_mir/const_eval.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
472472
_ptr: Pointer<Self::PointerTag>,
473473
_pointee_ty: Ty<'tcx>,
474474
_pointee_size: Size,
475-
_borrow_kind: Option<mir::BorrowKind>,
475+
_borrow_kind: Option<hir::Mutability>,
476476
) -> EvalResult<'tcx, Self::PointerTag> {
477477
Ok(())
478478
}
@@ -481,7 +481,9 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
481481
fn tag_dereference(
482482
_ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
483483
_ptr: Pointer<Self::PointerTag>,
484-
_ptr_ty: Ty<'tcx>,
484+
_pointee_ty: Ty<'tcx>,
485+
_pointee_size: Size,
486+
_borrow_kind: Option<hir::Mutability>,
485487
) -> EvalResult<'tcx, Self::PointerTag> {
486488
Ok(())
487489
}

src/librustc_mir/interpret/machine.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use std::borrow::{Borrow, Cow};
1616
use std::hash::Hash;
1717

18-
use rustc::hir::def_id::DefId;
18+
use rustc::hir::{self, def_id::DefId};
1919
use rustc::mir;
2020
use rustc::ty::{self, Ty, layout::{Size, TyLayout}, query::TyCtxtAt};
2121

@@ -206,21 +206,24 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
206206

207207
/// Executed when evaluating the `&` operator: Creating a new reference.
208208
/// This has the chance to adjust the tag.
209-
/// `borrow_kind` can be `None` in case a raw ptr is being created.
209+
/// `mutability` can be `None` in case a raw ptr is being created.
210210
fn tag_reference(
211211
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
212212
ptr: Pointer<Self::PointerTag>,
213213
pointee_ty: Ty<'tcx>,
214214
pointee_size: Size,
215-
borrow_kind: Option<mir::BorrowKind>,
215+
mutability: Option<hir::Mutability>,
216216
) -> EvalResult<'tcx, Self::PointerTag>;
217217

218218
/// Executed when evaluating the `*` operator: Following a reference.
219219
/// This has the change to adjust the tag.
220+
/// `mutability` can be `None` in case a raw ptr is being dereferenced.
220221
fn tag_dereference(
221222
ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
222223
ptr: Pointer<Self::PointerTag>,
223-
ptr_ty: Ty<'tcx>,
224+
pointee_ty: Ty<'tcx>,
225+
pointee_size: Size,
226+
mutability: Option<hir::Mutability>,
224227
) -> EvalResult<'tcx, Self::PointerTag>;
225228

226229
/// Execute a validation operation

src/librustc_mir/interpret/operand.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,16 @@ impl<'tcx, Tag> Value<Tag> {
217217
Value::ScalarPair(ptr, _) => ptr.not_undef(),
218218
}
219219
}
220+
221+
/// Convert the value into its metadata.
222+
/// Throws away the first half of a ScalarPair!
223+
#[inline]
224+
pub fn to_meta(self) -> EvalResult<'tcx, Option<Scalar<Tag>>> {
225+
Ok(match self {
226+
Value::Scalar(_) => None,
227+
Value::ScalarPair(_, meta) => Some(meta.not_undef()?),
228+
})
229+
}
220230
}
221231

222232
// ScalarPair needs a type to interpret, so we often have a value and a type together

src/librustc_mir/interpret/place.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use std::convert::TryFrom;
1616
use std::hash::Hash;
1717

18+
use rustc::hir;
1819
use rustc::mir;
1920
use rustc::ty::{self, Ty};
2021
use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout};
@@ -270,26 +271,31 @@ where
270271
&self,
271272
val: ValTy<'tcx, M::PointerTag>,
272273
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
274+
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
275+
let layout = self.layout_of(pointee_type)?;
276+
277+
let align = layout.align;
278+
let meta = val.to_meta()?;
279+
273280
let ptr = match val.to_scalar_ptr()? {
274281
Scalar::Ptr(ptr) if M::ENABLE_PTR_TRACKING_HOOKS => {
275282
// Machine might want to track the `*` operator
276-
let tag = M::tag_dereference(self, ptr, val.layout.ty)?;
283+
let (size, _) = self.size_and_align_of(meta, layout)?
284+
.expect("ref_to_mplace cannot determine size");
285+
let mutbl = match val.layout.ty.sty {
286+
// `builtin_deref` considers boxes immutable, that's useless for our purposes
287+
ty::Ref(_, _, mutbl) => Some(mutbl),
288+
ty::Adt(def, _) if def.is_box() => Some(hir::MutMutable),
289+
ty::RawPtr(_) => None,
290+
_ => bug!("Unexpected pointer type {}", val.layout.ty.sty),
291+
};
292+
let tag = M::tag_dereference(self, ptr, pointee_type, size, mutbl)?;
277293
Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
278294
}
279295
other => other,
280296
};
281297

282-
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
283-
let layout = self.layout_of(pointee_type)?;
284-
let align = layout.align;
285-
286-
let mplace = match *val {
287-
Value::Scalar(_) =>
288-
MemPlace { ptr, align, meta: None },
289-
Value::ScalarPair(_, meta) =>
290-
MemPlace { ptr, align, meta: Some(meta.not_undef()?) },
291-
};
292-
Ok(MPlaceTy { mplace, layout })
298+
Ok(MPlaceTy { mplace: MemPlace { ptr, align, meta }, layout })
293299
}
294300

295301
/// Turn a mplace into a (thin or fat) pointer, as a reference, pointing to the same space.
@@ -304,7 +310,12 @@ where
304310
// Machine might want to track the `&` operator
305311
let (size, _) = self.size_and_align_of_mplace(place)?
306312
.expect("create_ref cannot determine size");
307-
let tag = M::tag_reference(self, ptr, place.layout.ty, size, borrow_kind)?;
313+
let mutbl = match borrow_kind {
314+
Some(mir::BorrowKind::Mut { .. }) => Some(hir::MutMutable),
315+
Some(_) => Some(hir::MutImmutable),
316+
None => None,
317+
};
318+
let tag = M::tag_reference(self, ptr, place.layout.ty, size, mutbl)?;
308319
Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
309320
},
310321
other => other,

0 commit comments

Comments
 (0)