Closed
Description
Happens on the current beta release and the current nightly release.
Code shared by the playground by clicking on report an issue:
(I'm aware that this code won't work, but rustc should not crash here)
use std::marker::PhantomData;
trait UnRef {
type UnRef;
fn make_owned(self) -> Self::UnRef;
}
trait FamilyLt<'a> {
type Out: Sized;
}
struct RefValue<T>(PhantomData<T>);
impl<'a, T: 'a> FamilyLt<'a> for RefValue<T> {
type Out = &'a T;
}
trait Extract<'a, I>: Sized {
type Raw;
type Out;
fn extract(&'a self) -> Self::Out;
}
struct TupleIndex1;
struct TupleIndex2;
impl<'a, A: 'a, B: 'a> Extract<'a, TupleIndex1> for (A, B) {
type Raw = A;
type Out = &'a A;
fn extract(&'a self) -> &'a A {
&self.0
}
}
impl<'a, A: 'a, B: 'a> Extract<'a, TupleIndex2> for (A, B) {
type Raw = B;
type Out = &'a B;
fn extract(&'a self) -> &'a B {
&self.1
}
}
impl<'a, A: 'static, B: 'static, I1, I2> Extract<'a, (I1, I2)> for (A, B)
where
(A, B): Extract<'a, I1>,
(A, B): Extract<'a, I2>,
{
type Raw = (<(A, B) as Extract<'a, I1>>::Raw, <(A, B) as Extract<'a, I2>>::Raw);
type Out = (<(A, B) as Extract<'a, I1>>::Out, <(A, B) as Extract<'a, I2>>::Out);
fn extract(&'a self) -> Self::Out {
(
<(A, B) as Extract<I1>>::extract(self),
<(A, B) as Extract<I2>>::extract(self),
)
}
}
impl<'a, A> UnRef for &'a A
where
A: Clone,
{
type UnRef = A;
fn make_owned(self) -> A {
self.clone()
}
}
impl<'a, A, B> UnRef for (&'a A, &'a B)
where
A: Clone,
B: Clone,
{
type UnRef = (A, B);
fn make_owned(self) -> (A, B) {
(self.0.clone(), self.1.clone())
}
}
fn generic<T:'static, I, O>(t: T)
where
for<'a> T: Extract<'a, I, Out = O>,
//O: UnRef,
for<'a> <T as Extract<'a, I>>::Out: UnRef,
{
let extracted = t.extract();
let owned = extracted.make_owned();
}
fn main() {
let z = Some(String::from("foo"));
let out = {
let a = (z.clone(), z);
generic::<_, (TupleIndex1, TupleIndex2), _>(a);
};
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0599]: no method named `make_owned` found for type `O` in the current scope
--> src/main.rs:92:27
|
92 | let owned = extracted.make_owned();
| ^^^^^^^^^^
|
= note: the method `make_owned` exists but the following trait bounds were not satisfied:
`&O : UnRef`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `make_owned`, perhaps you need to implement it:
candidate #1: `UnRef`
error[E0277]: the trait bound `for<'a> <_ as Extract<'a, (TupleIndex1, TupleIndex2)>>::Out: UnRef` is not satisfied
--> src/main.rs:99:9
|
99 | generic::<_, (TupleIndex1, TupleIndex2), _>(a);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> UnRef` is not implemented for `<_ as Extract<'a, (TupleIndex1, TupleIndex2)>>::Out`
|
= help: the following implementations were found:
<&'a A as UnRef>
note: required by `generic`
--> src/main.rs:85:1
|
85 | / fn generic<T:'static, I, O>(t: T)
86 | | where
87 | | for<'a> T: Extract<'a, I, Out = O>,
88 | | //O: UnRef,
... |
92 | | let owned = extracted.make_owned();
93 | | }
| |_^
thread 'rustc' panicked at 'assertion failed: !ty.needs_infer() && !ty.has_placeholders()', src/librustc_typeck/check/writeback.rs:119:9
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: aborting due to 2 previous errors
Some errors occurred: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.34.0-nightly (f47ec2ad5 2019-02-14) running on x86_64-unknown-linux-gnu
note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type bin
note: some of the compiler flags provided by cargo are hidden
error: Could not compile `playground`.
To learn more, run the command again with --verbose.