| 
1 | 1 | use rustc_hir::def_id::DefId;  | 
2 |  | -use rustc_middle::ty::{self, TyCtxt, fold_regions};  | 
 | 2 | +use rustc_infer::infer::TyCtxtInferExt;  | 
 | 3 | +use rustc_infer::infer::canonical::query_response::make_query_region_constraints;  | 
 | 4 | +use rustc_infer::infer::resolve::OpportunisticRegionResolver;  | 
 | 5 | +use rustc_infer::traits::{Obligation, ObligationCause};  | 
 | 6 | +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions};  | 
 | 7 | +use rustc_trait_selection::traits::{ObligationCtxt, with_replaced_escaping_bound_vars};  | 
3 | 8 | 
 
  | 
4 | 9 | /// Return the set of types that should be taken into account when checking  | 
5 | 10 | /// trait bounds on a coroutine's internal state. This properly replaces  | 
@@ -29,8 +34,56 @@ pub(crate) fn coroutine_hidden_types<'tcx>(  | 
29 | 34 |  ty  | 
30 | 35 |  }),  | 
31 | 36 |  );  | 
 | 37 | + | 
 | 38 | + let assumptions = compute_assumptions(tcx, def_id, bound_tys);  | 
 | 39 | + | 
32 | 40 |  ty::EarlyBinder::bind(ty::Binder::bind_with_vars(  | 
33 |  | - ty::CoroutineWitnessTypes { types: bound_tys, assumptions: ty::List::empty() },  | 
 | 41 | + ty::CoroutineWitnessTypes { types: bound_tys, assumptions },  | 
34 | 42 |  tcx.mk_bound_variable_kinds(&vars),  | 
35 | 43 |  ))  | 
36 | 44 | }  | 
 | 45 | + | 
 | 46 | +fn compute_assumptions<'tcx>(  | 
 | 47 | + tcx: TyCtxt<'tcx>,  | 
 | 48 | + def_id: DefId,  | 
 | 49 | + bound_tys: &'tcx ty::List<Ty<'tcx>>,  | 
 | 50 | +) -> &'tcx ty::List<ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>> {  | 
 | 51 | + let infcx = tcx.infer_ctxt().build(ty::TypingMode::Analysis {  | 
 | 52 | + defining_opaque_types_and_generators: ty::List::empty(),  | 
 | 53 | + });  | 
 | 54 | + with_replaced_escaping_bound_vars(&infcx, &mut vec![None], bound_tys, |bound_tys| {  | 
 | 55 | + let param_env = tcx.param_env(def_id);  | 
 | 56 | + let ocx = ObligationCtxt::new(&infcx);  | 
 | 57 | + | 
 | 58 | + ocx.register_obligations(bound_tys.iter().map(|ty| {  | 
 | 59 | + Obligation::new(  | 
 | 60 | + tcx,  | 
 | 61 | + ObligationCause::dummy(),  | 
 | 62 | + param_env,  | 
 | 63 | + ty::ClauseKind::WellFormed(ty.into()),  | 
 | 64 | + )  | 
 | 65 | + }));  | 
 | 66 | + let _errors = ocx.select_all_or_error();  | 
 | 67 | + | 
 | 68 | + let region_obligations = infcx.take_registered_region_obligations();  | 
 | 69 | + let region_constraints = infcx.take_and_reset_region_constraints();  | 
 | 70 | + | 
 | 71 | + let outlives = make_query_region_constraints(  | 
 | 72 | + tcx,  | 
 | 73 | + region_obligations,  | 
 | 74 | + ®ion_constraints,  | 
 | 75 | + )  | 
 | 76 | + .outlives  | 
 | 77 | + .fold_with(&mut OpportunisticRegionResolver::new(&infcx));  | 
 | 78 | + | 
 | 79 | + tcx.mk_outlives_from_iter(  | 
 | 80 | + outlives  | 
 | 81 | + .into_iter()  | 
 | 82 | + .map(|(o, _)| o)  | 
 | 83 | + // FIXME(higher_ranked_auto): We probably should deeply resolve these before  | 
 | 84 | + // filtering out infers which only correspond to unconstrained infer regions  | 
 | 85 | + // which we can sometimes get.  | 
 | 86 | + .filter(|o| !o.has_infer()),  | 
 | 87 | + )  | 
 | 88 | + })  | 
 | 89 | +}  | 
0 commit comments