Cannot infer type even if specified.

853766d
Opened by jD91mZM2 at 2024-04-17 13:07:59

So, I got the type annotations needed error. I tried everything. It refuses to work.

		let tmp: Result<NamedTempFile, ()> = NamedTempFile::new().map_err::<(), _>(|_: std::io::Error| ());
		let mut tmp: NamedTempFile = tmp?;

Error

image

(please don't tell me the code is stupid. I have a valid reason to ignore the error)

If this is my fault, and not an issue with Rust, apologies for spamming you with yet another false issue :(
I feel horrible

  1. Could you provide the entire function for context? ? especially depends on the signature of the function it is in.

    Peter Atashian at 2017-06-04 15:50:00

  2. It's in a do catch without any variable assigning (do catch { ... };).

    jD91mZM2 at 2017-06-04 15:53:44

  3. Well, the whole function would also make it a little easier to see context in general -- right now, I can't even attempt to run this, which makes it hard to debug.

    Mark Rousskov at 2017-06-04 15:55:03

  4. Oh, I'm sorry. Here it is. Ignore the unfinishedness of it. That's because it is. Unfinished. I'm trying to get rid of the play function and instead use a catch block.

    jD91mZM2 at 2017-06-04 15:59:52

  5. Is there a chance you could produce an example that doesn't rely on external crates? That makes debugging easier. If that's not possible, no worries.

    Mark Rousskov at 2017-06-23 04:16:51

  6. The following code triggers the same error on rustc 1.21.0-nightly (d692a91fa 2017-08-04):

    #![feature(catch_expr)]
    
    pub struct X;
    
    pub fn new_x() -> Result<X, ()> {
        return Ok(X);
    }
    
    fn main() {
        do catch {
            let x: X = new_x()?;
            Ok(())
        };
    }
    

    (https://play.rust-lang.org/?gist=ffd0e7e68eb97486bf742bd63cc9cb2f&version=nightly)

    Amber Sprenkels at 2017-08-05 16:51:10

  7. @Mark-Simulacrum I have no idea why I didn't reply - probably forgot about it. I'm so sorry for being rude.

    @dsprenkels Thanks!!

    Seems like the problem is just in general returning a () error from do catch?

    jD91mZM2 at 2017-08-05 16:55:52

  8. I'm not really sure. The following code fails:

    #![feature(catch_expr)]
    
    fn main() {
        do catch {
            let x: () = Ok(())?;
            Ok(())
        };
    }
    

    But changing the return type does not seem to help. The following code also fails:

    #![feature(catch_expr)]
    
    fn main() {
        do catch {
            let x: () = Ok(())?;
            Ok(42)
        };
    }
    

    Note: the type of x also does not seem to matter.

    Amber Sprenkels at 2017-08-05 17:01:31

  9. To fix it you need to give a type to the catch expression, not the let declaration. The problem is that it cannot infer the error type due to use of From in ?.

    #![feature(catch_expr)]
    
    pub struct X;
    
    pub fn new_x() -> Result<X, ()> {
        return Ok(X);
    }
    
    fn main() {
        let _: Result<_, ()> = do catch {   // <---------
            let x: X = new_x()?;
            Ok(())
        };
    }
    

    The library should be able to instruct the inference engine to consider impl<T> From<T> for T as canonical impl, and choose that in case of ambiguity.

    (And yes, the diagnostic is also an issue.)

    kennytm at 2017-08-05 17:03:46

  10. The updated code will only work on 2018 edition:

    #![feature(try_blocks)]
    
    pub struct X;
    
    pub fn new_x() -> Result<X, ()> {
        return Ok(X);
    }
    
    fn main() {
        try {
            let x: X = new_x()?;
            Ok(())
        };
    }
    

    and result in

    error[E0284]: type annotations required: cannot resolve `<_ as std::ops::Try>::Ok == _`
      --> src/main.rs:11:20
       |
    11 |         let x: X = new_x()?;
       |                    ^^^^^^^^
    

    It should be possible to turn it into the following relatively easily

    error[E0284]: type annotations required: cannot resolve `<_ as std::ops::Try>::Ok == _`
      --> src/main.rs:11:20
       |
    11 |         let x: X = new_x()?;
       |                    ^^^^^^^^
    help: give a type to the `try` block without `_` type argument placeholders:
       |
    10 |     let _: Result<_, _> = try {
       |     ^^^^^^^^^^^^^^^^^^^^^
    

    Esteban Kuber at 2019-08-28 23:18:54

  11. Current output:

    error[E0282]: type annotations needed
      --> src/main.rs:12:9
       |
    12 |         Ok(())
       |         ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
       |
    help: consider specifying the generic arguments
       |
    12 |         Ok::<(), E>(())
       |           +++++++++
    

    After specifying the error type in the tail expression, we get another inference error on the ?:

    error[E0283]: type annotations needed
      --> src/main.rs:11:27
       |
    11 |         let x: X = new_x()?;
       |                           ^ cannot infer type
       |
       = note: multiple `impl`s satisfying `_: FromResidual<Result<Infallible, ()>>` found in the `core` crate:
               - impl<T, E, F> FromResidual<Result<Infallible, E>> for Poll<Option<Result<T, F>>>
                 where F: From<E>;
               - impl<T, E, F> FromResidual<Result<Infallible, E>> for Poll<Result<T, F>>
                 where F: From<E>;
               - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
                 where F: From<E>;
    

    Esteban Kuber at 2023-11-19 18:34:17