Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICE using HRTB #58484

Closed
weiznich opened this issue Feb 15, 2019 · 1 comment
Closed

ICE using HRTB #58484

weiznich opened this issue Feb 15, 2019 · 1 comment

Comments

@weiznich
Copy link
Contributor

Happens on the current beta release and the current nightly release.

Playground link

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);
    };
}

(Playground)

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.

@jonas-schievink
Copy link
Contributor

Closing in favor of #58483

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants