Skip to content

Typecheck error in body of async fn reported at point-of-use #73737

@bdonlan

Description

@bdonlan

I tried this code:

use std::marker::PhantomData;
use std::io;

use tokio; // 0.2.21
use tokio_util; // 0.3.1

use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::TcpStream;
use tokio_util::codec::{Encoder, Decoder};
use futures::stream::StreamExt;

use bytes::{BytesMut, Bytes};

struct Codec;

struct Message<'a> { _p: PhantomData<&'a u8> }

impl Encoder<Message<'static>> for Codec {
    type Error = io::Error;
    
    fn encode(&mut self, item: Message<'static>, dst: &mut BytesMut) -> Result<(), Self::Error> {
        todo!()
    }
}

impl Decoder for Codec {
    type Item = Message<'static>;
    type Error = io::Error;
    
    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
        todo!()
    }
}

async fn forwarder(sock: impl AsyncRead + AsyncWrite + Send + 'static) {
    let sock = Codec.framed(sock);
    let (sink, stream) = sock.split();
    
    stream.map(|msg| msg).forward(sink).await;
}

pub fn assert_send() {
    let s : TcpStream = todo!();
    let _b : Box<dyn Send> = Box::new(forwarder(s));
}

I expected to see this happen: A diagnostic would be issued at the line with the .forward call (or not at all).

Instead, this happened:

error[E0308]: mismatched types
  --> src/lib.rs:44:30
   |
44 |     let _b : Box<dyn Send> = Box::new(forwarder(s));
   |                              ^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected type `std::ops::FnOnce<(std::result::Result<Message<'static>, std::io::Error>,)>`
              found type `std::ops::FnOnce<(std::result::Result<Message<'_>, std::io::Error>,)>`

As you can see, this is reporting a typecheck error occurring in the implementation of forwarder, at the point of use of the async fn (where its implementation should be opaque).

Meta

Tested on the playground with both stable and nightly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions