0

The definition of Location::caller states:

pub fn caller() -> &'static Location<'static>`

This is a nightly-only experimental API. (track_caller #47809)

Returns the source location of the caller of this function. If that function's caller is annotated then its call location will be returned, and so on up the stack to the first call within a non-tracked function body.

That sounds to me like it should return &'static Option<Location<'static>>. Anything else seems to make walking the call stack much harder than it could be.

Is there a good reason for this decision?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
  • 1
    You mention walking the call stack, but as far as I know that's not the usecase of this API. Given the usage of finding the specific caller of a given callsite of `Location::caller()`, what is the case where `None` would be the response value? – loganfsmyth Mar 17 '20 at 03:20
  • Ah, you're right I was thinking the function was `caller(&self) -> Location` and that you'd get the root Location from the `PanicInfo::location`, so that you could walk the callstack via `while(location = location.caller()) { ... }`. But it doesn't give you that, just one point somewhere up the stack. – Michael Anderson Mar 17 '20 at 05:30

1 Answers1

2

It's impossible for a running function to not have a caller, so there's no time where None would be a possible return value.

You may be confused by the seemingly-poorly-worded clause:

If that function's caller is annotated [sic] then its call location will be returned

That probably should be worded as "annotated with #[track_caller]". What that means is that when the attribute is present, it's as if the function didn't exist and was textually inlined where it was called from.

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I think it was just misread by me - I had thought it meant it would only work if the function was annotated with `track_caller`. I also missed that it did not have an `&self` argument - which made me think it supported chaining like `here.caller().caller()` to take two steps up the call chain. – Michael Anderson Mar 18 '20 at 23:32