-
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
Span hygiene data should be serialized to crate metadata #68686
Comments
This is a big issue and one of the primary blockers for stabilizing #49300 (comment) suggests a cross-crate stable representation for |
This comment has been minimized.
This comment has been minimized.
Here's an idea for how to serialize We could just serialize the entire However, this approach interacts very badly with cross-crate serialization. Whenever we need to deserialize a The situation gets worse if we need to re-serialize cross-crate spans into our own metadata. This will propagate the extra This is essentially the same problem I described in #68718 (comment), but for If we assume that 'crate-local' spans are accessed much more frequently than 'cross-crate' spans, then I think we can come up with a better solution. We can turn enum SyntaxContextData {
Local(/* the current SyntaxContextData fields */),
Remote(CrateNum, SyntaxContext)
} When we create a fresh When we deserialize To retrieve information about a This will make access to With this approach, we can also heuristically choose to deserialize some cross-crate |
[experiment] rustc_metadata: Load metadata for indirect macro-only dependencies Imagine this dependency chain between crates ``` Executable crate -> Library crate -> Macro crate ``` where "Library crate" uses the macros from "Macro crate" for some code generation, but doesn't reexport them any further. Currently, when compiling "Executable crate" we don't even load metadata for it, because why would we want to load any metadata from "Macro crate" if it already did all its code generation job when compiling "Library crate". Right? Wrong! Hygiene data and spans (#68686, #68941) from "Macro crate" still may need to be decoded from "Executable crate". So we'll have to load them properly. Questions: - How this will affect compile times for larger crate trees in practice? How to measure it? Hygiene/span encoding/decoding will necessarily slow down compilation because right now we just don't do some work that we should do, but this introduces a whole new way to slow down things. E.g. loading metadata for `syn` (and its dependencies) when compiling your executable if one of its library dependencies uses it. - We are currently detecting whether a crate reexports macros from "Macro crate" or not, could we similarly detect whether a crate "reexports spans" and keep it unloaded if it doesn't? Or at least "reexports important spans" affecting hygiene, we can probably lose spans that only affect diagnostics.
rustc_metadata: Load metadata for indirect macro-only dependencies Imagine this dependency chain between crates ``` Executable crate -> Library crate -> Macro crate ``` where "Library crate" uses the macros from "Macro crate" for some code generation, but doesn't reexport them any further. Currently, when compiling "Executable crate" we don't even load metadata for it, because why would we want to load any metadata from "Macro crate" if it already did all its code generation job when compiling "Library crate". Right? Wrong! Hygiene data and spans (#68686, #68941) from "Macro crate" still may need to be decoded from "Executable crate". So we'll have to load them properly. Questions: - How this will affect compile times for larger crate trees in practice? How to measure it? Hygiene/span encoding/decoding will necessarily slow down compilation because right now we just don't do some work that we should do, but this introduces a whole new way to slow down things. E.g. loading metadata for `syn` (and its dependencies) when compiling your executable if one of its library dependencies uses it. - We are currently detecting whether a crate reexports macros from "Macro crate" or not, could we similarly detect whether a crate "reexports spans" and keep it unloaded if it doesn't? Or at least "reexports important spans" affecting hygiene, we can probably lose spans that only affect diagnostics.
Previously, we threw away the `Span` associated with a definition's identifier when we encoded crate metadata, causing us to lose location and hygiene information. We now store the identifier's `Span` in the crate metadata. When we decode items from the metadata, we combine the name and span back into an `Ident`. This improves the output of several tests, which previously had messages suppressed due to dummy spans. This is a prerequisite for rust-lang#68686, since throwing away a `Span` means that we lose hygiene information.
…t, r=petrochenkov Store idents for `DefPathData` into crate metadata Previously, we threw away the `Span` associated with a definition's identifier when we encoded crate metadata, causing us to lose location and hygiene information. We now store the identifier's `Span` in a side table, which gets encoded into the crate metadata. When we decode items from the metadata, we combine the name and span back into an `Ident`. This improves the output of several tests, which previously had messages suppressed due to dummy spans. This is a prerequisite for rust-lang#68686, since throwing away a `Span` means that we lose hygiene information.
Previously, we threw away the `Span` associated with a definition's identifier when we encoded crate metadata, causing us to lose location and hygiene information. We now store the identifier's `Span` in the crate metadata. When we decode items from the metadata, we combine the name and span back into an `Ident`. This improves the output of several tests, which previously had messages suppressed due to dummy spans. This is a prerequisite for rust-lang#68686, since throwing away a `Span` means that we lose hygiene information.
…t, r=petrochenkov Store idents for `DefPathData` into crate metadata Previously, we threw away the `Span` associated with a definition's identifier when we encoded crate metadata, causing us to lose location and hygiene information. We now store the identifier's `Span` in a side table, which gets encoded into the crate metadata. When we decode items from the metadata, we combine the name and span back into an `Ident`. This improves the output of several tests, which previously had messages suppressed due to dummy spans. This is a prerequisite for rust-lang#68686, since throwing away a `Span` means that we lose hygiene information.
…t, r=petrochenkov Store idents for `DefPathData` into crate metadata Previously, we threw away the `Span` associated with a definition's identifier when we encoded crate metadata, causing us to lose location and hygiene information. We now store the identifier's `Span` in a side table, which gets encoded into the crate metadata. When we decode items from the metadata, we combine the name and span back into an `Ident`. This improves the output of several tests, which previously had messages suppressed due to dummy spans. This is a prerequisite for rust-lang#68686, since throwing away a `Span` means that we lose hygiene information.
…t, r=petrochenkov Store idents for `DefPathData` into crate metadata Previously, we threw away the `Span` associated with a definition's identifier when we encoded crate metadata, causing us to lose location and hygiene information. We now store the identifier's `Span` in a side table, which gets encoded into the crate metadata. When we decode items from the metadata, we combine the name and span back into an `Ident`. This improves the output of several tests, which previously had messages suppressed due to dummy spans. This is a prerequisite for rust-lang#68686, since throwing away a `Span` means that we lose hygiene information.
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
When we serialize a
Span
to crate metadata, we currently throw away theSyntaxContext
:rust/src/librustc_span/lib.rs
Lines 631 to 650 in 34700c1
This is because the backing
HygieneData
is stored in a thread-local inrustc_span
, and not serialized into crate metadata.The result is that spans deserialized from crate metadata may have less information available than spans from the current crate. If the MIR inlining pass decides to inline a function from another crate, we may end up with suboptimal messages when we invoke
span.ctxt()
(e.g. when emitting debuginfo, and when evaluating thecaller_location
intrinsic).It would be useful if we were to serialize
HygieneData
into crate metadata, and deserialize spans with the properSyntaxContext
. This will also ensure that parallel compilation works properly, since storingHygieneData
in a thread local will cause problems if aSpan
is used on multiple threads.I'm not really sure how best to go about doing this.
ExpnId
s are currently unique per-crate, since they are never serialized. We need some way of makingExpnIds
globally unique.The text was updated successfully, but these errors were encountered: