How to return a struct with existential types?

Problem background:

I have a Cache, which can load Entity from a dataset by method load_entity (implemented with interior mutability).

I also have a Symbol type, which serves as a placeholder for Entity (loaded by Cache), and I implemented the Symbol with std::Lazy.

But here's the problem: I can't initialize the Symbol from Lazy<&Entity, some_closure_type>. How can I fix it?

#![feature(once_cell)]
use std::lazy::{Lazy};
use std::ops::Deref;

struct Entity;

struct Cache;

impl Cache {
    fn load_entity(&self) -> &Entity {
        todo!()
    }
}


struct EntitySymbol<Pointer>(Pointer);


impl<'cache, Pointer: Deref<Target=&'cache Entity>> EntitySymbol<Pointer> {
    fn new<'name>(name: &'name str, cache: &'cache Cache) -> Self {
        let x = Lazy::<&Entity, _>::new(|| { cache.load_entity() });
        Self(x)
    }
}

playground

The code yields the error:

error[E0308]: mismatched types
  --> src/main.rs:27:14
   |
24 | impl<'cache, Pointer: Deref<Target=&'cache Entity>> EntitySymbol<Pointer> {
   |              ------- this type parameter
25 |     fn new<'name>(name: &'name str, cache: &'cache Cache) -> Self {
26 |         let x = Lazy::<&Entity, _>::new(|| { cache.load_entity() });
   |                                         -------------------------- the found closure
27 |         Self(x)
   |              ^ expected type parameter `Pointer`, found struct `Lazy`
   |
   = note: expected type parameter `Pointer`
                      found struct `Lazy<&Entity, [closure@src/main.rs:26:41: 26:67]>`

Something like this might work for you, depending on the use-case

Rust Playground

1 Like