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

Type errors use 'expected' and 'found' in a confusing way #78539

Open
Lucretiel opened this issue Oct 29, 2020 · 2 comments
Open

Type errors use 'expected' and 'found' in a confusing way #78539

Lucretiel opened this issue Oct 29, 2020 · 2 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Lucretiel
Copy link
Contributor

Lucretiel commented Oct 29, 2020

Consider this snippet:

#[derive(Debug)]
struct SomeStuff {}

fn main() {
    let vec: Vec<SomeStuff> = vec![SomeStuff {}];

    vec.extend([
        SomeStuff {},
        SomeStuff {},
    ].into_iter());
}

This fails because array.into_iter() collapses to (&array).into_iter(), which provides a slice iterator that emits references, but Vec::extend wants values. This gives the following error:

error[E0271]: type mismatch resolving `<std::slice::Iter<'_, SomeStuff> as std::iter::IntoIterator>::Item == SomeStuff`
 --> src/main.rs:7:9
  |
7 |     vec.extend([
  |         ^^^^^^ expected reference, found struct `SomeStuff`
  |
  = note: expected reference `&SomeStuff`
                found struct `SomeStuff`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0271`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

This error, read naturally, seems to indicate that we have values but are expecting references. This confused a team member of mine today who didn't realize that arrays aren't iterable by-move. To quote:

It seems to want a reference to the items but I can’t see why?
...
Why would extend want a reference to the item? The vec needs ownership of the item at the end of the extend call.

From that perspective, the intuition is that the vec wants values, the array iterator is providing values, so why is the error message reporting that something is expecting a reference?

Additionally, while not strictly speaking part of the diagnostic, the first example in the docs (which is shown inline by rust-analyzer) looks like this:

image

This seems to show a slice being used without issue to extend something without explict copying or cloning. The disconnect is that String: Extend<&char>, but in this particular case it seemed to reinforce the idea that slices may be used to extend something by-move.

Meta

This issue was originally reported in rust 1.46.0:

rustc 1.46.0 (04488afe3 2020-08-24)
binary: rustc
commit-hash: 04488afe34512aa4c33566eb16d8c912a3ae04f9
commit-date: 2020-08-24
host: x86_64-apple-darwin
release: 1.46.0
LLVM version: 10.0

However, I've also reproduced it in current stable:

rustc 1.47.0 (18bf6b4f0 2020-10-07)
binary: rustc
commit-hash: 18bf6b4f01a6feaf7259ba7cdae58031af1b7b39
commit-date: 2020-10-07
host: x86_64-apple-darwin
release: 1.47.0
LLVM version: 11.0

and current nightly:

rustc 1.49.0-nightly (31530e5d1 2020-10-20)
binary: rustc
commit-hash: 31530e5d132ebcc3654baf2e5460599681520af0
commit-date: 2020-10-20
host: x86_64-apple-darwin
release: 1.49.0-nightly
LLVM version: 11.0
@Lucretiel Lucretiel added the C-bug Category: This is a bug. label Oct 29, 2020
@jyn514 jyn514 added A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. labels Oct 29, 2020
@jyn514 jyn514 changed the title Better diagnostics for extend-from-slice failure Type errors use 'expected' and 'found' in a confusing way Oct 29, 2020
@jyn514 jyn514 added the A-inference Area: Type inference label Oct 29, 2020
@SNCPlay42
Copy link
Contributor

Possibly related to #68561. Something like the fix for that, #80828 might be able to fix this (that PR itself doesn't appear to fix this).

@Noratrieb Noratrieb added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Apr 5, 2023
@estebank
Copy link
Contributor

Under 2021 edition, the output is:

error[E0596]: cannot borrow `vec` as mutable, as it is not declared as mutable
  --> src/main.rs:9:5
   |
9  | /     vec.extend([
10 | |         SomeStuff {},
11 | |         SomeStuff {},
12 | |     ].into_iter());
   | |__________________^ cannot borrow as mutable
   |
help: consider changing this to be mutable
   |
7  |     let mut vec: Vec<SomeStuff> = vec![SomeStuff {}];
   |         +++

Under 2018 edition, the output is:

error[E0271]: type mismatch resolving `<Iter<'_, SomeStuff> as IntoIterator>::Item == SomeStuff`
  --> <source>:9:16
   |
9  |       vec.extend([
   |  _________------_^
   | |         |
   | |         required by a bound introduced by this call
10 | |         SomeStuff {},
11 | |         SomeStuff {},
12 | |     ].into_iter());
   | |_________________^ expected `SomeStuff`, found `&SomeStuff`
   |
note: the method call chain might not have had the expected associated types
  --> <source>:12:7
   |
9  |       vec.extend([
   |  ________________-
10 | |         SomeStuff {},
11 | |         SomeStuff {},
12 | |     ].into_iter());
   | |     - ^^^^^^^^^^^ `IntoIterator::Item` is `&SomeStuff` here
   | |_____|
   |       this expression has type `[SomeStuff; 2]`
note: required by a bound in `extend`
  --> /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/iter/traits/collect.rs:377:5

The reversed "expected"/"found" labels are now fixed

@estebank estebank removed C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. labels Aug 23, 2023
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-inference Area: Type inference 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