use std::collections::HashMap;
use std::hash::Hash;
struct Watchable<'a, K, V, W: Watcher<'a, K, V>> {
    data: HashMap<K, V>,
    watchers: Vec<W>,
}
trait Watcher<'a, K, V> {
    fn before_new(&mut self, key: &'a K, value: &'a V);
}
struct IndexWatcher<'a, I: 'a, V: 'a> {
    data: HashMap<&'a I, &'a V>,
    indexer: fn(&V) -> &I,
}
impl<'a, K, V, I> Watcher<'a, K, V> for IndexWatcher<'a, I, V>
    where I: Eq + Hash
{
    fn before_new(&mut self, key: &'a K, value: &'a V) {
        let index = (self.indexer)(value);
        self.data.insert(index, value);
    }
}
error[E0392]: parameter `'a` is never used
 --> src/main.rs:4:18
  |
4 | struct Watchable<'a, K, V, W: Watcher<'a, K, V>> {
  |                  ^^ unused type parameter
  |
  = help: consider removing `'a` or using a marker such as `std::marker::PhantomData`
Is there any way to remove some lifetime annotation? It seems everything has the same lifetime a.
At first, I didn't put any specific lifetime:
struct IndexWatcher<I, V> {
    data: HashMap<&I, &V>,
    indexer: fn(&V) -> &I,
}
The compiler complained about lifetimes, so I added it:
struct IndexWatcher<'a, I: 'a, V: 'a> {
    data: HashMap<&'a I, &'a V>,
    indexer: fn(&V) -> &I,
}
When I tried to implement the trait without lifetimes:
trait Watcher<K, V> {
    fn before_new(&mut self, key: &K, value: &V);
}
impl<'a, K, V, I> Watcher<K, V> for IndexWatcher<'a, I, V>
    where I: Eq + Hash
{
    fn before_new(&mut self, key: &K, value: &V) {
        let index = (self.indexer)(value);
        self.data.insert(index, value);
    }
}
I got the error:
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
  --> <anon>:18:33
   |
18 |         self.data.insert(index, value);
   |                                 ^^^^^
   |
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> <anon>:17:21
   |
17 |         let index = (self.indexer)(value);
   |                     ^^^^^^^^^^^^^^^^^^^^^
   |
Hence my final version with lifetimes everywhere.
Ideally, I would like to use the trait in Watchable like the following:
impl<K, V, W: Watcher<K, V>> Watchable<K, V, W>
    where K: Eq + Hash {
    fn insert(&mut self, k: K, v: V) -> Option<V> {
        match self.data.entry(k) {
            Occupied(mut occupied) => {
                {
                    let k = occupied.key();
                    let old = occupied.get();
                    for watcher in &mut self.watchers {
                        watcher.before_change(k, &v, old);
                    }
                }
                let old = occupied.insert(v);
                Some(old)
            },
            Vacant(vacant) => {
                {
                    let k = vacant.key();
                    for watcher in &mut self.watchers {
                        watcher.before_new(k, &v);
                    }
                }
                vacant.insert(v);
                None
            }
        }
    }
}
trait Watcher<K, V> {
    fn before_new(&mut self, key: &K, value: &V);
    fn before_change(&mut self, key: &K, value: &V, old: &V);
}
 
     
    