question mark and try! obscure type inference errors

4d271d0
Opened by tinaun at 2024-02-15 02:40:26
use std::num::ParseIntError;

fn run() -> Result<(), ParseIntError> {
    let v = vec![1,2,3];

    let x = "1".parse()?;
    
    println!("{:?}", v[x]);    
    Ok(())
}

fn main() {
    let _ = run();
}

has the confusing error message

error[E0277]: the trait bound `(): std::str::FromStr` is not satisfied
 --> <anon>:6:17
  |
6 |     let x = "1".parse()?;
  |                 ^^^^^ the trait `std::str::FromStr` is not implemented for `()`

error[E0277]: the trait bound `std::vec::Vec<i32>: std::ops::Index<()>` is not satisfied
 --> <anon>:8:22
  |
8 |     println!("{:?}", v[x]);
  |                      ^^^^ the trait `std::ops::Index<()>` is not implemented for `std::vec::Vec<i32>`
  |
  = note: the type `std::vec::Vec<i32>` cannot be indexed by `()`

replacing the ? with .unwrap() gives a nicer explanation of the problem (try! gives the same error message as ?)

error[E0282]: unable to infer enough type information about `_`
 --> <anon>:6:9
  |
6 |     let x = "1".parse().unwrap();
  |         ^ cannot infer type for `_`
  |
  = note: type annotations or generic parameter binding required
  1. Triage: no change.

    Esteban Kuber at 2018-10-15 21:20:14

  2. Current output:

    error[E0277]: the type `[i32]` cannot be indexed by `()`
     --> f71.rs:8:22
      |
    8 |     println!("{:?}", v[x]);    
      |                      ^^^^ slice indices are of type `usize` or ranges of `usize`
      |
      = help: the trait `SliceIndex<[i32]>` is not implemented for `()`
      = help: the following other types implement trait `SliceIndex<T>`:
                <(Bound<usize>, Bound<usize>) as SliceIndex<str>>
                <(Bound<usize>, Bound<usize>) as SliceIndex<[T]>>
      = note: required for `Vec<i32>` to implement `Index<()>`
    
    error[E0277]: the trait bound `(): FromStr` is not satisfied
        --> f71.rs:6:17
         |
    6    |     let x = "1".parse()?;
         |                 ^^^^^ the trait `FromStr` is not implemented for `()`
         |
         = help: the following other types implement trait `FromStr`:
                   bool
                   char
                   isize
                   i8
                   i16
                   i32
                   i64
                   i128
                 and 29 others
    note: required by a bound in `core::str::<impl str>::parse`
        --> /home/gh-estebank/rust/library/core/src/str/mod.rs:2310:21
         |
    2310 |     pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
         |                     ^^^^^^^ required by this bound in `core::str::<impl str>::parse`
    

    Esteban Kuber at 2023-08-14 13:48:02

  3. Cases from #71685

    fn fn2(s: &str) -> Result<(), ()> {
        let s = s.parse().map_err(|_| ())?;
        Ok(())
    }
    
    #![feature(associated_type_bounds)]
    struct S;
    fn fn1<I: IntoIterator<Item: AsRef<S>>>(_iter: I) -> Result<(), ()> {
        Ok(())
    }
    
    async fn fn2(s: &str) -> Result<(), ()> {
        let s = s.parse().map_err(|_| ())?; // <- Spurious type deduced
        fn1(std::iter::once(s)).map_err(|e| ())?;
        Ok(())
    }
    

    Esteban Kuber at 2024-02-15 02:40:26