Closed
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
Metadata
Metadata
Assignees
Labels
Area: Lazy normalization (tracking issue: #60471)Area: Trait systemCategory: This is a bug.Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Medium priorityRelevant to the compiler team, which will review and decide on the PR/issue.Performance or correctness regression from one stable version to another.