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

"help: remove the extra argument" prints too much of the function arguments #106304

Open
jyn514 opened this issue Dec 30, 2022 · 15 comments
Open
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jyn514
Copy link
Member

jyn514 commented Dec 30, 2022

Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d6dfe3d605639255444883813f8376db

enum CargoMessage {
    CompilerArtifact {
        filenames: Vec<String>,
        target: CargoTarget,
        extra: bool,
    }
}

struct CargoTarget {
    crate_types: Vec<String>,
}

pub fn run_cargo() {
    let is_debug_info = |_| true;
    let is_dylib = |_| true;
    let is_check = true;
    let ok = stream_cargo(vec![], &mut |msg| {
        let (filenames, crate_types) = match msg {
            CargoMessage::CompilerArtifact {
                filenames,
                target: CargoTarget { crate_types },
                ..
            } => (filenames, crate_types),
            _ => return,
        };
        for filename in filenames {
            // Skip files like executables
            if !(filename.ends_with(".rlib")
                || filename.ends_with(".lib")
                || filename.ends_with(".a")
                || is_debug_info(&filename)
                || is_dylib(&filename)
                || (is_check && filename.ends_with(".rmeta")))
            {
                continue;
            }
        }
    });
}

pub fn stream_cargo(
    cb: &mut dyn FnMut(CargoMessage),
) -> bool {
  true
}

The current output is:

