diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index 989fc96732a5a..9428ff3ef15c4 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -162,6 +162,7 @@ impl fmt::Display for PanicInfo<'_> { /// /// panic!("Normal panic"); /// ``` +#[cfg_attr(not(bootstrap), lang = "panic_location")] #[derive(Debug)] #[stable(feature = "panic_hooks", since = "1.10.0")] pub struct Location<'a> { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index cab929389d6a4..a17b5a115b86b 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -366,6 +366,7 @@ language_item_table! { PanicFnLangItem, "panic", panic_fn, Target::Fn; PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn, Target::Fn; PanicInfoLangItem, "panic_info", panic_info, Target::Struct; + PanicLocationLangItem, "panic_location", panic_location, Target::Struct; PanicImplLangItem, "panic_impl", panic_impl, Target::Fn; // Libstd panic entry point. Necessary for const eval to be able to catch it BeginPanicFnLangItem, "begin_panic", begin_panic_fn, Target::Fn; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 5139c8085a583..e163f887a0297 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -1,4 +1,5 @@ use crate::hir::CodegenFnAttrFlags; +use crate::hir::Mutability; use crate::hir::Unsafety; use crate::hir::def::Namespace; use crate::hir::def_id::DefId; @@ -6,6 +7,7 @@ use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt}; use crate::ty::print::{FmtPrinter, Printer}; use crate::traits; use crate::middle::lang_items::DropInPlaceFnLangItem; +use rustc::middle::lang_items::PanicLocationLangItem; use rustc_target::spec::abi::Abi; use rustc_macros::HashStable; @@ -121,9 +123,29 @@ impl<'tcx> Instance<'tcx> { fn_sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output); fn_sig }); + } else if let InstanceDef::ReifyShim(..) = self.def { + // Modify fn(...) to fn(_location: &core::panic::Location, ...) + fn_sig = fn_sig.map_bound(|mut fn_sig| { + let mut inputs_and_output = fn_sig.inputs_and_output.to_vec(); + inputs_and_output.insert(0, Self::track_caller_ty(tcx)); + fn_sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output); + fn_sig + }); } fn_sig } + + /// Returns `&'static core::panic::Location`, for args of functions with #[track_caller]. + pub fn track_caller_ty(tcx: TyCtxt<'_>) -> Ty<'_> { + let panic_loc_item = tcx.require_lang_item(PanicLocationLangItem, None); + tcx.mk_ref( + tcx.mk_region(ty::RegionKind::ReStatic), + ty::TypeAndMut { + mutbl: Mutability::MutImmutable, + ty: tcx.type_of(panic_loc_item), + }, + ) + } } impl<'tcx> InstanceDef<'tcx> { diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index ffb70180bbb4b..8654da5f8c946 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -141,7 +141,9 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> { ArgInfo(ty, opt_ty_info, Some(&arg), self_arg) }); - let arguments = implicit_argument.into_iter().chain(explicit_arguments); + let arguments = implicit_argument.into_iter() + .chain(track_caller_argument(tcx, def_id)) + .chain(explicit_arguments); let (yield_ty, return_ty) = if body.generator_kind.is_some() { let gen_sig = match ty.kind { @@ -185,6 +187,17 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> { }) } +/// Returns the appropriate `ArgInfo` if the provided function has #[track_caller]. +fn track_caller_argument(tcx: TyCtxt<'_>, fn_def_id: DefId) -> Option> { + let codegen_flags = tcx.codegen_fn_attrs(fn_def_id).flags; + let has_track_caller = codegen_flags.contains(hir::CodegenFnAttrFlags::TRACK_CALLER); + if has_track_caller { + Some(ArgInfo(ty::Instance::track_caller_ty(tcx), None, None, None)) + } else { + None + } +} + /////////////////////////////////////////////////////////////////////////// // BuildMir -- walks a crate, looking for fn items and methods to build MIR from diff --git a/src/test/ui/rfc-2091-track-caller/pass.rs b/src/test/ui/rfc-2091-track-caller/pass.rs deleted file mode 100644 index f2c3f0dc59e01..0000000000000 --- a/src/test/ui/rfc-2091-track-caller/pass.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete - -#[track_caller] -fn f() {} - -fn main() { - f(); -} diff --git a/src/test/ui/rfc-2091-track-caller/pass.stderr b/src/test/ui/rfc-2091-track-caller/pass.stderr deleted file mode 100644 index b1fd23a6a9ddb..0000000000000 --- a/src/test/ui/rfc-2091-track-caller/pass.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: the feature `track_caller` is incomplete and may cause the compiler to crash - --> $DIR/pass.rs:2:12 - | -LL | #![feature(track_caller)] - | ^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - diff --git a/src/test/ui/rfc-2091-track-caller/should-pass.rs b/src/test/ui/rfc-2091-track-caller/should-pass.rs new file mode 100644 index 0000000000000..6faeadacb6936 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/should-pass.rs @@ -0,0 +1,12 @@ +// failure-status: 101 +// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" +// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" + +#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete + +#[track_caller] +fn f() {} + +fn main() { + f(); +} diff --git a/src/test/ui/rfc-2091-track-caller/should-pass.stderr b/src/test/ui/rfc-2091-track-caller/should-pass.stderr new file mode 100644 index 0000000000000..1160ddc890ee2 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/should-pass.stderr @@ -0,0 +1,21 @@ +warning: the feature `track_caller` is incomplete and may cause the compiler to crash + --> $DIR/should-pass.rs:5:12 + | +LL | #![feature(track_caller)] + | ^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +thread 'rustc' panicked at 'index out of bounds: the len is 0 but the index is 0', $SRC_DIR/libcore/slice/mod.rs:LL:COL +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. + +error: internal compiler error: unexpected panic + +note: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports + +note: rustc VERSION running on TARGET + +note: compiler flags: FLAGS +