Skip to content

Error "cannot infer type" when using '?' in async block + bad diagnostic #63502

Open
@russelltg

Description

@russelltg

This seems related to #42424, except I don't see an obvious workaround like in #42424.

#![feature(async_await)]

use std::io::Error;

fn make_unit() -> Result<(), Error> { 
    Ok(())
}

fn main() {
    let fut = async {
        make_unit()?;
        
        Ok(())
    };
}

Fails with the error

error[E0282]: type annotations needed for `impl std::future::Future`
  --> src/main.rs:11:9
   |
10 |     let fut = async {
   |         --- consider giving `fut` the explicit type `impl std::future::Future`, with the type parameters specified
11 |         make_unit()?;
   |         ^^^^^^^^^^^^ cannot infer type

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=ea7e5f7b6e1637f6a39aee0b8209c99e

First of all, it seems like this shouldn't be an error--it should be able to deduce that the return type is Result<(), io::Error>, but also the diagnostic does not work. If you try to add impl std::future::Future<Output=Result<(), Error>> as a type annotation, it also fails to compile because impl Trait is only allowed as return types and argument types.

Playground link

Activity

added
A-diagnosticsArea: Messages for errors, warnings, and lints
C-bugCategory: This is a bug.
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
requires-nightlyThis issue requires a nightly compiler in some way.
on Aug 12, 2019
added
AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.
on Aug 12, 2019
estebank

estebank commented on Aug 12, 2019

@estebank
Contributor

Opened #63504 for the incorrect suggestion. For the main issue, ? interacts in non-obvious ways with type inference because it does implicit conversion. In this case, because fut doesn't explicitly constraint what the expected type is, rustc doesn't know what Result<(), std::io:Error> should be converted to.

There are other similar tickets filed about these kind of type inference issues: #49391, #38508, #46333, #46680, #48089, #61152, #58517 and #63082.

(larger work around ? tracked in #31436)

cramertj

cramertj commented on Aug 13, 2019

@cramertj
Member

I don't see an obvious workaround

The workaround is this:

use std::io::Error;

fn make_unit() -> Result<(), Error> { 
    Ok(())
}

fn main() {
    let fut = async {
        make_unit()?;
        
        Ok::<(), Error>(())
    };
}
added a commit that references this issue on Aug 14, 2019

Rollup merge of rust-lang#63507 - estebank:type-inference-error, r=Ce…

d2d49d2

21 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsA-inferenceArea: Type inferenceA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.D-papercutDiagnostics: An error or lint that needs small tweaks.D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.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

        Participants

        @nikomatsakis@Centril@estebank@jonas-schievink@programmerjake

        Issue actions

          Error "cannot infer type" when using '?' in async block + bad diagnostic · Issue #63502 · rust-lang/rust