-
Couldn't load subscription status.
- Fork 13.9k
Description
I honestly don't really know how to describe this one.
On stable the uncommented version works as expected, although it yields an ICE on both Beta and Nightly.
On all three release channels, the commented portion of the code fails to resolve
<(PhantomData<A>, PhantomData<B>, PhantomData<C>) as Foo<'a>>::Item as (&'a A, &'a B, &'a C), although they are the same type.
use std::marker::PhantomData;
trait Foo<'a> {
type Item: 'a;
fn consume<F>(self, f: F) where F: Fn(Self::Item);
}
fn get<T>() -> T { unimplemented!() }
impl<'a, A: 'a, B: 'a, C: 'a> Foo<'a> for
(PhantomData<A>, PhantomData<B>, PhantomData<C>) {
type Item = (&'a A, &'a B, &'a C);
fn consume<F>(self, f: F) where F: Fn(Self::Item) {
f(get());
}
}
#[derive(Clone)]
struct Wrap<T> {
foo: T,
}
impl<T: for<'a> Foo<'a>> Wrap<T> {
fn consume<F>(self, f: F) where F: for<'a> Fn(<T as Foo<'a>>::Item) {
self.foo.consume(f);
}
}
fn drop3<A, B, C>(_: A, _: B, _: C) {}
fn main() {
let foo = (PhantomData::<u32>, PhantomData::<f32>, PhantomData::<i32>);
let wrap = Wrap {
foo: foo
};
wrap.clone().consume(|item| {
let (a, b, c) = item;
drop3(a, b, c);
});
// uncomment to break
// wrap.consume(|(a, b, c)| drop3(a, b, c));
}The expected behavior is that I should be able to call wrap.consume() and match on the argument as a tuple. Note that without the indirection through "Wrap", this works as expected. In my program, the wrapper does more work which cannot be stripped away.
playground: http://is.gd/EYtNFj