Repository: rust
Issue: If specialization is involved, associated types are not evaluated even on last crate.
Labels: T-compiler,A-specialization,C-bug,F-specialization

As current specialization does not support returning `default type XX` from default method (so it can be specialized separately), I used a trick to do this.

Playground: https://play.rust-lang.org/?gist=d4bbcd09ae0cd3044d2da9879fc489a0&version=nightly

It compiles, and I expected it to work, but I noticed that it doesn't work because associated type isn't evaluated.



```sh
error[E0369]: binary operation `==` cannot be applied to type `<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out`
  --> src/main.rs:72:5
   |
72 |     assert_eq!(1.op(), (1, 2).op());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: an implementation of `std::cmp::PartialEq` might be missing for `<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0277]: the trait bound `<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out: std::fmt::Debug` is not satisfied
  --> src/main.rs:72:5
   |
72 |     assert_eq!(1.op(), (1, 2).op());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out` cannot be formatted using `:?`; if it is defined in your crate, add `#[derive(Debug)]` or manually implement it
   |
   = help: the trait `std::fmt::Debug` is not implemented for `<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out`
   = note: required because of the requirements on the impl of `std::fmt::Debug` for `&<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out`
   = note: required by `std::fmt::Debug::fmt`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0277]: the trait bound `{integer}: std::cmp::PartialEq<<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out>` is not satisfied
  --> src/main.rs:73:5
   |
73 |     assert_eq!((1, 2).op(), 1.op());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't compare `{integer}` with `<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out`
   |
   = help: the trait `std::cmp::PartialEq<<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out>` is not implemented for `{integer}`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0277]: the trait bound `<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out: std::fmt::Debug` is not satisfied
  --> src/main.rs:73:5
   |
73 |     assert_eq!((1, 2).op(), 1.op());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out` cannot be formatted using `:?`; if it is defined in your crate, add `#[derive(Debug)]` or manually implement it
   |
   = help: the trait `std::fmt::Debug` is not implemented for `<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out`
   = note: required because of the requirements on the impl of `std::fmt::Debug` for `&<<{integer} as Specializer>::Specialized as SpecialzedTrait>::Out`
   = note: required by `std::fmt::Debug::fmt`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error: aborting due to 4 previous errors

error: Could not compile `playground`.

To learn more, run the command again with --verbose.
```

I assume it's not evaluated because rustc thinks it *can* be specialized. But it can't be, because
  - it's last crate
  - it's not public

To make it not specializable, I tried auto trait like https://play.rust-lang.org/?gist=d4bbcd09ae0cd3044d2da9879fc489a0&version=nightly , but it doesn't work because `impl<A, B> !NotTuple for (A, B) {}` implies `!NotTuple` for any struct with `(A, B)`.

```sh
error[E0277]: the trait bound `T: NotTuple` is not satisfied
  --> src\main.rs:80:9
   |
80 | impl<T> AssertAll for T {}
   |         ^^^^^^^^^ the trait `NotTuple` is not implemented for `T`
   |
   = help: consider adding a `where T: NotTuple` bound
   = note: required because of the requirements on the impl of `Specializer` for `T`
   = note: required because of the requirements on the impl of `MyTrait` for `T`

error: aborting due to previous error

error: Could not compile `issue`.

To learn more, run the command again with --verbose.


```