Change:
//! failure, but rather because the target type `Foo<Y>` is itself just //! not well-formed. Basically we get to assume well-formedness of all //! types involved before considering variance. <ins> //! //! ### Associated types //! //! Any trait with an associated type is invariant with respect to all //! of its inputs. To see why this makes sense, consider what //! subtyping for a trait reference means: //! //!    <T as Trait> <: <U as Trait> //! //! means that if I know that `T as Trait`, //! I also know that `U as //! Trait`. Moreover, if you think of it as //! dictionary passing style, it means that //! a dictionary for `<T as Trait>` is safe //! to use where a dictionary for `<U as //! Trait>` is expected. //! //! The problem is that when you can //! project types out from `<T as Trait>`, //! the relationship to types projected out //! of `<U as Trait>` is completely unknown //! unless `T==U` (see #21726 for more //! details). Making `Trait` invariant //! ensures that this is true. //! //! *Historical note: we used to preserve this invariant another way, //! by tweaking the subtyping rules and requiring that when a type `T` //! appeared as part of a projection, that was considered an invariant //! location, but this version does away with the need for those //! somewhat "special-case-feeling" rules.* //! //! Another related reason is that if we didn't make traits with //! associated types invariant, then projection is no longer a //! function with a single result. Consider: //! //! ``` //! trait Identity { type Out; fn foo(&self); } //! impl<T> Identity for T { type Out = T; ... } //! ``` //! //! Now if I have `<&'static () as Identity>::Out`, this can be //! validly derived as `&'a ()` for any `'a`: //! //!    <&'a () as Identity> <: <&'static () as Identity> //!    if &'static () < : &'a ()   -- Identity is contravariant in Self //!    if 'static : 'a             -- Subtyping rules for relations //! //! This change otoh means that `<'static () as Identity>::Out` is //! always `&'static ()` (which might then be upcast to `'a ()`, //! separately). This was helpful in solving #21750. </ins> use self::VarianceTerm::*; use self::ParamKind::*;

Discussion:
Attempting to compile with and yields the following ICE:
Reduced test case: Still ICEs with The ICE goes away if the on the is changed to a bare instead of a reference.
Slightly different test case: EDIT: Nevermind, it's the same but uses a closure instead of the more general .
I have bisected this issue to rust-lang/rust (from )
A workaround would be simply:
This doesn't help much if you need to call methods that are on the trait (which was on the original code).
cc me
This is blocking collect-rs from compiling.
This is interesting. The culprit is : it registers obligations from implementation's methods into an hybrid parameter environment which has trait's methods in it. In the example given in this issue, when the associate type is projected out, the implementation's method acquires an extra lifetime variable. The trait's method doesn't have it so the lifetime resolution fails in an ICE later on. I'm not sure how to fix that though.
This compiles so at first glance it looks like a viable workaround: But if one tries to really use as an , compiler panics on an assertion failure:
Getting this with some hashing code.

will output something along the lines of: Start hash BYTES: [69, 84, 87, 87, 100, 57, 118, 102, 80, 97, 122, 56, 100, 116, 80, 82, 74, 78, 104, 116, 109, 51, 88, 54, 56, 98, 56, 97, 66, 119, 105, 116, 90, 114, 50, 83, 107, 99, 51, 52, 89, 121, 121, 112, 86, 116, 57, 66, 120, 87, 86, 112, 88, 55, 66, 49, 76, 90, 86, 48, 49, 53, 56, 53, 52, 48, 56, 56, 49, 53, 54, 48, 51] lyra2 finished: CfV9jehQVXsVnx6Vrg5f9VgHVkWeatbrFGxKVz2knfEc Starting argon thread 'certificate::tests::checkcertdiff' panicked at 'index out of bounds: the len is 0 but the index is 31',