rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
99.11k stars 12.8k forks source link

ICE: Failed to unify obligation #46397

Closed valff closed 7 years ago

valff commented 7 years ago

Internal compiler error on stable 1.22.1.

Playground

struct A;
struct B;

trait Foo<'a> {
  type Bar;
}

impl<'a> Foo<'a> for B {
  type Bar = A;
}

trait Bar: for<'a> Foo<'a> {
  fn f<F: for<'a> FnOnce(<Self as Foo<'a>>::Bar)>(&mut self, f: F) {}
}

impl Bar for B {}

fn main() {
  B.f(drop);
}

Output:

error: internal compiler error: /checkout/src/librustc/traits/project.rs:1421: Failed to unify obligation `Obligation(predicate=ProjectionTy { substs: Slice([fn(_) {std::mem::drop::<_>}, (<B as Foo<'a>>::Bar,)]), item_def_id: DefId { krate: CrateNum(2), index: DefIndex(0:951) => core[7b69]::ops[0]::function[0]::FnOnce[0]::Output[0] } },depth=0)` with poly_projection `Binder(ProjectionPredicate(ProjectionTy { substs: Slice([fn(_) {std::mem::drop::<_>}, (A,)]), item_def_id: DefId { krate: CrateNum(2), index: DefIndex(0:951) => core[7b69]::ops[0]::function[0]::FnOnce[0]::Output[0] } }, ()))`: Sorts(ExpectedFound { expected: A, found: <B as Foo<'a>>::Bar })
  --> src/main.rs:19:5
   |
19 |   B.f(drop);
   |     ^

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.22.1 (05e2e1c41 2017-11-22) running on x86_64-unknown-linux-gnu

thread 'rustc' panicked at 'Box<Any>', /checkout/src/librustc_errors/lib.rs:439:8
note: Run with `RUST_BACKTRACE=1` for a backtrace.
valff commented 7 years ago

Also possibly a related bug. I'm trying to emulate generic associated types:

Playground

trait Foo<'a> {
  type Bar;
}

trait Bar: for<'a> Foo<'a> {
  fn f<F>(&mut self, f: F)
  where
    F: for<'a> FnOnce(<Self as Foo<'a>>::Bar) -> <Self as Foo<'a>>::Bar,
  {
  }
}

fn main() {}

I confused with the error:

error[E0582]: binding for associated type Output references lifetime 'a, which does not appear in the trait input types

Input and output should be the same. Why output references 'a, while input not?

If this is not a bug, I'll appreciate any hints to workaround this limitation.

michaelwoerister commented 7 years ago

Thanks for the bug report, @valff. Closing as duplicate of https://github.com/rust-lang/rust/issues/43623.