From 86e55b1882ac492d6234e5c5f97c7f151a11f5d2 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Thu, 24 Oct 2019 17:35:02 -0700 Subject: [PATCH] Always use consteval to codegen caller_location. --- src/librustc/query/mod.rs | 6 ++++ src/librustc/ty/query/keys.rs | 10 +++++++ src/librustc_codegen_llvm/builder.rs | 16 ---------- src/librustc_codegen_ssa/mir/block.rs | 30 ++++++++++++------- src/librustc_codegen_ssa/traits/statics.rs | 2 -- src/librustc_mir/const_eval.rs | 8 ++--- src/librustc_mir/interpret/intern.rs | 7 ++--- src/librustc_mir/interpret/intrinsics.rs | 8 ++++- .../interpret/intrinsics/caller_location.rs | 29 ++++++++---------- src/librustc_mir/lib.rs | 1 + src/librustc_typeck/check/intrinsic.rs | 12 ++++---- 11 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index fdca6d0e17a..aa37cbb92a7 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -466,6 +466,12 @@ 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 { diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index 0a217e9ae66..a9e0a5d6ab5 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -208,3 +208,13 @@ fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { DUMMY_SP } } + +impl Key for (Symbol, u32, u32) { + fn query_crate(&self) -> CrateNum { + LOCAL_CRATE + } + + fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 8ac1c7b36fc..312c41b88b0 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -2,7 +2,6 @@ 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::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 @@ fn get_static(&mut self, def_id: DefId) -> &'ll Value { // 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> { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 2462ba0a33e..79855311f37 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -15,7 +15,7 @@ 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 @@ fn codegen_assert_terminator<'b>( 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 @@ fn codegen_call_terminator<'b>( 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 @@ fn codegen_call_terminator<'b>( 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 @@ fn codegen_arguments_untupled( } } + 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 diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs index f63cea51f43..5c108f9fa6c 100644 --- a/src/librustc_codegen_ssa/traits/statics.rs +++ b/src/librustc_codegen_ssa/traits/statics.rs @@ -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; } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index eed26c32b7a..89bdf7391c3 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -18,7 +18,7 @@ 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) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 646d1783c8e..924529d7f55 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -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 @@ fn visit_primitive(&mut self, mplace: MPlaceTy<'tcx>) -> InterpResult<'tcx> { 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, 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), diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 12e080869c7..519f4f03222 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -98,7 +98,13 @@ pub fn emulate_intrinsic( 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" | diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/src/librustc_mir/interpret/intrinsics/caller_location.rs index 5addb13b61c..249d2f9ff53 100644 --- a/src/librustc_mir/interpret/intrinsics/caller_location.rs +++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs @@ -2,23 +2,19 @@ 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 @@ pub fn write_caller_location( .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 @@ pub fn write_caller_location( 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) } } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 98d5487870a..4d604cb025c 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -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) diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 2c5757b1c9f..76cc7062d3b 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -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 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()), -- GitLab