Always use consteval to codegen caller_location.
This commit is contained in:
parent
017877cbbe
commit
86e55b1882
@ -466,6 +466,12 @@ rustc_queries! {
|
||||
no_force
|
||||
desc { "extract field of const" }
|
||||
}
|
||||
|
||||
query const_caller_location(key: (syntax_pos::Symbol, u32, u32)) -> &'tcx ty::Const<'tcx> {
|
||||
eval_always
|
||||
no_force
|
||||
desc { "get a &core::panic::Location referring to a span" }
|
||||
}
|
||||
}
|
||||
|
||||
TypeChecking {
|
||||
|
@ -208,3 +208,13 @@ impl<'tcx, T> Key for Canonical<'tcx, T> {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (Symbol, u32, u32) {
|
||||
fn query_crate(&self) -> CrateNum {
|
||||
LOCAL_CRATE
|
||||
}
|
||||
|
||||
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ use crate::llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope};
|
||||
use crate::llvm::{self, False, BasicBlock};
|
||||
use crate::common::Funclet;
|
||||
use crate::context::CodegenCx;
|
||||
use crate::syntax_pos::Pos;
|
||||
use crate::type_::Type;
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
use crate::value::Value;
|
||||
@ -24,7 +23,6 @@ use std::ffi::CStr;
|
||||
use std::ops::{Deref, Range};
|
||||
use std::ptr;
|
||||
use std::iter::TrustedLen;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
// All Builders must have an llfn associated with them
|
||||
#[must_use]
|
||||
@ -1068,20 +1066,6 @@ impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> {
|
||||
// Forward to the `get_static` method of `CodegenCx`
|
||||
self.cx().get_static(def_id)
|
||||
}
|
||||
|
||||
fn static_panic_location(&mut self, loc: &syntax::source_map::Loc) -> Self::Value {
|
||||
let filename = Symbol::intern(&loc.file.name.to_string());
|
||||
let filename = self.const_str(filename);
|
||||
let line = self.const_u32(loc.line as u32);
|
||||
let col = self.const_u32(loc.col.to_usize() as u32 + 1);
|
||||
let struct_ = self.const_struct(&[filename.0, filename.1, line, col], false);
|
||||
|
||||
let align = self.tcx.data_layout.aggregate_align.abi
|
||||
.max(self.tcx.data_layout.i32_align.abi)
|
||||
.max(self.tcx.data_layout.pointer_align.abi);
|
||||
// FIXME(eddyb) move this into miri, it can be correct if e.g. field order changes
|
||||
self.static_addr_of(struct_, align, Some("panic_loc"))
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<'a, 'll, 'tcx> {
|
||||
|
@ -15,7 +15,7 @@ use crate::traits::*;
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::{source_map::Span, symbol::Symbol};
|
||||
|
||||
use super::{FunctionCx, LocalRef};
|
||||
use super::place::PlaceRef;
|
||||
@ -420,8 +420,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
self.set_debug_loc(&mut bx, terminator.source_info);
|
||||
|
||||
// Get the location information.
|
||||
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
|
||||
let location = bx.static_panic_location(&loc);
|
||||
let location = self.get_caller_location(&mut bx, span).immediate();
|
||||
|
||||
// Put together the arguments to the panic entry point.
|
||||
let (lang_item, args) = match msg {
|
||||
@ -534,11 +533,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let ty = instance.unwrap().substs.type_at(0);
|
||||
let layout = bx.layout_of(ty);
|
||||
if layout.abi.is_uninhabited() {
|
||||
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
|
||||
|
||||
let msg_str = format!("Attempted to instantiate uninhabited type {}", ty);
|
||||
let msg = bx.const_str(Symbol::intern(&msg_str));
|
||||
let location = bx.static_panic_location(&loc);
|
||||
let location = self.get_caller_location(&mut bx, span).immediate();
|
||||
|
||||
// Obtain the panic entry point.
|
||||
let def_id =
|
||||
@ -584,13 +581,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
|
||||
if intrinsic == Some("caller_location") {
|
||||
if let Some((_, target)) = destination.as_ref() {
|
||||
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
|
||||
let location = bx.static_panic_location(&loc);
|
||||
let location = self.get_caller_location(&mut bx, span);
|
||||
|
||||
if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
|
||||
Immediate(location).store(&mut bx, tmp);
|
||||
location.val.store(&mut bx, tmp);
|
||||
}
|
||||
self.store_return(&mut bx, ret_dest, &fn_ty.ret, location);
|
||||
self.store_return(&mut bx, ret_dest, &fn_ty.ret, location.immediate());
|
||||
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[*target]);
|
||||
helper.funclet_br(self, &mut bx, *target);
|
||||
@ -994,6 +990,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_caller_location(
|
||||
&mut self,
|
||||
bx: &mut Bx,
|
||||
span: Span,
|
||||
) -> OperandRef<'tcx, Bx::Value> {
|
||||
let caller = bx.tcx().sess.source_map().lookup_char_pos(span.lo());
|
||||
let const_loc = bx.tcx().const_caller_location((
|
||||
Symbol::intern(&caller.file.name.to_string()),
|
||||
caller.line as u32,
|
||||
caller.col_display as u32 + 1,
|
||||
));
|
||||
OperandRef::from_const(bx, const_loc)
|
||||
}
|
||||
|
||||
fn get_personality_slot(
|
||||
&mut self,
|
||||
bx: &mut Bx
|
||||
|
@ -1,5 +1,4 @@
|
||||
use super::BackendTypes;
|
||||
use syntax::source_map::Loc;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::layout::Align;
|
||||
|
||||
@ -10,5 +9,4 @@ pub trait StaticMethods: BackendTypes {
|
||||
|
||||
pub trait StaticBuilderMethods: BackendTypes {
|
||||
fn get_static(&mut self, def_id: DefId) -> Self::Value;
|
||||
fn static_panic_location(&mut self, loc: &Loc) -> Self::Value;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use rustc::traits::Reveal;
|
||||
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,
|
||||
@ -159,11 +159,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
|
||||
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)
|
||||
|
@ -6,7 +6,6 @@
|
||||
use rustc::ty::{Ty, self};
|
||||
use rustc::mir::interpret::{InterpResult, ErrorHandled};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use super::validity::RefTracking;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
||||
@ -270,12 +269,12 @@ for
|
||||
|
||||
pub fn intern_const_alloc_recursive(
|
||||
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
|
||||
def_id: DefId,
|
||||
// The `mutability` of the place, ignoring the type.
|
||||
place_mut: Option<hir::Mutability>,
|
||||
ret: MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let tcx = ecx.tcx;
|
||||
// this `mutability` is the mutability of the place, ignoring the type
|
||||
let (base_mutability, base_intern_mode) = match tcx.static_mutability(def_id) {
|
||||
let (base_mutability, base_intern_mode) = match place_mut {
|
||||
Some(hir::Mutability::MutImmutable) => (Mutability::Immutable, InternMode::Static),
|
||||
// `static mut` doesn't care about interior mutability, it's mutable anyway
|
||||
Some(hir::Mutability::MutMutable) => (Mutability::Mutable, InternMode::Static),
|
||||
|
@ -98,7 +98,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..];
|
||||
match intrinsic_name {
|
||||
"caller_location" => {
|
||||
self.write_caller_location(span, dest)?;
|
||||
let caller = self.tcx.sess.source_map().lookup_char_pos(span.lo());
|
||||
let location = self.alloc_caller_location(
|
||||
Symbol::intern(&caller.file.name.to_string()),
|
||||
caller.line as u32,
|
||||
caller.col_display as u32 + 1,
|
||||
)?;
|
||||
self.write_scalar(location.ptr, dest)?;
|
||||
}
|
||||
|
||||
"min_align_of" |
|
||||
|
@ -2,23 +2,19 @@ use rustc::middle::lang_items::PanicLocationLangItem;
|
||||
use rustc::mir::interpret::{Pointer, PointerArithmetic, Scalar};
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc_target::abi::{LayoutOf, Size};
|
||||
use syntax_pos::Span;
|
||||
use syntax_pos::Symbol;
|
||||
|
||||
use crate::interpret::{
|
||||
MemoryKind,
|
||||
intrinsics::{InterpCx, InterpResult, Machine, PlaceTy},
|
||||
};
|
||||
use crate::interpret::{MemoryKind, MPlaceTy, intrinsics::{InterpCx, InterpResult, Machine}};
|
||||
|
||||
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
pub fn write_caller_location(
|
||||
pub fn alloc_caller_location(
|
||||
&mut self,
|
||||
span: Span,
|
||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let caller = self.tcx.sess.source_map().lookup_char_pos(span.lo());
|
||||
let filename = caller.file.name.to_string();
|
||||
let line = Scalar::from_u32(caller.line as u32);
|
||||
let col = Scalar::from_u32(caller.col_display as u32 + 1);
|
||||
filename: Symbol,
|
||||
line: u32,
|
||||
col: u32,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||
let line = Scalar::from_u32(line);
|
||||
let col = Scalar::from_u32(col);
|
||||
|
||||
let ptr_size = self.pointer_size();
|
||||
let u32_size = Size::from_bits(32);
|
||||
@ -27,10 +23,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
.subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_static.into()].iter()));
|
||||
let loc_layout = self.layout_of(loc_ty)?;
|
||||
|
||||
let file_alloc = self.tcx.allocate_bytes(filename.as_bytes());
|
||||
let file_alloc = self.tcx.allocate_bytes(filename.as_str().as_bytes());
|
||||
let file_ptr = Pointer::new(file_alloc, Size::ZERO);
|
||||
let file = Scalar::Ptr(self.tag_static_base_pointer(file_ptr));
|
||||
let file_len = Scalar::from_uint(filename.len() as u128, ptr_size);
|
||||
let file_len = Scalar::from_uint(filename.as_str().len() as u128, ptr_size);
|
||||
|
||||
let location = self.allocate(loc_layout, MemoryKind::Stack);
|
||||
|
||||
@ -48,7 +44,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
alloc.write_scalar(layout, line_out, line.into(), u32_size)?;
|
||||
alloc.write_scalar(layout, col_out, col.into(), u32_size)?;
|
||||
|
||||
self.write_scalar(location.ptr, dest)?;
|
||||
Ok(())
|
||||
Ok(location)
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ pub fn provide(providers: &mut Providers<'_>) {
|
||||
providers.const_eval = const_eval::const_eval_provider;
|
||||
providers.const_eval_raw = const_eval::const_eval_raw_provider;
|
||||
providers.check_match = hair::pattern::check_match;
|
||||
providers.const_caller_location = const_eval::const_caller_location;
|
||||
providers.const_field = |tcx, param_env_and_value| {
|
||||
let (param_env, (value, field)) = param_env_and_value.into_parts();
|
||||
const_eval::const_field(tcx, param_env, None, field, value)
|
||||
|
@ -1,7 +1,6 @@
|
||||
//! Type-checking for the rust-intrinsic and platform-intrinsic
|
||||
//! intrinsics that the compiler exposes.
|
||||
|
||||
use rustc::hir::{self, Mutability};
|
||||
use rustc::middle::lang_items::PanicLocationLangItem;
|
||||
use rustc::traits::{ObligationCause, ObligationCauseCode};
|
||||
use rustc::ty::{self, TyCtxt, Ty};
|
||||
@ -11,6 +10,8 @@ use crate::require_same_types;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
use rustc::hir;
|
||||
|
||||
use std::iter;
|
||||
|
||||
fn equate_intrinsic_type<'tcx>(
|
||||
@ -146,13 +147,10 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
|
||||
"caller_location" => (
|
||||
0,
|
||||
vec![],
|
||||
tcx.mk_ref(
|
||||
tcx.mk_imm_ref(
|
||||
tcx.lifetimes.re_static,
|
||||
ty::TypeAndMut {
|
||||
mutbl: Mutability::MutImmutable,
|
||||
ty: tcx.type_of(tcx.require_lang_item(PanicLocationLangItem, None))
|
||||
.subst(tcx, tcx.mk_substs([tcx.lifetimes.re_static.into()].iter())),
|
||||
},
|
||||
tcx.type_of(tcx.require_lang_item(PanicLocationLangItem, None))
|
||||
.subst(tcx, tcx.mk_substs([tcx.lifetimes.re_static.into()].iter())),
|
||||
),
|
||||
),
|
||||
"panic_if_uninhabited" => (1, Vec::new(), tcx.mk_unit()),
|
||||
|
Loading…
x
Reference in New Issue
Block a user