Simplified code:
struct A(/**/);
trait Foo {}
trait Bar {
fn bar(a: &A) -> impl Foo;
fn baz() -> impl Foo {
let a = A();
Self::bar(&a)
}
}
Error:
error[E0597]: `a` does not live long enough
--> src/lib.rs:10:19
|
9 | let a = A();
| - binding `a` declared here
10 | Self::bar(&a)
| ----------^^-
| | |
| | borrowed value does not live long enough
| argument requires that `a` is borrowed for `'static`
11 | }
| - `a` dropped here while still borrowed
It can be resolved by returning a concrete type that implements Foo
or Box<dyn Foo>
instead of impl Foo
, but I want to keep returning impl Foo
without introducing additional overhead.
Examples that work but I don't want:
struct A(/**/);
trait Foo {}
struct B;
impl Foo for B {}
trait Bar {
fn bar(a: &A) -> B;
fn baz() -> impl Foo {
let a = A();
Self::bar(&a)
}
}
struct A(/**/);
trait Foo {}
trait Bar {
fn bar(a: &A) -> Box<dyn Foo>;
fn baz() -> Box<dyn Foo> {
let a = A();
Self::bar(&a)
}
}
I don't fully understand why it doesn't work, but a workaround is to make the return type an associated type to the trait:
struct A(/**/);
trait Foo {}
trait Bar {
type BarRet: Foo;
fn bar(a: &A) -> Self::BarRet;
fn baz() -> impl Foo {
let a = A();
Self::bar(&a)
}
}