error[[E0061]](https://doc.rust-lang.org/stable/error-index.html#E0061): this function takes 1 argument but 2 arguments were supplied
  --> src/lib.rs:17:14
   |
17 |     let ok = stream_cargo(vec![], &mut |msg| {
   |              ^^^^^^^^^^^^ ------ argument of type `Vec<_>` unexpected
   |
note: function defined here
  --> src/lib.rs:41:8
   |
41 | pub fn stream_cargo(
   |        ^^^^^^^^^^^^
42 |     cb: &mut dyn FnMut(CargoMessage),
   |     --------------------------------
help: remove the extra argument
   |
17 ~     let ok = stream_cargo(&mut |msg| {
18 +         let (filenames, crate_types) = match msg {
19 +             CargoMessage::CompilerArtifact {
20 +                 filenames,
21 +                 target: CargoTarget { crate_types },
22 +                 ..
23 +             } => (filenames, crate_types),
24 +             _ => return,
25 +         };
26 +         for filename in filenames {
27 +             // Skip files like executables
28 +             if !(filename.ends_with(".rlib")
29 +                 || filename.ends_with(".lib")
30 +                 || filename.ends_with(".a")
31 +                 || is_debug_info(&filename)
32 +                 || is_dylib(&filename)
33 +                 || (is_check && filename.ends_with(".rmeta")))
34 +             {
35 +                 continue;
36 +             }
37 +         }
38 ~     });
   |

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

Ideally the output should look like:

error[E0061]: this function takes 1 argument but 2 arguments were supplied
  --> src/lib.rs:17:14
   |
17 |     let ok = stream_cargo(vec![], &mut |msg| {
   |              ^^^^^^^^^^^^ ------ argument of type `Vec<_>` unexpected
   |
note: function defined here
  --> src/lib.rs:41:8
   |
41 | pub fn stream_cargo(
   |        ^^^^^^^^^^^^
42 |     cb: &mut dyn FnMut(CargoMessage),
   |     --------------------------------
help: remove the extra argument
   |
17 ~     let ok = stream_cargo(&mut |msg| {

Printing the entire body of the closure is ... a bit much 😆

@jyn514 jyn514 added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. labels Dec 30, 2022
@jyn514
Copy link
Member Author

jyn514 commented Dec 30, 2022

@estebank says

Namely it should be a multipart suggestion that only touches the parts that changed, not the whole arg list.

@jyn514 jyn514 added the A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` label Dec 30, 2022
@Ezrashaw
Copy link
Contributor

Ezrashaw commented Jan 1, 2023

@rustbot claim

@jyn514
Copy link
Member Author

jyn514 commented Jan 1, 2023

@Ezrashaw fyi I think @estebank said they'd already started working on this, you might want to ask him how far he's gotten

@Ezrashaw
Copy link
Contributor

Ezrashaw commented Jan 1, 2023

@Ezrashaw fyi I think @estebank said they'd already started working on this, you might want to ask him how far he's gotten

Oh, if he is working on this then that's all fine, not really much point in duplicated work.

@estebank
Copy link
Contributor

estebank commented Jan 1, 2023

@Ezrashaw I did some work on this in #106347, but it only addresses removal of arguments and I would love it if you push it further, like fixing the case where removing multiple trailing arguments leaves behind a trailing comma.

@Ezrashaw
Copy link
Contributor

Ezrashaw commented Jan 1, 2023

@Ezrashaw I did some work on this in #106347, but it only addresses removal of arguments and I would love it if you push it further, like fixing the case where removing multiple trailing arguments leaves behind a trailing comma.

Ok, I'll have a look. Might be a little out of my skill level so if you or @jyn514 could mentor be a bit that would be great. I also haven't looked at your PR yet so I assume that would be a good place to start.

@rustbot claim

@Ezrashaw
Copy link
Contributor

Ezrashaw commented Jan 1, 2023

@estebank It appears you have fixed the trailing commas?

@estebank
Copy link
Contributor

estebank commented Jan 2, 2023

I figured a cheat to get that to work (when removing remove foo, instead of , foo), but there's still a lot to do around the other suggestions, like swapping arguments and adding arguments (those still use the "full span" approach).

@Ezrashaw
Copy link
Contributor

Ezrashaw commented Jan 2, 2023

I've been looking around the relevant bits of compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs and I think I understand it (seems to have aged badly). I really need some mentoring though to understand how to implement it (I'm looking at Error::Missing/ provide the argument).

@estebank
Copy link
Contributor

estebank commented Jan 2, 2023

@Ezrashaw I would try to collect the vec with the suggestions always, and if we detect that it is the straightforward case you emit the targeted suggestion, otherwise you fallback on the current logic. I would look at swap for example: if there're only swapped arg cases, then the logic for coming up with the suggestion would be relatively easy, where you suggest one snippet in the span of the other, as many times as necessary.

@Ezrashaw
Copy link
Contributor

Ezrashaw commented Jan 2, 2023

@estebank And then the old full-span logic can be phased out eventually. I'll be working on this, just slowly because I'm new and on holiday.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Feb 16, 2023
…O8Ki

More accurate spans for arg removal suggestion

Partially address rust-lang#106304.
@WaffleLapkin
Copy link
Member

What is the status here? @Ezrashaw are you still working on this? (also cc #109782 as it changed how commas are worked around again)

@Ezrashaw
Copy link
Contributor

I'm not sure exactly what the status is here. I will work on it at some point, but if someone else wants to then that's all good.

AFAIK, Esteban's PR was expanded a bit to cover some extra cases, however there are still some sub-optimal cases where the full span is used.

@estebank
Copy link
Contributor

We should make sure we have a single test that covers all of the different cases, at the very least to notice when anyone changes the handling of these :)

@est31
Copy link
Member

est31 commented Dec 2, 2023

Just hit a version of this today. For the following snippet:

fn foo(a: (), b: u32) {}

fn main() {
    foo("hi", (), 42u32, ());
}

rustc gives:

error[E0061]: this function takes 2 arguments but 4 arguments were supplied
 --> src/main.rs:4:5
  |
4 |     foo("hi", (), 42u32, ());
  |     ^^^ ----             -- unexpected argument of type `()`
  |         |
  |         unexpected argument of type `&'static str`
  |
note: function defined here
 --> src/main.rs:1:4
  |
1 | fn foo(a: (), b: u32) {}
  |    ^^^ -----  ------
help: remove the extra arguments
  |
4 -     foo("hi", (), 42u32, ());
4 +     foo(, (), 42u32);
  |

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

Not sure why @WaffleLapkin 's #109782 didn't work in this instance...

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 21, 2024
…chenkov

Added more scenarios where comma to be removed in the function arg

This is an attempt to address the problem methion in rust-lang#106304 (comment).

Copy the annotation to explain the fix

If the next Error::Extra ("next") doesn't next to current ("current")

```
fn foo(_: (), _: u32) {}
- foo("current", (), 1u32, "next")
+ foo((), 1u32)
```

If the previous error is not a `Error::Extra`, then do not trim the next comma

```
- foo((), "current", 42u32, "next")
+ foo((), 42u32)
```

Frankly, this is a fix from a test case and may not cover all scenarios
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Oct 21, 2024
Rollup merge of rust-lang#126588 - linyihai:trim-extra-comma, r=petrochenkov

Added more scenarios where comma to be removed in the function arg

This is an attempt to address the problem methion in rust-lang#106304 (comment).

Copy the annotation to explain the fix

If the next Error::Extra ("next") doesn't next to current ("current")

```
fn foo(_: (), _: u32) {}
- foo("current", (), 1u32, "next")
+ foo((), 1u32)
```

If the previous error is not a `Error::Extra`, then do not trim the next comma

```
- foo((), "current", 42u32, "next")
+ foo((), 42u32)
```

Frankly, this is a fix from a test case and may not cover all scenarios
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants