4 ms·
You might be interested to know that the + '_ is inferred from the lifetime of the trait bound it comes from. By default if no lifetime is involved what will be
by estebank 6y ago
You might be interested to know that the + '_ is inferred from the lifetime of the trait bound it comes from. By default if no lifetime is involved what will be inferred is 'static (namely, an owned thing). This means that if you write Box<dyn My trait<'_>> that's enough. If MyTrait doesn't have a lifetime parameter then you might have to write Box<dyn MyTrait + '_> to "flip the inference" from the default, but that only comes up in practice on return types, particularly with impl Trait.
TL;DR: Trait<'a> is actually understood as Trait<'a> + 'a.
- IshKebab 6y agoI don't think so. Try removing the `+ '_` from this code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=97692026a1d749b0e3fba760a2b1759a https://play.rust-lang.org/?version=stable&mode=debug&editio...
- estebank 6y agoOh, you're right. Clearly I'd forgotten the rule. `'a` is not inferred for `dyn Trait<'a>`, it is inferred for `&'a dyn Trait`[1]. [1]: https://github.com/rust-lang/rfcs/blob/master/text/0599-default-object-bound.md https://github.com/rust-lang/rfcs/blob/master/text/0599-defa...
- IshKebab 6y agoAha! Thanks for the link. Why isn't this in the official documentation anywhere? Also I'm going to point people here next time someone tries to claim that Rust is simple.
- estebank 6y agoIf you look at the date that RFC is from before my time. My guess would be that you don't need to know the rule: 95% of the time you don't need to use `+ '_` anywhere (these rules predate the ability to use `'_` to begin with, which is why the RFC talks about `+ 'a` only) because the behavior matches the user's expectation (not having to write `&'a Foo<'a> + 'a`), and, nowadays, when on the 5% of cases you do need 'a the compiler will tell you about it help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound | 14 | fn things(&self) -> Box<dyn Things<'_> + '_> { | ^^^^ Edit: having said that, the docs do explain these rules[1], reachable from the trait object documentation[2], while it seems that The Book doesn't. I'm also noticing that my confusion was likely due to `&'r Ref<'q, Trait>` being interpreted as `&'r Ref<'q, Trait+'q>`, which is behavior that was introduced in a follow up RFC[3]. [1]: https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes https://doc.rust-lang.org/reference/lifetime-elision.html#de... [2]: https://doc.rust-lang.org/reference/types/trait-object.html?highlight=trait,object#trait-object-lifetime-bounds https://doc.rust-lang.org/reference/types/trait-object.html?... [3]: https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md https://github.com/rust-lang/rfcs/blob/master/text/1156-adju...