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

Suggest tuple-parentheses for enum variants #90677

Merged
merged 5 commits into from
Jan 28, 2022

Conversation

bobrippling
Copy link
Contributor

@bobrippling bobrippling commented Nov 7, 2021

This follows on from #86493 / #86481, making the parentheses suggestion. To summarise, given the following code:

fn f() -> Option<(i32, i8)> {
    Some(1, 2)
}

The current output is:

error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
 --> b.rs:2:5
  |
2 |     Some(1, 2)
  |     ^^^^ -  - supplied 2 arguments
  |     |
  |     expected 1 argument

error: aborting due to previous error

For more information about this error, try `rustc --explain E0061`.

With this change, rustc will now suggest parentheses when:

  • The callee is expecting a single tuple argument
  • The number of arguments passed matches the element count in the above tuple
  • The arguments' types match the tuple's fields
error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
 --> b.rs:2:5
  |
2 |     Some(1, 2)
  |     ^^^^ -  - supplied 2 arguments
  |
help: use parentheses to construct a tuple
  |
2 |     Some((1, 2))
  |          +    +

@rust-highfive
Copy link
Collaborator

r? @michaelwoerister

(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 Nov 7, 2021
@bobrippling
Copy link
Contributor Author

I would quite like to also handle normal functions with this change, currently the below doesn't get the tuple suggestion:

fn f(_: (i32, i32)) {
}

pub fn main() {
    f(1, 2);
}

This appears to be because expected_inputs_for_expected_output short-circuits because there's no expectation on the type. I suspect this isn't the right rabbit-hole to be going down though.

@camelid camelid added the A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` label Nov 8, 2021
@camelid
Copy link
Member

camelid commented Nov 8, 2021

Can you add a UI test for this? It would go in src/test/ui/suggestions (or a similar location) and look roughly like this:

fn f() -> Option<(i32, i8)> {
    Some(1, 2)
    //~^ ERROR this enum variant takes 1 argument but 2 arguments were supplied
}

@michaelwoerister
Copy link
Member

r? rust-lang/diagnostics

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@oli-obk
Copy link
Contributor

oli-obk commented Nov 19, 2021

I would quite like to also handle normal functions with this change, currently the below doesn't get the tuple suggestion:

fn f(_: (i32, i32)) {
}

pub fn main() {
    f(1, 2);
}

This appears to be because expected_inputs_for_expected_output short-circuits because there's no expectation on the type. I suspect this isn't the right rabbit-hole to be going down though.

I think we could merge without this change, as it's not that common to have tuple arguments to regular functions. Though I may just be blind here due to my codebases not having this ^^

@bobrippling
Copy link
Contributor Author

I would quite like to also handle normal functions with this change, currently the below doesn't get the tuple suggestion:

fn f(_: (i32, i32)) {
}

pub fn main() {
    f(1, 2);
}

[...]

I think we could merge without this change, as it's not that common to have tuple arguments to regular functions. Though I may just be blind here due to my codebases not having this ^^

Luckily there weren't many adjustments to make to handle this too, although I'd agree with you that it's far less common, at least in codebases I've been through too.

Let me know what you think - rebased + tidied the commits.

@bobrippling bobrippling marked this pull request as ready for review November 20, 2021 12:05
@apiraino apiraino added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Nov 22, 2021
@oli-obk
Copy link
Contributor

oli-obk commented Nov 24, 2021

r? @camelid

@rust-highfive rust-highfive assigned camelid and unassigned oli-obk Nov 24, 2021
@camelid camelid added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 24, 2021
@camelid
Copy link
Member

camelid commented Nov 28, 2021

Left some comments.

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs Outdated Show resolved Hide resolved
compiler/rustc_infer/src/infer/error_reporting/mod.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/fn_ctxt/checks.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/fn_ctxt/checks.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/fn_ctxt/checks.rs Outdated Show resolved Hide resolved
@camelid
Copy link
Member

camelid commented Jan 25, 2022

If you rebase, I can approve this :)

@camelid camelid added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 25, 2022
@bobrippling
Copy link
Contributor Author

No worries, thanks for sticking with me and for the review! I appreciate the guidance :)

@camelid camelid added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 26, 2022
Copy link
Member

@camelid camelid left a comment

Choose a reason for hiding this comment

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

Thanks again!

@camelid
Copy link
Member

camelid commented Jan 27, 2022

@bors r+

@bors
Copy link
Contributor

bors commented Jan 27, 2022

📌 Commit a8bac98 has been approved by camelid

@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 Jan 27, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 28, 2022
…=camelid

Suggest tuple-parentheses for enum variants

This follows on from rust-lang#86493 / rust-lang#86481, making the parentheses suggestion. To summarise, given the following code:

```rust
fn f() -> Option<(i32, i8)> {
    Some(1, 2)
}
```

The current output is:

```
error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
 --> b.rs:2:5
  |
2 |     Some(1, 2)
  |     ^^^^ -  - supplied 2 arguments
  |     |
  |     expected 1 argument

error: aborting due to previous error

For more information about this error, try `rustc --explain E0061`.
```

With this change, `rustc` will now suggest parentheses when:
- The callee is expecting a single tuple argument
- The number of arguments passed matches the element count in the above tuple
- The arguments' types match the tuple's fields

```
error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
 --> b.rs:2:5
  |
2 |     Some(1, 2)
  |     ^^^^ -  - supplied 2 arguments
  |
help: use parentheses to construct a tuple
  |
2 |     Some((1, 2))
  |          +    +
```
@bors
Copy link
Contributor

bors commented Jan 28, 2022

⌛ Testing commit a8bac98 with merge e0e70c0...

@bors
Copy link
Contributor

bors commented Jan 28, 2022

☀️ Test successful - checks-actions
Approved by: camelid
Pushing e0e70c0 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jan 28, 2022
@bors bors merged commit e0e70c0 into rust-lang:master Jan 28, 2022
@rustbot rustbot added this to the 1.60.0 milestone Jan 28, 2022
error = Some((expected_arg_count, supplied_arg_count, "E0061", sugg_unit));

// are we passing elements of a tuple without the tuple parentheses?
let expected_input_tys = if expected_input_tys.is_empty() {
Copy link
Member

Choose a reason for hiding this comment

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

This is essentially duplicated on line 217.

Copy link
Member

Choose a reason for hiding this comment

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

I guess this is because we need it for the call to suggested_tuple_wrap?

Copy link
Member

Choose a reason for hiding this comment

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

I think this whole (pre-existing) function could be cleaned up a lot in general. Like, why does this if (and the one on L217) even need to exist? And why is an empty list used as a sentinel value?

Copy link
Member

Choose a reason for hiding this comment

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

I'm thinking of trying to refactor it myself.

Copy link
Member

Choose a reason for hiding this comment

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

Note that this gets changed quite a bit in #92364

Changing empty list as a sentinel is something orthogonal that I've thought about and worth doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, the empty list led to a lot of confusion during the development of this too - like you say, it being used as a sentinel could be made more explicit (or even removed).

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (e0e70c0): 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

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Feb 7, 2022
… r=camelid

Suggest 1-tuple parentheses on exprs without existing parens

A follow-on from rust-lang#86116, split out from rust-lang#90677.

This alters the suggestion to add a trailing comma to create a 1-tuple - previously we would only apply this if the relevant expression was parenthesised. We now make the suggestion regardless of parentheses, which reduces the fragility of the check (w.r.t formatting).

e.g.
```rust
let a: Option<(i32,)> = Some(3);
```

gets the below suggestion:

```rust
let a: Option<(i32,)> = Some((3,));
//                           ^ ^^
```

This change also improves the suggestion in other ways, such as by only making the suggestion if the types would match after the suggestion is applied and making the suggestion a multipart suggestion.
m-ou-se added a commit to m-ou-se/rust that referenced this pull request Feb 7, 2022
… r=camelid

Suggest 1-tuple parentheses on exprs without existing parens

A follow-on from rust-lang#86116, split out from rust-lang#90677.

This alters the suggestion to add a trailing comma to create a 1-tuple - previously we would only apply this if the relevant expression was parenthesised. We now make the suggestion regardless of parentheses, which reduces the fragility of the check (w.r.t formatting).

e.g.
```rust
let a: Option<(i32,)> = Some(3);
```

gets the below suggestion:

```rust
let a: Option<(i32,)> = Some((3,));
//                           ^ ^^
```

This change also improves the suggestion in other ways, such as by only making the suggestion if the types would match after the suggestion is applied and making the suggestion a multipart suggestion.
m-ou-se added a commit to m-ou-se/rust that referenced this pull request Feb 7, 2022
… r=camelid

Suggest 1-tuple parentheses on exprs without existing parens

A follow-on from rust-lang#86116, split out from rust-lang#90677.

This alters the suggestion to add a trailing comma to create a 1-tuple - previously we would only apply this if the relevant expression was parenthesised. We now make the suggestion regardless of parentheses, which reduces the fragility of the check (w.r.t formatting).

e.g.
```rust
let a: Option<(i32,)> = Some(3);
```

gets the below suggestion:

```rust
let a: Option<(i32,)> = Some((3,));
//                           ^ ^^
```

This change also improves the suggestion in other ways, such as by only making the suggestion if the types would match after the suggestion is applied and making the suggestion a multipart suggestion.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.