Hello everyone,
While working on a personal project, I ended up fighting the borrow checker for a piece a code that should be totally fine.
The problem is about cloning a struct where a field is an enum where one variant holds a Cow of a u8 slice:
#[derive(Debug)]
enum TestEnum<'a> {
Variant1,
Variant2(Cow<'a, [u8]>),
Variant3,
}
#[derive(Debug)]
struct TestStruct<'a> {
e: TestEnum<'a>,
}
In all the various examples i tried, i noticed that the only way to please the borrow checker is to manually enumerate all the variants in the match statement. If you use a fallback _ or combine various variants in one arm, the borrow checker complains.
Does not work:
impl<'a> TestStruct<'a> {
fn into_owned<'b>(self) -> TestStruct<'b> {
let Self {
e,
} = self;
match e {
TestEnum::Variant2(data) => TestStruct {
e: TestEnum::Variant2(data.into_owned().into()),
},
e @ _ => TestStruct {
e,
},
}
}
}
Does not work:
impl<'a> TestStruct<'a> {
fn into_owned<'b>(self) -> TestStruct<'b> {
let Self {
e,
} = self;
match e {
TestEnum::Variant2(data) => TestStruct {
e: TestEnum::Variant2(data.into_owned().into()),
},
e @ TestEnum::Variant1 | e @ TestEnum::Variant3 => TestStruct {
e,
},
}
}
}
Does work:
impl<'a> TestStruct<'a> {
fn into_owned<'b>(self) -> TestStruct<'b> {
let Self {
e,
} = self;
match e {
TestEnum::Variant2(data) => TestStruct {
e: TestEnum::Variant2(data.into_owned().into()),
},
TestEnum::Variant1 => TestStruct {
e: TestEnum::Variant1,
},
TestEnum::Variant3 => TestStruct {
e: TestEnum::Variant3,
},
}
}
}
I would like to understand better the problem the borrow checker is facing that forbids me to write code like the first example, as that is ideally what i want. Or find a way to not have to enumerate all the variants as in my real project as i have many.
Thank you in advance for your help / explanations!