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

Handle desugaring in impl trait bound suggestion #80211

Merged
merged 1 commit into from
Dec 21, 2020

Conversation

wabain
Copy link
Contributor

@wabain wabain commented Dec 20, 2020

Fixes #79843.

When an associated type of a generic function parameter needs extra bounds, the diagnostics may suggest replacing an impl Trait with a named type parameter so that it can be referenced in the where clause. On stable and nightly, the suggestion can be malformed, for instance transforming:

async fn run(_: &(), foo: impl Foo) -> std::io::Result<()>

Into:

async fn run(_: &, F: Foo(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send
                 ^^^^^^^^         ^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Where we want something like:

async fn run<F: Foo>(_: &(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send
            ^^^^^^^^              ^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^

The problem is that the elided lifetime of &() is added as a generic parameter when desugaring the async fn; the suggestion code sees this as an existing generic parameter and tries to use its span as an anchor to inject F into the parameter list. There doesn't seem to be an entirely principled way to check which generic parameters in the HIR were explicitly named in the source, so this commit changes the heuristics when generating the suggestion to only consider type parameters whose spans are contained within the span of the Generics when determining how to insert an additional type parameter into the declaration. (And to be safe it also excludes parameters whose spans are marked as originating from desugaring, although that doesn't seem to handle this elided lifetime.)

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @petrochenkov (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.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 20, 2020
@petrochenkov
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Dec 20, 2020

📌 Commit b76c9be has been approved by petrochenkov

@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 Dec 20, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Dec 21, 2020
…ion, r=petrochenkov

Handle desugaring in impl trait bound suggestion

Fixes rust-lang#79843.

When an associated type of a generic function parameter needs extra bounds, the diagnostics may suggest replacing an `impl Trait` with a named type parameter so that it can be referenced in the where clause. On stable and nightly, the suggestion can be malformed, for instance transforming:

```rust
async fn run(_: &(), foo: impl Foo) -> std::io::Result<()>
```

Into:

```rust
async fn run(_: &, F: Foo(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send
                 ^^^^^^^^         ^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

Where we want something like:

```rust
async fn run<F: Foo>(_: &(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send
            ^^^^^^^^              ^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

The problem is that the elided lifetime of `&()` is added as a generic parameter when desugaring the async fn; the suggestion code sees this as an existing generic parameter and tries to use its span as an anchor to inject `F` into the parameter list. There doesn't seem to be an entirely principled way to check which generic parameters in the HIR were explicitly named in the source, so this commit changes the heuristics when generating the suggestion to only consider type parameters whose spans are contained within the span of the `Generics` when determining how to insert an additional type parameter into the declaration. (And to be safe it also excludes parameters whose spans are marked as originating from desugaring, although that doesn't seem to handle this elided lifetime.)
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 21, 2020
Rollup of 11 pull requests

Successful merges:

 - rust-lang#80159 (Add array search aliases)
 - rust-lang#80166 (Edit rustc_middle docs)
 - rust-lang#80170 (Fix ICE when lookup method in trait for type that have bound vars)
 - rust-lang#80171 (Edit rustc_middle::ty::TyKind docs)
 - rust-lang#80199 (also const-check FakeRead)
 - rust-lang#80211 (Handle desugaring in impl trait bound suggestion)
 - rust-lang#80236 (Use pointer type in AtomicPtr::swap implementation)
 - rust-lang#80239 (Update Clippy)
 - rust-lang#80240 (make sure installer only creates directories in DESTDIR)
 - rust-lang#80244 (Cleanup markdown span handling)
 - rust-lang#80250 (Minor cleanups in LateResolver)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 2528acb into rust-lang:master Dec 21, 2020
@rustbot rustbot added this to the 1.50.0 milestone Dec 21, 2020
@bors
Copy link
Contributor

bors commented Dec 21, 2020

⌛ Testing commit b76c9be with merge 15d1f81...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
5 participants