2020-07-26 11:53:24 -05:00
|
|
|
//@ run-pass
|
|
|
|
|
|
|
|
trait Tracked {
|
|
|
|
#[track_caller]
|
2021-01-24 12:32:37 -06:00
|
|
|
fn track_caller_trait_method(&self, line: u32, col: u32) {
|
2020-07-26 11:53:24 -05:00
|
|
|
let location = std::panic::Location::caller();
|
|
|
|
assert_eq!(location.file(), file!());
|
2021-01-24 12:32:37 -06:00
|
|
|
// The trait method definition is annotated with `#[track_caller]`,
|
|
|
|
// so caller location information will work through a method
|
|
|
|
// call on a trait object
|
|
|
|
assert_eq!(location.line(), line, "Bad line");
|
|
|
|
assert_eq!(location.column(), col, "Bad col");
|
2020-07-26 11:53:24 -05:00
|
|
|
}
|
2021-01-24 12:32:37 -06:00
|
|
|
|
|
|
|
fn track_caller_not_on_trait_method(&self);
|
|
|
|
|
|
|
|
#[track_caller]
|
|
|
|
fn track_caller_through_self(self: Box<Self>, line: u32, col: u32);
|
2020-07-26 11:53:24 -05:00
|
|
|
}
|
|
|
|
|
2021-01-24 12:32:37 -06:00
|
|
|
impl Tracked for () {
|
|
|
|
// We have `#[track_caller]` on the implementation of the method,
|
|
|
|
// but not on the definition of the method in the trait. Therefore,
|
|
|
|
// caller location information will *not* work through a method call
|
|
|
|
// on a trait object. Instead, we will get the location of this method
|
|
|
|
#[track_caller]
|
|
|
|
fn track_caller_not_on_trait_method(&self) {
|
|
|
|
let location = std::panic::Location::caller();
|
|
|
|
assert_eq!(location.file(), file!());
|
|
|
|
assert_eq!(location.line(), line!() - 3);
|
|
|
|
assert_eq!(location.column(), 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
// We don't have a `#[track_caller]` attribute, but
|
|
|
|
// `#[track_caller]` is present on the trait definition,
|
|
|
|
// so we'll still get location information
|
|
|
|
fn track_caller_through_self(self: Box<Self>, line: u32, col: u32) {
|
|
|
|
let location = std::panic::Location::caller();
|
|
|
|
assert_eq!(location.file(), file!());
|
|
|
|
// The trait method definition is annotated with `#[track_caller]`,
|
|
|
|
// so caller location information will work through a method
|
|
|
|
// call on a trait object
|
|
|
|
assert_eq!(location.line(), line, "Bad line");
|
|
|
|
assert_eq!(location.column(), col, "Bad col");
|
|
|
|
}
|
|
|
|
}
|
2020-07-26 11:53:24 -05:00
|
|
|
|
|
|
|
fn main() {
|
2021-01-24 12:32:37 -06:00
|
|
|
let tracked: &dyn Tracked = &();
|
2021-01-24 17:48:03 -06:00
|
|
|
// The column is the start of 'track_caller_trait_method'
|
|
|
|
tracked.track_caller_trait_method(line!(), 13);
|
2020-07-26 11:53:24 -05:00
|
|
|
|
|
|
|
const TRACKED: &dyn Tracked = &();
|
2021-01-24 17:48:03 -06:00
|
|
|
// The column is the start of 'track_caller_trait_method'
|
|
|
|
TRACKED.track_caller_trait_method(line!(), 13);
|
2021-01-24 12:32:37 -06:00
|
|
|
TRACKED.track_caller_not_on_trait_method();
|
|
|
|
|
2021-01-24 17:48:03 -06:00
|
|
|
// The column is the start of `track_caller_through_self`
|
2021-01-24 12:32:37 -06:00
|
|
|
let boxed: Box<dyn Tracked> = Box::new(());
|
2021-01-24 17:48:03 -06:00
|
|
|
boxed.track_caller_through_self(line!(), 11);
|
2020-07-26 11:53:24 -05:00
|
|
|
}
|