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