Why this can cause error [E0495]?


#1

Greeting,

I been working on 50 lines of code for almost a week now, and got stuck because some lifetime problems.

Here is the code I’m currently working on:

use std::io::{ Read, Error as StdIoError, Result as StdIoResult };
use std::result::{ Result as StdResult };
use std::net::SocketAddr;

pub type Result = StdResult<(), ErrorKind>;

#[derive(Debug)]
pub enum ErrorKind {
    ServeFailed(StdIoError),
}

pub trait Client { // This is some methods of the Client
    fn read(&mut self, reader: &Read) -> StdIoResult<usize>;
}

pub trait Handler<'a> { // Handler builds a Client internally and return the borrow of the newly built Client.
    fn client(&mut self) -> &'a mut Client;
}

pub trait Serve {
    fn listening(&self) -> SocketAddr;
    fn serve<'a>(&mut self, handler: &mut Handler<'a>) -> Result;
}

pub struct Server<S>(S);

impl<S: Serve> Server<S> {
    pub fn new(s: S) -> Self {
        Server(s)
    }

    pub fn listening(&self) -> SocketAddr {
        self.0.listening()
    }

    pub fn serve<'a>(&mut self, handler: &mut Handler<'a>) -> Result {
        self.0.serve(handler)
    }
}

Code above can compile without any problem, but the nightmare starts as soon as I try to implement it. For example, when I try to implement Handler like this:

use std::io::{ Result as StdIoResult, Read };

use super::Service::{ Handler as Service, Client as ServiceClient };

pub struct Handler {
    client: Client,
}

pub struct Client {}

impl Handler {
    pub fn new() -> Self {
        Handler{
            client: Client{}, // Build a single Client for test
        }
    }
}

impl<'a> Service<'a> for Handler {
    fn client(&mut self) -> &'a mut ServiceClient {
        &mut self.client
    }
}

impl ServiceClient for Client {
    fn read(&mut self, reader: &Read) -> StdIoResult<usize> {
        Ok(0)
    }
}

Then I got error:

error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
  --> src/infrastructure/server/handler.rs:23:9
   |
23 |         &mut self.client
   |         ^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 22:5...
  --> src/infrastructure/server/handler.rs:22:5
   |
22 | /     fn client(&mut self) -> &'a mut ServiceClient {
23 | |         &mut self.client
24 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/infrastructure/server/handler.rs:23:9
   |
23 |         &mut self.client
   |         ^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 21:1...
  --> src/infrastructure/server/handler.rs:21:1
   |
21 | / impl<'a> Service<'a> for Handler {
22 | |     fn client(&mut self) -> &'a mut ServiceClient {
23 | |         &mut self.client
24 | |     }
25 | | }
   | |_^
note: ...so that expression is assignable (expected &'a mut infrastructure::service::server::Client + 'a, found &mut infrastructure::service::server::Client + 'a)
  --> src/infrastructure/server/handler.rs:23:9
   |
23 |         &mut self.client
   |         ^^^^^^^^^^^^^^^^

I found this is very confusing, as I already defined a lifetime for Handler, then the client method should effected by it (So as &mut self I guess).

// file1
pub trait Handler<'a> {
                  ^^ Defined here

    fn client(&mut self) -> &'a mut Client;
                             ^^ Used here
}

// file2
impl<'a> Service<'a> for Handler {
     ^^          ^^
     |             Applied here 
     |
     \__ Declared here

    fn client(&mut self) -> &'a mut ServiceClient {
        &mut self.client
    }
}

I’m misunderstood something?

BTW: I do ‘solved’ the problem by change:

fn client(&mut self) -> &'a mut Client;

to

