add 'raw reference' to the machine hook, and use that in ptr-to-raw casts

This commit is contained in:
Ralf Jung 2018-10-17 14:50:36 +02:00
parent 24724efe1c
commit bc647e9d33
6 changed files with 24 additions and 10 deletions

View file

@ -468,7 +468,7 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
_ptr: Pointer<Self::PointerTag>,
_pointee_ty: Ty<'tcx>,
_pointee_size: Size,
_borrow_kind: mir::BorrowKind,
_borrow_kind: Option<mir::BorrowKind>,
) -> EvalResult<'tcx, Self::PointerTag> {
Ok(())
}

View file

@ -38,7 +38,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
dest: PlaceTy<'tcx, M::PointerTag>,
) -> EvalResult<'tcx> {
let src_layout = src.layout;
let dst_layout = dest.layout;
use rustc::mir::CastKind::*;
match kind {
Unsize => {
@ -47,7 +46,19 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
Misc => {
let src = self.read_value(src)?;
if self.type_is_fat_ptr(src_layout.ty) {
if src.layout.ty.is_region_ptr() && dest.layout.ty.is_unsafe_ptr() {
// For the purpose of the "ptr tag hooks", treat this as creating
// a new, raw reference.
let place = self.ref_to_mplace(src)?;
let _val = self.create_ref(place, None)?;
// FIXME: The blog post said we should now also erase the tag.
// That would amount to using `_val` instead of `src` from here on.
// However, do we really want to do that? `transmute` doesn't
// do it either and we have to support that, somehow.
}
if self.type_is_fat_ptr(src.layout.ty) {
match (*src, self.type_is_fat_ptr(dest.layout.ty)) {
// pointers to extern types
(Value::Scalar(_),_) |
@ -65,11 +76,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
match src_layout.variants {
layout::Variants::Single { index } => {
if let Some(def) = src_layout.ty.ty_adt_def() {
// Cast from a univariant enum
assert!(src.layout.is_zst());
let discr_val = def
.discriminant_for_variant(*self.tcx, index)
.val;
return self.write_scalar(
Scalar::from_uint(discr_val, dst_layout.size),
Scalar::from_uint(discr_val, dest.layout.size),
dest);
}
}
@ -85,7 +98,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
ReifyFnPointer => {
// The src operand does not matter, just its type
match src_layout.ty.sty {
match src.layout.ty.sty {
ty::FnDef(def_id, substs) => {
if self.tcx.has_attr(def_id, "rustc_args_required_const") {
bug!("reifying a fn ptr that requires \
@ -117,7 +130,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
ClosureFnPointer => {
// The src operand does not matter, just its type
match src_layout.ty.sty {
match src.layout.ty.sty {
ty::Closure(def_id, substs) => {
let substs = self.tcx.subst_and_normalize_erasing_regions(
self.substs(),

View file

@ -201,12 +201,13 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
/// Executed when evaluating the `&` operator: Creating a new reference.
/// This has the chance to adjust the tag.
/// `borrow_kind` can be `None` in case a raw ptr is being created.
fn tag_reference(
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
ptr: Pointer<Self::PointerTag>,
pointee_ty: Ty<'tcx>,
pointee_size: Size,
borrow_kind: mir::BorrowKind,
borrow_kind: Option<mir::BorrowKind>,
) -> EvalResult<'tcx, Self::PointerTag>;
/// Executed when evaluating the `*` operator: Following a reference.

View file

@ -291,7 +291,7 @@ where
pub fn create_ref(
&mut self,
place: MPlaceTy<'tcx, M::PointerTag>,
borrow_kind: mir::BorrowKind,
borrow_kind: Option<mir::BorrowKind>,
) -> EvalResult<'tcx, Value<M::PointerTag>> {
let ptr = match place.ptr {
Scalar::Ptr(ptr) => {

View file

@ -251,7 +251,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
Ref(_, borrow_kind, ref place) => {
let src = self.eval_place(place)?;
let val = self.force_allocation(src)?;
let val = self.create_ref(val, borrow_kind)?;
let val = self.create_ref(val, Some(borrow_kind))?;
self.write_value(val, dest)?;
}

View file

@ -448,7 +448,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
let arg = OpTy {
op: Operand::Immediate(self.create_ref(
place,
mir::BorrowKind::Mut { allow_two_phase_borrow: false }
None // this is a "raw reference"
)?),
layout: self.layout_of(self.tcx.mk_mut_ptr(place.layout.ty))?,
};