Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: <!-- 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<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
It doesn't seem to be related to GAT, only influenced by TAIT.
seems like another version of
claim

Discussion:
use crate::infer::{InferCtxt, InferOk, TypeFreshener}; use crate::traits::error_reporting::TypeErrCtxtExt; <ins> use crate::traits::project::try_normalize_with_depth_to; </ins> use crate::traits::project::ProjectAndUnifyResult; use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey;

return Ok(cycle_result); } <del> let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack)); </del> <ins> let (result, dep_node) = self.in_task(|this| { let mut result = this.evaluate_stack(&stack)?; // fix issue #103563, we don't normalize // nested obligations which produced by `TraitDef` candidate // (i.e. using bounds on assoc items as assumptions). // because we don't have enough information to // normalize these obligations before evaluating. // so we will try to normalize the obligation and evaluate again. // we will replace it with new solver in the future. if EvaluationResult::EvaluatedToErr == result && fresh_trait_pred.has_projections() && fresh_trait_pred.is_global() { let mut nested_obligations = Vec::new(); let predicate = try_normalize_with_depth_to( this, param_env, obligation.cause.clone(), obligation.recursion_depth + 1, obligation.predicate, &mut nested_obligations, ); if predicate != obligation.predicate { let mut nested_result = EvaluationResult::EvaluatedToOk; for obligation in nested_obligations { nested_result = cmp::max( this.evaluate_predicate_recursively(stack.list(), obligation)?, nested_result, ); } if nested_result.must_apply_modulo_regions() { let obligation = obligation.with(this.tcx(), predicate); result = cmp::max( nested_result, this.evaluate_trait_predicate_recursively(stack.list(), obligation)?, ); } } } Ok::<_, OverflowError>(result) }); </ins> let result = result?; if !result.must_apply_modulo_regions() {

<ins> // build-pass fn main() { let mut log_service = LogService { inner: Inner }; log_service.call(()); } pub trait Service<Request> { type Response; fn call(&mut self, req: Request) -> Self::Response; } pub struct LogService<S> { inner: S, } impl<T, U, S> Service<T> for LogService<S> where S: Service<T, Response = U>, U: Extension + 'static, for<'a> U::Item<'a>: std::fmt::Debug, { type Response = S::Response; fn call(&mut self, req: T) -> Self::Response { self.inner.call(req) } } pub struct Inner; impl Service<()> for Inner { type Response = Resp; fn call(&mut self, req: ()) -> Self::Response { Resp::A(req) } } pub trait Extension { type Item<'a>; fn touch<F>(self, f: F) -> Self where for<'a> F: Fn(Self::Item<'a>); } pub enum Resp { A(()), } impl Extension for Resp { type Item<'a> = RespItem<'a>; fn touch<F>(self, _f: F) -> Self where for<'a> F: Fn(Self::Item<'a>), { match self { Self::A(a) => Self::A(a), } } } pub enum RespItem<'a> { A(&'a ()), } impl<'a> std::fmt::Debug for RespItem<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::A(arg0) => f.debug_tuple("A").field(arg0).finish(), } } } </ins>