Reputation: 520
I need to tell the compiler that F
returns something that implements SomeTrait
with the lifetime 'a
:
trait SomeTrait {}
fn foo<P, Q, F>(func: F)
where
Q: SomeTrait,
F: for<'a> Fn(&'a P) -> Q + 'a,
{}
But I get this error:
error[E0261]: use of undeclared lifetime name `'a`
--> src/main.rs:6:33
|
6 | F: for<'a> Fn(&'a P) -> Q + 'a,
| ^^ undeclared lifetime
It is like it doesn't understand Q + 'a
.
Upvotes: 3
Views: 175
Reputation: 5530
Q
is not a trait, it is a type; something like T: Q + 'a
doesn't make sense.
If you try F: for<'a> Fn(&'a P) -> (Q + 'a)
you'll get:
error[E0404]: expected trait, found type parameter `Q`
Your example actually parses like F: (for<'a> Fn(&'a P) -> Q) + 'a
- and it should be obvious why that doesn't work.
Now to:
I need to tell the compiler that
F
returns something that implementsSomeTrait
with lifetime'a
.
Your function can't return different types depending on (passed) lifetimes apart from using those lifetimes for references or generic lifetime parameters. You could write a Rust compiler that simply ignores lifetimes completely, and if the original program was valid it would still do the same thing.
There is no way yet to specify type parameters that take generic parameters, for either lifetimes or types.
If there was, it could look like this:
trait SomeTrait {}
fn foo<P, for<'a> Q<'a>, F>(func: F)
where
for<'a> Q<'a>: SomeTrait,
for<'a> F: Fn(&'a P) -> Q<'a>,
{
}
Upvotes: 4
Reputation: 7579
Lifetimes can only be given to references. Changing the line to this works:
F: for<'a> Fn(&'a P) -> &'a Q
An object by itself does not have a "lifetime" as such - it lives until it is dropped. The borrow checker, however, must be informed of how long the object thst a reference points to lives relative to other referenced objects. That's where lifetimes come in.
Upvotes: 1