Skip to content

ICE using HRTB  #58483

Closed
Closed
@weiznich

Description

@weiznich

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions