33<!-- toc -->
44
55Approved in [ RFC 2091] , this feature enables the accurate reporting of caller location during panics
6- initiated from functions like ` Option::unwrap ` , ` Result::expect ` , and ` Index::index ` . This feature
7- adds the [ ` #[track_caller] ` ] [ attr-reference ] attribute for functions, the
8- [ ` caller_location ` ] [ intrinsic ] intrinsic, and the stabilization-friendly
6+ initiated from functions like ` Option::unwrap ` , ` Result::expect ` , and ` Index::index ` . This feature
7+ adds the [ ` #[track_caller] ` ] [ attr-reference ] attribute for functions, the
8+ [ ` caller_location ` ] [ intrinsic ] intrinsic, and the stabilization-friendly
99[ ` core::panic::Location::caller ` ] [ wrapper ] wrapper.
1010
1111## Motivating Example
@@ -30,25 +30,25 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
3030As of 1.42, we get a much more helpful message:
3131
3232```
33- $ rustc +1.42.0 example.rs; example.exe
33+ $ rustc +1.42.0 example.rs; example.exe
3434thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', example.rs:3:5
3535note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
3636```
3737
3838These error messages are achieved through a combination of changes to ` panic! ` internals to make use
39- of ` core::panic::Location::caller ` and a number of ` #[track_caller] ` annotations in the standard
39+ of ` core::panic::Location::caller ` and a number of ` #[track_caller] ` annotations in the standard
4040library which propagate caller information.
4141
4242## Reading Caller Location
4343
4444Previously, ` panic! ` made use of the ` file!() ` , ` line!() ` , and ` column!() ` macros to construct a
4545[ ` Location ` ] pointing to where the panic occurred. These macros couldn't be given an overridden
46- location, so functions which intentionally invoked ` panic! ` couldn't provide their own location,
46+ location, so functions which intentionally invoked ` panic! ` couldn't provide their own location,
4747hiding the actual source of error.
4848
49- Internally, ` panic!() ` now calls [ ` core::panic::Location::caller() ` ] [ wrapper ] to find out where it
50- was expanded. This function is itself annotated with ` #[track_caller] ` and wraps the
51- [ ` caller_location ` ] [ intrinsic ] compiler intrinsic implemented by rustc. This intrinsic is easiest
49+ Internally, ` panic!() ` now calls [ ` core::panic::Location::caller() ` ] [ wrapper ] to find out where it
50+ was expanded. This function is itself annotated with ` #[track_caller] ` and wraps the
51+ [ ` caller_location ` ] [ intrinsic ] compiler intrinsic implemented by rustc. This intrinsic is easiest
5252explained in terms of how it works in a ` const ` context.
5353
5454## Caller Location in ` const `
@@ -58,20 +58,20 @@ to find the right location and allocating a const value to return.
5858
5959### Finding the right ` Location `
6060
61- In a const context we "walk up the stack" from where the intrinsic is invoked, stopping when we
61+ In a const context we "walk up the stack" from where the intrinsic is invoked, stopping when we
6262reach the first function call in the stack which does * not* have the attribute. This walk is in
6363[ ` InterpCx::find_closest_untracked_caller_location() ` ] [ const-find-closest ] .
6464
65- Starting at the bottom, we iterate up over stack [ ` Frame ` ] [ const-frame ] s in the
65+ Starting at the bottom, we iterate up over stack [ ` Frame ` ] [ const-frame ] s in the
6666[ ` InterpCx::stack ` ] [ const-stack ] , calling
67- [ ` InstanceDef::requires_caller_location ` ] [ requires-location ] on the
67+ [ ` InstanceDef::requires_caller_location ` ] [ requires-location ] on the
6868[ ` Instance ` s from each ` Frame ` ] [ frame-instance ] . We stop once we find one that returns ` false ` and
6969return the span of the * previous* frame which was the "topmost" tracked function.
7070
7171### Allocating a static ` Location `
7272
73- Once we have a ` Span ` , we need to allocate static memory for the ` Location ` , which is performed by
74- the [ ` TyCtxt::const_caller_location() ` ] [ const-location-query ] query. Internally this calls
73+ Once we have a ` Span ` , we need to allocate static memory for the ` Location ` , which is performed by
74+ the [ ` TyCtxt::const_caller_location() ` ] [ const-location-query ] query. Internally this calls
7575[ ` InterpCx::alloc_caller_location() ` ] [ alloc-location ] and results in a unique
7676[ memory kind] [ location-memory-kind ] (` MemoryKind::CallerLocation ` ). The SSA codegen backend is able
7777to emit code for these same values, and we use this code there as well.
@@ -80,14 +80,14 @@ Once our `Location` has been allocated in static memory, our intrinsic returns a
8080
8181## Generating code for ` #[track_caller] ` callees
8282
83- To generate efficient code for a tracked function and its callers, we need to provide the same
83+ To generate efficient code for a tracked function and its callers, we need to provide the same
8484behavior from the intrinsic's point of view without having a stack to walk up at runtime. We invert
8585the approach: as we grow the stack down we pass an additional argument to calls of tracked functions
8686rather than walking up the stack when the intrinsic is called. That additional argument can be
8787returned wherever the caller location is queried.
8888
8989The argument we append is of type ` &'static core::panic::Location<'static> ` . A reference was chosen
90- to avoid unnecessary copying because a pointer is a third the size of
90+ to avoid unnecessary copying because a pointer is a third the size of
9191` std::mem::size_of::<core::panic::Location>() == 24 ` at time of writing.
9292
9393When generating a call to a function which is tracked, we pass the location argument the value of
@@ -153,12 +153,12 @@ probably the best we can do without modifying fully-stabilized type signatures.
153153
154154> * Note:* We always emit a [ ` ReifyShim ` ] when taking a pointer to a tracked function. While the
155155> constraint here is imposed by codegen contexts, we don't know during MIR construction of the shim
156- > whether we'll be called in a const context (safe to ignore shim) or in a codegen context (unsafe
156+ > whether we'll be called in a const context (safe to ignore shim) or in a codegen context (unsafe
157157> to ignore shim). Even if we did know, the results from const and codegen contexts must agree.
158158
159159## The Attribute
160160
161- The ` #[track_caller] ` attribute is checked alongside other codegen attributes to ensure the
161+ The ` #[track_caller] ` attribute is checked alongside other codegen attributes to ensure the
162162function:
163163
164164* has the ` "Rust" ` ABI (as opposed to e.g., ` "C" ` )
@@ -173,7 +173,7 @@ used in both const and codegen contexts to ensure correct propagation.
173173
174174When applied to trait method implementations, the attribute works as it does for regular functions.
175175
176- When applied to a trait method prototype, the attribute applies to all implementations of the
176+ When applied to a trait method prototype, the attribute applies to all implementations of the
177177method. When applied to a default trait method implementation, the attribute takes effect on
178178that implementation * and* any overrides.
179179
@@ -205,14 +205,14 @@ trait TrackedFourWays {
205205 assert_tracked! ();
206206 }
207207
208- /// Overrides of this implementation are tracked (it is too).
208+ /// Overrides of this implementation are tracked (it is too).
209209 #[track_caller]
210210 fn default_tracked_to_override () {
211211 assert_tracked! ();
212212 }
213213}
214214
215- /// This impl uses the default impl for `default_tracked` and provides its own for
215+ /// This impl uses the default impl for `default_tracked` and provides its own for
216216/// `default_tracked_to_override`.
217217impl TrackedFourWays for () {
218218 fn blanket_tracked () {
@@ -255,7 +255,7 @@ up on the tracking issue. During the course of implementing that, it was also di
255255implementation was possible without modifying the number of arguments in a function's MIR, which
256256would simplify later stages and unlock use in traits.
257257
258- Because the RFC's implementation strategy could not readily support traits, the semantics were not
258+ Because the RFC's implementation strategy could not readily support traits, the semantics were not
259259originally specified. They have since been implemented following the path which seemed most correct
260260to the author and reviewers.
261261
0 commit comments