Skip to content

Type inference reports misleading diagonstics  #69455

Closed
@contrun

Description

@contrun

I tried this code:

fn main() {
    let xs: Vec<u64> = vec![1, 2, 3];
    println!("{}", 23u64 + xs.iter().sum());
}

I expected to see this happen: I expect rust to tell me I should be more precise about 23u64 + xs.iter().sum().

fn main() {
    let xs: Vec<u64> = vec![1, 2, 3];
    
    // This works
    let temp: u64 = xs.iter().sum();
    println!("{}", 23u64 + temp);
    
    // This reports error correctly.
    let test = 23u64 + xs.iter().sum();
    println!("{}", test)
}

Instead, this happened:

error[E0284]: type annotations needed for `std::vec::Vec<u64>`
 --> src/main.rs:3:26
  |
2 |     let xs: Vec<u64> = vec![1, 2, 3];
  |         -- consider giving `xs` the explicit type `std::vec::Vec<u64>`, where the type parameter `u64` is specified
3 |     println!("{}", 23u64 + xs.iter().sum());
  |                          ^ cannot infer type for type `u64`
  |
  = note: cannot resolve `<u64 as std::ops::Add<_>>::Output == _`

error: aborting due to previous error

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

A method call variant of this problem is

pub trait Test<Rhs = Self> {
    type Output;

    fn test(self, rhs: Rhs) -> Self::Output;
}

impl Test<u32> for u64 {
    type Output = u64;

    fn test(self, other: u32) -> u64 { self + (other as u64) }
}

impl Test<u64> for u64 {
    type Output = u64;

    fn test(self, other: u64) -> u64 {
        (self + other) as u64
    }
}


fn main() {
    let xs: Vec<u64> = vec![1, 2, 3];
    println!("{}", 23u64.test(xs.iter().sum()));
}

The only difference is that self.test is a method call, while + is a binary operator.

rustc --version --verbose

rustc 1.43.0-nightly (158127853 2020-03-10)
binary: rustc
commit-hash: 15812785344d913d779d9738fe3cca8de56f71d5
commit-date: 2020-03-10
host: x86_64-unknown-linux-gnu
release: 1.43.0-nightly
LLVM version: 9.0

Related issue: #69214

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions