-
Notifications
You must be signed in to change notification settings - Fork 721
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
Add fake return to improve span on type error in tracing::instrument
#2270
Conversation
Note: Is it possible to provide a UI test (like https://github.com/dtolnay/trybuild) for tracing macros? Otherwise, any recommendations on how to provide a test for this change, since all affected code is not expected to compile (and thus probably doesn't work with a traditional unit test)? |
4dfe046
to
7393f85
Compare
it's fine to introduce a dev dependency on |
@davidbarsky just told me to do the same -- will do! |
cd2f3a1
to
b4dcdcb
Compare
Okay, think this is ready for review. Sorry for the force-pushes, wanted to make sure the history was clean. |
b4dcdcb
to
9d04b17
Compare
9d04b17
to
9aea0e5
Compare
(as a side note, you don't need to force push to branches, as all pull requests will be merged by squashing. see https://github.com/tokio-rs/tracing/blob/master/CONTRIBUTING.md#commit-squashing for details.) |
Good to know. Guess I really should've read the contributing guide first, my bad. |
74aa64c
to
33354fd
Compare
(sorry, that force push is because I am dumb and don't know how to use git) |
no worries, it's nto a big deal! |
mercurial + the diff tool encourages the equivalent of force pushes, but github punishes you for it, so no worries. |
also used to force-pushing when working on rustc because bors doesn't auto-squash 😸 |
CI failure is a new clippy warning, unrelated to this change: https://github.com/tokio-rs/tracing/runs/7842367961?check_suite_focus=true I'll fix that on |
## Motivation Return type errors on instrumented async functions are a bit vague, since the type error originates within the macro itself due to the indirection of additional `async {}` blocks generated in the proc-macro (and due to the way that inference propagates around in Rust). This leads to a pretty difficult to understand error. For example: ```rust #[instrument] async fn foo() -> String { "" } ``` results in... ``` error[E0308]: mismatched types --> src/main.rs:1:1 | 1 | #[tracing::instrument] | ^^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` | | | expected struct `String`, found `&str` ``` ## Solution Installs a fake `return` statement as the first thing that happens in the auto-generated block of an instrumented async function. This causes the coercion machinery within rustc to infer the right return type (matching the the outer function) eagerly, as opposed to after the `async {}` block has been type-checked. This will cause us to both be able to point out the return type span correctly, and properly suggest fixes on the expressions that cause the type mismatch. After this change, the example code above compiles to: ``` error[E0308]: mismatched types --> src/main.rs:3:5 | 3 | "" | ^^- help: try using a conversion method: `.to_string()` | | | expected struct `String`, found `&str` | note: return type inferred to be `String` here --> src/main.rs:2:20 | 2 | async fn foo() -> String { | ^^^^^^ ```
## Motivation Return type errors on instrumented async functions are a bit vague, since the type error originates within the macro itself due to the indirection of additional `async {}` blocks generated in the proc-macro (and due to the way that inference propagates around in Rust). This leads to a pretty difficult to understand error. For example: ```rust #[instrument] async fn foo() -> String { "" } ``` results in... ``` error[E0308]: mismatched types --> src/main.rs:1:1 | 1 | #[tracing::instrument] | ^^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` | | | expected struct `String`, found `&str` ``` ## Solution Installs a fake `return` statement as the first thing that happens in the auto-generated block of an instrumented async function. This causes the coercion machinery within rustc to infer the right return type (matching the the outer function) eagerly, as opposed to after the `async {}` block has been type-checked. This will cause us to both be able to point out the return type span correctly, and properly suggest fixes on the expressions that cause the type mismatch. After this change, the example code above compiles to: ``` error[E0308]: mismatched types --> src/main.rs:3:5 | 3 | "" | ^^- help: try using a conversion method: `.to_string()` | | | expected struct `String`, found `&str` | note: return type inferred to be `String` here --> src/main.rs:2:20 | 2 | async fn foo() -> String { | ^^^^^^ ```
## Motivation Return type errors on instrumented async functions are a bit vague, since the type error originates within the macro itself due to the indirection of additional `async {}` blocks generated in the proc-macro (and due to the way that inference propagates around in Rust). This leads to a pretty difficult to understand error. For example: ```rust #[instrument] async fn foo() -> String { "" } ``` results in... ``` error[E0308]: mismatched types --> src/main.rs:1:1 | 1 | #[tracing::instrument] | ^^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` | | | expected struct `String`, found `&str` ``` ## Solution Installs a fake `return` statement as the first thing that happens in the auto-generated block of an instrumented async function. This causes the coercion machinery within rustc to infer the right return type (matching the the outer function) eagerly, as opposed to after the `async {}` block has been type-checked. This will cause us to both be able to point out the return type span correctly, and properly suggest fixes on the expressions that cause the type mismatch. After this change, the example code above compiles to: ``` error[E0308]: mismatched types --> src/main.rs:3:5 | 3 | "" | ^^- help: try using a conversion method: `.to_string()` | | | expected struct `String`, found `&str` | note: return type inferred to be `String` here --> src/main.rs:2:20 | 2 | async fn foo() -> String { | ^^^^^^ ```
# 0.1.23 (October 6, 2022) This release of `tracing-attributes` fixes a bug where compiler diagnostic spans for type errorsin `#[instrument]`ed `async fn`s have the location of the `#[instrument]` attribute rather than the location of the actual error, and a bug where inner attributes in `#[instrument]`ed functions would cause a compiler error. ### Fixed - Fix incorrect handling of inner attributes in `#[instrument]`ed functions ([#2307]) - Add fake return to improve spans generated for type errors in `async fn`s ([#2270]) - Updated `syn` dependency to fix compilation with `-Z minimal-versions` ([#2246]) Thanks to new contributors @compiler-errors and @e-nomem, as well as @CAD97, for contributing to this release! [#2307]: #2307 [#2270]: #2270 [#2246]: #2246
# 0.1.23 (October 6, 2022) This release of `tracing-attributes` fixes a bug where compiler diagnostic spans for type errors in `#[instrument]`ed `async fn`s have the location of the `#[instrument]` attribute rather than the location of the actual error, and a bug where inner attributes in `#[instrument]`ed functions would cause a compiler error. ### Fixed - Fix incorrect handling of inner attributes in `#[instrument]`ed functions ([#2307]) - Add fake return to improve spans generated for type errors in `async fn`s ([#2270]) - Updated `syn` dependency to fix compilation with `-Z minimal-versions` ([#2246]) Thanks to new contributors @compiler-errors and @e-nomem, as well as @CAD97, for contributing to this release! [#2307]: #2307 [#2270]: #2270 [#2246]: #2246
# 0.1.37 (October 6, 2022) This release of `tracing` incorporates changes from `tracing-core` [v0.1.30][core-0.1.30] and `tracing-attributes` [v0.1.23][0.1.23], including the new `Subscriber::on_register_dispatch` method for performing late initialization after a `Subscriber` is registered as a `Dispatch`, and bugfixes for the `#[instrument]` attribute. Additionally, it fixes instances of the `bare_trait_objects` lint, which is now a warning on `tracing`'s MSRV and will become an error in the next edition. ### Fixed - **attributes**: Incorrect handling of inner attributes in `#[instrument]`ed functions (#2307) - **attributes**: Incorrect location of compiler diagnostic spans generated for type errors in `#[instrument]`ed `async fn`s (#2270) - **attributes**: Updated `syn` dependency to fix compilation with `-Z minimal-versions` (#2246) - `bare_trait_objects` warning in `valueset!` macro expansion (#2308) ### Added - **core**: `Subscriber::on_register_dispatch` method (#2269) - **core**: `WeakDispatch` type and `Dispatch::downgrade()` function (#2293) ### Changed - `tracing-core`: updated to [0.1.30][core-0.1.30] - `tracing-attributes`: updated to [0.1.23][attrs-0.1.23] ### Documented - Added [`tracing-web`] and [`reqwest-tracing`] to related crates (#2283], [#2331) Thanks to new contributors @compiler-errors, @e-nomem, @WorldSEnder, @Xiami2012, and @tl-rodrigo-gryzinski, as well as @jswrenn and @CAD97, for contributing to this release! [core-0.1.30]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.30 [attrs-0.1.23]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.23 [`tracing-web`]: https://crates.io/crates/tracing-web/ [`reqwest-tracing`]: https://crates.io/crates/reqwest-tracing/
# 0.1.37 (October 6, 2022) This release of `tracing` incorporates changes from `tracing-core` [v0.1.30][core-0.1.30] and `tracing-attributes` [v0.1.23][attrs-0.1.23], including the new `Subscriber::on_register_dispatch` method for performing late initialization after a `Subscriber` is registered as a `Dispatch`, and bugfixes for the `#[instrument]` attribute. Additionally, it fixes instances of the `bare_trait_objects` lint, which is now a warning on `tracing`'s MSRV and will become an error in the next edition. ### Fixed - **attributes**: Incorrect handling of inner attributes in `#[instrument]`ed functions (#2307) - **attributes**: Incorrect location of compiler diagnostic spans generated for type errors in `#[instrument]`ed `async fn`s (#2270) - **attributes**: Updated `syn` dependency to fix compilation with `-Z minimal-versions` (#2246) - `bare_trait_objects` warning in `valueset!` macro expansion (#2308) ### Added - **core**: `Subscriber::on_register_dispatch` method (#2269) - **core**: `WeakDispatch` type and `Dispatch::downgrade()` function (#2293) ### Changed - `tracing-core`: updated to [0.1.30][core-0.1.30] - `tracing-attributes`: updated to [0.1.23][attrs-0.1.23] ### Documented - Added [`tracing-web`] and [`reqwest-tracing`] to related crates (#2283, #2331) Thanks to new contributors @compiler-errors, @e-nomem, @WorldSEnder, @Xiami2012, and @tl-rodrigo-gryzinski, as well as @jswrenn and @CAD97, for contributing to this release! [core-0.1.30]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.30 [attrs-0.1.23]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.23 [`tracing-web`]: https://crates.io/crates/tracing-web/ [`reqwest-tracing`]: https://crates.io/crates/reqwest-tracing/
Would it be too much to ask for an tracing/tracing-attributes/src/expand.rs Lines 66 to 73 in 196e83e
We use |
I think opening a PR for this would be fine. Alternatively, one could do the same thing as Though please be careful that it handles return-position |
## Motivation PR #2270 added an unreachable branch with an explicit return value to `#[instrument]` in `async fn`s in order to fix type inference issues. That PR added the appropriate `#[allow]` attribute for the Rust compiler's unreachable code linting, but not Clippy's, so a Clippy warning is still emitted. See: #2270 (comment) ## Solution Adding the clippy lint warning as discussed here: #2270 (comment)
## Motivation PR #2270 added an unreachable branch with an explicit return value to `#[instrument]` in `async fn`s in order to fix type inference issues. That PR added the appropriate `#[allow]` attribute for the Rust compiler's unreachable code linting, but not Clippy's, so a Clippy warning is still emitted. See: tokio-rs/tracing#2270 (comment) ## Solution Adding the clippy lint warning as discussed here: tokio-rs/tracing#2270 (comment)
The fake return edge was added in tokio-rs#2270 to improve type errors in instrumented async functions. However, it meant that the user block was being modified outside of `gen_block`. This created a negative interaction with tokio-rs#1614, which suppressed a clippy lint internally while explicitly enabling it on the user block. The installed fake return edge generated this same lint, but the user had no way to suppress it: lint directives above the instrumentation were ignored because of the internal suppression, and lints inside the user block could not influence the fake return edge's scope. We now avoid modifying the user block outside of `gen_block`, and restrict the fake return edge to async functions. We also apply the same clippy lint suppression technique to the installed fake return edge. Closes tokio-rs#2410.
## Motivation PR #2270 added an unreachable branch with an explicit return value to `#[instrument]` in `async fn`s in order to fix type inference issues. That PR added the appropriate `#[allow]` attribute for the Rust compiler's unreachable code linting, but not Clippy's, so a Clippy warning is still emitted. See: #2270 (comment) ## Solution Adding the clippy lint warning as discussed here: #2270 (comment)
## Motivation PR #2270 added an unreachable branch with an explicit return value to `#[instrument]` in `async fn`s in order to fix type inference issues. That PR added the appropriate `#[allow]` attribute for the Rust compiler's unreachable code linting, but not Clippy's, so a Clippy warning is still emitted. See: #2270 (comment) ## Solution Adding the clippy lint warning as discussed here: #2270 (comment)
# 0.1.23 (October 6, 2022) This release of `tracing-attributes` fixes a bug where compiler diagnostic spans for type errors in `#[instrument]`ed `async fn`s have the location of the `#[instrument]` attribute rather than the location of the actual error, and a bug where inner attributes in `#[instrument]`ed functions would cause a compiler error. ### Fixed - Fix incorrect handling of inner attributes in `#[instrument]`ed functions ([tokio-rs#2307]) - Add fake return to improve spans generated for type errors in `async fn`s ([tokio-rs#2270]) - Updated `syn` dependency to fix compilation with `-Z minimal-versions` ([tokio-rs#2246]) Thanks to new contributors @compiler-errors and @e-nomem, as well as @CAD97, for contributing to this release! [tokio-rs#2307]: tokio-rs#2307 [tokio-rs#2270]: tokio-rs#2270 [tokio-rs#2246]: tokio-rs#2246
# 0.1.37 (October 6, 2022) This release of `tracing` incorporates changes from `tracing-core` [v0.1.30][core-0.1.30] and `tracing-attributes` [v0.1.23][attrs-0.1.23], including the new `Subscriber::on_register_dispatch` method for performing late initialization after a `Subscriber` is registered as a `Dispatch`, and bugfixes for the `#[instrument]` attribute. Additionally, it fixes instances of the `bare_trait_objects` lint, which is now a warning on `tracing`'s MSRV and will become an error in the next edition. ### Fixed - **attributes**: Incorrect handling of inner attributes in `#[instrument]`ed functions (tokio-rs#2307) - **attributes**: Incorrect location of compiler diagnostic spans generated for type errors in `#[instrument]`ed `async fn`s (tokio-rs#2270) - **attributes**: Updated `syn` dependency to fix compilation with `-Z minimal-versions` (tokio-rs#2246) - `bare_trait_objects` warning in `valueset!` macro expansion (tokio-rs#2308) ### Added - **core**: `Subscriber::on_register_dispatch` method (tokio-rs#2269) - **core**: `WeakDispatch` type and `Dispatch::downgrade()` function (tokio-rs#2293) ### Changed - `tracing-core`: updated to [0.1.30][core-0.1.30] - `tracing-attributes`: updated to [0.1.23][attrs-0.1.23] ### Documented - Added [`tracing-web`] and [`reqwest-tracing`] to related crates (tokio-rs#2283, tokio-rs#2331) Thanks to new contributors @compiler-errors, @e-nomem, @WorldSEnder, @Xiami2012, and @tl-rodrigo-gryzinski, as well as @jswrenn and @CAD97, for contributing to this release! [core-0.1.30]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.30 [attrs-0.1.23]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.23 [`tracing-web`]: https://crates.io/crates/tracing-web/ [`reqwest-tracing`]: https://crates.io/crates/reqwest-tracing/
Motivation
Return type errors on instrumented async functions are a bit vague, since the type error originates within the macro itself due to the indirection of additional
async {}
blocks generated in the proc-macro (and due to the way that inference propagates around in Rust).This leads to a pretty difficult to understand error. For example:
results in...
Solution
Installs a fake
return
statement as the first thing that happens in the auto-generated block of an instrumented async function.This causes the coercion machinery within rustc to infer the right return type (matching the the outer function) eagerly, as opposed to after the
async {}
block has been type-checked.This will cause us to both be able to point out the return type span correctly, and properly suggest fixes on the expressions that cause the type mismatch.
After this change, the example code above compiles to: