-
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
Fix rustdoc rendering of by-value mutable arguments in async fn #76730
Fix rustdoc rendering of by-value mutable arguments in async fn #76730
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @jyn514 (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
Would you like me to prepare any tests for this fix? |
Yes please; add them to |
Welp, looks like this broke something. Not sure why. r? @ecstatic-morse for review or re-assignment |
hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) => { | ||
(ident, true) | ||
} | ||
hir::PatKind::Binding(_, _, ident, _) => (ident, true), |
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.
Actually, I wonder if this would work if you changed it to Unannotated | Mutable
instead; that would avoid changing the logic for ref mut
and I don't think that's valid in function parameters anyway.
hir::PatKind::Binding(_, _, ident, _) => (ident, true), | |
hir::PatKind::Binding(hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable, _, ident, _) => (ident, true), |
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.
and I don't think that's valid in function parameters anyway
It clearly is, see the error message above. So yeah, I'm not sure how to fix this.
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 issue, it seems, is as described in the comments above:
// If `<pattern>` is a simple ident, then it is lowered to a single
// `let <pattern> = <pattern>;` statement as an optimization.
I don't think that this is considered valid:
let mut bad1 = mut bad1;
let ref mut bad2 = ref mut bad2;
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.
This comment a little further down the page elaborates on the reasoning:
rust/compiler/rustc_ast_lowering/src/item.rs
Lines 1129 to 1132 in c101116
if is_simple_parameter { | |
// If this is the simple case, then we only insert one statement that is | |
// `let <pat> = <pat>;`. We re-use the original argument's pattern so that | |
// `HirId`s are densely assigned. |
It seems that not reusing the original argument's pattern will mean that the HirId
s will no longer be densely assigned. I wonder if this is still a pressing concern that must be addressed before considering this PR for merging, the current CI failures aside.
Is setting aside a special case for mutable assignment patterns even a good idea? Sure, it would fix the rendering issue in rustdoc
, but perhaps this change to the AST lowering logic would have other implications elsewhere in the compiler?
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.
It seems that the tests now pass with the suggested change from @jyn514, but this is not yet ready to merge. I'm assuming that although, for example, let ref mut foo = ref mut foo;
is invalid Rust, CI is passing because there are no tests in place to catch this. Once I add tests in place, we can check whether this change is safe or not.
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.
perhaps this change to the AST lowering logic would have other implications elsewhere in the compiler?
Right, this is why I asked for feedback from ecstatic-morse. Rustdoc doesn't really have a way to fix this on its end.
dac7e70
to
12a0c16
Compare
In the simple case we aren't actually inserting fn foo(ref mut x: i32) {
let ref mut y = x;
} i.e. trying to take a mutable reference to I think we don't want this However, we do actually want to preserve the original identifier for rustdoc to use, anytime the pattern is a binding. For P.S. Keeping HirId's dense is just an optimization, not as important as correctness. |
Ok, that makes a lot of sense! So something like this would work: let (ident, is_simple_parameter) = match parameter.pat.kind {
hir::PatKind::Binding(
hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
_,
ident,
_,
) => (ident, true),
hir::PatKind::Binding(_, _, ident, _) => (ident, false), @ebkalderon do you mind implementing that? |
Also, please add a test for both of these cases: |
Yep, I'm on it! |
Ping from triage. @ebkalderon, are you still working on this? |
@ebkalderon do you mind if I take over this PR? It's most of the way there, I'd hate for it to be lost in limbo. |
12a0c16
to
7abe582
Compare
7abe582
to
26b11d6
Compare
@bors r+ rollup Thanks all! |
📌 Commit 96793d3 has been approved by |
…nc-fn, r=tmandry Fix rustdoc rendering of by-value mutable arguments in async fn r? `@jyn514` Fixes rust-lang#76517.
It failed CI: https://github.com/rust-lang-ci/rust/runs/1389783331 @bors: r- |
This should fix `rustdoc` rendering of by-value mutable arguments in `async fn` contexts.
Reusing bindings causes errors later in lowering: ``` error[E0596]: cannot borrow `vec` as mutable, as it is not declared as mutable --> /checkout/src/test/ui/async-await/argument-patterns.rs:12:20 | LL | async fn b(n: u32, ref mut vec: A) { | ^^^^^^^^^^^ | | | cannot borrow as mutable | help: consider changing this to be mutable: `mut vec` ```
96793d3
to
38127ca
Compare
@bors r=tmandry rollup |
📌 Commit 38127ca has been approved by |
Rollup of 7 pull requests Successful merges: - rust-lang#76730 (Fix rustdoc rendering of by-value mutable arguments in async fn) - rust-lang#78836 (Implement destructuring assignment for structs and slices) - rust-lang#78857 (Improve BinaryHeap performance) - rust-lang#78950 (Add asm register information for SPIR-V) - rust-lang#78970 (update rustfmt to v1.4.25) - rust-lang#78972 (Update cargo) - rust-lang#78987 (extend min_const_generics param ty tests) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
r? @jyn514
Fixes #76517.