-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement #[track_caller] attribute. (RFC 2091 4/N) #65881
Conversation
r? @zackmdavis (rust_highfive has picked a reviewer for you, use r? to override) |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
d34f76a
to
0d42c3b
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
☔ The latest upstream changes (presumably #65885) made this pull request unmergeable. Please resolve the merge conflicts. |
0d42c3b
to
ebbcd40
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
ebbcd40
to
a308999
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
☔ The latest upstream changes (presumably #65919) made this pull request unmergeable. Please resolve the merge conflicts. |
Ping from triage: |
This is pending #65947 right now. (is it problematic to have a WIP/draft PR open for a while?) |
Marking as blocked on #65947. |
a308999
to
b621eb7
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
☔ The latest upstream changes (presumably #66143) made this pull request unmergeable. Please resolve the merge conflicts. |
b621eb7
to
78d8622
Compare
I implemented the remaining functionality on top of @eddyb's branch from #65947, pushing it here now to see how it behaves on tests. If you're taking a look at this it would be great to get your review on #65947 first since this PR depends on it, and I'll need to remove the rebased commits once that lands to make this more easily reviewed. |
ef95b38
to
15d1f7c
Compare
@bors r=eddyb,oli-obk |
📌 Commit 15d1f7c has been approved by |
Implement #[track_caller] attribute. (RFC 2091 4/N) Implements the `#[track_caller]` attribute in both const and codegen contexts. The const implementation walks up the stack to find the nearest untracked callsite. The codegen implementation adds an implicit argument to tracked function calls, and populates it with either a call to the previously-landed intrinsic or if the caller has `#[track_caller]` with a copy of the location passed to the current function. Also includes a little cleanup and a few comments in the other caller location areas. [Depends on: 65664](#65664) [RFC 2091 text](https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md) [Tracking issue](#47809) [Tracking doc](https://paper.dropbox.com/doc/track_rfc_2091_impl-notes--Anf1NwnIb0xcRv31YLIadyj0Ag-rwCdRc2fi2yvRZ7syGZ9q#:uid=863513134494965680023183&h2=TODO-actually-pass-location-to)
💔 Test failed - checks-azure |
Azure says that the macOS i686 build was canceled? https://dev.azure.com/rust-lang/rust/_build/results?buildId=15399 EDIT: ah, there's more detail:
|
@bors retry |
Implement #[track_caller] attribute. (RFC 2091 4/N) Implements the `#[track_caller]` attribute in both const and codegen contexts. The const implementation walks up the stack to find the nearest untracked callsite. The codegen implementation adds an implicit argument to tracked function calls, and populates it with either a call to the previously-landed intrinsic or if the caller has `#[track_caller]` with a copy of the location passed to the current function. Also includes a little cleanup and a few comments in the other caller location areas. [Depends on: 65664](#65664) [RFC 2091 text](https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md) [Tracking issue](#47809) [Tracking doc](https://paper.dropbox.com/doc/track_rfc_2091_impl-notes--Anf1NwnIb0xcRv31YLIadyj0Ag-rwCdRc2fi2yvRZ7syGZ9q#:uid=863513134494965680023183&h2=TODO-actually-pass-location-to)
☀️ Test successful - checks-azure |
Stabilize `#[track_caller]`. # Stabilization Report RFC: [2091] Tracking issue: rust-lang#47809 ## Summary From the [rustc-dev-guide chapter][dev-guide]: > Take this example program: ```rust fn main() { let foo: Option<()> = None; foo.unwrap(); // this should produce a useful panic message! } ``` > Prior to Rust 1.42, panics like this `unwrap()` printed a location in libcore: ``` $ rustc +1.41.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value',...core\macros\mod.rs:15:40 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ``` > As of 1.42, we get a much more helpful message: ``` $ rustc +1.42.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', example.rs:3:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` > These error messages are achieved through a combination of changes to `panic!` internals to make use of `core::panic::Location::caller` and a number of `#[track_caller]` annotations in the standard library which propagate caller information. The attribute adds an implicit caller location argument to the ABI of annotated functions, but does not affect the type or MIR of the function. We implement the feature entirely in codegen and in the const evaluator. ## Bottom Line This PR stabilizes the use of `#[track_caller]` everywhere, including traits and extern blocks. It also stabilizes `core::panic::Location::caller`, although the use of that function in a const context remains gated by `#![feature(const_caller_location)]`. The implementation for the feature already changed the output of panic messages for a number of std functions, as described in the [1.42 release announcement]. The attribute's use in `Index` and `IndexMut` traits is visible to users since 1.44. ## Tests All of the tests for this feature live under [src/test/ui/rfc-2091-track-caller][tests] in the repo. Noteworthy cases: * [use of attr in std] * validates user-facing benefit of the feature * [trait attribute inheritance] * covers subtle behavior designed during implementation and not RFC'd * [const/codegen equivalence] * this was the result of a suspected edge case and investigation * [diverging function support] * covers an unresolved question from the RFC * [fn pointers and shims] * covers important potential sources of unsoundness ## Documentation The rustc-dev-guide now has a chapter on [Implicit Caller Location][dev-guide]. I have an [open PR to the reference][attr-reference-pr] documenting the attribute. The intrinsic's [wrapper] includes some examples as well. ## Implementation History * 2019-10-02: [`#[track_caller]` feature gate (RFC 2091 1/N) rust-lang#65037](rust-lang#65037) * Picked up the patch that @ayosec had started on the feature gate. * 2019-10-13: [Add `Instance::resolve_for_fn_ptr` (RFC 2091 rust-lang#2/N) rust-lang#65182](rust-lang#65182) * 2019-10-20: ~~[WIP Add MIR argument for #[track_caller] (RFC 2091 3/N) rust-lang#65258](rust-lang#65258 * Abandoned approach to send location as a MIR argument. * 2019-10-28: [`std::panic::Location` is a lang_item, add `core::intrinsics::caller_location` (RFC 2091 3/N) rust-lang#65664](rust-lang#65664) * 2019-12-07: [Implement #[track_caller] attribute. (RFC 2091 4/N) rust-lang#65881](rust-lang#65881) * 2020-01-04: [libstd uses `core::panic::Location` where possible. rust-lang#67137](rust-lang#67137) * 2020-01-08: [`Option::{expect,unwrap}` and `Result::{expect, expect_err, unwrap, unwrap_err}` have `#[track_caller]` rust-lang#67887](rust-lang#67887) * 2020-01-20: [Fix #[track_caller] and function pointers rust-lang#68302](rust-lang#68302) (fixed rust-lang#68178) * 2020-03-23: [#[track_caller] in traits rust-lang#69251](rust-lang#69251) * 2020-03-24: [#[track_caller] on core::ops::{Index, IndexMut}. rust-lang#70234](rust-lang#70234) * 2020-04-08 [Support `#[track_caller]` on functions in `extern "Rust" { ... }` rust-lang#70916](rust-lang#70916) ## Unresolveds ### From the RFC > Currently the RFC simply prohibit applying #[track_caller] to trait methods as a future-proofing > measure. **Resolved.** See the dev-guide documentation and the tests section above. > Diverging functions should be supported. **Resolved.** See the tests section above. > The closure foo::{{closure}} should inherit most attributes applied to the function foo, ... **Resolved.** This unknown was related to specifics of the implementation which were made irrelevant by the final implementation. ### Binary Size I [instrumented track_caller to use custom sections][measure-size] in a local build and discovered relatively minor binary size usage for the feature overall. I'm leaving the issue open to discuss whether we want to upstream custom section support. There's an [open issue to discuss mitigation strategies][mitigate-size]. Some decisions remain about the "right" strategies to reduce size without overly constraining the compiler implementation. I'd be excited to see someone carry that work forward but my opinion is that we shouldn't block stabilization on implementing compiler flags for redaction. ### Specialization There's an [open issue][specialization] on the semantics of the attribute in specialization chains. I'm inclined to move forward with stabilization without an exact resolution here given that specialization is itself unstable, but I also think it should be an easy question to resolve. ### Location only points to the start of a call span rust-lang#69977 was resolved by rust-lang#73182, and the next step should probably be to [extend `Location` with a notion of the end of a call](rust-lang#73554). ### Regression of std's panic messages rust-lang#70963 should be resolved by serializing span hygeine to crate metadata: rust-lang#68686. [2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md [dev-guide]: https://rustc-dev-guide.rust-lang.org/codegen/implicit-caller-location.html [specialization]: rust-lang#70293 [measure-size]: rust-lang#70579 [mitigate-size]: rust-lang#70580 [attr-reference-pr]: rust-lang/reference#742 [wrapper]: https://doc.rust-lang.org/nightly/core/panic/struct.Location.html#method.caller [tests]: https://github.com/rust-lang/rust/tree/master/src/test/ui/rfc-2091-track-caller [const/codegen equivalence]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs [diverging function support]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/diverging-caller-location.rs [use of attr in std]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs [fn pointers and shims]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs [trait attribute inheritance]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-trait-impls.rs [1.42 release announcement]: https://blog.rust-lang.org/2020/03/12/Rust-1.42.html#useful-line-numbers-in-option-and-result-panic-messages
Stabilize `#[track_caller]`. # Stabilization Report RFC: [2091] Tracking issue: rust-lang#47809 ## Summary From the [rustc-dev-guide chapter][dev-guide]: > Take this example program: ```rust fn main() { let foo: Option<()> = None; foo.unwrap(); // this should produce a useful panic message! } ``` > Prior to Rust 1.42, panics like this `unwrap()` printed a location in libcore: ``` $ rustc +1.41.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value',...core\macros\mod.rs:15:40 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ``` > As of 1.42, we get a much more helpful message: ``` $ rustc +1.42.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', example.rs:3:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` > These error messages are achieved through a combination of changes to `panic!` internals to make use of `core::panic::Location::caller` and a number of `#[track_caller]` annotations in the standard library which propagate caller information. The attribute adds an implicit caller location argument to the ABI of annotated functions, but does not affect the type or MIR of the function. We implement the feature entirely in codegen and in the const evaluator. ## Bottom Line This PR stabilizes the use of `#[track_caller]` everywhere, including traits and extern blocks. It also stabilizes `core::panic::Location::caller`, although the use of that function in a const context remains gated by `#![feature(const_caller_location)]`. The implementation for the feature already changed the output of panic messages for a number of std functions, as described in the [1.42 release announcement]. The attribute's use in `Index` and `IndexMut` traits is visible to users since 1.44. ## Tests All of the tests for this feature live under [src/test/ui/rfc-2091-track-caller][tests] in the repo. Noteworthy cases: * [use of attr in std] * validates user-facing benefit of the feature * [trait attribute inheritance] * covers subtle behavior designed during implementation and not RFC'd * [const/codegen equivalence] * this was the result of a suspected edge case and investigation * [diverging function support] * covers an unresolved question from the RFC * [fn pointers and shims] * covers important potential sources of unsoundness ## Documentation The rustc-dev-guide now has a chapter on [Implicit Caller Location][dev-guide]. I have an [open PR to the reference][attr-reference-pr] documenting the attribute. The intrinsic's [wrapper] includes some examples as well. ## Implementation History * 2019-10-02: [`#[track_caller]` feature gate (RFC 2091 1/N) rust-lang#65037](rust-lang#65037) * Picked up the patch that @ayosec had started on the feature gate. * 2019-10-13: [Add `Instance::resolve_for_fn_ptr` (RFC 2091 rust-lang#2/N) rust-lang#65182](rust-lang#65182) * 2019-10-20: ~~[WIP Add MIR argument for #[track_caller] (RFC 2091 3/N) rust-lang#65258](rust-lang#65258 * Abandoned approach to send location as a MIR argument. * 2019-10-28: [`std::panic::Location` is a lang_item, add `core::intrinsics::caller_location` (RFC 2091 3/N) rust-lang#65664](rust-lang#65664) * 2019-12-07: [Implement #[track_caller] attribute. (RFC 2091 4/N) rust-lang#65881](rust-lang#65881) * 2020-01-04: [libstd uses `core::panic::Location` where possible. rust-lang#67137](rust-lang#67137) * 2020-01-08: [`Option::{expect,unwrap}` and `Result::{expect, expect_err, unwrap, unwrap_err}` have `#[track_caller]` rust-lang#67887](rust-lang#67887) * 2020-01-20: [Fix #[track_caller] and function pointers rust-lang#68302](rust-lang#68302) (fixed rust-lang#68178) * 2020-03-23: [#[track_caller] in traits rust-lang#69251](rust-lang#69251) * 2020-03-24: [#[track_caller] on core::ops::{Index, IndexMut}. rust-lang#70234](rust-lang#70234) * 2020-04-08 [Support `#[track_caller]` on functions in `extern "Rust" { ... }` rust-lang#70916](rust-lang#70916) ## Unresolveds ### From the RFC > Currently the RFC simply prohibit applying #[track_caller] to trait methods as a future-proofing > measure. **Resolved.** See the dev-guide documentation and the tests section above. > Diverging functions should be supported. **Resolved.** See the tests section above. > The closure foo::{{closure}} should inherit most attributes applied to the function foo, ... **Resolved.** This unknown was related to specifics of the implementation which were made irrelevant by the final implementation. ### Binary Size I [instrumented track_caller to use custom sections][measure-size] in a local build and discovered relatively minor binary size usage for the feature overall. I'm leaving the issue open to discuss whether we want to upstream custom section support. There's an [open issue to discuss mitigation strategies][mitigate-size]. Some decisions remain about the "right" strategies to reduce size without overly constraining the compiler implementation. I'd be excited to see someone carry that work forward but my opinion is that we shouldn't block stabilization on implementing compiler flags for redaction. ### Specialization There's an [open issue][specialization] on the semantics of the attribute in specialization chains. I'm inclined to move forward with stabilization without an exact resolution here given that specialization is itself unstable, but I also think it should be an easy question to resolve. ### Location only points to the start of a call span rust-lang#69977 was resolved by rust-lang#73182, and the next step should probably be to [extend `Location` with a notion of the end of a call](rust-lang#73554). ### Regression of std's panic messages rust-lang#70963 should be resolved by serializing span hygeine to crate metadata: rust-lang#68686. [2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md [dev-guide]: https://rustc-dev-guide.rust-lang.org/codegen/implicit-caller-location.html [specialization]: rust-lang#70293 [measure-size]: rust-lang#70579 [mitigate-size]: rust-lang#70580 [attr-reference-pr]: rust-lang/reference#742 [wrapper]: https://doc.rust-lang.org/nightly/core/panic/struct.Location.html#method.caller [tests]: https://github.com/rust-lang/rust/tree/master/src/test/ui/rfc-2091-track-caller [const/codegen equivalence]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs [diverging function support]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/diverging-caller-location.rs [use of attr in std]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs [fn pointers and shims]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs [trait attribute inheritance]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-trait-impls.rs [1.42 release announcement]: https://blog.rust-lang.org/2020/03/12/Rust-1.42.html#useful-line-numbers-in-option-and-result-panic-messages
Stabilize `#[track_caller]`. # Stabilization Report RFC: [2091] Tracking issue: rust-lang#47809 ## Summary From the [rustc-dev-guide chapter][dev-guide]: > Take this example program: ```rust fn main() { let foo: Option<()> = None; foo.unwrap(); // this should produce a useful panic message! } ``` > Prior to Rust 1.42, panics like this `unwrap()` printed a location in libcore: ``` $ rustc +1.41.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value',...core\macros\mod.rs:15:40 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ``` > As of 1.42, we get a much more helpful message: ``` $ rustc +1.42.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', example.rs:3:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` > These error messages are achieved through a combination of changes to `panic!` internals to make use of `core::panic::Location::caller` and a number of `#[track_caller]` annotations in the standard library which propagate caller information. The attribute adds an implicit caller location argument to the ABI of annotated functions, but does not affect the type or MIR of the function. We implement the feature entirely in codegen and in the const evaluator. ## Bottom Line This PR stabilizes the use of `#[track_caller]` everywhere, including traits and extern blocks. It also stabilizes `core::panic::Location::caller`, although the use of that function in a const context remains gated by `#![feature(const_caller_location)]`. The implementation for the feature already changed the output of panic messages for a number of std functions, as described in the [1.42 release announcement]. The attribute's use in `Index` and `IndexMut` traits is visible to users since 1.44. ## Tests All of the tests for this feature live under [src/test/ui/rfc-2091-track-caller][tests] in the repo. Noteworthy cases: * [use of attr in std] * validates user-facing benefit of the feature * [trait attribute inheritance] * covers subtle behavior designed during implementation and not RFC'd * [const/codegen equivalence] * this was the result of a suspected edge case and investigation * [diverging function support] * covers an unresolved question from the RFC * [fn pointers and shims] * covers important potential sources of unsoundness ## Documentation The rustc-dev-guide now has a chapter on [Implicit Caller Location][dev-guide]. I have an [open PR to the reference][attr-reference-pr] documenting the attribute. The intrinsic's [wrapper] includes some examples as well. ## Implementation History * 2019-10-02: [`#[track_caller]` feature gate (RFC 2091 1/N) rust-lang#65037](rust-lang#65037) * Picked up the patch that @ayosec had started on the feature gate. * 2019-10-13: [Add `Instance::resolve_for_fn_ptr` (RFC 2091 rust-lang#2/N) rust-lang#65182](rust-lang#65182) * 2019-10-20: ~~[WIP Add MIR argument for #[track_caller] (RFC 2091 3/N) rust-lang#65258](rust-lang#65258 * Abandoned approach to send location as a MIR argument. * 2019-10-28: [`std::panic::Location` is a lang_item, add `core::intrinsics::caller_location` (RFC 2091 3/N) rust-lang#65664](rust-lang#65664) * 2019-12-07: [Implement #[track_caller] attribute. (RFC 2091 4/N) rust-lang#65881](rust-lang#65881) * 2020-01-04: [libstd uses `core::panic::Location` where possible. rust-lang#67137](rust-lang#67137) * 2020-01-08: [`Option::{expect,unwrap}` and `Result::{expect, expect_err, unwrap, unwrap_err}` have `#[track_caller]` rust-lang#67887](rust-lang#67887) * 2020-01-20: [Fix #[track_caller] and function pointers rust-lang#68302](rust-lang#68302) (fixed rust-lang#68178) * 2020-03-23: [#[track_caller] in traits rust-lang#69251](rust-lang#69251) * 2020-03-24: [#[track_caller] on core::ops::{Index, IndexMut}. rust-lang#70234](rust-lang#70234) * 2020-04-08 [Support `#[track_caller]` on functions in `extern "Rust" { ... }` rust-lang#70916](rust-lang#70916) ## Unresolveds ### From the RFC > Currently the RFC simply prohibit applying #[track_caller] to trait methods as a future-proofing > measure. **Resolved.** See the dev-guide documentation and the tests section above. > Diverging functions should be supported. **Resolved.** See the tests section above. > The closure foo::{{closure}} should inherit most attributes applied to the function foo, ... **Resolved.** This unknown was related to specifics of the implementation which were made irrelevant by the final implementation. ### Binary Size I [instrumented track_caller to use custom sections][measure-size] in a local build and discovered relatively minor binary size usage for the feature overall. I'm leaving the issue open to discuss whether we want to upstream custom section support. There's an [open issue to discuss mitigation strategies][mitigate-size]. Some decisions remain about the "right" strategies to reduce size without overly constraining the compiler implementation. I'd be excited to see someone carry that work forward but my opinion is that we shouldn't block stabilization on implementing compiler flags for redaction. ### Specialization There's an [open issue][specialization] on the semantics of the attribute in specialization chains. I'm inclined to move forward with stabilization without an exact resolution here given that specialization is itself unstable, but I also think it should be an easy question to resolve. ### Location only points to the start of a call span rust-lang#69977 was resolved by rust-lang#73182, and the next step should probably be to [extend `Location` with a notion of the end of a call](rust-lang#73554). ### Regression of std's panic messages rust-lang#70963 should be resolved by serializing span hygeine to crate metadata: rust-lang#68686. [2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md [dev-guide]: https://rustc-dev-guide.rust-lang.org/codegen/implicit-caller-location.html [specialization]: rust-lang#70293 [measure-size]: rust-lang#70579 [mitigate-size]: rust-lang#70580 [attr-reference-pr]: rust-lang/reference#742 [wrapper]: https://doc.rust-lang.org/nightly/core/panic/struct.Location.html#method.caller [tests]: https://github.com/rust-lang/rust/tree/master/src/test/ui/rfc-2091-track-caller [const/codegen equivalence]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs [diverging function support]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/diverging-caller-location.rs [use of attr in std]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs [fn pointers and shims]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs [trait attribute inheritance]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-trait-impls.rs [1.42 release announcement]: https://blog.rust-lang.org/2020/03/12/Rust-1.42.html#useful-line-numbers-in-option-and-result-panic-messages
Stabilize `#[track_caller]`. # Stabilization Report RFC: [2091] Tracking issue: rust-lang#47809 ## Summary From the [rustc-dev-guide chapter][dev-guide]: > Take this example program: ```rust fn main() { let foo: Option<()> = None; foo.unwrap(); // this should produce a useful panic message! } ``` > Prior to Rust 1.42, panics like this `unwrap()` printed a location in libcore: ``` $ rustc +1.41.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value',...core\macros\mod.rs:15:40 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ``` > As of 1.42, we get a much more helpful message: ``` $ rustc +1.42.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', example.rs:3:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` > These error messages are achieved through a combination of changes to `panic!` internals to make use of `core::panic::Location::caller` and a number of `#[track_caller]` annotations in the standard library which propagate caller information. The attribute adds an implicit caller location argument to the ABI of annotated functions, but does not affect the type or MIR of the function. We implement the feature entirely in codegen and in the const evaluator. ## Bottom Line This PR stabilizes the use of `#[track_caller]` everywhere, including traits and extern blocks. It also stabilizes `core::panic::Location::caller`, although the use of that function in a const context remains gated by `#![feature(const_caller_location)]`. The implementation for the feature already changed the output of panic messages for a number of std functions, as described in the [1.42 release announcement]. The attribute's use in `Index` and `IndexMut` traits is visible to users since 1.44. ## Tests All of the tests for this feature live under [src/test/ui/rfc-2091-track-caller][tests] in the repo. Noteworthy cases: * [use of attr in std] * validates user-facing benefit of the feature * [trait attribute inheritance] * covers subtle behavior designed during implementation and not RFC'd * [const/codegen equivalence] * this was the result of a suspected edge case and investigation * [diverging function support] * covers an unresolved question from the RFC * [fn pointers and shims] * covers important potential sources of unsoundness ## Documentation The rustc-dev-guide now has a chapter on [Implicit Caller Location][dev-guide]. I have an [open PR to the reference][attr-reference-pr] documenting the attribute. The intrinsic's [wrapper] includes some examples as well. ## Implementation History * 2019-10-02: [`#[track_caller]` feature gate (RFC 2091 1/N) rust-lang#65037](rust-lang#65037) * Picked up the patch that @ayosec had started on the feature gate. * 2019-10-13: [Add `Instance::resolve_for_fn_ptr` (RFC 2091 rust-lang#2/N) rust-lang#65182](rust-lang#65182) * 2019-10-20: ~~[WIP Add MIR argument for #[track_caller] (RFC 2091 3/N) rust-lang#65258](rust-lang#65258 * Abandoned approach to send location as a MIR argument. * 2019-10-28: [`std::panic::Location` is a lang_item, add `core::intrinsics::caller_location` (RFC 2091 3/N) rust-lang#65664](rust-lang#65664) * 2019-12-07: [Implement #[track_caller] attribute. (RFC 2091 4/N) rust-lang#65881](rust-lang#65881) * 2020-01-04: [libstd uses `core::panic::Location` where possible. rust-lang#67137](rust-lang#67137) * 2020-01-08: [`Option::{expect,unwrap}` and `Result::{expect, expect_err, unwrap, unwrap_err}` have `#[track_caller]` rust-lang#67887](rust-lang#67887) * 2020-01-20: [Fix #[track_caller] and function pointers rust-lang#68302](rust-lang#68302) (fixed rust-lang#68178) * 2020-03-23: [#[track_caller] in traits rust-lang#69251](rust-lang#69251) * 2020-03-24: [#[track_caller] on core::ops::{Index, IndexMut}. rust-lang#70234](rust-lang#70234) * 2020-04-08 [Support `#[track_caller]` on functions in `extern "Rust" { ... }` rust-lang#70916](rust-lang#70916) ## Unresolveds ### From the RFC > Currently the RFC simply prohibit applying #[track_caller] to trait methods as a future-proofing > measure. **Resolved.** See the dev-guide documentation and the tests section above. > Diverging functions should be supported. **Resolved.** See the tests section above. > The closure foo::{{closure}} should inherit most attributes applied to the function foo, ... **Resolved.** This unknown was related to specifics of the implementation which were made irrelevant by the final implementation. ### Binary Size I [instrumented track_caller to use custom sections][measure-size] in a local build and discovered relatively minor binary size usage for the feature overall. I'm leaving the issue open to discuss whether we want to upstream custom section support. There's an [open issue to discuss mitigation strategies][mitigate-size]. Some decisions remain about the "right" strategies to reduce size without overly constraining the compiler implementation. I'd be excited to see someone carry that work forward but my opinion is that we shouldn't block stabilization on implementing compiler flags for redaction. ### Specialization There's an [open issue][specialization] on the semantics of the attribute in specialization chains. I'm inclined to move forward with stabilization without an exact resolution here given that specialization is itself unstable, but I also think it should be an easy question to resolve. ### Location only points to the start of a call span rust-lang#69977 was resolved by rust-lang#73182, and the next step should probably be to [extend `Location` with a notion of the end of a call](rust-lang#73554). ### Regression of std's panic messages rust-lang#70963 should be resolved by serializing span hygeine to crate metadata: rust-lang#68686. [2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md [dev-guide]: https://rustc-dev-guide.rust-lang.org/codegen/implicit-caller-location.html [specialization]: rust-lang#70293 [measure-size]: rust-lang#70579 [mitigate-size]: rust-lang#70580 [attr-reference-pr]: rust-lang/reference#742 [wrapper]: https://doc.rust-lang.org/nightly/core/panic/struct.Location.html#method.caller [tests]: https://github.com/rust-lang/rust/tree/master/src/test/ui/rfc-2091-track-caller [const/codegen equivalence]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs [diverging function support]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/diverging-caller-location.rs [use of attr in std]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs [fn pointers and shims]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs [trait attribute inheritance]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-trait-impls.rs [1.42 release announcement]: https://blog.rust-lang.org/2020/03/12/Rust-1.42.html#useful-line-numbers-in-option-and-result-panic-messages
Stabilize `#[track_caller]`. # Stabilization Report RFC: [2091] Tracking issue: rust-lang#47809 ## Summary From the [rustc-dev-guide chapter][dev-guide]: > Take this example program: ```rust fn main() { let foo: Option<()> = None; foo.unwrap(); // this should produce a useful panic message! } ``` > Prior to Rust 1.42, panics like this `unwrap()` printed a location in libcore: ``` $ rustc +1.41.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value',...core\macros\mod.rs:15:40 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ``` > As of 1.42, we get a much more helpful message: ``` $ rustc +1.42.0 example.rs; example.exe thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', example.rs:3:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` > These error messages are achieved through a combination of changes to `panic!` internals to make use of `core::panic::Location::caller` and a number of `#[track_caller]` annotations in the standard library which propagate caller information. The attribute adds an implicit caller location argument to the ABI of annotated functions, but does not affect the type or MIR of the function. We implement the feature entirely in codegen and in the const evaluator. ## Bottom Line This PR stabilizes the use of `#[track_caller]` everywhere, including traits and extern blocks. It also stabilizes `core::panic::Location::caller`, although the use of that function in a const context remains gated by `#![feature(const_caller_location)]`. The implementation for the feature already changed the output of panic messages for a number of std functions, as described in the [1.42 release announcement]. The attribute's use in `Index` and `IndexMut` traits is visible to users since 1.44. ## Tests All of the tests for this feature live under [src/test/ui/rfc-2091-track-caller][tests] in the repo. Noteworthy cases: * [use of attr in std] * validates user-facing benefit of the feature * [trait attribute inheritance] * covers subtle behavior designed during implementation and not RFC'd * [const/codegen equivalence] * this was the result of a suspected edge case and investigation * [diverging function support] * covers an unresolved question from the RFC * [fn pointers and shims] * covers important potential sources of unsoundness ## Documentation The rustc-dev-guide now has a chapter on [Implicit Caller Location][dev-guide]. I have an [open PR to the reference][attr-reference-pr] documenting the attribute. The intrinsic's [wrapper] includes some examples as well. ## Implementation History * 2019-10-02: [`#[track_caller]` feature gate (RFC 2091 1/N) rust-lang#65037](rust-lang#65037) * Picked up the patch that @ayosec had started on the feature gate. * 2019-10-13: [Add `Instance::resolve_for_fn_ptr` (RFC 2091 rust-lang#2/N) rust-lang#65182](rust-lang#65182) * 2019-10-20: ~~[WIP Add MIR argument for #[track_caller] (RFC 2091 3/N) rust-lang#65258](rust-lang#65258 * Abandoned approach to send location as a MIR argument. * 2019-10-28: [`std::panic::Location` is a lang_item, add `core::intrinsics::caller_location` (RFC 2091 3/N) rust-lang#65664](rust-lang#65664) * 2019-12-07: [Implement #[track_caller] attribute. (RFC 2091 4/N) rust-lang#65881](rust-lang#65881) * 2020-01-04: [libstd uses `core::panic::Location` where possible. rust-lang#67137](rust-lang#67137) * 2020-01-08: [`Option::{expect,unwrap}` and `Result::{expect, expect_err, unwrap, unwrap_err}` have `#[track_caller]` rust-lang#67887](rust-lang#67887) * 2020-01-20: [Fix #[track_caller] and function pointers rust-lang#68302](rust-lang#68302) (fixed rust-lang#68178) * 2020-03-23: [#[track_caller] in traits rust-lang#69251](rust-lang#69251) * 2020-03-24: [#[track_caller] on core::ops::{Index, IndexMut}. rust-lang#70234](rust-lang#70234) * 2020-04-08 [Support `#[track_caller]` on functions in `extern "Rust" { ... }` rust-lang#70916](rust-lang#70916) ## Unresolveds ### From the RFC > Currently the RFC simply prohibit applying #[track_caller] to trait methods as a future-proofing > measure. **Resolved.** See the dev-guide documentation and the tests section above. > Diverging functions should be supported. **Resolved.** See the tests section above. > The closure foo::{{closure}} should inherit most attributes applied to the function foo, ... **Resolved.** This unknown was related to specifics of the implementation which were made irrelevant by the final implementation. ### Binary Size I [instrumented track_caller to use custom sections][measure-size] in a local build and discovered relatively minor binary size usage for the feature overall. I'm leaving the issue open to discuss whether we want to upstream custom section support. There's an [open issue to discuss mitigation strategies][mitigate-size]. Some decisions remain about the "right" strategies to reduce size without overly constraining the compiler implementation. I'd be excited to see someone carry that work forward but my opinion is that we shouldn't block stabilization on implementing compiler flags for redaction. ### Specialization There's an [open issue][specialization] on the semantics of the attribute in specialization chains. I'm inclined to move forward with stabilization without an exact resolution here given that specialization is itself unstable, but I also think it should be an easy question to resolve. ### Location only points to the start of a call span rust-lang#69977 was resolved by rust-lang#73182, and the next step should probably be to [extend `Location` with a notion of the end of a call](rust-lang#73554). ### Regression of std's panic messages rust-lang#70963 should be resolved by serializing span hygeine to crate metadata: rust-lang#68686. [2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md [dev-guide]: https://rustc-dev-guide.rust-lang.org/codegen/implicit-caller-location.html [specialization]: rust-lang#70293 [measure-size]: rust-lang#70579 [mitigate-size]: rust-lang#70580 [attr-reference-pr]: rust-lang/reference#742 [wrapper]: https://doc.rust-lang.org/nightly/core/panic/struct.Location.html#method.caller [tests]: https://github.com/rust-lang/rust/tree/master/src/test/ui/rfc-2091-track-caller [const/codegen equivalence]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs [diverging function support]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/diverging-caller-location.rs [use of attr in std]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs [fn pointers and shims]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs [trait attribute inheritance]: https://github.com/rust-lang/rust/blob/master/src/test/ui/rfc-2091-track-caller/tracked-trait-impls.rs [1.42 release announcement]: https://blog.rust-lang.org/2020/03/12/Rust-1.42.html#useful-line-numbers-in-option-and-result-panic-messages
Implements the
#[track_caller]
attribute in both const and codegen contexts.The const implementation walks up the stack to find the nearest untracked callsite.
The codegen implementation adds an implicit argument to tracked function calls, and populates it with either a call to the previously-landed intrinsic or if the caller has
#[track_caller]
with a copy of the location passed to the current function.Also includes a little cleanup and a few comments in the other caller location areas.
Depends on: 65664
RFC 2091 text
Tracking issue
Tracking doc