@@ -2343,7 +2343,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2343
2343
2344
2344
Scope :: TraitRefBoundary { s, .. } => {
2345
2345
// 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.
2347
2358
in_poly_trait_ref = false ;
2348
2359
scope = s;
2349
2360
}
@@ -2369,6 +2380,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2369
2380
// We've already seen a binder that is a poly trait ref and this one is too,
2370
2381
// that means that they are nested and we are concatenating the bound vars;
2371
2382
// 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.)
2372
2394
( true , true ) => { }
2373
2395
// We've exited nested poly trait refs; add one to the late depth and mark
2374
2396
// that we are no longer in nested trait refs
0 commit comments