0

I am still having problems with lifetimes in Rust. I want to use a closure that implements a trait that returns a reference, but I can't figure out how to make the compiler happy.

This is kind of an extension of this question I asked recently which I got working, but now when I add a closure to the program it won't compile.

I think part of my problem is I don't really understand the difference between declaring a lifetime in an impl block, and using for in a where clause.

If I can get it to work using lifetimes in an impl block or lifetimes in a for block, I would be happy, but I would also like to know the difference between them.

Edit: The last 2 links are links to a Rust playground with code I can't get to compile. The first link is also shown below:

pub struct Response<'a>{
    data: &'a str
}

pub enum Action<'a>{
    Next(Response<'a>),
    Done
}

pub trait Handler<'a>: Send + Sync{
    fn handle(&self, res: Response<'a>) -> Action<'a>;
}

impl<'a, T> Handler<'a> for T
where T: Send + Sync + Fn(Response<'a>) -> Action<'a> {
    fn handle(&self, res: Response<'a>) -> Action<'a>{
        (*self)(res)
    }
}

fn main(){
    println!("running");
    do_something_with_handler(|res: Response| -> Action{
        //this closure should implement Handler

        //Action::Done //This compiles if Done is returned instead of Next
        Action::Next(res)
    });
}

pub fn do_something_with_handler<'a, T>(handler: T) where T: Handler<'a> + 'static{
    //do something here
}

// This isn't used in this example, but I want to make sure the trait
// can still be implemented for arbitrary types
struct SomethingElse;

impl<'a> Handler<'a> for SomethingElse{
    fn handle(&self, res: Response<'a>) -> Action<'a>{
        Action::Next(res)
    }
}
Community
  • 1
  • 1
Nathan Fox
  • 582
  • 6
  • 16
  • 2
    A reduction of the problem to its essence: [something with `let f = |s| s; h(f);` does not work](http://is.gd/RIrNxZ), [*but something with `h(|s| s);` does*](http://is.gd/GJHrXc). – Chris Morgan Aug 26 '15 at 23:44
  • 1
    This is a bit vague, could you post the not working code? – Matthieu M. Aug 27 '15 at 06:47
  • @MatthieuM. The not working code was in a link to a Rust Playground, but I edited the question to make this more obvious – Nathan Fox Aug 27 '15 at 11:43
  • 1
    @NathanFuchs: Thanks, in general SO favors content to be *on SO*, because links go stale (especially minified URLs, they have a short expiry date). – Matthieu M. Aug 27 '15 at 12:21
  • Amusingly, removing some type annotations from your second example gets it working: http://is.gd/jswjjB – Rym Aug 27 '15 at 14:16
  • @ChrisMorgan your simplified example seems like a compiler bug. Is there a tracking issue for this in Github? – Nathan Fox Aug 27 '15 at 22:26
  • @Rym Your code doesn't compile anymore. – Adrian Heine Dec 29 '15 at 19:40
  • My guess is it's related to this change: https://github.com/rust-lang/rfcs/pull/1214 – Rym Jan 02 '16 at 23:14

0 Answers0