Reputation: 2148
I'm designing a simple type to hold either a Vec<u8>
or a slice (mut or not mut). I'm having problems on lifetime constraints and this time I don't know why there are conflicting requirements:
use std::vec::Vec;
pub enum EncodedPacket<'a> {
Owned(Vec<u8>),
Ref(&'a [u8]),
RefMut(&'a mut [u8])
}
impl<'a> EncodedPacket<'a> {
pub fn new_ref(slice: &'a [u8]) -> EncodedPacket<'a> {
EncodedPacket::Ref(slice)
}
pub fn new_ref_mut(slice: &'a mut [u8]) -> EncodedPacket<'a> {
EncodedPacket::RefMut(slice)
}
pub fn new_owned(vec: Vec<u8>) -> EncodedPacket<'a> {
EncodedPacket::Owned(vec)
}
}
impl<'a> Clone for EncodedPacket<'a> {
fn clone(&self) -> Self {
match self {
EncodedPacket::Owned(vec)=> EncodedPacket::new_owned(*vec),
EncodedPacket::Ref(slice) => EncodedPacket::new_ref(*slice),
EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
}
}
}
Error:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements
--> src/lib.rs:28:35
|
28 | EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
| ^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 24:14...
--> src/lib.rs:24:14
|
24 | fn clone(&self) -> Self {
| ^^^^^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:28:35
|
28 | EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
| ^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 23:6...
--> src/lib.rs:23:6
|
23 | impl<'a> Clone for EncodedPacket<'a> {
| ^^
note: ...so that the expression is assignable
--> src/lib.rs:25:9
|
25 | / match self {
26 | | EncodedPacket::Owned(vec)=> EncodedPacket::new_owned(*vec),
27 | | EncodedPacket::Ref(slice) => EncodedPacket::new_ref(*slice),
28 | | EncodedPacket::RefMut(slice) => EncodedPacket::new_ref_mut(*slice)
29 | | }
| |_________^
= note: expected `EncodedPacket<'a>`
found `EncodedPacket<'_>`
I'm just recreating EncodedPacket
with the same internal things, I don't see why there are conflicting lifetime requirements at all.
Upvotes: 1
Views: 61
Reputation: 42708
You cannot clone a mutable reference. One way of doing this would be to wrap it in Rc
and Rc<RefCell>
:
use std::vec::Vec;
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Clone)]
pub enum EncodedPacket<'a> {
Owned(Vec<u8>),
Ref(Rc<&'a [u8]>),
RefMut(Rc<RefCell<&'a mut [u8]>>)
}
impl<'a> EncodedPacket<'a> {
pub fn new_ref(slice: &'a [u8]) -> EncodedPacket<'a> {
EncodedPacket::Ref(Rc::new(slice))
}
pub fn new_ref_mut(slice: &'a mut [u8]) -> EncodedPacket<'a> {
EncodedPacket::RefMut(Rc::new(RefCell::new(slice)))
}
pub fn new_owned(vec: Vec<u8>) -> EncodedPacket<'a> {
EncodedPacket::Owned(vec)
}
}
Upvotes: 3