-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Lifetime mismatch with Option as_mut and map #91292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The diagnostic in question:
It seems that pub fn open(&'_ mut self) -> Option<&'_ mut (dyn SectionData + '_)> I'm not sure off the top of my head what's causing the lifetime mismatch here. It seems like returning |
Here's another fix that works: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7f61519b420c4725dcacddd9a80f69ee Two steps to get there. First, since pub struct SectionMut<'a> {
data: &'a mut Option<Box<dyn SectionData + 'a>>,
} Then in the impl, you don't want to tie the trait object's lifetime to the passed-in lifetime, but to the one on the impl: impl<'a> SectionMut<'a> {
pub fn open(&mut self) -> Option<&mut (dyn SectionData + 'a)> { I'm more and more questioning whether the EDIT: Opened #91302 for that conversation. |
That won't fix the case where the Box is inside of another structure like so: pub struct SectionEntry
{
data: Box<dyn SectionData>,
/* some other private fields in here */
}
pub struct SectionMut<'a>
{
entry: &'a mut SectionEntry
} |
The lifetime can simply be propagated to the inner struct: pub struct SectionEntry<'a> {
data: Box<dyn SectionData + 'a>,
// all the private fields you want
}
pub struct SectionMut<'a> {
entry: &'a mut SectionEntry<'a>,
} |
Why would I want to restrict my dyn trait to a specific lifetime? It shouldn't be. |
It isn't restricting the data behind the With it, you can now use borrowed data in your E.g: struct SectionDataWithReference<'a>(&'a u8);
impl SectionData for SectionDataWithReference<'_> { ... }
let num = 5;
let mut entry = SectionEntry {
data: Box::new(SectionDataWithReference(&num)),
};
let sm = SectionMut {
entry: &mut entry,
}; |
I think you misunderstood my point with SectionEntry. SectionEntry cannot have a lifetime as it's what's stored in a container and passing the lifetime to the container itself is just increasing complexity of the API and has no benefit because the underlying trait in all cases will always be created in a Box not a lifetime based box. EDIT: also adding explicit lifetimes in generics adds a restriction which is that all other parent containers must also keep track of this lifetime. |
With a limited lifetime, everything* above it has to have a lifetime or generic. E.g: If your container is a * Allocators are different the user keeps track of types, not the allocator. |
Yeah I know and that's the problem, restricting dyn traits to have always generic lifetimes in my case renders them completely useless. The original problem here is that if the return type of the function is explicitly |
Consider the following code:
I find it strange that a match statement works but not the map function with as_mut. On the IRC a user found a way to fix it by replacing
Option<&mut dyn SectionData>
withOption<&mut dyn SectionData + 'static>
. Which is also weird considering 'static is supposed to be implicit. What's also weird is this works perfectly with as_ref alone.EDIT: I could track the issue down to
dyn
(again). When removing thedyn SectionData
and replacing it with a concrete struct everything works fine.The text was updated successfully, but these errors were encountered: