@@ -7,7 +7,10 @@ use rustc_middle::ty::{
7
7
TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitor ,
8
8
} ;
9
9
use rustc_session:: config:: TraitSolver ;
10
- use rustc_span:: def_id:: { DefId , CRATE_DEF_ID } ;
10
+ use rustc_span:: {
11
+ def_id:: { DefId , CRATE_DEF_ID } ,
12
+ DUMMY_SP ,
13
+ } ;
11
14
use rustc_trait_selection:: traits;
12
15
13
16
fn sized_constraint_for_ty < ' tcx > (
@@ -275,16 +278,22 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
275
278
}
276
279
277
280
fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> std:: ops:: ControlFlow < Self :: BreakTy > {
278
- if let ty:: Alias ( ty:: Projection , alias_ty ) = * ty. kind ( )
279
- && self . tcx . is_impl_trait_in_trait ( alias_ty . def_id )
280
- && self . tcx . impl_trait_in_trait_parent_fn ( alias_ty . def_id ) == self . fn_def_id
281
- && self . seen . insert ( alias_ty . def_id )
281
+ if let ty:: Alias ( ty:: Projection , unshifted_alias_ty ) = * ty. kind ( )
282
+ && self . tcx . is_impl_trait_in_trait ( unshifted_alias_ty . def_id )
283
+ && self . tcx . impl_trait_in_trait_parent_fn ( unshifted_alias_ty . def_id ) == self . fn_def_id
284
+ && self . seen . insert ( unshifted_alias_ty . def_id )
282
285
{
283
286
// We have entered some binders as we've walked into the
284
287
// bounds of the RPITIT. Shift these binders back out when
285
288
// constructing the top-level projection predicate.
286
- let alias_ty = self . tcx . fold_regions ( alias_ty , |re, _ | {
289
+ let shifted_alias_ty = self . tcx . fold_regions ( unshifted_alias_ty , |re, depth | {
287
290
if let ty:: ReLateBound ( index, bv) = re. kind ( ) {
291
+ if depth != ty:: INNERMOST {
292
+ return self . tcx . mk_re_error_with_message (
293
+ DUMMY_SP ,
294
+ "we shouldn't walk non-predicate binders with `impl Trait`..." ,
295
+ ) ;
296
+ }
288
297
self . tcx . mk_re_late_bound ( index. shifted_out_to_binder ( self . depth ) , bv)
289
298
} else {
290
299
re
@@ -295,26 +304,27 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
295
304
// the `type_of` of the trait's associated item. If we're using the old lowering
296
305
// strategy, then just reinterpret the associated type like an opaque :^)
297
306
let default_ty = if self . tcx . lower_impl_trait_in_trait_to_assoc_ty ( ) {
298
- self
299
- . tcx
300
- . type_of ( alias_ty. def_id )
301
- . subst ( self . tcx , alias_ty. substs )
307
+ self . tcx . type_of ( shifted_alias_ty. def_id ) . subst ( self . tcx , shifted_alias_ty. substs )
302
308
} else {
303
- self . tcx . mk_alias ( ty:: Opaque , alias_ty )
309
+ self . tcx . mk_alias ( ty:: Opaque , shifted_alias_ty )
304
310
} ;
305
311
306
312
self . predicates . push (
307
313
ty:: Binder :: bind_with_vars (
308
- ty:: ProjectionPredicate {
309
- projection_ty : alias_ty,
310
- term : default_ty. into ( ) ,
311
- } ,
314
+ ty:: ProjectionPredicate { projection_ty : shifted_alias_ty, term : default_ty. into ( ) } ,
312
315
self . bound_vars ,
313
316
)
314
317
. to_predicate ( self . tcx ) ,
315
318
) ;
316
319
317
- for bound in self . tcx . item_bounds ( alias_ty. def_id ) . subst_iter ( self . tcx , alias_ty. substs )
320
+ // We walk the *un-shifted* alias ty, because we're tracking the de bruijn
321
+ // binder depth, and if we were to walk `shifted_alias_ty` instead, we'd
322
+ // have to reset `self.depth` back to `ty::INNERMOST` or something. It's
323
+ // easier to just do this.
324
+ for bound in self
325
+ . tcx
326
+ . item_bounds ( unshifted_alias_ty. def_id )
327
+ . subst_iter ( self . tcx , unshifted_alias_ty. substs )
318
328
{
319
329
bound. visit_with ( self ) ;
320
330
}
0 commit comments