add 'raw reference' to the machine hook, and use that in ptr-to-raw casts
This commit is contained in:
parent
24724efe1c
commit
bc647e9d33
6 changed files with 24 additions and 10 deletions
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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)?;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))?,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue