Auto merge of #65881 - anp:implicit-caller-location, r=eddyb,oli-obk
Implement #[track_caller] attribute. (RFC 2091 4/N) Implements the `#[track_caller]` attribute in both const and codegen contexts. The const implementation walks up the stack to find the nearest untracked callsite. The codegen implementation adds an implicit argument to tracked function calls, and populates it with either a call to the previously-landed intrinsic or if the caller has `#[track_caller]` with a copy of the location passed to the current function. Also includes a little cleanup and a few comments in the other caller location areas. [Depends on: 65664](https://github.com/rust-lang/rust/pull/65664) [RFC 2091 text](https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md) [Tracking issue](https://github.com/rust-lang/rust/issues/47809) [Tracking doc](https://paper.dropbox.com/doc/track_rfc_2091_impl-notes--Anf1NwnIb0xcRv31YLIadyj0Ag-rwCdRc2fi2yvRZ7syGZ9q#:uid=863513134494965680023183&h2=TODO-actually-pass-location-to)
This commit is contained in:
commit
de17464b14
35 changed files with 286 additions and 141 deletions
|
|
@ -8,6 +8,7 @@ use crate::session::Session;
|
|||
use crate::session::config::{BorrowckMode, OutputFilenames};
|
||||
use crate::session::config::CrateType;
|
||||
use crate::middle;
|
||||
use crate::middle::lang_items::PanicLocationLangItem;
|
||||
use crate::hir::{self, TraitCandidate, HirId, ItemKind, ItemLocalId, Node};
|
||||
use crate::hir::def::{Res, DefKind, Export};
|
||||
use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
|
||||
|
|
@ -1588,6 +1589,15 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
pub fn has_strict_asm_symbol_naming(&self) -> bool {
|
||||
self.sess.target.target.arch.contains("nvptx")
|
||||
}
|
||||
|
||||
/// Returns `&'static core::panic::Location<'static>`.
|
||||
pub fn caller_location_ty(&self) -> Ty<'tcx> {
|
||||
self.mk_imm_ref(
|
||||
self.lifetimes.re_static,
|
||||
self.type_of(self.require_lang_item(PanicLocationLangItem, None))
|
||||
.subst(*self, self.mk_substs([self.lifetimes.re_static.into()].iter())),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> GlobalCtxt<'tcx> {
|
||||
|
|
|
|||
|
|
@ -116,6 +116,10 @@ impl<'tcx> InstanceDef<'tcx> {
|
|||
}
|
||||
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
|
||||
}
|
||||
|
||||
pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
|
||||
tcx.codegen_fn_attrs(self.def_id()).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Display for Instance<'tcx> {
|
||||
|
|
@ -255,11 +259,8 @@ impl<'tcx> Instance<'tcx> {
|
|||
) -> Option<Instance<'tcx>> {
|
||||
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
|
||||
Instance::resolve(tcx, param_env, def_id, substs).map(|mut resolved| {
|
||||
let has_track_caller = |def| tcx.codegen_fn_attrs(def).flags
|
||||
.contains(CodegenFnAttrFlags::TRACK_CALLER);
|
||||
|
||||
match resolved.def {
|
||||
InstanceDef::Item(def_id) if has_track_caller(def_id) => {
|
||||
InstanceDef::Item(def_id) if resolved.def.requires_caller_location(tcx) => {
|
||||
debug!(" => fn pointer created for function with #[track_caller]");
|
||||
resolved.def = InstanceDef::ReifyShim(def_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2434,6 +2434,7 @@ where
|
|||
cx: &C,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
extra_args: &[Ty<'tcx>],
|
||||
caller_location: Option<Ty<'tcx>>,
|
||||
mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
|
||||
) -> Self;
|
||||
fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi);
|
||||
|
|
@ -2448,13 +2449,19 @@ where
|
|||
+ HasParamEnv<'tcx>,
|
||||
{
|
||||
fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
|
||||
call::FnAbi::new_internal(cx, sig, extra_args, |ty, _| ArgAbi::new(cx.layout_of(ty)))
|
||||
call::FnAbi::new_internal(cx, sig, extra_args, None, |ty, _| ArgAbi::new(cx.layout_of(ty)))
|
||||
}
|
||||
|
||||
fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
|
||||
let sig = instance.fn_sig_for_fn_abi(cx.tcx());
|
||||
|
||||
call::FnAbi::new_internal(cx, sig, extra_args, |ty, arg_idx| {
|
||||
let caller_location = if instance.def.requires_caller_location(cx.tcx()) {
|
||||
Some(cx.tcx().caller_location_ty())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
call::FnAbi::new_internal(cx, sig, extra_args, caller_location, |ty, arg_idx| {
|
||||
let mut layout = cx.layout_of(ty);
|
||||
// Don't pass the vtable, it's not an argument of the virtual fn.
|
||||
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
|
||||
|
|
@ -2512,6 +2519,7 @@ where
|
|||
cx: &C,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
extra_args: &[Ty<'tcx>],
|
||||
caller_location: Option<Ty<'tcx>>,
|
||||
mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
|
||||
) -> Self {
|
||||
debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
|
||||
|
|
@ -2684,6 +2692,7 @@ where
|
|||
.iter()
|
||||
.cloned()
|
||||
.chain(extra_args)
|
||||
.chain(caller_location)
|
||||
.enumerate()
|
||||
.map(|(i, ty)| arg_of(ty, Some(i)))
|
||||
.collect(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue