Skip to content
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

More robust fallback for use suggestion #94584

Merged
merged 8 commits into from
Mar 15, 2022

Conversation

pnkfelix
Copy link
Member

@pnkfelix pnkfelix commented Mar 4, 2022

Our old way to suggest where to add uses would first look for pre-existing uses in the relevant crate/module, and if there are no uses, it would fallback on trying to use another item as the basis for the suggestion.

But this was fragile, as illustrated in issue #87613

This PR instead identifies span of the first token after any inner attributes, and uses that as the fallback for the use suggestion.

Fix #87613

…uence,

then we just suggest the first legal position where you could inject a use.

To do this, I added `inject_use_span` field to `ModSpans`, and populate it in
parser (it is the span of the first token found after inner attributes, if any).
Then I rewrote the use-suggestion code to utilize it, and threw out some stuff
that is now unnecessary with this in place. (I think the result is easier to
understand.)

Then I added a test of issue 87613.
@rust-highfive
Copy link
Collaborator

Some changes occurred in src/tools/rustfmt.

cc @calebcartwright

@rustbot rustbot added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Mar 4, 2022
@rust-highfive
Copy link
Collaborator

r? @estebank

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 4, 2022
@pnkfelix
Copy link
Member Author

pnkfelix commented Mar 4, 2022

There is still one case that this arguably doesn't handle perfectly, namely this:

/* hey
whazzup */ fn main() {
    Command::new("git outta here");
}

where this still suggests:

2 | whazzup */ use std::process::Command;
  |                                      

