@@ -1544,42 +1544,81 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
1544
1544
span : Span ,
1545
1545
) {
1546
1546
let tcx = wfcx. tcx ( ) ;
1547
- if let Some ( assoc_item) = tcx. opt_associated_item ( fn_def_id. to_def_id ( ) )
1548
- && assoc_item. container == ty:: AssocItemContainer :: TraitContainer
1549
- {
1550
- // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Even with the new lowering
1551
- // strategy, we can't just call `check_associated_item` on the new RPITITs,
1552
- // because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail.
1553
- // That's because we need to check that the bounds of the RPITIT hold using
1554
- // the special substs that we create during opaque type lowering, otherwise we're
1555
- // getting a bunch of early bound and free regions mixed up... Haven't looked too
1556
- // deep into this, though.
1557
- for arg in fn_output. walk ( ) {
1558
- if let ty:: GenericArgKind :: Type ( ty) = arg. unpack ( )
1559
- // RPITITs are always eagerly normalized into opaques, so always look for an
1560
- // opaque here.
1561
- && let ty:: Alias ( ty:: Opaque , opaque_ty) = ty. kind ( )
1562
- && let Some ( opaque_def_id) = opaque_ty. def_id . as_local ( )
1563
- && let opaque = tcx. hir ( ) . expect_item ( opaque_def_id) . expect_opaque_ty ( )
1564
- && let hir:: OpaqueTyOrigin :: FnReturn ( source) | hir:: OpaqueTyOrigin :: AsyncFn ( source) = opaque. origin
1565
- && source == fn_def_id
1547
+ let Some ( assoc_item) = tcx. opt_associated_item ( fn_def_id. to_def_id ( ) ) else {
1548
+ return ;
1549
+ } ;
1550
+ if assoc_item. container != ty:: AssocItemContainer :: TraitContainer {
1551
+ return ;
1552
+ }
1553
+ fn_output. visit_with ( & mut ImplTraitInTraitFinder {
1554
+ wfcx,
1555
+ fn_def_id,
1556
+ depth : ty:: INNERMOST ,
1557
+ seen : FxHashSet :: default ( ) ,
1558
+ } ) ;
1559
+ }
1560
+
1561
+ // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Even with the new lowering
1562
+ // strategy, we can't just call `check_associated_item` on the new RPITITs,
1563
+ // because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail.
1564
+ // That's because we need to check that the bounds of the RPITIT hold using
1565
+ // the special substs that we create during opaque type lowering, otherwise we're
1566
+ // getting a bunch of early bound and free regions mixed up... Haven't looked too
1567
+ // deep into this, though.
1568
+ struct ImplTraitInTraitFinder < ' a , ' tcx > {
1569
+ wfcx : & ' a WfCheckingCtxt < ' a , ' tcx > ,
1570
+ fn_def_id : LocalDefId ,
1571
+ depth : ty:: DebruijnIndex ,
1572
+ seen : FxHashSet < DefId > ,
1573
+ }
1574
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for ImplTraitInTraitFinder < ' _ , ' tcx > {
1575
+ type BreakTy = !;
1576
+
1577
+ fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> ControlFlow < !> {
1578
+ let tcx = self . wfcx . tcx ( ) ;
1579
+ if let ty:: Alias ( ty:: Opaque , unshifted_opaque_ty) = * ty. kind ( )
1580
+ && self . seen . insert ( unshifted_opaque_ty. def_id )
1581
+ && let Some ( opaque_def_id) = unshifted_opaque_ty. def_id . as_local ( )
1582
+ && let opaque = tcx. hir ( ) . expect_item ( opaque_def_id) . expect_opaque_ty ( )
1583
+ && let hir:: OpaqueTyOrigin :: FnReturn ( source) | hir:: OpaqueTyOrigin :: AsyncFn ( source) = opaque. origin
1584
+ && source == self . fn_def_id
1585
+ {
1586
+ let opaque_ty = tcx. fold_regions ( unshifted_opaque_ty, |re, depth| {
1587
+ if let ty:: ReLateBound ( index, bv) = re. kind ( ) {
1588
+ if depth != ty:: INNERMOST {
1589
+ return tcx. mk_re_error_with_message (
1590
+ DUMMY_SP ,
1591
+ "we shouldn't walk non-predicate binders with `impl Trait`..." ,
1592
+ ) ;
1593
+ }
1594
+ tcx. mk_re_late_bound ( index. shifted_out_to_binder ( self . depth ) , bv)
1595
+ } else {
1596
+ re
1597
+ }
1598
+ } ) ;
1599
+ for ( bound, bound_span) in tcx
1600
+ . bound_explicit_item_bounds ( opaque_ty. def_id )
1601
+ . subst_iter_copied ( tcx, opaque_ty. substs )
1566
1602
{
1567
- let span = tcx. def_span ( opaque_ty. def_id ) ;
1568
- let bounds = wfcx. tcx ( ) . explicit_item_bounds ( opaque_ty. def_id ) ;
1569
- let wf_obligations = bounds. iter ( ) . flat_map ( |& ( bound, bound_span) | {
1570
- let bound = ty:: EarlyBinder ( bound) . subst ( tcx, opaque_ty. substs ) ;
1571
- let normalized_bound = wfcx. normalize ( span, None , bound) ;
1572
- traits:: wf:: predicate_obligations (
1573
- wfcx. infcx ,
1574
- wfcx. param_env ,
1575
- wfcx. body_def_id ,
1576
- normalized_bound,
1577
- bound_span,
1578
- )
1579
- } ) ;
1580
- wfcx. register_obligations ( wf_obligations) ;
1603
+ let bound = self . wfcx . normalize ( bound_span, None , bound) ;
1604
+ self . wfcx . register_obligations ( traits:: wf:: predicate_obligations (
1605
+ self . wfcx . infcx ,
1606
+ self . wfcx . param_env ,
1607
+ self . wfcx . body_def_id ,
1608
+ bound,
1609
+ bound_span,
1610
+ ) ) ;
1611
+ // Set the debruijn index back to innermost here, since we already eagerly
1612
+ // shifted the substs that we use to generate these bounds. This is unfortunately
1613
+ // subtly different behavior than the `ImplTraitInTraitFinder` we use in `param_env`,
1614
+ // but that function doesn't actually need to normalize the bound it's visiting
1615
+ // (whereas we have to do so here)...
1616
+ let old_depth = std:: mem:: replace ( & mut self . depth , ty:: INNERMOST ) ;
1617
+ bound. visit_with ( self ) ;
1618
+ self . depth = old_depth;
1581
1619
}
1582
1620
}
1621
+ ty. super_visit_with ( self )
1583
1622
}
1584
1623
}
1585
1624
0 commit comments