-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Support #[track_caller]
on closures and generators
#87064
Conversation
r? @estebank (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
9ab0cbd
to
9ef105d
Compare
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit 9ef105d74208a3bd339678a75595d9b9b4144aee with merge 0dc3a7eeb0512b0600339922ece622801ae932f0... |
☀️ Try build successful - checks-actions |
Queued 0dc3a7eeb0512b0600339922ece622801ae932f0 with parent ca99e3e, future comparison URL. |
Finished benchmarking try commit (0dc3a7eeb0512b0600339922ece622801ae932f0): comparison url. Summary: This benchmark run did not return any significant changes. If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. @bors rollup=never |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code changes look reasonable.
The language team discussed this in the last meeting, and had several thoughts: A separate feature gate to avoid coupling this would be good -- in particular, while stmt_expr_attributes is unlikely to stabilize, coupling these two seems like a footgun for ourselves in the future. There was some discussion about the implications this has for future stabilization of the Fn traits (Fn, FnMut, FnOnce). I think the primary concern is that making sure that the behavior for closures matches placing @Aaron1011 Can you adjust or clarify for these two points? I think it could be useful to provide a lang-team oriented summary of the PR, rather than one oriented towards compiler team reviewers -- currently there are some details in the PR description that reference (hopefully) internal constructs to the compiler. (Please re-nominate once these are clarified). |
9ef105d
to
95d4fb8
Compare
I've added a feature gate
That's correct. The |
☔ The latest upstream changes (presumably #83484) made this pull request unmergeable. Please resolve the merge conflicts. |
Thanks @Aaron1011! This was discussed in the last lang team meeting and there was general sentiment of moving ahead, but we wanted to see the PR description updated (e.g., it looks like the feature gate being added is not there yet). It might also be helpful to provide a concise description for T-lang FCP. I've tried to do so in this comment -- maybe you can take that as a base and uplift it into the PR description. The main bit is that I've tried to stay out of compiler internal impl details with this summary, which (AFAICT) do not affect the language surface area. Once the description is updated it's likely we can kickoff fcp here. This PR adds support for placing the The attribute is currently "double" feature gated -- both stmt_expr_attributes (preexisting) and closure_track_caller (newly added) must be enabled in order to place these attributes on closures. As the Fn* traits lack a track_caller attribute in their definition, caller information does not propagate when invoking closures through |
@estebank Are there any other changes that you'd like me to make? |
☔ The latest upstream changes (presumably #88865) made this pull request unmergeable. Please resolve the merge conflicts. |
411742f
to
ad01acf
Compare
This PR allows applying a `#[track_caller]` attribute to a closure/generator expression. The attribute as interpreted as applying to the compiler-generated implementation of the corresponding trait method (`FnOnce::call_once`, `FnMut::call_mut`, `Fn::call`, or `Generator::resume`). This feature does not have its own feature gate - however, it requires `#![feature(stmt_expr_attributes)]` in order to actually apply an attribute to a closure or generator. This is implemented in the same way as for functions - an extra location argument is appended to the end of the ABI. For closures, this argument is *not* part of the 'tupled' argument storing the parameters - the final closure argument for `#[track_caller]` closures is no longer a tuple. For direct (monomorphized) calls, the necessary support was already implemented - we just needeed to adjust some assertions around checking the ABI and argument count to take closures into account. For calls through a trait object, more work was needed. When creating a `ReifyShim`, we need to create a shim for the trait method (e.g. `FnOnce::call_mut`) - unlike normal functions, closures are never invoked directly, and always go through a trait method. Additional handling was needed for `InstanceDef::ClosureOnceShim`. In order to pass location information throgh a direct (monomorphized) call to `FnOnce::call_once` on an `FnMut` closure, we need to make `ClosureOnceShim` aware of `#[tracked_caller]`. A new field `track_caller` is added to `ClosureOnceShim` - this is used by `InstanceDef::requires_caller` location, allowing codegen to pass through the extra location argument. Since `ClosureOnceShim.track_caller` is only used by codegen, we end up generating two identical MIR shims - one for `track_caller == true`, and one for `track_caller == false`. However, these two shims are used by the entire crate (i.e. it's two shims total, not two shims per unique closure), so this shouldn't a big deal.
ad01acf
to
94b19fa
Compare
@bors r+ |
📌 Commit 94b19fa has been approved by |
☀️ Test successful - checks-actions |
Tested on commit rust-lang/rust@0132f82. Direct link to PR: <rust-lang/rust#87064> 💔 rls on linux: test-pass → test-fail (cc @Xanewok).
Finished benchmarking commit (0132f82): comparison url. Summary: This change led to large relevant mixed results 🤷 in compiler performance.
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression |
The large majority of performance regressions were quite small and many were historically noisy benchmarks. Looking at the non-noisy benchmarks nothing seemed to stand out as a clear culprit. There were some test cases that indicated large jumps in @estebank @Aaron1011 anything to add here or should we mark as triaged? |
From my end, nothing stands out as interesting. |
add tests for track_caller in closures and generators taken from rust-lang/rust#87064
add tests for track_caller in closures and generators taken from rust-lang#87064
Lang team summary
This PR adds support for placing the
#[track_caller]
attribute on closure and generator expressions. This attribute's addition behaves identically (from a users perspective) to the attribute being placed on the method in impl Fn/FnOnce/FnMut for ... generated by compiler.The attribute is currently "double" feature gated -- both
stmt_expr_attributes
(preexisting) andclosure_track_caller
(newly added) must be enabled in order to place these attributes on closures.As the Fn* traits lack a
#[track_caller]
attribute in their definition, caller information does not propagate when invoking closures through dyn Fn*. There is no limitation that this PR adds in supporting this; it can be added in the future.Implementation details
This is implemented in the same way as for functions - an extra
location argument is appended to the end of the ABI. For closures,
this argument is not part of the 'tupled' argument storing the
parameters - the final closure argument for
#[track_caller]
closuresis no longer a tuple.
For direct (monomorphized) calls, the necessary support was already
implemented - we just needeed to adjust some assertions around checking
the ABI and argument count to take closures into account.
For calls through a trait object, more work was needed.
When creating a
ReifyShim
, we need to create a shimfor the trait method (e.g.
FnOnce::call_mut
) - unlike normalfunctions, closures are never invoked directly, and always go through a
trait method.
Additional handling was needed for
InstanceDef::ClosureOnceShim
. Inorder to pass location information throgh a direct (monomorphized) call
to
FnOnce::call_once
on anFnMut
closure, we need to makeClosureOnceShim
aware of#[tracked_caller]
. A new fieldtrack_caller
is added toClosureOnceShim
- this is used byInstanceDef::requires_caller
location, allowing codegen topass through the extra location argument.
Since
ClosureOnceShim.track_caller
is only used by codegen,we end up generating two identical MIR shims - one for
track_caller == true
, and one fortrack_caller == false
. However,these two shims are used by the entire crate (i.e. it's two shims total,
not two shims per unique closure), so this shouldn't a big deal.