Return and use Self from trait with concrete lifetime

I'm trying to define a Trait that will be used as a builder. It needs a new method that return Self. For other reasons the trait must have a lifetime parameter. Is this context I unable to implement some default methods (error: a does not live long enough on g method). I've created a minimal example to show the problem. Changing the definition 'trait Y' for 'impl X' make the code works.

Is this forum the right place to ask this kind of question?

trait Y<'a>: Sized {
//impl<'a> X<'a> {
    fn new() -> Self;
    //fn new() -> Self {
    //    X{a: &v}
    //}
    
    fn f(&'a self) {
    }
    
    fn g() where Self: 'a {
        let a = Self::new();
        a.f();
    }
}

struct X<'a> {
    a: &'a i32
}

static v: i32 = 10;

fn main() {}

The problem appears to be the &'a self on f() - this lifetime must be a different one than the trait's. Try &self there.

In the real code I need that lifetime... But why this works with struct X?

A call to a.f in g requires that Self implement Y<'inside_g> where 'inside_g is the body of g. It seems there's no guarantee that it does.

I'm getting an ICE trying to ensure this with

    fn g() where for <'r> Self: Y<'r> {
        let a = Self::new();
        a.f();
    }

In case of a struct there's no such problem: you just get a X<'inside_g>.


It feels that mixing methods that reference 'a and ones that don't in a single trait is a bad idea and you'll have to change the approach.

Bug reported https://github.com/rust-lang/rust/issues/27989

1 Like