I tried to implement a trait for applying a function to all fields of struct trough an enum Variant
, which should hopefully be always inlined at compilation.
Sadly I am not able to figure out the lifetimes at all. The following code returns:
pub enum Variant<'a> { Str(&'a str), Int(usize) }
impl<'a> From<&'a str> for Variant<'a> {
fn from(value: &'a str) -> Self {
Variant::Str(value)
}
}
pub struct Foo<T> { foo: T }
pub trait Foreach {
fn foreach(&self, fun: impl FnMut(&Variant));
}
impl<'a,T:'a> Foreach for Foo<T> where &'a T: Into<Variant<'a>>{
fn foreach(&'a self, fun: impl FnMut(&Variant<'a>)) {
fun("Foo: ".into());
fun(&(&self.foo).into()); // The variant should never escape this scope. The function should consume it immediately.
}
}
Following error:
error[E0308]: method not compatible with trait
--> src/lib.rs:17:5
|
17 | fn foreach(&'a self, fun: impl FnMut(&Variant<'a>)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected fn pointer `fn(&Foo<T>, _)`
found fn pointer `fn(&'a Foo<T>, _)`
note: the anonymous lifetime #1 defined on the method body at 17:5...
--> src/lib.rs:17:5
|
17 | / fn foreach(&'a self, fun: impl FnMut(&Variant<'a>)) {
18 | | fun("Foo: ".into());
19 | | fun(&(&self.foo).into()); // The variant should never escape this scope. The function should consume it immediately.
20 | | }
| |_____^
note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 16:6
--> src/lib.rs:16:6
|
16 | impl<'a,T:'a> Foreach for Foo<T> where &'a T: Into<Variant<'a>>{
| ^^
error[E0277]: the trait bound `&Variant<'_>: std::convert::From<&str>` is not satisfied
--> src/lib.rs:18:13
|
18 | fun("Foo: ".into());
| ^^^^^^^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `&Variant<'_>`
|
= help: the following implementations were found:
<Variant<'a> as std::convert::From<&'a str>>
= note: `std::convert::From<&str>` is implemented for `&mut Variant<'_>`, but not for `&Variant<'_>`
= note: required because of the requirements on the impl of `std::convert::Into<&Variant<'_>>` for `&str`