I'm trying to make a trait that can either retrieve (and return a reference to) a trait object of another trait, or create one (and return a boxed version of it), leaving the choice to the implementor (which means I need to restrict the returned object's lifetime to that of the producer). However, I'm running into errors:
use std::borrow::Borrow;
use std::collections::HashMap;
trait A {
fn foobar(&self) {
println!("!");
}
}
trait ProducerOrContainer {
fn get_a<'a>(&'a self, name: &'a str) -> Option<Box<dyn A + 'a>>;
}
impl<'b, B: Borrow<A>> ProducerOrContainer for HashMap<&'b str, B> {
fn get_a<'a>(&'a self, name: &'a str) -> Option<Box<dyn A + 'a>> {
self.get(name).map(|borrow| Box::new(borrow.borrow()))
}
}
The error is:
error[E0308]: mismatched types
--> src/main.rs:20:9
|
20 | self.get(name).map(|borrow| Box::new(borrow.borrow()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait A, found &A
|
= note: expected type `std::option::Option<std::boxed::Box<dyn A + 'a>>`
found type `std::option::Option<std::boxed::Box<&dyn A>>`
Which puzzles me, because I'd expect a &A
to be an A
too. I've tried to impl<'a> A for &'a A
, but that doesn't help either. Is there any way to fix this?