about summary refs log tree commit diff
path: root/src/librustc_codegen_ssa
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-10-28 04:53:06 +0100
committerGitHub <noreply@github.com>2019-10-28 04:53:06 +0100
commit4728d66206c82c98aa4e1fad751e8aae7489c242 (patch)
treea95e0d577f867d3fba9346478e13bcac3dc793a8 /src/librustc_codegen_ssa
parentc8eefdffe9480bbd84554eab3343f71f04af8f9a (diff)
parent86e55b1882ac492d6234e5c5f97c7f151a11f5d2 (diff)
Rollup merge of #65664 - anp:panic-location, r=eddyb
`std::panic::Location` is a lang_item, add `core::intrinsics::caller_location` (RFC 2091 3/N)

[Tracking issue](https://github.com/rust-lang/rust/issues/47809)
[RFC text](https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md)

@eddyb suggested doing this intrinsic implementation ahead of actually implementing the `#[track_caller]` attribute so that there's an easily tested intermediate step between adding the shim and wiring up the attribute.
Diffstat (limited to 'src/librustc_codegen_ssa')
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs81
-rw-r--r--src/librustc_codegen_ssa/traits/consts.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/statics.rs9
3 files changed, 40 insertions, 52 deletions
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 28441cae26e..79855311f37 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -15,8 +15,7 @@ use crate::traits::*;
 
 use std::borrow::Cow;
 
-use syntax::symbol::Symbol;
-use syntax_pos::Pos;
+use syntax::{source_map::Span, symbol::Symbol};
 
 use super::{FunctionCx, LocalRef};
 use super::place::PlaceRef;
@@ -421,38 +420,19 @@ 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 filename = Symbol::intern(&loc.file.name.to_string());
-        let line = bx.const_u32(loc.line as u32);
-        let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
+        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 {
             PanicInfo::BoundsCheck { ref len, ref index } => {
                 let len = self.codegen_operand(&mut bx, len).immediate();
                 let index = self.codegen_operand(&mut bx, index).immediate();
-
-                let file_line_col = bx.static_panic_msg(
-                    None,
-                    filename,
-                    line,
-                    col,
-                    "panic_bounds_check_loc",
-                );
-                (lang_items::PanicBoundsCheckFnLangItem,
-                    vec![file_line_col, index, len])
+                (lang_items::PanicBoundsCheckFnLangItem, vec![location, index, len])
             }
             _ => {
                 let msg_str = Symbol::intern(msg.description());
-                let msg_file_line_col = bx.static_panic_msg(
-                    Some(msg_str),
-                    filename,
-                    line,
-                    col,
-                    "panic_loc",
-                );
-                (lang_items::PanicFnLangItem,
-                    vec![msg_file_line_col])
+                let msg = bx.const_str(msg_str);
+                (lang_items::PanicFnLangItem, vec![msg.0, msg.1, location])
             }
         };
 
@@ -553,23 +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 filename = Symbol::intern(&loc.file.name.to_string());
-                let line = bx.const_u32(loc.line as u32);
-                let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
-
-                let str = format!(
-                    "Attempted to instantiate uninhabited type {}",
-                    ty
-                );
-                let msg_str = Symbol::intern(&str);
-                let msg_file_line_col = bx.static_panic_msg(
-                    Some(msg_str),
-                    filename,
-                    line,
-                    col,
-                    "panic_loc",
-                );
+                let msg_str = format!("Attempted to instantiate uninhabited type {}", ty);
+                let msg = bx.const_str(Symbol::intern(&msg_str));
+                let location = self.get_caller_location(&mut bx, span).immediate();
 
                 // Obtain the panic entry point.
                 let def_id =
@@ -587,7 +553,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     &mut bx,
                     fn_ty,
                     llfn,
-                    &[msg_file_line_col],
+                    &[msg.0, msg.1, location],
                     destination.as_ref().map(|(_, bb)| (ReturnDest::Nothing, *bb)),
                     cleanup,
                 );
@@ -613,6 +579,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             ReturnDest::Nothing
         };
 
+        if intrinsic == Some("caller_location") {
+            if let Some((_, target)) = destination.as_ref() {
+                let location = self.get_caller_location(&mut bx, span);
+
+                if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
+                    location.val.store(&mut bx, tmp);
+                }
+                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);
+            }
+            return;
+        }
+
         if intrinsic.is_some() && intrinsic != Some("drop_in_place") {
             let dest = match ret_dest {
                 _ if fn_ty.ret.is_indirect() => llargs[0],
@@ -1009,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
diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs
index 95ada60fae0..8c462e77d5e 100644
--- a/src/librustc_codegen_ssa/traits/consts.rs
+++ b/src/librustc_codegen_ssa/traits/consts.rs
@@ -3,6 +3,7 @@ use crate::mir::place::PlaceRef;
 use rustc::mir::interpret::Allocation;
 use rustc::mir::interpret::Scalar;
 use rustc::ty::layout;
+use syntax_pos::Symbol;
 
 pub trait ConstMethods<'tcx>: BackendTypes {
     // Constant constructors
@@ -19,6 +20,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {
     fn const_u8(&self, i: u8) -> Self::Value;
     fn const_real(&self, t: Self::Type, val: f64) -> Self::Value;
 
+    fn const_str(&self, s: Symbol) -> (Self::Value, Self::Value);
     fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
 
     fn const_to_opt_uint(&self, v: Self::Value) -> Option<u64>;
diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs
index 73c4c053979..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_pos::symbol::Symbol;
 use rustc::hir::def_id::DefId;
 use rustc::ty::layout::Align;
 
@@ -10,12 +9,4 @@ pub trait StaticMethods: BackendTypes {
 
 pub trait StaticBuilderMethods: BackendTypes {
     fn get_static(&mut self, def_id: DefId) -> Self::Value;
-    fn static_panic_msg(
-        &mut self,
-        msg: Option<Symbol>,
-        filename: Symbol,
-        line: Self::Value,
-        col: Self::Value,
-        kind: &str,
-    ) -> Self::Value;
 }