Repository navigation
Hint for missing lifetime bound on trait object is missing if type alias is used #103582
Description
Activity
- addedA-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Oct 26, 2022 A similar issue occurs for fields of a struct, but that might be harder to fix.
@rustbot claim
I've run into the same confusing error, but with a function call:
fn create_confirmation_dialog<'a>() -> Option<MessageDialogLayer<'a>> { Some(MessageDialogLayer::new(Color::LightRed, "Error", "Test", Box::new(MessageDialogActionMap::ok()))) }
After searching for a while, I found it was because a
Box<dyn MessageDialogActions<'a>parameter in mynewfunction was implicitly converted intoBox<dyn ... + 'static>. Very confusing for a beginner, especially with the additional compiler notes about variance that don't seem to even be relevant here?pub fn new(..., actions: Box<dyn MessageDialogActions<'a>>) -> Self // error pub fn new(..., actions: Box<dyn MessageDialogActions<'a> + 'a>) -> Self // correct
This is the closest existing issue I found, is this a similar enough case or should I open a new issue?
- addedA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsD-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.Diagnostics: An error or lint that doesn't give enough information about the problem at hand.A-dyn-traitArea: trait objects, vtable layoutArea: trait objects, vtable layout
on Dec 21, 2024 Re. the snippet from the issue description, ideally the compiler would suggest:
- type BoxedGreeter = Box<dyn Greeter>; + type BoxedGreeter<'a> = Box<dyn Greeter + 'a>;
This makes the snippet compile (unless the lint
elided_lifetime_in_pathswas denied) becauseBoxedGreeterin the return type meansBoxGreeter<'_>which "picks up" the anonymous lifetime of theselfparameter.Current output:
error: lifetime may not live long enough --> src/lib.rs:19:9 | 18 | pub fn get(&self, i: usize) -> BoxedGreeter { | - let's call the lifetime of this reference `'1` 19 | Box::new(FixedGreeter(&self.0[i])) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` | help: to declare that the trait object captures data from argument `self`, you can add a lifetime parameter `'a` in the type alias | 5 | type BoxedGreeter<'a> = Box<dyn Greeter + 'a>; | ++++ ++++error: lifetime may not live long enough --> src/lib.rs:17:9 | 16 | pub fn get(&self, i: usize) -> Box<dyn Greeter> { | - let's call the lifetime of this reference `'1` 17 | Box::new(FixedGreeter(&self.0[i])) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` | help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound | 16 | pub fn get(&self, i: usize) -> Box<dyn Greeter + '_> { | ++++

Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a0979812dc1acbc732481dd2d3185637
The current output is:
However, by removing the type alias: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=bfde1cf5c8a72349b117aa21bbd61c3d
The output looks like this, which is much more helpful:
Without the hint, this error isn't very helpful for beginners, as it doesn't do anything to explain why
'1must outlive'static. It would be helpful if a similar hint could be provided when a type alias is used.