@@ -1544,42 +1544,81 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
15441544 span : Span ,
15451545) {
15461546 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 )
15661602 {
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;
15811619 }
15821620 }
1621+ ty. super_visit_with ( self )
15831622 }
15841623}
15851624
0 commit comments