rust/tests/ui/rfcs/rfc-2091-track-caller/tracked-trait-obj.rs

62 lines
2.3 KiB
Rust

//@ run-pass
trait Tracked {
#[track_caller]
fn track_caller_trait_method(&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");
}
fn track_caller_not_on_trait_method(&self);
#[track_caller]
fn track_caller_through_self(self: Box<Self>, line: u32, col: u32);
}
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");
}
}
fn main() {
let tracked: &dyn Tracked = &();
// The column is the start of 'track_caller_trait_method'
tracked.track_caller_trait_method(line!(), 13);
const TRACKED: &dyn Tracked = &();
// The column is the start of 'track_caller_trait_method'
TRACKED.track_caller_trait_method(line!(), 13);
TRACKED.track_caller_not_on_trait_method();
// The column is the start of `track_caller_through_self`
let boxed: Box<dyn Tracked> = Box::new(());
boxed.track_caller_through_self(line!(), 11);
}