`Self` lifetimes and static enum methods

I've always wondered if there is a better way of doing the following, specifically if there is some variation of the impl declaration that would allow me to use Self:X(X) instead of XY:X(X). Currently swapping XY with Self results in a somewhat misleading compile err/suggestion. I suppose I could also use the anon lifetime in the impl decl but I notice it makes the aforementioned compiler diagnostic even worse.

#[derive(Debug)]
struct X;
#[derive(Debug)]
struct Y;

struct Union {
    x: X,
    y: Y
}

enum Tag {
    X, Y
}

#[derive(Debug)]
enum XY<'a> {
    X(&'a X),
    Y(&'a Y)
}

impl<'s> XY<'s> {
    fn new(t: Tag, u: &Union) -> XY {
        match t {
            Tag::X => XY::X(&u.x),
            Tag::Y => XY::Y(&u.y),
        }
    }
}

fn main() {
    let u = Union{ x: X, y: Y };
    let xy = XY::new(Tag::X, &u);
    
    dbg!(xy);
}

(Sidenote: Union is a misleading name for a struct that holds both your types simultaneously IMO.)

That's the same as

impl<'s> XY<'s> {
    fn new<'u>(t: Tag, u: &'u Union) -> XY<'u> {

If you want the returned type to be the same as Self, you need the lifetime in the returned type to be 's.

impl<'s> XY<'s> {
    fn new(t: Tag, u: &'s Union) -> Self {
        match t {
            Tag::X => Self::X(&u.x),
            Tag::Y => Self::Y(&u.y),
        }
    }
}

See also.

1 Like

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.