Rustup to rustc 1.17.0-nightly (be760566c 2017-02-28)
This commit is contained in:
parent
8878a4030a
commit
8405770b51
@ -1,15 +1,14 @@
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use rustc::mir;
|
||||
use rustc::ty::{BareFnTy, Ty, FnSig, layout};
|
||||
use syntax::abi::Abi;
|
||||
use rustc::ty::{PolyFnSig, Ty, layout};
|
||||
use memory::{Pointer, Function};
|
||||
use rustc_const_math::ConstMathErr;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum EvalError<'tcx> {
|
||||
FunctionPointerTyMismatch(Abi, &'tcx FnSig<'tcx>, &'tcx BareFnTy<'tcx>),
|
||||
FunctionPointerTyMismatch(PolyFnSig<'tcx>, PolyFnSig<'tcx>),
|
||||
NoMirFor(String),
|
||||
UnterminatedCString(Pointer),
|
||||
DanglingPointerDeref,
|
||||
@ -151,8 +150,8 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
|
||||
ptr.offset, ptr.offset + size, ptr.alloc_id, allocation_size)
|
||||
},
|
||||
EvalError::NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
|
||||
EvalError::FunctionPointerTyMismatch(abi, sig, got) =>
|
||||
write!(f, "tried to call a function with abi {:?} and sig {:?} through a function pointer of type {:?}", abi, sig, got),
|
||||
EvalError::FunctionPointerTyMismatch(sig, got) =>
|
||||
write!(f, "tried to call a function with sig {} through a function pointer of type {}", sig.skip_binder(), got.skip_binder()),
|
||||
EvalError::ArrayIndexOutOfBounds(span, len, index) =>
|
||||
write!(f, "index out of bounds: the len is {} but the index is {} at {:?}", len, index, span),
|
||||
EvalError::Math(span, ref err) =>
|
||||
|
@ -181,8 +181,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
Float(ConstFloat::F32(f)) => PrimVal::from_f32(f),
|
||||
Float(ConstFloat::F64(f)) => PrimVal::from_f64(f),
|
||||
Float(ConstFloat::FInfer { .. }) =>
|
||||
bug!("uninferred constants only exist before typeck"),
|
||||
|
||||
Bool(b) => PrimVal::from_bool(b),
|
||||
Char(c) => PrimVal::from_char(c),
|
||||
@ -196,7 +194,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
Struct(_) => unimplemented!(),
|
||||
Tuple(_) => unimplemented!(),
|
||||
Function(_) => unimplemented!(),
|
||||
Function(_, _) => unimplemented!(),
|
||||
Array(_) => unimplemented!(),
|
||||
Repeat(_, _) => unimplemented!(),
|
||||
};
|
||||
@ -457,7 +455,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
General { discr, ref variants, .. } => {
|
||||
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
|
||||
let discr_val = adt_def.variants[variant].disr_val;
|
||||
let discr_val = adt_def.discriminants(self.tcx)
|
||||
.nth(variant)
|
||||
.expect("broken mir: Adt variant id invalid")
|
||||
.to_u128_unchecked();
|
||||
let discr_size = discr.size().bytes();
|
||||
if variants[variant].packed {
|
||||
let ptr = self.force_allocation(dest)?.to_ptr_and_extra().0;
|
||||
@ -530,7 +531,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
CEnum { .. } => {
|
||||
assert_eq!(operands.len(), 0);
|
||||
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
|
||||
let n = adt_def.variants[variant].disr_val;
|
||||
let n = adt_def.discriminants(self.tcx)
|
||||
.nth(variant)
|
||||
.expect("broken mir: Adt variant index invalid")
|
||||
.to_u128_unchecked();
|
||||
self.write_primval(dest, PrimVal::Bytes(n), dest_ty)?;
|
||||
} else {
|
||||
bug!("tried to assign {:?} to Layout::CEnum", kind);
|
||||
@ -640,9 +644,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
ReifyFnPointer => match self.operand_ty(operand).sty {
|
||||
ty::TyFnDef(def_id, substs, fn_ty) => {
|
||||
let fn_ty = self.tcx.erase_regions(&fn_ty);
|
||||
let fn_ptr = self.memory.create_fn_ptr(self.tcx,def_id, substs, fn_ty);
|
||||
ty::TyFnDef(def_id, substs, sig) => {
|
||||
let fn_ptr = self.memory.create_fn_ptr(def_id, substs, sig);
|
||||
self.write_value(Value::ByVal(PrimVal::Ptr(fn_ptr)), dest, dest_ty)?;
|
||||
},
|
||||
ref other => bug!("reify fn pointer on {:?}", other),
|
||||
@ -658,8 +661,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
ClosureFnPointer => match self.operand_ty(operand).sty {
|
||||
ty::TyClosure(def_id, substs) => {
|
||||
let fn_ty = self.tcx.closure_type(def_id, substs);
|
||||
let fn_ptr = self.memory.create_fn_ptr_from_noncapture_closure(self.tcx, def_id, substs, fn_ty);
|
||||
let fn_ty = self.tcx.closure_type(def_id);
|
||||
let fn_ptr = self.memory.create_fn_ptr_from_noncapture_closure(def_id, substs, fn_ty);
|
||||
self.write_value(Value::ByVal(PrimVal::Ptr(fn_ptr)), dest, dest_ty)?;
|
||||
},
|
||||
ref other => bug!("reify fn pointer on {:?}", other),
|
||||
@ -673,7 +676,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let ptr = self.force_allocation(lval)?.to_ptr();
|
||||
let discr_val = self.read_discriminant_value(ptr, ty)?;
|
||||
if let ty::TyAdt(adt_def, _) = ty.sty {
|
||||
if adt_def.variants.iter().all(|v| discr_val != v.disr_val) {
|
||||
if adt_def.discriminants(self.tcx).all(|v| discr_val != v.to_u128_unchecked()) {
|
||||
return Err(EvalError::InvalidDiscriminant);
|
||||
}
|
||||
} else {
|
||||
|
@ -3,12 +3,10 @@ use std::collections::{btree_map, BTreeMap, HashMap, HashSet, VecDeque, BTreeSet
|
||||
use std::{fmt, iter, ptr, mem, io};
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::{self, BareFnTy, ClosureTy, ClosureSubsts, TyCtxt};
|
||||
use rustc::ty::{self, PolyFnSig, ClosureSubsts};
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::layout::{self, TargetDataLayout};
|
||||
|
||||
use syntax::abi::Abi;
|
||||
|
||||
use error::{EvalError, EvalResult};
|
||||
use value::PrimVal;
|
||||
|
||||
@ -109,8 +107,7 @@ impl Pointer {
|
||||
pub struct FunctionDefinition<'tcx> {
|
||||
pub def_id: DefId,
|
||||
pub substs: &'tcx Substs<'tcx>,
|
||||
pub abi: Abi,
|
||||
pub sig: &'tcx ty::FnSig<'tcx>,
|
||||
pub sig: PolyFnSig<'tcx>,
|
||||
}
|
||||
|
||||
/// Either a concrete function, or a glue function
|
||||
@ -127,7 +124,7 @@ pub enum Function<'tcx> {
|
||||
DropGlue(ty::Ty<'tcx>),
|
||||
/// Glue required to treat the ptr part of a fat pointer
|
||||
/// as a function pointer
|
||||
FnPtrAsTraitObject(&'tcx ty::FnSig<'tcx>),
|
||||
FnPtrAsTraitObject(PolyFnSig<'tcx>),
|
||||
/// Glue for Closures
|
||||
Closure(FunctionDefinition<'tcx>),
|
||||
/// Glue for noncapturing closures casted to function pointers
|
||||
@ -217,67 +214,43 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
self.alloc_map.iter()
|
||||
}
|
||||
|
||||
pub fn create_closure_ptr(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, substs: ClosureSubsts<'tcx>, fn_ty: ClosureTy<'tcx>) -> Pointer {
|
||||
// FIXME: this is a hack
|
||||
let fn_ty = tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: fn_ty.unsafety,
|
||||
abi: fn_ty.abi,
|
||||
sig: fn_ty.sig,
|
||||
});
|
||||
pub fn create_closure_ptr(&mut self, def_id: DefId, substs: ClosureSubsts<'tcx>, sig: PolyFnSig<'tcx>) -> Pointer {
|
||||
self.create_fn_alloc(Function::Closure(FunctionDefinition {
|
||||
def_id,
|
||||
substs: substs.substs,
|
||||
abi: fn_ty.abi,
|
||||
// FIXME: why doesn't this compile?
|
||||
//sig: tcx.erase_late_bound_regions(&fn_ty.sig),
|
||||
sig: fn_ty.sig.skip_binder(),
|
||||
sig,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn create_fn_ptr_from_noncapture_closure(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, substs: ClosureSubsts<'tcx>, fn_ty: ClosureTy<'tcx>) -> Pointer {
|
||||
// FIXME: this is a hack
|
||||
let fn_ty = tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: fn_ty.unsafety,
|
||||
abi: fn_ty.abi,
|
||||
sig: fn_ty.sig,
|
||||
});
|
||||
pub fn create_fn_ptr_from_noncapture_closure(&mut self, def_id: DefId, substs: ClosureSubsts<'tcx>, sig: PolyFnSig<'tcx>) -> Pointer {
|
||||
self.create_fn_alloc(Function::NonCaptureClosureAsFnPtr(FunctionDefinition {
|
||||
def_id,
|
||||
substs: substs.substs,
|
||||
abi: Abi::Rust, // adjust abi
|
||||
// FIXME: why doesn't this compile?
|
||||
//sig: tcx.erase_late_bound_regions(&fn_ty.sig),
|
||||
sig: fn_ty.sig.skip_binder(),
|
||||
sig,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn create_fn_as_trait_glue(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>, fn_ty: &'tcx BareFnTy<'tcx>) -> Pointer {
|
||||
pub fn create_fn_as_trait_glue(&mut self, def_id: DefId, substs: &'tcx Substs, sig: PolyFnSig<'tcx>) -> Pointer {
|
||||
self.create_fn_alloc(Function::FnDefAsTraitObject(FunctionDefinition {
|
||||
def_id,
|
||||
substs,
|
||||
abi: fn_ty.abi,
|
||||
// FIXME: why doesn't this compile?
|
||||
//sig: tcx.erase_late_bound_regions(&fn_ty.sig),
|
||||
sig: fn_ty.sig.skip_binder(),
|
||||
sig,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn create_fn_ptr_as_trait_glue(&mut self, fn_ty: &'tcx BareFnTy<'tcx>) -> Pointer {
|
||||
self.create_fn_alloc(Function::FnPtrAsTraitObject(fn_ty.sig.skip_binder()))
|
||||
pub fn create_fn_ptr_as_trait_glue(&mut self, sig: PolyFnSig<'tcx>) -> Pointer {
|
||||
self.create_fn_alloc(Function::FnPtrAsTraitObject(sig))
|
||||
}
|
||||
|
||||
pub fn create_drop_glue(&mut self, ty: ty::Ty<'tcx>) -> Pointer {
|
||||
self.create_fn_alloc(Function::DropGlue(ty))
|
||||
}
|
||||
|
||||
pub fn create_fn_ptr(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>, fn_ty: &'tcx BareFnTy<'tcx>) -> Pointer {
|
||||
pub fn create_fn_ptr(&mut self, def_id: DefId, substs: &'tcx Substs, sig: PolyFnSig<'tcx>) -> Pointer {
|
||||
self.create_fn_alloc(Function::Concrete(FunctionDefinition {
|
||||
def_id,
|
||||
substs,
|
||||
abi: fn_ty.abi,
|
||||
// FIXME: why doesn't this compile?
|
||||
//sig: tcx.erase_late_bound_regions(&fn_ty.sig),
|
||||
sig: fn_ty.sig.skip_binder(),
|
||||
sig,
|
||||
}))
|
||||
}
|
||||
|
||||
@ -623,12 +596,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
|
||||
fn dump_fn_def<'tcx>(fn_def: FunctionDefinition<'tcx>) -> String {
|
||||
let name = ty::tls::with(|tcx| tcx.item_path_str(fn_def.def_id));
|
||||
let abi = if fn_def.abi == Abi::Rust {
|
||||
format!("")
|
||||
} else {
|
||||
format!("extern {} ", fn_def.abi)
|
||||
};
|
||||
format!("function pointer: {}: {}{}", name, abi, fn_def.sig)
|
||||
format!("function pointer: {}: {}", name, fn_def.sig.skip_binder())
|
||||
}
|
||||
|
||||
/// Byte accessors
|
||||
|
@ -97,7 +97,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let (adt_ptr, extra) = lval.to_ptr_and_extra();
|
||||
|
||||
// run drop impl before the fields' drop impls
|
||||
if let Some(drop_def_id) = adt_def.destructor() {
|
||||
if let Some(drop_def_id) = adt_def.destructor(self.tcx) {
|
||||
let trait_ref = ty::Binder(ty::TraitRef {
|
||||
def_id: self.tcx.lang_items.drop_trait().unwrap(),
|
||||
substs: self.tcx.mk_substs_trait(ty, &[]),
|
||||
@ -121,7 +121,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
Layout::General { .. } => {
|
||||
let discr_val = self.read_discriminant_value(adt_ptr, ty)? as u128;
|
||||
let ptr = self.force_allocation(lval)?.to_ptr();
|
||||
match adt_def.variants.iter().position(|v| discr_val == v.disr_val) {
|
||||
match adt_def.discriminants(self.tcx).position(|v| discr_val == v.to_u128_unchecked()) {
|
||||
Some(i) => {
|
||||
lval = Lvalue::Ptr {
|
||||
ptr,
|
||||
|
@ -3,8 +3,10 @@ use rustc::mir;
|
||||
use rustc::ty::layout::Layout;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc_const_math::ConstInt;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::attr;
|
||||
use syntax::abi::Abi;
|
||||
|
||||
use error::{EvalError, EvalResult};
|
||||
use eval_context::{EvalContext, IntegerExt, StackPopCleanup, is_inhabited};
|
||||
@ -62,11 +64,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
let func_ty = self.operand_ty(func);
|
||||
let fn_def = match func_ty.sty {
|
||||
ty::TyFnPtr(bare_fn_ty) => {
|
||||
ty::TyFnPtr(bare_sig) => {
|
||||
let fn_ptr = self.eval_operand_to_primval(func)?.to_ptr()?;
|
||||
let fn_def = self.memory.get_fn(fn_ptr.alloc_id)?;
|
||||
let bare_sig = self.tcx.erase_late_bound_regions_and_normalize(&bare_fn_ty.sig);
|
||||
let bare_sig = self.tcx.erase_regions(&bare_sig);
|
||||
match fn_def {
|
||||
Function::Concrete(fn_def) => {
|
||||
// transmuting function pointers in miri is fine as long as the number of
|
||||
@ -74,21 +74,21 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
// FIXME: also check the size of the arguments' type and the return type
|
||||
// Didn't get it to work, since that triggers an assertion in rustc which
|
||||
// checks whether the type has escaping regions
|
||||
if fn_def.abi != bare_fn_ty.abi ||
|
||||
fn_def.sig.variadic != bare_sig.variadic ||
|
||||
fn_def.sig.inputs().len() != bare_sig.inputs().len() {
|
||||
return Err(EvalError::FunctionPointerTyMismatch(fn_def.abi, fn_def.sig, bare_fn_ty));
|
||||
if fn_def.sig.abi() != bare_sig.abi() ||
|
||||
fn_def.sig.variadic() != bare_sig.variadic() ||
|
||||
fn_def.sig.inputs().skip_binder().len() != bare_sig.inputs().skip_binder().len() {
|
||||
return Err(EvalError::FunctionPointerTyMismatch(fn_def.sig, bare_sig));
|
||||
}
|
||||
},
|
||||
Function::NonCaptureClosureAsFnPtr(fn_def) => {
|
||||
if fn_def.abi != bare_fn_ty.abi ||
|
||||
fn_def.sig.variadic != bare_sig.variadic ||
|
||||
fn_def.sig.inputs().len() != 1 {
|
||||
return Err(EvalError::FunctionPointerTyMismatch(fn_def.abi, fn_def.sig, bare_fn_ty));
|
||||
assert_eq!(fn_def.sig.abi(), Abi::RustCall);
|
||||
if fn_def.sig.variadic() != bare_sig.variadic() ||
|
||||
fn_def.sig.inputs().skip_binder().len() != 1 {
|
||||
return Err(EvalError::FunctionPointerTyMismatch(fn_def.sig, bare_sig));
|
||||
}
|
||||
if let ty::TyTuple(fields, _) = fn_def.sig.inputs()[0].sty {
|
||||
if fields.len() != bare_sig.inputs().len() {
|
||||
return Err(EvalError::FunctionPointerTyMismatch(fn_def.abi, fn_def.sig, bare_fn_ty));
|
||||
if let ty::TyTuple(fields, _) = fn_def.sig.inputs().skip_binder()[0].sty {
|
||||
if fields.len() != bare_sig.inputs().skip_binder().len() {
|
||||
return Err(EvalError::FunctionPointerTyMismatch(fn_def.sig, bare_sig));
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -99,8 +99,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
ty::TyFnDef(def_id, substs, fn_ty) => Function::Concrete(FunctionDefinition {
|
||||
def_id,
|
||||
substs,
|
||||
abi: fn_ty.abi,
|
||||
sig: fn_ty.sig.skip_binder(),
|
||||
sig: fn_ty,
|
||||
}),
|
||||
|
||||
_ => {
|
||||
@ -165,8 +164,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
use syntax::abi::Abi;
|
||||
match fn_def {
|
||||
// Intrinsics can only be addressed directly
|
||||
Function::Concrete(FunctionDefinition { def_id, substs, abi: Abi::RustIntrinsic, sig }) => {
|
||||
let ty = sig.output();
|
||||
Function::Concrete(FunctionDefinition { def_id, substs, sig }) if sig.abi() == Abi::RustIntrinsic => {
|
||||
let ty = *sig.output().skip_binder();
|
||||
let layout = self.type_layout(ty)?;
|
||||
let (ret, target) = match destination {
|
||||
Some(dest) if is_inhabited(self.tcx, ty) => dest,
|
||||
@ -177,8 +176,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
Ok(())
|
||||
},
|
||||
// C functions can only be addressed directly
|
||||
Function::Concrete(FunctionDefinition { def_id, abi: Abi::C, sig, ..}) => {
|
||||
let ty = sig.output();
|
||||
Function::Concrete(FunctionDefinition { def_id, sig, ..}) if sig.abi() == Abi::C => {
|
||||
let ty = *sig.output().skip_binder();
|
||||
let (ret, target) = destination.unwrap();
|
||||
self.call_c_abi(def_id, arg_operands, ret, ty)?;
|
||||
self.dump_local(ret);
|
||||
@ -186,8 +185,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
Ok(())
|
||||
},
|
||||
Function::DropGlue(_) => Err(EvalError::ManuallyCalledDropGlue),
|
||||
Function::Concrete(FunctionDefinition { def_id, abi: Abi::RustCall, sig, substs }) |
|
||||
Function::Concrete(FunctionDefinition { def_id, abi: Abi::Rust, sig, substs }) => {
|
||||
Function::Concrete(FunctionDefinition { def_id, sig, substs }) if sig.abi() == Abi::Rust || sig.abi() == Abi::RustCall => {
|
||||
let mut args = Vec::new();
|
||||
for arg in arg_operands {
|
||||
let arg_val = self.eval_operand(arg)?;
|
||||
@ -204,20 +202,20 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
};
|
||||
|
||||
// FIXME(eddyb) Detect ADT constructors more efficiently.
|
||||
if let Some(adt_def) = sig.output().ty_adt_def() {
|
||||
if let Some(v) = adt_def.variants.iter().find(|v| resolved_def_id == v.did) {
|
||||
if let Some(adt_def) = sig.output().skip_binder().ty_adt_def() {
|
||||
let dids = adt_def.variants.iter().map(|v| v.did);
|
||||
let discrs = adt_def.discriminants(self.tcx).map(ConstInt::to_u128_unchecked);
|
||||
if let Some((_, disr_val)) = dids.zip(discrs).find(|&(did, _)| resolved_def_id == did) {
|
||||
let (lvalue, target) = destination.expect("tuple struct constructors can't diverge");
|
||||
let dest_ty = self.tcx.item_type(adt_def.did);
|
||||
let dest_layout = self.type_layout(dest_ty)?;
|
||||
trace!("layout({:?}) = {:#?}", dest_ty, dest_layout);
|
||||
match *dest_layout {
|
||||
Layout::Univariant { .. } => {
|
||||
let disr_val = v.disr_val;
|
||||
assert_eq!(disr_val, 0);
|
||||
self.assign_fields(lvalue, dest_ty, args)?;
|
||||
},
|
||||
Layout::General { discr, ref variants, .. } => {
|
||||
let disr_val = v.disr_val;
|
||||
let discr_size = discr.size().bytes();
|
||||
self.assign_discr_and_fields(
|
||||
lvalue,
|
||||
@ -230,7 +228,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
)?;
|
||||
},
|
||||
Layout::StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
|
||||
let disr_val = v.disr_val;
|
||||
if nndiscr as u128 == disr_val {
|
||||
self.assign_fields(lvalue, dest_ty, args)?;
|
||||
} else {
|
||||
@ -268,7 +265,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
span,
|
||||
)
|
||||
},
|
||||
Function::NonCaptureClosureAsFnPtr(FunctionDefinition { def_id, abi: Abi::Rust, substs, sig }) => {
|
||||
Function::NonCaptureClosureAsFnPtr(FunctionDefinition { def_id, substs, sig }) if sig.abi() == Abi::RustCall => {
|
||||
let mut args = Vec::new();
|
||||
for arg in arg_operands {
|
||||
let arg_val = self.eval_operand(arg)?;
|
||||
@ -277,7 +274,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
}
|
||||
args.insert(0, (
|
||||
Value::ByVal(PrimVal::Undef),
|
||||
sig.inputs()[0],
|
||||
sig.inputs().skip_binder()[0],
|
||||
));
|
||||
self.eval_fn_call_inner(
|
||||
def_id,
|
||||
|
@ -113,7 +113,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
match self.memory.get_fn(fn_ptr.alloc_id)? {
|
||||
Function::FnDefAsTraitObject(fn_def) => {
|
||||
trace!("sig: {:#?}", fn_def.sig);
|
||||
assert!(fn_def.abi != abi::Abi::RustCall);
|
||||
assert!(fn_def.sig.abi() != abi::Abi::RustCall);
|
||||
assert_eq!(args.len(), 2);
|
||||
// a function item turned into a closure trait object
|
||||
// the first arg is just there to give use the vtable
|
||||
@ -126,14 +126,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
trace!("sig: {:#?}", fn_def.sig);
|
||||
args[0] = (
|
||||
Value::ByVal(PrimVal::Ptr(self_ptr)),
|
||||
fn_def.sig.inputs()[0],
|
||||
fn_def.sig.inputs().skip_binder()[0],
|
||||
);
|
||||
Ok((fn_def.def_id, fn_def.substs, Vec::new()))
|
||||
},
|
||||
Function::NonCaptureClosureAsFnPtr(fn_def) => {
|
||||
args.insert(0, (
|
||||
Value::ByVal(PrimVal::Undef),
|
||||
fn_def.sig.inputs()[0],
|
||||
fn_def.sig.inputs().skip_binder()[0],
|
||||
));
|
||||
Ok((fn_def.def_id, fn_def.substs, Vec::new()))
|
||||
}
|
||||
@ -155,7 +155,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
Function::NonCaptureClosureAsFnPtr(fn_def) => {
|
||||
args.insert(0, (
|
||||
Value::ByVal(PrimVal::Undef),
|
||||
fn_def.sig.inputs()[0],
|
||||
fn_def.sig.inputs().skip_binder()[0],
|
||||
));
|
||||
fn_def
|
||||
},
|
||||
@ -220,7 +220,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
_ => bug!("bad function type: {}", fn_ty),
|
||||
};
|
||||
let fn_ty = self.tcx.erase_regions(&fn_ty);
|
||||
self.memory.create_fn_ptr(self.tcx, mth.method.def_id, mth.substs, fn_ty)
|
||||
self.memory.create_fn_ptr(mth.method.def_id, mth.substs, fn_ty)
|
||||
}))
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
@ -233,15 +233,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
..
|
||||
}
|
||||
) => {
|
||||
let closure_type = self.tcx.closure_type(closure_def_id, substs);
|
||||
vec![Some(self.memory.create_closure_ptr(self.tcx, closure_def_id, substs, closure_type))].into_iter()
|
||||
let closure_type = self.tcx.closure_type(closure_def_id);
|
||||
vec![Some(self.memory.create_closure_ptr(closure_def_id, substs, closure_type))].into_iter()
|
||||
}
|
||||
|
||||
// turn a function definition into a Fn trait object
|
||||
traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, .. }) => {
|
||||
match fn_ty.sty {
|
||||
ty::TyFnDef(did, substs, bare_fn_ty) => {
|
||||
vec![Some(self.memory.create_fn_as_trait_glue(self.tcx, did, substs, bare_fn_ty))].into_iter()
|
||||
vec![Some(self.memory.create_fn_as_trait_glue(did, substs, bare_fn_ty))].into_iter()
|
||||
},
|
||||
ty::TyFnPtr(bare_fn_ty) => {
|
||||
vec![Some(self.memory.create_fn_ptr_as_trait_glue(bare_fn_ty))].into_iter()
|
||||
@ -275,13 +275,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
// in case there is no drop function to be called, this still needs to be initialized
|
||||
self.memory.write_usize(vtable, 0)?;
|
||||
if let ty::TyAdt(adt_def, substs) = trait_ref.self_ty().sty {
|
||||
if let Some(drop_def_id) = adt_def.destructor() {
|
||||
if let Some(drop_def_id) = adt_def.destructor(self.tcx) {
|
||||
let fn_ty = match self.tcx.item_type(drop_def_id).sty {
|
||||
ty::TyFnDef(_, _, fn_ty) => self.tcx.erase_regions(&fn_ty),
|
||||
_ => bug!("drop method is not a TyFnDef"),
|
||||
};
|
||||
// The real type is taken from the self argument in `fn drop(&mut self)`
|
||||
let real_ty = match fn_ty.sig.skip_binder().inputs()[0].sty {
|
||||
let real_ty = match fn_ty.inputs().skip_binder()[0].sty {
|
||||
ty::TyRef(_, mt) => self.monomorphize(mt.ty, substs),
|
||||
_ => bug!("first argument of Drop::drop must be &mut T"),
|
||||
};
|
||||
|
@ -5,5 +5,5 @@ fn main() {
|
||||
std::mem::transmute::<fn(), fn(i32)>(f)
|
||||
};
|
||||
|
||||
g(42) //~ ERROR tried to call a function with abi Rust and sig
|
||||
g(42) //~ ERROR tried to call a function with sig fn() through a function pointer of type fn(i32)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user