I’m having trouble using a generic function that takes a generic trait object as a parameter. When I try to call the function, the compiler complains “error: the trait Next
is not implemented for the type &'a mut Next<Type=Type> + 'a
[E0277]”. In my opinion, the Next
trait is object-safe for any parameter Type
, so Next
should be implemented by any &Next<Type>
(by my reading of Huon’s Object-Safety article); is there any way to check that it is object-safe?
Incidentally, I’m having no problem doing pretty much the same thing with an Iterator
, and I don’t know how that is different.
trait Next {
type Type;
fn next(&mut self) -> Option<Self::Type>;
}
struct NextImpl<Type> {
next: Option<Type>,
}
impl<Type> Next for NextImpl<Type> {
type Type = Type;
fn next(&mut self) -> Option<Self::Type> {
let mut ret = None;
std::mem::swap(&mut self.next, &mut ret);
ret
}
}
struct DelegatingNext<'a, Type> {
delegate: &'a mut Next<Type=Type>,
}
impl<'a, Type> Next for DelegatingNext<'a, Type> {
type Type = Type;
fn next(&mut self) -> Option<Self::Type> {
self.delegate.next()
// error: the trait `Next` is not implemented for the type `&'a mut Next<Type=Type> + 'a` [E0277]
// Next::next(&mut self.delegate)
// ^~~~~~~~~~
// error: the trait `Next` is not implemented for the type `&'a mut Next<Type=Type> + 'a` [E0277]
// if (true) {
// next_next1(&mut self.delegate)
// ^~~~~~~~~~
// error: the trait `Next` is not implemented for the type `&'a mut Next<Type=Type> + 'a` [E0277]
// next_next2(&mut self.delegate)
// ^~~~~~~~~~~~~~~~~~
}
}
fn next_next1<'a, NextType: Next + ?Sized>(m: &'a mut NextType) -> Option<NextType::Type> {
m.next()
}
fn next_next2<'a, Type>(m: &'a mut Next<Type=Type>) -> Option<Type> {
m.next()
}
struct DelegatingIterator<'b, T> {
iter: &'b mut Iterator<Item=T>,
}
impl<'b, T> DelegatingIterator<'b, T> {
fn next(&mut self) -> Option<T> {
let iter: &mut Iterator<Item=T> = self.iter;
iterator_next1(iter)
// error: the trait `core::marker::Sized` is not implemented for the type `core::iter::Iterator<Item=T>` [E0277]
// note: `core::iter::Iterator<Item=T>` does not have a constant size known at compile-time
// iterator_next2(iter)
// ^~~~~~~~~~~~~~
// OK
// iterator_next3(iter)
// OK
// iterator_next4(iter)
}
}
fn iterator_next1<'a, T>(iter: &mut Iterator<Item=T>) -> Option<T> {
iter.next()
}
fn iterator_next2<It: Iterator>(iter: &mut It) -> Option<It::Item> {
iter.next()
}
fn iterator_next3<It: Iterator + ?Sized>(iter: &mut It) -> Option<It::Item> {
iter.next()
}
fn iterator_next4<'a, Item>(iter: &mut Iterator<Item=Item>) -> Option<Item> {
iter.next()
}
fn main() {
let mut m = NextImpl {next: Some("hi")};
let mut delegating_model = DelegatingNext {delegate: &mut m};
assert!(Some("hi") == delegating_model.next());
let v: Vec<i32> = vec!(1, 2, 3);
let mut iter = v.iter();
assert_eq!(Some(&1), (DelegatingIterator {iter: &mut iter }).next());
}