(but that suggestion isn't wrong, and I expect that case to be absurdly rare, so I think its reasonable to just go ahead with this approach.)

@rust-log-analyzer

This comment has been minimized.

@calebcartwright
Copy link
Member

calebcartwright commented Mar 4, 2022

re: The rustfmt test failure, I'd think a fmt/tidy run would sort it.

That particular test is a bootstrapping sort for rustfmt which runs rustfmt against itself. Technically that means in this repository that test runs with a slightly different version of rustfmt than what x.py has pinned, so let me know if there's anything strange/conflicting with the formatting there.

Edit: Disregard the above. Believe manual formatting on the subtree is required when editing in tree, in part because of those differences between the two repos in how formatting is executed

@ehuss
Copy link
Contributor

ehuss commented Mar 4, 2022

Nice!

There is a duplicate use placement finder at find_use_placement. Is it feasible to keep the implementations in sync?

Can you also update use_suggestion_placement.rs to remove the FIXME? Essentially something like:

--- a/src/test/ui/resolve/use_suggestion_placement.rs
    b/src/test/ui/resolve/use_suggestion_placement.rs
@@ -10,11  10,7 @@ mod m {
 }

 mod foo {
-    // FIXME: UsePlacementFinder is broken because active attributes are
-    // removed, and thus the `derive` attribute here is not in the AST.
-    // An inert attribute should work, though.
-    // #[derive(Debug)]
-    #[allow(warnings)]
     #[derive(Debug)]
     pub struct Foo;

     // test whether the use suggestion isn't

@pnkfelix
Copy link
Member Author

pnkfelix commented Mar 4, 2022

There is a duplicate use placement finder at find_use_placement. Is it feasible to keep the implementations in sync?

Oh, I don't know! I didn't know about that, but it seems obvious that I should try to do that.

Can you also update use_suggestion_placement.rs to remove the FIXME? Essentially something like:

Will do!

… PR fixes.

(There is another issue, in that the fixed output is not ideally indented, but
that is a pre-existing issue and should not block this PR.)
@rust-log-analyzer

This comment has been minimized.

@pnkfelix
Copy link
Member Author

pnkfelix commented Mar 7, 2022

Nice!

There is a duplicate use placement finder at find_use_placement. Is it feasible to keep the implementations in sync?

Okay, I looked into doing this.

Unfortunately, the code I'm adding here is using the AST, but by the time typeck runs, the AST is long gone.

I don't want to block this PR on figuring out the best way to bring these two parts into sync. (E.g. one could thread down the same span information that I attached to the AST.) I will add a fixme at least, though.

@pnkfelix
Copy link
Member Author

pnkfelix commented Mar 7, 2022

@calebcartwright can you explain this part of the rustfmt formatting error to me? (see below)

Mismatch at src/parse/parser.rs:113:
         let result = catch_unwind(AssertUnwindSafe(|| {
             let mut parser = new_parser_from_file(sess.inner(), path, Some(span));
             match parser.parse_mod(&TokenKind::Eof) {
-                Ok((a,
                     a,

                     ast::ModSpans {
                         inner_span,
                         inner_span,

namely, why on earth is the diff saying that its removing Ok(( from the text?

Was there a line that got removed in the report? I would have perhaps expected to see:

             match parser.parse_mod(&TokenKind::Eof) {
-                Ok((a,
                 Ok((
                     a,
                     i,

…ng it in

sync with the method added in PR 94584.
@calebcartwright
Copy link
Member

It does look a bit odd @pnkfelix, I haven't noticed it before. Worth noting though that these tests are using an internal, rudimentary diff emitter because of where/how the test is constructed, and it's not the same emitter and output for standard end user invocations of rustfmt.

May take a look at this if we get time, but not too concerned given it's only seen by the small audience of those modifying rustfmt source. Here's what an end user would see and what I would expect:

             match parser.parse_mod(&TokenKind::Eof) {
-                Ok((a, i, ast::ModSpans { inner_span, inject_use_span: _ })) => Some((a, i, inner_span)),
                 Ok((
                     a,
                     i,
                     ast::ModSpans {
                         inner_span,
                         inject_use_span: _,
                     },
                 )) => Some((a, i, inner_span)),

Copy link
Contributor

@estebank estebank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me with or without the change to the test.

The follow up work to keep the suggestion span in the hir might be a good first-timer issue.

src/test/ui/proc-macro/amputate-span.rs Show resolved Hide resolved
Comment on lines -17 to -20
// FIXME: UsePlacementFinder is broken because active attributes are
// removed, and thus the `derive` attribute here is not in the AST.
// An inert attribute should work, though.
// #[derive(Debug)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bug has driven me nuts for a really long time, so thanks for fixing it ❤️

@pnkfelix
Copy link
Member Author

@bors r=ekuber rollup

@bors
Copy link
Contributor

bors commented Mar 14, 2022

📌 Commit 8f4c6b0 has been approved by ekuber

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 14, 2022
@pnkfelix
Copy link
Member Author

The follow up work to keep the suggestion span in the hir might be a good first-timer issue.

Filed as #94941

@bors
Copy link
Contributor

bors commented Mar 15, 2022

⌛ Testing commit 8f4c6b0 with merge 95561b3...

@bors
Copy link
Contributor

bors commented Mar 15, 2022

☀️ Test successful - checks-actions
Approved by: ekuber
Pushing 95561b3 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Mar 15, 2022
@bors bors merged commit 95561b3 into rust-lang:master Mar 15, 2022
@rustbot rustbot added this to the 1.61.0 milestone Mar 15, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (95561b3): comparison url.

Summary: This benchmark run did not return any relevant results.

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

calebcartwright pushed a commit to calebcartwright/rust that referenced this pull request Mar 30, 2022
… r=ekuber

More robust fallback for `use` suggestion

Our old way to suggest where to add `use`s would first look for pre-existing `use`s in the relevant crate/module, and if there are *no* uses, it would fallback on trying to use another item as the basis for the suggestion.

But this was fragile, as illustrated in issue rust-lang#87613

This PR instead identifies span of the first token after any inner attributes, and uses *that* as the fallback for the `use` suggestion.

Fix rust-lang#87613
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Apr 14, 2022
…cement, r=pnkfelix

remove find_use_placement

A more robust solution to finding where to place use suggestions was added in rust-lang#94584.
The algorithm uses the AST to find the span for the suggestion so we pass this span
down to the HIR during lowering and use it instead of calling `find_use_placement`

Fixes rust-lang#94941
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Apr 15, 2022
…cement, r=pnkfelix

remove find_use_placement

A more robust solution to finding where to place use suggestions was added in rust-lang#94584.
The algorithm uses the AST to find the span for the suggestion so we pass this span
down to the HIR during lowering and use it instead of calling `find_use_placement`

Fixes rust-lang#94941
RalfJung added a commit to RalfJung/rust that referenced this pull request Apr 15, 2022
…cement, r=pnkfelix

remove find_use_placement

A more robust solution to finding where to place use suggestions was added in rust-lang#94584.
The algorithm uses the AST to find the span for the suggestion so we pass this span
down to the HIR during lowering and use it instead of calling `find_use_placement`

Fixes rust-lang#94941
RalfJung added a commit to RalfJung/rust that referenced this pull request Apr 15, 2022
…cement, r=pnkfelix

remove find_use_placement

A more robust solution to finding where to place use suggestions was added in rust-lang#94584.
The algorithm uses the AST to find the span for the suggestion so we pass this span
down to the HIR during lowering and use it instead of calling `find_use_placement`

Fixes rust-lang#94941
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Apr 15, 2022
…cement, r=pnkfelix

remove find_use_placement

A more robust solution to finding where to place use suggestions was added in rust-lang#94584.
The algorithm uses the AST to find the span for the suggestion so we pass this span
down to the HIR during lowering and use it instead of calling `find_use_placement`

Fixes rust-lang#94941
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Strange async use ...; compiler suggestion
10 participants