@@ -7,8 +7,8 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
77use rustc_errors:: ErrorGuaranteed ;
88use rustc_hir:: def:: DefKind ;
99use rustc_hir:: lang_items:: LangItem ;
10- use rustc_infer:: infer:: DefineOpaqueTypes ;
1110use rustc_infer:: infer:: resolve:: OpportunisticRegionResolver ;
11+ use rustc_infer:: infer:: { DefineOpaqueTypes , RegionVariableOrigin } ;
1212use rustc_infer:: traits:: { ObligationCauseCode , PredicateObligations } ;
1313pub use rustc_middle:: traits:: Reveal ;
1414use rustc_middle:: traits:: select:: OverflowError ;
@@ -19,6 +19,7 @@ use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
1919use rustc_middle:: ty:: { self , Term , Ty , TyCtxt , TypingMode , Upcast } ;
2020use rustc_middle:: { bug, span_bug} ;
2121use rustc_span:: symbol:: sym;
22+ use thin_vec:: thin_vec;
2223use tracing:: { debug, instrument} ;
2324
2425use super :: {
@@ -62,6 +63,9 @@ enum ProjectionCandidate<'tcx> {
6263 /// Bounds specified on an object type
6364 Object ( ty:: PolyProjectionPredicate < ' tcx > ) ,
6465
66+ /// Built-in bound for a dyn async fn in trait
67+ ObjectRpitit ,
68+
6569 /// From an "impl" (or a "pseudo-impl" returned by select)
6670 Select ( Selection < ' tcx > ) ,
6771}
@@ -852,6 +856,17 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
852856 env_predicates,
853857 false ,
854858 ) ;
859+
860+ // `dyn Trait` automagically project their AFITs to `dyn* Future`.
861+ if tcx. is_impl_trait_in_trait ( obligation. predicate . def_id )
862+ && let Some ( out_trait_def_id) = data. principal_def_id ( )
863+ && let rpitit_trait_def_id = tcx. parent ( obligation. predicate . def_id )
864+ && tcx
865+ . supertrait_def_ids ( out_trait_def_id)
866+ . any ( |trait_def_id| trait_def_id == rpitit_trait_def_id)
867+ {
868+ candidate_set. push_candidate ( ProjectionCandidate :: ObjectRpitit ) ;
869+ }
855870}
856871
857872#[ instrument(
@@ -1270,6 +1285,8 @@ fn confirm_candidate<'cx, 'tcx>(
12701285 ProjectionCandidate :: Select ( impl_source) => {
12711286 confirm_select_candidate ( selcx, obligation, impl_source)
12721287 }
1288+
1289+ ProjectionCandidate :: ObjectRpitit => confirm_object_rpitit_candidate ( selcx, obligation) ,
12731290 } ;
12741291
12751292 // When checking for cycle during evaluation, we compare predicates with
@@ -2057,6 +2074,45 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20572074 }
20582075}
20592076
2077+ fn confirm_object_rpitit_candidate < ' cx , ' tcx > (
2078+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
2079+ obligation : & ProjectionTermObligation < ' tcx > ,
2080+ ) -> Progress < ' tcx > {
2081+ let tcx = selcx. tcx ( ) ;
2082+ let mut obligations = thin_vec ! [ ] ;
2083+
2084+ // Compute an intersection lifetime for all the input components of this GAT.
2085+ let intersection =
2086+ selcx. infcx . next_region_var ( RegionVariableOrigin :: MiscVariable ( obligation. cause . span ) ) ;
2087+ for component in obligation. predicate . args {
2088+ match component. unpack ( ) {
2089+ ty:: GenericArgKind :: Lifetime ( lt) => {
2090+ obligations. push ( obligation. with ( tcx, ty:: OutlivesPredicate ( lt, intersection) ) ) ;
2091+ }
2092+ ty:: GenericArgKind :: Type ( ty) => {
2093+ obligations. push ( obligation. with ( tcx, ty:: OutlivesPredicate ( ty, intersection) ) ) ;
2094+ }
2095+ ty:: GenericArgKind :: Const ( _ct) => {
2096+ // Consts have no outlives...
2097+ }
2098+ }
2099+ }
2100+
2101+ Progress {
2102+ term : Ty :: new_dynamic (
2103+ tcx,
2104+ tcx. item_bounds_to_existential_predicates (
2105+ obligation. predicate . def_id ,
2106+ obligation. predicate . args ,
2107+ ) ,
2108+ intersection,
2109+ ty:: DynStar ,
2110+ )
2111+ . into ( ) ,
2112+ obligations,
2113+ }
2114+ }
2115+
20602116// Get obligations corresponding to the predicates from the where-clause of the
20612117// associated type itself.
20622118fn assoc_ty_own_obligations < ' cx , ' tcx > (
0 commit comments