Repository: rust
Issue: Specifying one associated type makes Rust forget about the constraint on the other ones
Labels: A-trait-system,E-needs-test,A-closures,A-associated-items,T-compiler,A-impl-trait,C-bug,E-needs-bisection,T-types

I tried this code (which is actually the minimum reproduction I could find, as the bug seems to disappear when I try to reduce it more):

```rust
use std::marker::PhantomData;

pub struct XImpl<T, E, F2, F1>
where
	F2: Fn(E),
{
	f1: F1,
	f2: F2,
	_ghost: PhantomData<(T, E)>,
}

pub trait X<T>: Sized {
	type F1;
	type F2: Fn(Self::E);
	type E;

	fn and<NewF1, NewF1Generator>(self, f: NewF1Generator) -> XImpl<T, Self::E, Self::F2, NewF1>
	where
		NewF1Generator: FnOnce(Self::F1) -> NewF1;
}

impl<T, E, F2, F1> X<T> for XImpl<T, E, F2, F1>
where
	F2: Fn(E),
{
	type E = E;
	type F2 = F2;
	type F1 = F1;

	fn and<NewF1, NewF1Generator>(self, f: NewF1Generator) -> XImpl<T, E, F2, NewF1>
	where
		NewF1Generator: FnOnce(F1) -> NewF1,
	{
		XImpl {
			f1: f(self.f1),
			f2: self.f2,
			_ghost: PhantomData,
		}
	}
}

fn f() -> impl X<()> {
	XImpl {
		f1: || (),
		f2: |()| (),
		_ghost: PhantomData,
	}
}

fn f2() -> impl X<()> {
	f().and(|rb| rb)
}
```

It does compile: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=54e239ced207241c8438dddbc325ef19

If however we specify the value for the associated type `E` in `f` and `f2`, so that code calling `f2()` can depend on knowing the type `E`:
```rust
fn f() -> impl X<(), E = ()> {
	XImpl {
		f1: || (),
		f2: |()| (),
		_ghost: PhantomData,
	}
}

fn f2() -> impl X<(), E = ()> {
	f().and(|rb| rb)
}
```
The compiler seems to forget that any `X::F2` implements `Fn(Self::E)`, and stops compiling: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1e84aea4402bd45da498aace9682b1ad
```
   Compiling playground v0.0.1 (/playground)
error[E0277]: expected a `std::ops::Fn<((),)>` closure, found `<impl X<()> as X<()>>::F2`
  --> src/lib.rs:51:6
   |
51 |     f().and(|rb| rb)
   |         ^^^ expected an `Fn<((),)>` closure, found `<impl X<()> as X<()>>::F2`
   |
   = help: the trait `std::ops::Fn<((),)>` is not implemented for `<impl X<()> as X<()>>::F2`

error[E0277]: expected a `std::ops::Fn<((),)>` closure, found `<impl X<()> as X<()>>::F2`
  --> src/lib.rs:51:2
   |
12 | pub trait X<T>: Sized {
   | --------------------- required by `X`
...
51 |     f().and(|rb| rb)
   |     ^^^^^^^^^^^^^^^^ expected an `Fn<((),)>` closure, found `<impl X<()> as X<()>>::F2`
   |
   = help: the trait `std::ops::Fn<((),)>` is not implemented for `<impl X<()> as X<()>>::F2`

error[E0277]: expected a `std::ops::Fn<((),)>` closure, found `<impl X<()> as X<()>>::F2`
  --> src/lib.rs:50:12
   |
50 | fn f2() -> impl X<(), E = ()> {
   |            ^^^^^^^^^^^^^^^^^^ expected an `Fn<((),)>` closure, found `<impl X<()> as X<()>>::F2`
51 |     f().and(|rb| rb)
   |     ---------------- this returned value is of type `XImpl<(), (), <impl X<()> as X<()>>::F2, <impl X<()> as X<()>>::F1>`
   |
   = help: the trait `std::ops::Fn<((),)>` is not implemented for `<impl X<()> as X<()>>::F2`
   = note: required because of the requirements on the impl of `X<()>` for `XImpl<(), (), <impl X<()> as X<()>>::F2, <impl X<()> as X<()>>::F1>`
   = note: the return type of a function must have a statically known size
```

Note that the bug does not happen if `F2: Fn()` instead of `F2: Fn(E)`:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=266f91f2ba2f0730148c4dea8c3732a4

It does not happen either if `F2: Fn(T)` instead of `F2: Fn(E)`:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e37b04bfdeec2a1ebddc10a4422931e8

### Meta
`rustc --version --verbose`:
```
rustc 1.43.1 (8d69840ab 2020-05-04)
binary: rustc
commit-hash: 8d69840ab92ea7f4d323420088dd8c9775f180cd
commit-date: 2020-05-04
host: x86_64-unknown-linux-gnu
release: 1.43.1
LLVM version: 9.0
```

This also happens on nightly.