@@ -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 } ;
1313use rustc_middle:: traits:: select:: OverflowError ;
1414use rustc_middle:: traits:: { BuiltinImplSource , ImplSource , ImplSourceUserDefinedData } ;
@@ -18,6 +18,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
1818use rustc_middle:: ty:: { self , Term , Ty , TyCtxt , TypingMode , Upcast } ;
1919use rustc_middle:: { bug, span_bug} ;
2020use rustc_span:: symbol:: sym;
21+ use thin_vec:: thin_vec;
2122use tracing:: { debug, instrument} ;
2223
2324use super :: {
@@ -61,6 +62,9 @@ enum ProjectionCandidate<'tcx> {
6162 /// Bounds specified on an object type
6263 Object ( ty:: PolyProjectionPredicate < ' tcx > ) ,
6364
65+ /// Built-in bound for a dyn async fn in trait
66+ ObjectRpitit ,
67+
6468 /// From an "impl" (or a "pseudo-impl" returned by select)
6569 Select ( Selection < ' tcx > ) ,
6670}
@@ -827,6 +831,17 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
827831 env_predicates,
828832 false ,
829833 ) ;
834+
835+ // `dyn Trait` automagically project their AFITs to `dyn* Future`.
836+ if tcx. is_impl_trait_in_trait ( obligation. predicate . def_id )
837+ && let Some ( out_trait_def_id) = data. principal_def_id ( )
838+ && let rpitit_trait_def_id = tcx. parent ( obligation. predicate . def_id )
839+ && tcx
840+ . supertrait_def_ids ( out_trait_def_id)
841+ . any ( |trait_def_id| trait_def_id == rpitit_trait_def_id)
842+ {
843+ candidate_set. push_candidate ( ProjectionCandidate :: ObjectRpitit ) ;
844+ }
830845}
831846
832847#[ instrument(
@@ -1247,6 +1262,8 @@ fn confirm_candidate<'cx, 'tcx>(
12471262 ProjectionCandidate :: Select ( impl_source) => {
12481263 confirm_select_candidate ( selcx, obligation, impl_source)
12491264 }
1265+
1266+ ProjectionCandidate :: ObjectRpitit => confirm_object_rpitit_candidate ( selcx, obligation) ,
12501267 } ;
12511268
12521269 // When checking for cycle during evaluation, we compare predicates with
@@ -2034,6 +2051,45 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20342051 }
20352052}
20362053
2054+ fn confirm_object_rpitit_candidate < ' cx , ' tcx > (
2055+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
2056+ obligation : & ProjectionTermObligation < ' tcx > ,
2057+ ) -> Progress < ' tcx > {
2058+ let tcx = selcx. tcx ( ) ;
2059+ let mut obligations = thin_vec ! [ ] ;
2060+
2061+ // Compute an intersection lifetime for all the input components of this GAT.
2062+ let intersection =
2063+ selcx. infcx . next_region_var ( RegionVariableOrigin :: MiscVariable ( obligation. cause . span ) ) ;
2064+ for component in obligation. predicate . args {
2065+ match component. unpack ( ) {
2066+ ty:: GenericArgKind :: Lifetime ( lt) => {
2067+ obligations. push ( obligation. with ( tcx, ty:: OutlivesPredicate ( lt, intersection) ) ) ;
2068+ }
2069+ ty:: GenericArgKind :: Type ( ty) => {
2070+ obligations. push ( obligation. with ( tcx, ty:: OutlivesPredicate ( ty, intersection) ) ) ;
2071+ }
2072+ ty:: GenericArgKind :: Const ( _ct) => {
2073+ // Consts have no outlives...
2074+ }
2075+ }
2076+ }
2077+
2078+ Progress {
2079+ term : Ty :: new_dynamic (
2080+ tcx,
2081+ tcx. item_bounds_to_existential_predicates (
2082+ obligation. predicate . def_id ,
2083+ obligation. predicate . args ,
2084+ ) ,
2085+ intersection,
2086+ ty:: DynStar ,
2087+ )
2088+ . into ( ) ,
2089+ obligations,
2090+ }
2091+ }
2092+
20372093// Get obligations corresponding to the predicates from the where-clause of the
20382094// associated type itself.
20392095fn assoc_ty_own_obligations < ' cx , ' tcx > (
0 commit comments