@@ -2343,7 +2343,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23432343
23442344 Scope :: TraitRefBoundary { s, .. } => {
23452345 // We've exited nested poly trait refs; mark that we are no longer in nested trait refs.
2346- // We don't increase the late depth because this isn't a `Binder` scope
2346+ // We don't increase the late depth because this isn't a `Binder` scope.
2347+ //
2348+ // This came up in #83737, which boiled down to a case like this:
2349+ //
2350+ // ```
2351+ // F: for<> Fn(&()) -> Box<dyn for<> Future<Output = ()> + Unpin>,
2352+ // // ^^^^^
2353+
2354+ // ```
2355+ //
2356+ // Here, as we traverse upwards from the `dyn for<>` binder, we want to reset `in_poly_trait_ref`
2357+ // to false, so that we avoid excess contaenation when we encounter the outer `for<>` binder.
23472358 in_poly_trait_ref = false ;
23482359 scope = s;
23492360 }
@@ -2369,6 +2380,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23692380 // We've already seen a binder that is a poly trait ref and this one is too,
23702381 // that means that they are nested and we are concatenating the bound vars;
23712382 // don't increase the late depth.
2383+ //
2384+ // This happens specifically with associated trait bounds like the following:
2385+ //
2386+ // ```
2387+ // for<'a> T: Iterator<Item: for<'b> Foo<'a, 'b>>
2388+ // ```
2389+ //
2390+ // In this case, as we traverse `for<'b>`, we would increment `late_depth` but
2391+ // set `in_poly_trait_ref` to true. Then when we traverse `for<'a>`, we would
2392+ // not increment `late_depth` again. (NB: Niko thinks this logic is actually
2393+ // wrong.)
23722394 ( true , true ) => { }
23732395 // We've exited nested poly trait refs; add one to the late depth and mark
23742396 // that we are no longer in nested trait refs
0 commit comments