Send trait is implemented for a specific lifetime only

I'm getting this error on some code:

  ::: /root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/marker.rs:38:1
   |
38 | / pub unsafe auto trait Send {
39 | |     // empty.
40 | | }
   | |_- trait `std::marker::Send` defined here
   |
   = note: `std::marker::Send` would have to be implemented for the type `async_vpn_socket::SmolSocket<'_, '0, '1>`, for any two lifetimes `'0` and `'1`...
   = note: ...but `std::marker::Send` is actually implemented for the type `async_vpn_socket::SmolSocket<'_, '2, '_>`, for some specific lifetime `'2`

for which I created a minimum verifiable example:

use std::pin::Pin;
use std::future::Future;
use futures::future::{BoxFuture, FutureExt};

struct SmolSocket<'a, 'b: 'a, 'c: 'a + 'b> {
    a: &'a[u8],
    b: &'b[u8],
    c: &'c[u8],
}

pub trait AsyncSocket {
    fn tcp_socket_send<'a>(&'a mut self, data: &'a [u8]) -> Pin<Box<dyn Future<Output=Result<(),()>> + Send + 'a>>;
}

struct B<'a, 'b: 'a, 'c: 'a + 'b>{
    smol_socket: SmolSocket<'a, 'b, 'c>
}


impl<'a, 'b: 'a, 'c: 'a + 'b> AsyncSocket for B<'a, 'b, 'c> {
    fn tcp_socket_send<'d>(&'d mut self, data: &'d [u8]) -> Pin<Box<dyn Future<Output=Result<(),()>> + Send + 'd>> {
        async move {
            let a = &self.smol_socket;
            let b = data;
            Ok(())
        }.boxed()   
    }
}

Playground

However my example compiles without any problems. I couldn't reproduce the error to post here, therefore I'm trying to understand how impl Send works. How is it possible that Send is implemented for async_vpn_socket::SmolSocket<'_, '2, '_>, for some specific lifetime `'2?

I even tried doing

unsafe impl<'a, 'b: 'a, 'c: 'a + 'b> Send for SmolSocket<'a, 'b, 'c> {}

on the original code but it didn't change the error.

Even unsafe impl for any possible lifetime everything won't work...

What is happening?

What's the real definition of async_vpn_socket::SmolSocket? In the provided example, it's obviously Send, since all its fields are Send.

It contains both Interface from smoltcp/ethernet.rs at master · Dirbaio/smoltcp · GitHub and SocketSet from smoltcp/set.rs at master · Dirbaio/smoltcp · GitHub. Both share the same lifetime constraints

Which one do you think is interfeiring into the Send lifetime? By the way, how does the lifetime constraints interfeer with the Send automatic implementation?

I tried to place them into playground but I think there's no way to add github dependencies

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.