@@ -350,7 +350,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
350350 debug ! ( "constrain_opaque_type: bounds={:#?}" , bounds) ;
351351 let opaque_type = tcx. mk_opaque ( def_id, opaque_defn. substs ) ;
352352
353- let required_region_bounds = tcx. required_region_bounds ( opaque_type, bounds. predicates ) ;
353+ let required_region_bounds =
354+ required_region_bounds ( tcx, opaque_type, bounds. predicates ) ;
354355 debug_assert ! ( !required_region_bounds. is_empty( ) ) ;
355356
356357 for required_region in required_region_bounds {
@@ -1133,7 +1134,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
11331134
11341135 debug ! ( "instantiate_opaque_types: bounds={:?}" , bounds) ;
11351136
1136- let required_region_bounds = tcx . required_region_bounds ( ty, bounds. predicates . clone ( ) ) ;
1137+ let required_region_bounds = required_region_bounds ( tcx , ty, bounds. predicates . clone ( ) ) ;
11371138 debug ! ( "instantiate_opaque_types: required_region_bounds={:?}" , required_region_bounds) ;
11381139
11391140 // Make sure that we are in fact defining the *entire* type
@@ -1228,3 +1229,67 @@ pub fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: DefId, opaque_hir_id: hir
12281229 ) ;
12291230 res
12301231}
1232+
1233+ /// Given a set of predicates that apply to an object type, returns
1234+ /// the region bounds that the (erased) `Self` type must
1235+ /// outlive. Precisely *because* the `Self` type is erased, the
1236+ /// parameter `erased_self_ty` must be supplied to indicate what type
1237+ /// has been used to represent `Self` in the predicates
1238+ /// themselves. This should really be a unique type; `FreshTy(0)` is a
1239+ /// popular choice.
1240+ ///
1241+ /// N.B., in some cases, particularly around higher-ranked bounds,
1242+ /// this function returns a kind of conservative approximation.
1243+ /// That is, all regions returned by this function are definitely
1244+ /// required, but there may be other region bounds that are not
1245+ /// returned, as well as requirements like `for<'a> T: 'a`.
1246+ ///
1247+ /// Requires that trait definitions have been processed so that we can
1248+ /// elaborate predicates and walk supertraits.
1249+ //
1250+ // FIXME: callers may only have a `&[Predicate]`, not a `Vec`, so that's
1251+ // what this code should accept.
1252+ crate fn required_region_bounds (
1253+ tcx : TyCtxt < ' tcx > ,
1254+ erased_self_ty : Ty < ' tcx > ,
1255+ predicates : Vec < ty:: Predicate < ' tcx > > ,
1256+ ) -> Vec < ty:: Region < ' tcx > > {
1257+ debug ! (
1258+ "required_region_bounds(erased_self_ty={:?}, predicates={:?})" ,
1259+ erased_self_ty, predicates
1260+ ) ;
1261+
1262+ assert ! ( !erased_self_ty. has_escaping_bound_vars( ) ) ;
1263+
1264+ traits:: elaborate_predicates ( tcx, predicates)
1265+ . filter_map ( |predicate| {
1266+ match predicate {
1267+ ty:: Predicate :: Projection ( ..)
1268+ | ty:: Predicate :: Trait ( ..)
1269+ | ty:: Predicate :: Subtype ( ..)
1270+ | ty:: Predicate :: WellFormed ( ..)
1271+ | ty:: Predicate :: ObjectSafe ( ..)
1272+ | ty:: Predicate :: ClosureKind ( ..)
1273+ | ty:: Predicate :: RegionOutlives ( ..)
1274+ | ty:: Predicate :: ConstEvaluatable ( ..) => None ,
1275+ ty:: Predicate :: TypeOutlives ( predicate) => {
1276+ // Search for a bound of the form `erased_self_ty
1277+ // : 'a`, but be wary of something like `for<'a>
1278+ // erased_self_ty : 'a` (we interpret a
1279+ // higher-ranked bound like that as 'static,
1280+ // though at present the code in `fulfill.rs`
1281+ // considers such bounds to be unsatisfiable, so
1282+ // it's kind of a moot point since you could never
1283+ // construct such an object, but this seems
1284+ // correct even if that code changes).
1285+ let ty:: OutlivesPredicate ( ref t, ref r) = predicate. skip_binder ( ) ;
1286+ if t == & erased_self_ty && !r. has_escaping_bound_vars ( ) {
1287+ Some ( * r)
1288+ } else {
1289+ None
1290+ }
1291+ }
1292+ }
1293+ } )
1294+ . collect ( )
1295+ }
0 commit comments