#![feature(box_syntax)]
use std::sync::Arc;
pub struct Session<K, V> {
key: K,
store: Arc<Box<SessionStore<K, V>>>
}
impl<K, V> Session<K, V> {
fn new(key: K, store: Box<SessionStore<K, V>>) -> Session<K, V> {
Session {
key: key,
store: Arc::new(store)
}
}
}
trait SessionStore<K, V>: Clone + Copy + Sync {
fn select_session(&mut self, key: K) -> Session<K, V> {
Session::new(key, box self.clone())
}
}
fn main() {
println!("Hello, world!");
}
This is the error message.
:13:20: 13:28 error: the trait
SessionStore
cannot be made into an object [E0038]
:13 store: Arc::new(store)
^~~~~~~~
:13:20: 13:28 help: see the detailed explanation for E0038
:13:20: 13:28 note: the trait cannot require thatSelf : Sized
:13 store: Arc::new(store)
^~~~~~~~
:13:20: 13:28 note: the trait cannot require thatSelf : Sized
:13 store: Arc::new(store)
^~~~~~~~
:13:20: 13:28 note: the trait cannot require thatSelf : Sized
:13 store: Arc::new(store)
^~~~~~~~
:13:20: 13:28 note: the trait cannot require thatSelf : Sized
:13 store: Arc::new(store)
^~~~~~~~
:20:27: 20:43 error: the traitSessionStore
cannot be made into an object [E0038]
:20 Session::new(key, box self.clone())
^~~~~~~~~~~~~~~~
:20:27: 20:43 help: see the detailed explanation for E0038
:20:27: 20:43 note: the trait cannot require thatSelf : Sized
:20 Session::new(key, box self.clone())
^~~~~~~~~~~~~~~~
:20:27: 20:43 note: the trait cannot require thatSelf : Sized
:20 Session::new(key, box self.clone())
^~~~~~~~~~~~~~~~
:20:27: 20:43 note: the trait cannot require thatSelf : Sized
:20 Session::new(key, box self.clone())
^~~~~~~~~~~~~~~~
:20:27: 20:43 note: the trait cannot require thatSelf : Sized
:20 Session::new(key, box self.clone())
^~~~~~~~~~~~~~~~
error: aborting due to 2 previous errors
playpen: application terminated with error code 101
I found an explanation of the error and what caused it in this StackOverflow answer. Rust has a concept called object safety that, basically, means that some traits are not suitable for being trait objects (i.e. Box<Trait>
or &Trait
) and it happens that requiring the Self
type of the trait to be Sized
(having a known size at compile time) prevents the trait from being used as a trait object. An other thing is having methods with generics.
Now you may wonder how this applies to your trait. Well, you have never actually specified that it requires Sized
(as in trait MyTrait: Sized
) so it must be something in Sync
, Copy
or Clone
. Looking at their definitions in core
, where they originates (the std
docs happens to hide their requirements), reveals that Sync
is totally independent and doesn't require Sized
, Copy
requires only Clone
, but Clone
does require Sized
. Aha!
So, what can we do to solve this problem? Well, it does depend on how your actual code works, but I think that your best bet may be to only require Clone
for select_session
, like this:
trait SessionStore<K, V>: Sync {
fn select_session(&mut self, key: K) -> Session<K, V> where Self: Clone + 'static {
Session::new(key, box self.clone())
}
}
The trait itself will only require Sync
, but the where clause limits the use of select_session
to only be allowed if Clone
is also implemented. The 'static
bound is required because Box<T>
is Box<T + 'static>
by default and I didn't include the Copy
bound because it wasn't actually use, but you can change it however you want.
An other alternative is maybe to redefine Session
to avoid the boxed trait, but it depends on your actual situation. It could look something like this:
pub struct Session<K, S> {
key: K,
store: Arc<S>
}
impl<K, S: SessionStore<K>> Session<K, S> {
fn new(key: K, store: S) -> Session<K, S> {
Session {
key: key,
store: Arc::new(store)
}
}
}
trait SessionStore<K>: Sync + Clone {
fn select_session(&mut self, key: K) -> Session<K, Self> {
Session::new(key, self.clone())
}
}
There we go! I hope this gives you some help in solving your problem.
thnx, a lot!!!