Skip to content

Commit

Permalink
Document #[track_caller].
Browse files Browse the repository at this point in the history
  • Loading branch information
anp committed May 21, 2020
1 parent a6efccd commit 2c93941
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ The following is an index of all built-in attributes.
- [`cold`] — Hint that a function is unlikely to be called.
- [`no_builtins`] — Disables use of certain built-in functions.
- [`target_feature`] — Configure platform-specific code generation.
- [`track_caller`] - Pass the parent call location to `std::panic::Location::caller()`.
- Documentation
- `doc` — Specifies documentation. See [The Rustdoc Book] for more
information. [Doc comments] are transformed into `doc` attributes.
Expand Down Expand Up @@ -294,6 +295,7 @@ The following is an index of all built-in attributes.
[`should_panic`]: attributes/testing.md#the-should_panic-attribute
[`target_feature`]: attributes/codegen.md#the-target_feature-attribute
[`test`]: attributes/testing.md#the-test-attribute
[`track_caller`]: attributes/codegen.md#the-track_caller-attribute
[`type_length_limit`]: attributes/limits.md#the-type_length_limit-attribute
[`used`]: abi.md#the-used-attribute
[`warn`]: attributes/diagnostics.md#lint-check-attributes
Expand Down
52 changes: 52 additions & 0 deletions src/attributes/codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,54 @@ feature detection on the x86 platforms.
> may be enabled or disabled for an entire crate with the
> [`-C target-feature`] flag.
## The `track_caller` attribute

The `track_caller` attribute may be applied to any function with [`"Rust"` ABI][rust-abi]. When
applied to trait functions and methods, the attribute applies to all implementations. If the trait
provides a default implementation with the attribute, then the attribute also applies to override
implementations.

When applied to a function in an `extern` block the attribute must also be applied to any linked
implementations, otherwise undefined behavior results. When applied to a function which is made
available to an `extern` block, the declaration in the `extern` block must also have the attribute,
otherwise undefined behavior results.

### Behavior

Applying the attribute to a function `f` allows code within `f` to observe the [`Location`] of the
"topmost" tracked call that led to `f`'s invocation. At the point of observation, an implementation
behaves as if it walks up the stack from `f`'s frame to find the nearest frame of an *unattributed*
function `outer`, and it returns the [`Location`] of the tracked call in `outer`.

> Note: `core` provides [`core::panic::Location::caller`] for observing caller locations. It wraps
> the [`core::intrinsics::caller_location`] intrinsic implemented by `rustc`.
#### Examples

If `f` is called directly by `outer`, code in `f` observes its callsite within `outer`.

If `f` is called by another attributed function `g` which is in turn called by `outer`, code in both
`f` and `g` observes `g`'s callsite within `outer`.

If `g` is called by another attributed function `h` which is in turn called by `outer`, all code in
`f`, `g`, and `h` observes `h`'s callsite within `outer`, and so on.

### Limitations

This information is a hint and implementations are not required to preserve it.

In particular, coercing a function with `#[track_caller]` to a function pointer creates a shim which
appears to observers to have been called at the attributed function's definition site, losing actual
caller information across virtual calls. A common example of this coercion is the creation of a
trait object whose methods are attributed.

> Note: The aforementioned shim for function pointers is necessary because `rustc` implements
> `track_caller` in a codegen context by appending an implicit parameter to the function ABI, but
> this would be unsound for an indirect call because the parameter is not a part of the function's
> type and a given function pointer type may or may not refer to a function with the attribute. The
> creation of a shim hides the implicit parameter from callers of the function pointer, preserving
> soundness.
[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
[`-C target-cpu`]: ../../rustc/codegen-options/index.html#target-cpu
[`-C target-feature`]: ../../rustc/codegen-options/index.html#target-feature
Expand All @@ -155,3 +203,7 @@ feature detection on the x86 platforms.
[trait]: ../items/traits.md
[undefined behavior]: ../behavior-considered-undefined.md
[unsafe function]: ../unsafe-functions.md
[rust-abi]: ../items/external-blocks.md#abi
[`core::intrinsics::caller_location`]: ../../core/intrinsics/fn.caller_location.html
[`core::panic::Location::caller`]: ../../core/panic/struct.Location.html#method.caller
[`Location`]: ../../core/panic/struct.Location.html

0 comments on commit 2c93941

Please sign in to comment.