@@ -7,8 +7,8 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
7
7
use rustc_errors:: ErrorGuaranteed ;
8
8
use rustc_hir:: def:: DefKind ;
9
9
use rustc_hir:: lang_items:: LangItem ;
10
- use rustc_infer:: infer:: DefineOpaqueTypes ;
11
10
use rustc_infer:: infer:: resolve:: OpportunisticRegionResolver ;
11
+ use rustc_infer:: infer:: { DefineOpaqueTypes , RegionVariableOrigin } ;
12
12
use rustc_infer:: traits:: { ObligationCauseCode , PredicateObligations } ;
13
13
use rustc_middle:: traits:: select:: OverflowError ;
14
14
use rustc_middle:: traits:: { BuiltinImplSource , ImplSource , ImplSourceUserDefinedData } ;
@@ -18,6 +18,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
18
18
use rustc_middle:: ty:: { self , Term , Ty , TyCtxt , TypingMode , Upcast } ;
19
19
use rustc_middle:: { bug, span_bug} ;
20
20
use rustc_span:: symbol:: sym;
21
+ use thin_vec:: thin_vec;
21
22
use tracing:: { debug, instrument} ;
22
23
23
24
use super :: {
@@ -61,6 +62,9 @@ enum ProjectionCandidate<'tcx> {
61
62
/// Bounds specified on an object type
62
63
Object ( ty:: PolyProjectionPredicate < ' tcx > ) ,
63
64
65
+ /// Built-in bound for a dyn async fn in trait
66
+ ObjectRpitit ,
67
+
64
68
/// From an "impl" (or a "pseudo-impl" returned by select)
65
69
Select ( Selection < ' tcx > ) ,
66
70
}
@@ -827,6 +831,17 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
827
831
env_predicates,
828
832
false ,
829
833
) ;
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
+ }
830
845
}
831
846
832
847
#[ instrument(
@@ -1247,6 +1262,8 @@ fn confirm_candidate<'cx, 'tcx>(
1247
1262
ProjectionCandidate :: Select ( impl_source) => {
1248
1263
confirm_select_candidate ( selcx, obligation, impl_source)
1249
1264
}
1265
+
1266
+ ProjectionCandidate :: ObjectRpitit => confirm_object_rpitit_candidate ( selcx, obligation) ,
1250
1267
} ;
1251
1268
1252
1269
// When checking for cycle during evaluation, we compare predicates with
@@ -2034,6 +2051,45 @@ fn confirm_impl_candidate<'cx, 'tcx>(
2034
2051
}
2035
2052
}
2036
2053
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
+
2037
2093
// Get obligations corresponding to the predicates from the where-clause of the
2038
2094
// associated type itself.
2039
2095
fn assoc_ty_own_obligations < ' cx , ' tcx > (
0 commit comments