use rustc::hir::def::DefKind;
use rustc::hir::def_id::DefId;
+use rustc::middle::lang_items::PanicLocationLangItem;
use rustc::mir::interpret::{ConstEvalErr, ErrorHandled, ScalarMaybeUndef};
use rustc::mir;
use rustc::ty::{self, Ty, TyCtxt, subst::Subst};
use rustc_data_structures::fx::FxHashMap;
use crate::interpret::eval_nullary_intrinsic;
-use syntax::source_map::{Span, DUMMY_SP};
+use syntax::{source_map::{Span, DUMMY_SP}, symbol::Symbol};
use crate::interpret::{self,
PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar, Pointer,
0,
),
};
- let len = b.to_usize(&ecx.tcx.tcx).unwrap();
+ let len = b.to_machine_usize(&ecx.tcx.tcx).unwrap();
let start = start.try_into().unwrap();
let len: usize = len.try_into().unwrap();
ConstValue::Slice {
ecx.run()?;
// Intern the result
- intern_const_alloc_recursive(
- ecx,
- cid.instance.def_id(),
- ret,
- )?;
+ intern_const_alloc_recursive(ecx, tcx.static_mutability(cid.instance.def_id()), ret)?;
debug!("eval_body_using_ecx done: {:?}", *ret);
Ok(ret)
args: &[OpTy<'tcx>],
dest: Option<PlaceTy<'tcx>>,
ret: Option<mir::BasicBlock>,
+ _unwind: Option<mir::BasicBlock> // unwinding is not supported in consts
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
debug!("eval_fn_call: {:?}", instance);
// Only check non-glue functions
fn call_intrinsic(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
+ span: Span,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx>],
- dest: PlaceTy<'tcx>,
+ dest: Option<PlaceTy<'tcx>>,
) -> InterpResult<'tcx> {
- if ecx.emulate_intrinsic(instance, args, dest)? {
+ if ecx.emulate_intrinsic(span, instance, args, dest)? {
return Ok(());
}
// An intrinsic that we do not support
fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
Ok(())
}
-
- /// Called immediately before a stack frame gets popped.
- #[inline(always)]
- fn stack_pop(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _extra: ()) -> InterpResult<'tcx> {
- Ok(())
- }
}
/// Extracts a field of a (variant of a) const.
op_to_const(&ecx, field)
}
+pub fn const_caller_location<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ (file, line, col): (Symbol, u32, u32),
+) -> &'tcx ty::Const<'tcx> {
+ trace!("const_caller_location: {}:{}:{}", file, line, col);
+ let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all());
+
+ let loc_ty = tcx.mk_imm_ref(
+ tcx.lifetimes.re_static,
+ tcx.type_of(tcx.require_lang_item(PanicLocationLangItem, None))
+ .subst(tcx, tcx.mk_substs([tcx.lifetimes.re_static.into()].iter())),
+ );
+ let loc_place = ecx.alloc_caller_location(file, line, col).unwrap();
+ intern_const_alloc_recursive(&mut ecx, None, loc_place).unwrap();
+ let loc_const = ty::Const {
+ ty: loc_ty,
+ val: ConstValue::Scalar(loc_place.ptr.into()),
+ };
+
+ tcx.mk_const(loc_const)
+}
+
// this function uses `unwrap` copiously, because an already validated constant must have valid
// fields and can thus never fail outside of compiler bugs
pub fn const_variant_index<'tcx>(