Skip to content

Async-related type error messages defy expectations (in span location) #65180

Closed
@nagisa

Description

@nagisa

Consider for example this code (using hyper-0.13.0):

use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, TcpListener};

#[derive(failure::Fail, Debug)]
enum Error {
    #[fail(display="Cannot bind to port {}", _1)]
    CannotBind(#[cause] std::io::Error, u16),
    #[fail(display="Cannot create a server")]
    UncreatableServer(#[cause] hyper::Error),
    #[fail(display="Could not start serving metrics")]
    Unservable(#[cause] hyper::Error),
}

async fn serve_metrics(
    port: u16,
) -> Result<(), Error> {
    let bind_addrs = [
        SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, port, 0, 0)),
        SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, port)),
    ];
    let listener = TcpListener::bind(&bind_addrs[..]).map_err(|e| Error::CannotBind(e, port))?;
    let server = hyper::server::Server::from_tcp(listener).map_err(Error::UncreatableServer)?;

    let server = server.serve(hyper::service::make_service_fn(move |_| {
        async move {
            Ok(hyper::service::service_fn(move |req| {
                async move {
                    hyper::Response::builder()
                        .status(hyper::StatusCode::NOT_FOUND)
                        .body(hyper::Body::empty())
                }
            }))
        }
    }));
    server.await.map_err(Error::Unservable)
}

This code will fail to compile due to types which cannot be fully inferred, with an error like this:

error[E0698]: type inside `async` object must be known in this context
  --> src/lib.rs:23:25
   |
23 |     let server = server.serve(hyper::service::make_service_fn(move |_| {
   |                         ^^^^^ cannot infer type for `ME`
   |
note: the type is part of the `async` object because of this `await`
  --> src/lib.rs:34:5
   |
34 |     server.await.map_err(Error::Unservable)
   |     ^^^^^^^^^^^^

However neither of these spans are anywhere near to the real problem which is the fact that Err variant is not inferred for Ok(hyper::service::service_fn(...)).

Metadata

Metadata

Assignees

Labels

A-async-awaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsAsyncAwait-PolishAsync-await issues that are part of the "polish" areaAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.D-papercutDiagnostics: An error or lint that needs small tweaks.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