I have started to learn Rust. Currently I'm trying to learn how to properly use lifetime annotations and think I have understood the basics quite well. However, I have on several occasions encountered the following structure:
fn<'a> foo(a: &'a str, ...) -> &str + 'a
The str
is not relevant it can be any type really, my question is specifically what &str + 'a
mean (I might not be using it correctly, which is why I'm asking about it) as opposed to &'a str
. As a real world example I have encountered it in this tutorial for async rust where they write:
fn foo_expanded<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a
I'm speculating that it might have to do with that Future
is a trait and not a type, but I have been unable to verify it in any official documentation and have not found any source on what the syntax mean.
First of all, the syntax shown in your post is not allowed.
fn<'a> foo(a: &'a str, ...) -> &str + 'a
There are two reasons:
Otherwise you would get one of the two following errors:
error[E0178]: expected a path on the left-hand side of `+`, not `&str`
--> ./ex_056.rs:11:43
|
11 | fn _get<'a>(ms: &'a MyStruct, s: &str) -> &str + 'a {
| ^^^^^^^^^ help: try adding parentheses: `&(str + 'a)`
or
error[E0404]: expected trait, found builtin type `str`
--> ./ex_056.rs:15:31
|
15 | fn _get2<'a>(s: &'a str) -> &(str + 'a) {
| ^^^ not a trait
Thus it's not valid.
As a crude guess, I imagine that you have been misled by not a complete type but just a trait
object. Since such a notation was allowed in 2015 but now it is deprecated, as you can see in the following warning:
warning: trait objects without an explicit `dyn` are deprecated
--> ./ex_056.rs:15:31
|
15 | fn _get2<'a>(s: &'a str) -> &(str + 'a) {
| ^^^^^^^^ help: use `dyn`: `dyn str + 'a`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
Your first example (&str + 'a
) is not valid. The + 'a
notation can only be applied to a trait.
Your second example: impl Future<Output = u8> + 'a
means that foo_expanded
returns some unknown type that implements the trait Future<Output = u8>
and that this unknown type may contain references with the 'a
lifetime. Therefore you won't be able to use the returned value once the 'a
lifetime expires.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With