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

Add hint to correct Vec::append into Vec::push when the wrong method is used. #87212

Closed
John2143 opened this issue Jul 17, 2021 · 2 comments · Fixed by #120730
Closed

Add hint to correct Vec::append into Vec::push when the wrong method is used. #87212

John2143 opened this issue Jul 17, 2021 · 2 comments · Fixed by #120730
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@John2143
Copy link

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

struct Thing;

fn main() {
    let mut stuff: Vec<Thing> = Vec::new();

    stuff.append(Thing);
}

The current output is:

error[E0308]: mismatched types
 --> src/main.rs:6:18
  |
6 |     stuff.append(Thing);
  |                  ^^^^^ expected `&mut Vec<Thing>`, found struct `Thing`
  |
  = note: expected mutable reference `&mut Vec<Thing>`
                        found struct `Thing`

Ideally the output should look like:

error[E0308]: mismatched types
 --> src/main.rs:6:18
  |
6 |     stuff.append(Thing);
  |                  ^^^^^
  |                  |
  |                  expected `&mut Vec<Thing>`, found struct `Thing`
  |                  help: use `push` to add a single element
  |
  = note: expected mutable reference `&mut Vec<Thing>`
                        found struct `Thing`

There should be some kind of suggestion to use push when a value T is incorrectly append-ed onto a Vec<T>. This likely only trips up newcomers to rust, but I know a fair number of python users who had this as their first error message. There are likely some some other collections this could apply to, but Vec would definitely constitute most of these mistakes.

If nobody is immediately opposed to this change, I would like to try to implement this. I would need some help with where to make this change, but this seems like a fair introduction into editing compiler output.

It may also be helpful to just add a section mentioning push to the append function docs.

@John2143 John2143 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. labels Jul 17, 2021
@SkiFire13
Copy link
Contributor

If it's just changing the documentation you can do it here:

/// Moves all the elements of `other` into `Self`, leaving `other` empty.
///
/// # Panics
///
/// Panics if the number of elements in the vector overflows a `usize`.
///
/// # Examples
///
/// ```
/// let mut vec = vec![1, 2, 3];
/// let mut vec2 = vec![4, 5, 6];
/// vec.append(&mut vec2);
/// assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
/// assert_eq!(vec2, []);
/// ```
#[cfg(not(no_global_oom_handling))]
#[inline]
#[stable(feature = "append", since = "1.4.0")]
pub fn append(&mut self, other: &mut Self) {
unsafe {
self.append_elements(other.as_slice() as _);
other.set_len(0);
}
}

@leonardo-m
Copy link

append is used in Python, so this could be a common enough mistake.

@inquisitivecrystal inquisitivecrystal added C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. labels Jul 18, 2021
@TaKO8Ki TaKO8Ki self-assigned this Mar 14, 2022
@TaKO8Ki TaKO8Ki removed their assignment Jun 1, 2022
@chenyukang chenyukang self-assigned this Feb 13, 2024
oli-obk added a commit to oli-obk/rust that referenced this issue Feb 15, 2024
Provide suggestions through `rustc_confusables` annotations

Help with common API confusion, like asking for `push` when the data structure really has `append`.

```
error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope
  --> $DIR/rustc_confusables_std_cases.rs:17:7
   |
LL |     x.size();
   |       ^^^^
   |
help: you might have meant to use `len`
   |
LL |     x.len();
   |       ~~~
help: there is a method with a similar name
   |
LL |     x.resize();
   |       ~~~~~~
```

Fix rust-lang#59450 (we can open subsequent tickets for specific cases).

Fix rust-lang#108437:

```
error[E0599]: `Option<{integer}>` is not an iterator
   --> f101.rs:3:9
    |
3   |     opt.flat_map(|val| Some(val));
    |         ^^^^^^^^ `Option<{integer}>` is not an iterator
    |
   ::: /home/gh-estebank/rust/library/core/src/option.rs:571:1
    |
571 | pub enum Option<T> {
    | ------------------ doesn't satisfy `Option<{integer}>: Iterator`
    |
    = note: the following trait bounds were not satisfied:
            `Option<{integer}>: Iterator`
            which is required by `&mut Option<{integer}>: Iterator`
help: you might have meant to use `and_then`
    |
3   |     opt.and_then(|val| Some(val));
    |         ~~~~~~~~
```

On type error of method call arguments, look at confusables for suggestion. Fix rust-lang#87212:

```
error[E0308]: mismatched types
    --> f101.rs:8:18
     |
8    |     stuff.append(Thing);
     |           ------ ^^^^^ expected `&mut Vec<Thing>`, found `Thing`
     |           |
     |           arguments to this method are incorrect
     |
     = note: expected mutable reference `&mut Vec<Thing>`
                           found struct `Thing`
note: method defined here
    --> /home/gh-estebank/rust/library/alloc/src/vec/mod.rs:2025:12
     |
2025 |     pub fn append(&mut self, other: &mut Self) {
     |            ^^^^^^
help: you might have meant to use `push`
     |
8    |     stuff.push(Thing);
     |           ~~~~
```
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 17, 2024
Provide suggestions through `rustc_confusables` annotations

Help with common API confusion, like asking for `push` when the data structure really has `append`.

```
error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope
  --> $DIR/rustc_confusables_std_cases.rs:17:7
   |
LL |     x.size();
   |       ^^^^
   |
help: you might have meant to use `len`
   |
LL |     x.len();
   |       ~~~
help: there is a method with a similar name
   |
LL |     x.resize();
   |       ~~~~~~
```

Fix rust-lang#59450 (we can open subsequent tickets for specific cases).

Fix rust-lang#108437:

```
error[E0599]: `Option<{integer}>` is not an iterator
   --> f101.rs:3:9
    |
3   |     opt.flat_map(|val| Some(val));
    |         ^^^^^^^^ `Option<{integer}>` is not an iterator
    |
   ::: /home/gh-estebank/rust/library/core/src/option.rs:571:1
    |
571 | pub enum Option<T> {
    | ------------------ doesn't satisfy `Option<{integer}>: Iterator`
    |
    = note: the following trait bounds were not satisfied:
            `Option<{integer}>: Iterator`
            which is required by `&mut Option<{integer}>: Iterator`
help: you might have meant to use `and_then`
    |
3   |     opt.and_then(|val| Some(val));
    |         ~~~~~~~~
```

On type error of method call arguments, look at confusables for suggestion. Fix rust-lang#87212:

```
error[E0308]: mismatched types
    --> f101.rs:8:18
     |
8    |     stuff.append(Thing);
     |           ------ ^^^^^ expected `&mut Vec<Thing>`, found `Thing`
     |           |
     |           arguments to this method are incorrect
     |
     = note: expected mutable reference `&mut Vec<Thing>`
                           found struct `Thing`
note: method defined here
    --> /home/gh-estebank/rust/library/alloc/src/vec/mod.rs:2025:12
     |
2025 |     pub fn append(&mut self, other: &mut Self) {
     |            ^^^^^^
help: you might have meant to use `push`
     |
8    |     stuff.push(Thing);
     |           ~~~~
```
@bors bors closed this as completed in a28d221 Feb 23, 2024
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 C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
6 participants