fn client(&'a mut self) -> &'a mut Client;
           ^^ Notice this

And it works, not sure why :roll_eyes:


#2
fn client(&mut self) -> &'a mut Client;

This says you have a mutable borrow of self for some (elided lifetime), but returning a mutable borrow of lifetime 'a, where 'a is a lifetime parameter of the entire struct. If this were allowed, then you can imagine the following:

let mut handler = ...;
let first = handler.client(); // get the first mutable borrow. mutable borrow of `self` starts and ends at the method invocation. 
let second = handler.client(); // get the second mutable borrow.  Ditto about the mutable borrow of self

This is illegal because you now have 2 mutable references active at the same time to the same reference.

What should happen here, to ensure borrow rules, is that handler needs to be borrowed mutably for at least as long as the mutable reference you’re returning; that prevents the let second line from compiling because handler cannot be borrowed mutably since it’s still borrowed mutably from the previous line.

When you changed the fn signature to fn client(&'a mut self) -> &'a mut Client, that’s exactly what you’ve done by putting 'a as the lifetime on the mutable borrow of self.

Note that doing this essentially borrows self for its entire life.

Why do you have this:

pub trait Handler<'a> { // Handler builds a Client internally and return the borrow of the newly built Client.
    fn client(&mut self) -> &'a mut Client;
}

rather than:

pub trait Handler { // Handler builds a Client internally and return the borrow of the newly built Client.
    fn client(&mut self) -> &mut Client;
}

#3

LOL, looks like I’m doing something completely wrong here :hushed:

My plan was that the client will build and return a new Client every time when I calls it, I don’t know whether or not this works.

The reason of why I’m using Handler<'a> rather than just Handler is because somewhere down the line, I want to save the borrowed Client to another struct. And I need a lifetime parameter to do that:

use super::service::{ Handler, Client as HandlerClient };

pub struct Client<'a> {
    socket: Option<TcpStream>,
    interest: Ready,
    client: Option<&'a mut HandlerClient>,
                    ^^ Mainly for this
}

impl<'a> Client<'a> {
    ...
    pub fn new(socket: TcpStream, client_handler: &'a mut HandlerClient) -> Self {
        Client{
            socket: Some(socket),
            interest: Ready::readable() | Ready::writable(),
            client: Some(client_handler),
        }
    }
   ...

If I didn’t use Handler<'a>, I will get an error like this:

error[E0623]: lifetime mismatch
  --> src/supplier/mio/server.rs:95:53
   |
77 |         handler: &mut Handler,
   |                  ------------ these two types are declared with different lifetimes...
78 |         listen_socket: &TcpListener,
79 |         clients: &mut Clients,
   |                       -------
...
95 |             let client_token = match clients.insert(Client::new(client_stream, handler.client())) {
   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...but data from `handler` flows into `clients` here

Where the Clients:

use super::service::{ Serve, Handler, Result as ServiceResult, ErrorKind as ServiceErrorKind };
use super::service::{ Client as ServiceClient };
use super::client::Client;

pub type Clients<'a> = slab::Slab<Client<'a>, Token>;

pub struct Server<'a> {
    listener: TcpListener,
    token: Token,
    poll: Poll,
    clients: Clients<'a>,
    events: Events,
}

impl<'a> Server<'a> {
    ... 

    fn handle_server_event(
        handler: &mut Handler, // Here
        listen_socket: &TcpListener,
        clients: &mut Clients, // And there
        poll: &Poll,
        readiness: Ready,
    ) -> StdIoResult<()> {
        ....
            let client_token = match clients.insert(Client::new(client_stream, handler.client())) {
                                           //  Where I actually call the client method ^^
                Ok(id) => id,
                Err(e) => return Err(StdIoError::new(
                    StdIoErrorKind::Other, "Client registration failed")),
            };
        ....

I don’t know how to programming now :confused:


#4

It sounds like you want a Client that’s owned by the Server, and the Client owns a handler. I don’t immediately see why you need references (and therefore lifetimes) at all.

If you want to build a new client each time, you should return a Client (or whatever name) value, not a mutable reference to it.


#5

You know what, I think I figured out how to actually resolve the problem now.

I was going to return the value instead of borrow, but got defeated by a “Sized” problem. The code was like following:

trait Test {
    fn a_method(&self);
}

trait TestBuilder {
    type T: Test;

    fn build(&self) -> Self::T;
}

#[derive(Debug)]
struct ImplTest {}

impl Test for ImplTest {
    fn a_method(&self) {}
}

struct ImplTestBuilder {}

impl ImplTestBuilder {
    pub fn new() -> ImplTestBuilder {
        ImplTestBuilder{}
    }
}

impl TestBuilder for ImplTestBuilder {
    type T = ImplTest;

    fn build(&self) -> Self::T {
        ImplTest{}
    }
}

fn build(builder: &TestBuilder<T=Test>) -> Test {
                                           ^^^^ `Test + 'static` does not have a constant size known at compile-time
    builder.build()
}

fn main() {
    let builder = ImplTestBuilder::new();

    println!("{:?}", build::<ImplTest>(&builder));
}

And just moments ago I thought: Hey why not

fn build<A: Test>(builder: &TestBuilder<T=A>) -> A {
    builder.build()
}

fn main() {
    let builder = ImplTestBuilder::new();

    build::<ImplTest>(&builder);
}

Then, it worked. Oh, I’m so cute, I’m going to rub my face all around my monitor right now :upside_down_face:

Thank you for your help!