Unused lifetime parameter in Enum Type

pub enum Entry<'a, V, O>
where
    V: Vacant<'a> + 'a,
    O: Occupied<'a> + 'a,
{
    Vacant(V),
    Occupied(O),
}
pub trait Vacant<'a> {
    fn insert(self, value: Vec<u8>) -> &'a mut [u8];
}

pub trait Occupied<'a> {
    fn insert(self, value: Vec<u8>) -> &'a mut [u8];
}

fn main() {}
   Compiling playground v0.0.1 (/playground)
error[E0392]: parameter `'a` is never used
 --> src/main.rs:1:16
  |
1 | pub enum Entry<'a, V, O>
  |                ^^ unused parameter
  |
  = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`

For more information about this error, try `rustc --explain E0392`.
error: could not compile `playground` due to previous error

I want create a custom Entry type like in BTreeMap, but left the Vacant/Occupied as a trait bounded lifetime 'a so that users can provide their Entry implementions used in different containers. How can I compile enum type Entry successfully ? If I was using struct type EntryStruct , it would be easy with std::marker::PhantomData<&'a ()> , but I cannot do in enum type .

Just omit the bounds from the trait definition

pub enum Entry<V, O>
{
  Vacant(V),
  Occupied(O),
}

and introduce the bounds on impl blocks


impl<'a, V: Vacant<'a> + 'a, O: Occupied<'a> + 'a> Entry<V, O>
{
  pub fn insert(self, value: Vec<u8>) -> &'a mut [u8]
  {
    match self {
      Entry::Vacant(v) => v.insert(value),
      Entry::Occupied(o) => o.insert(value),
    }
  }
}

Having the bounds on the type definition is sometimes convenient because it prevents you from even constructing values, so produces errors early on instead of later when you try to use the value. If you really wanted the bounds you would have to use phantom data, same as is done in hashmap:

pub struct VacantEntry<'a, V> {..};
pub struct OccupiedEntry<'a, O> {..};

pub enum Entry<'a, V, O>
where
    V: Vacant<'a> + 'a,
    O: Occupied<'a> + 'a,
{
  Vacant(VacantEntry<'a, V>),
  Occupied(OccupiedEntry<'a, O>),
}

I think that the compiler considers this lifetime parameter unused because an instantiation of the trait is not obligated to use it, e.g.

struct X{}
impl<'a> Vacant<'a> for X {}
impl<'a> Occupied<'a> for X {}
type EntryXX = Entry<X, X>;

Here its impls don't mention the lifetime, and X : 'static so that the bound X : 'a is vacuous.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.