Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --issue appeared when going from 1 -2, was able to fix it by adding 3 <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
I've only skimmed the code but this is very likely due to the diagnostic method constructing a projection, more precisely an , with created for the trait item, not the associated type (with (pseudo) ), so we're missing the own generic arguments for the GAT.

Discussion:
#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] <ins> #![feature(assert_matches)] </ins> #![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)]

use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP}; use rustc_target::spec::abi; <ins> use std::assert_matches::debug_assert_matches; </ins> use std::borrow::Cow; use std::iter;

}; let origin = TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }; <del> let trait_def_id = proj.trait_def_id(self.tcx); </del> // Make `Self` be equivalent to the type of the call chain // expression we're looking at now, so that we can tell what // for example `Iterator::Item` is at this point in the chain. <del> let args = GenericArgs::for_item(self.tcx, trait_def_id, |param, _| { match param.kind { ty::GenericParamDefKind::Type { .. } => { if param.index == 0 { return prev_ty.into(); } } ty::GenericParamDefKind::Lifetime | ty::GenericParamDefKind::Const { .. } => {} </del> <ins> let args = GenericArgs::for_item(self.tcx, proj.def_id, |param, _| { if param.index == 0 { debug_assert_matches!(param.kind, ty::GenericParamDefKind::Type { .. }); return prev_ty.into(); </ins> } self.var_for_def(span, param) }); // This will hold the resolved type of the associated type, if the // current expression implements the trait that associated type is // in. For example, this would be what `Iterator::Item` is here. <del> let ty_var = self.infcx.next_ty_var(origin); </del> <ins> let ty = self.infcx.next_ty_var(origin); </ins> // This corresponds to `<ExprTy as Iterator>::Item = _`. let projection = ty::Binder::dummy(ty::PredicateKind::Clause( ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty: ty::AliasTy::new(self.tcx, proj.def_id, args), <del> term: ty_var.into(), </del> <ins> term: ty.into(), </ins> }), )); let body_def_id = self.tcx.hir().enclosing_body_owner(body_id);

param_env, projection, )); <del> if ocx.select_where_possible().is_empty() { // `ty_var` now holds the type that `Item` is for `ExprTy`. let ty_var = self.resolve_vars_if_possible(ty_var); assocs_in_this_method.push(Some((span, (proj.def_id, ty_var)))); </del> <ins> if ocx.select_where_possible().is_empty() && let ty = self.resolve_vars_if_possible(ty) && !ty.is_ty_var() { assocs_in_this_method.push(Some((span, (proj.def_id, ty)))); </ins> } else { // `<ExprTy as Iterator>` didn't select, so likely we've // reached the end of the iterator chain, like the originating <del> // `Vec<_>`. </del> <ins> // `Vec<_>` or the `ty` couldn't be determined. </ins> // Keep the space consistent for later zipping. assocs_in_this_method.push(None); }

<ins> // Regression test for issue #121898. trait Base { type Base<B>; } trait Functor<A>: Base { fn fmap<B>(self, f: impl Fn(A) -> B) -> Self::Base<B> where Self::Base<B>: Functor<B>; } fn fmap2<T, A, B, C>(input: T, f1: impl Fn(A) -> B, f2: impl Fn(B) -> C) -> T::Base<C> where T: Functor<A>, T::Base<B>: Functor<B, Base<C> = T::Base<C>>, { input.fmap(f1).fmap(f2) //~^ ERROR the trait bound `<T as Base>::Base<C>: Functor<C>` is not satisfied } fn main() {} </ins>

<ins> error[E0277]: the trait bound `<T as Base>::Base<C>: Functor<C>` is not satisfied --> $DIR/method-chain-gats.rs:18:20 | LL |     input.fmap(f1).fmap(f2) |                    ^^^^ the trait `Functor<C>` is not implemented for `<T as Base>::Base<C>` | note: the method call chain might not have had the expected associated types --> $DIR/method-chain-gats.rs:13:29 | LL | fn fmap2<T, A, B, C>(input: T, f1: impl Fn(A) -> B, f2: impl Fn(B) -> C) -> T::Base<C> |                             ^ `Base::Base` is `<T as Base>::Base<_>` here note: required by a bound in `Functor::fmap` --> $DIR/method-chain-gats.rs:10:24 | LL |     fn fmap<B>(self, f: impl Fn(A) -> B) -> Self::Base<B> |        ---- required by a bound in this associated function LL |     where LL |         Self::Base<B>: Functor<B>; |                        ^^^^^^^^^^ required by this bound in `Functor::fmap` help: consider further restricting the associated type | LL |     T::Base<B>: Functor<B, Base<C> = T::Base<C>>, <T as Base>::Base<C>: Functor<C> |                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. </ins>