Implement #[track_caller] in const.
This commit is contained in:
parent
234c9f21d9
commit
9ab065dcda
@ -116,6 +116,10 @@ impl<'tcx> InstanceDef<'tcx> {
|
|||||||
}
|
}
|
||||||
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
|
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> {
|
impl<'tcx> fmt::Display for Instance<'tcx> {
|
||||||
@ -255,11 +259,8 @@ impl<'tcx> Instance<'tcx> {
|
|||||||
) -> Option<Instance<'tcx>> {
|
) -> Option<Instance<'tcx>> {
|
||||||
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
|
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
|
||||||
Instance::resolve(tcx, param_env, def_id, substs).map(|mut resolved| {
|
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 {
|
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]");
|
debug!(" => fn pointer created for function with #[track_caller]");
|
||||||
resolved.def = InstanceDef::ReifyShim(def_id);
|
resolved.def = InstanceDef::ReifyShim(def_id);
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
// `src/librustc/ty/constness.rs`
|
// `src/librustc/ty/constness.rs`
|
||||||
match intrinsic_name {
|
match intrinsic_name {
|
||||||
sym::caller_location => {
|
sym::caller_location => {
|
||||||
|
let span = self.find_closest_untracked_caller_location(span);
|
||||||
let location = self.alloc_caller_location_for_span(span);
|
let location = self.alloc_caller_location_for_span(span);
|
||||||
self.write_scalar(location.ptr, dest)?;
|
self.write_scalar(location.ptr, dest)?;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,28 @@ use syntax_pos::{Symbol, Span};
|
|||||||
use crate::interpret::{Scalar, MemoryKind, MPlaceTy, intrinsics::{InterpCx, Machine}};
|
use crate::interpret::{Scalar, MemoryKind, MPlaceTy, intrinsics::{InterpCx, Machine}};
|
||||||
|
|
||||||
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
/// Walks up the callstack from the intrinsic's callsite, searching for the first frame which is
|
||||||
|
/// not `#[track_caller]`. Returns the (passed) span of the intrinsic's callsite if the first
|
||||||
|
/// frame in the stack is untracked so that we can display the callsite of the intrinsic within
|
||||||
|
/// that function.
|
||||||
|
crate fn find_closest_untracked_caller_location(
|
||||||
|
&self,
|
||||||
|
intrinsic_loc: Span,
|
||||||
|
) -> Span {
|
||||||
|
debug!("finding closest untracked caller relative to {:?}", intrinsic_loc);
|
||||||
|
|
||||||
|
let mut caller_span = intrinsic_loc;
|
||||||
|
for next_caller in self.stack.iter().rev() {
|
||||||
|
if !next_caller.instance.def.requires_caller_location(*self.tcx) {
|
||||||
|
return caller_span;
|
||||||
|
}
|
||||||
|
caller_span = next_caller.span;
|
||||||
|
}
|
||||||
|
|
||||||
|
intrinsic_loc
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
|
||||||
crate fn alloc_caller_location(
|
crate fn alloc_caller_location(
|
||||||
&mut self,
|
&mut self,
|
||||||
filename: Symbol,
|
filename: Symbol,
|
||||||
|
@ -1,23 +1,41 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#![feature(const_fn, core_intrinsics)]
|
#![feature(const_fn, core_intrinsics, track_caller)]
|
||||||
|
|
||||||
use std::{intrinsics::caller_location, panic::Location};
|
use std::{intrinsics::caller_location, panic::Location};
|
||||||
|
|
||||||
const LOCATION: &Location = caller_location();
|
const LOCATION: &Location = caller_location();
|
||||||
const NESTED: &Location = {
|
|
||||||
const fn nested_location() -> &'static Location<'static> {
|
const TRACKED: &Location = tracked();
|
||||||
|
#[track_caller]
|
||||||
|
const fn tracked() -> &'static Location <'static> {
|
||||||
caller_location()
|
caller_location()
|
||||||
};
|
}
|
||||||
nested_location()
|
|
||||||
};
|
const NESTED: &Location = nested_location();
|
||||||
|
const fn nested_location() -> &'static Location<'static> {
|
||||||
|
caller_location()
|
||||||
|
}
|
||||||
|
|
||||||
|
const CONTAINED: &Location = contained();
|
||||||
|
const fn contained() -> &'static Location<'static> {
|
||||||
|
tracked()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(LOCATION.file(), file!());
|
assert_eq!(LOCATION.file(), file!());
|
||||||
assert_eq!(LOCATION.line(), 7);
|
assert_eq!(LOCATION.line(), 7);
|
||||||
assert_eq!(LOCATION.column(), 29);
|
assert_eq!(LOCATION.column(), 29);
|
||||||
|
|
||||||
|
assert_eq!(TRACKED.file(), file!());
|
||||||
|
assert_eq!(TRACKED.line(), 9);
|
||||||
|
assert_eq!(TRACKED.column(), 28);
|
||||||
|
|
||||||
assert_eq!(NESTED.file(), file!());
|
assert_eq!(NESTED.file(), file!());
|
||||||
assert_eq!(NESTED.line(), 10);
|
assert_eq!(NESTED.line(), 17);
|
||||||
assert_eq!(NESTED.column(), 9);
|
assert_eq!(NESTED.column(), 5);
|
||||||
|
|
||||||
|
assert_eq!(CONTAINED.file(), file!());
|
||||||
|
assert_eq!(CONTAINED.line(), 22);
|
||||||
|
assert_eq!(CONTAINED.column(), 5);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
|
||||||
|
--> $DIR/const_caller_location.rs:3:39
|
||||||
|
|
|
||||||
|
LL | #![feature(const_fn, core_intrinsics, track_caller)]
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user