diff --git a/src/error.rs b/src/error.rs index 72eedba5e3e18a60599b44e35e28129b05d8b31b..34b672dda91e19ac9d1e37c8670a7b4c99e32bd4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 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) => diff --git a/src/eval_context.rs b/src/eval_context.rs index 1a1102c13a1c0d4b7f7f48303a1634ee504ebff4..9b23b849fc9b785193653958b0b3d1c90a88b3f2 100644 --- a/src/eval_context.rs +++ b/src/eval_context.rs @@ -181,8 +181,6 @@ pub(super) fn const_to_value(&mut self, const_val: &ConstVal) -> EvalResult<'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 @@ pub(super) fn const_to_value(&mut self, const_val: &ConstVal) -> EvalResult<'tcx Struct(_) => unimplemented!(), Tuple(_) => unimplemented!(), - Function(_) => unimplemented!(), + Function(_, _) => unimplemented!(), Array(_) => unimplemented!(), Repeat(_, _) => unimplemented!(), }; @@ -457,7 +455,10 @@ pub(super) fn eval_rvalue_into_lvalue( 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 @@ pub(super) fn eval_rvalue_into_lvalue( 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 @@ pub(super) fn eval_rvalue_into_lvalue( } 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 @@ pub(super) fn eval_rvalue_into_lvalue( 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 @@ pub(super) fn eval_rvalue_into_lvalue( 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 { diff --git a/src/memory.rs b/src/memory.rs index fd035b7fcba691c98bb5698592aa76e20ce96483..44959ea6728607d6c73c2656bd9d571549c8ff15 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -3,12 +3,10 @@ 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 @@ pub fn never_ptr() -> Self { 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 @@ pub fn allocations(&self) -> ::std::collections::hash_map::Iter, 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 @@ pub fn leak_report(&self) -> usize { 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 diff --git a/src/terminator/drop.rs b/src/terminator/drop.rs index 289bae89c3c64e79409b1eebc90b409b4a2d81c4..e8bd2164b84a28f2a7dd4220116fc7eeec7389b2 100644 --- a/src/terminator/drop.rs +++ b/src/terminator/drop.rs @@ -97,7 +97,7 @@ pub fn drop( 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 @@ pub fn drop( 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, diff --git a/src/terminator/mod.rs b/src/terminator/mod.rs index 0befb5ba9fc1cda259aca3bf78f778a25c858b60..14392eda32623c9225158c8cd3407afa40ed4f68 100644 --- a/src/terminator/mod.rs +++ b/src/terminator/mod.rs @@ -3,8 +3,10 @@ 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 @@ pub(super) fn eval_terminator( 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 @@ pub(super) fn eval_terminator( // 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 @@ pub(super) fn eval_terminator( 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 @@ fn eval_fn_call( 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 @@ fn eval_fn_call( 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 @@ fn eval_fn_call( 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 @@ fn eval_fn_call( }; // 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 @@ fn eval_fn_call( )?; }, 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 @@ fn eval_fn_call( 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 @@ fn eval_fn_call( } args.insert(0, ( Value::ByVal(PrimVal::Undef), - sig.inputs()[0], + sig.inputs().skip_binder()[0], )); self.eval_fn_call_inner( def_id, diff --git a/src/traits.rs b/src/traits.rs index 36293dde5322f6452c0bf3a3f98460572fa5b8de..986efc987de35529b05f1de3cc1d596eb0f4f1d5 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -113,7 +113,7 @@ pub(crate) fn trait_method( 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 @@ pub(crate) fn trait_method( 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 @@ pub(crate) fn trait_method( 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 @@ pub fn get_vtable(&mut self, trait_ref: ty::PolyTraitRef<'tcx>) -> EvalResult<'t _ => 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::>() .into_iter() @@ -233,15 +233,15 @@ pub fn get_vtable(&mut self, trait_ref: ty::PolyTraitRef<'tcx>) -> EvalResult<'t .. } ) => { - 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 @@ pub fn get_vtable(&mut self, trait_ref: ty::PolyTraitRef<'tcx>) -> EvalResult<'t // 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"), }; diff --git a/tests/compile-fail/cast_fn_ptr.rs b/tests/compile-fail/cast_fn_ptr.rs index c8070913f1cb5da88d3ba643275dffe6ac6813d3..7509ae6ed77cb5de14fc77cc85aea86d432d7b60 100644 --- a/tests/compile-fail/cast_fn_ptr.rs +++ b/tests/compile-fail/cast_fn_ptr.rs @@ -5,5 +5,5 @@ fn f() {} std::mem::transmute::(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) }