@@ -350,7 +350,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
350
350
debug ! ( "constrain_opaque_type: bounds={:#?}" , bounds) ;
351
351
let opaque_type = tcx. mk_opaque ( def_id, opaque_defn. substs ) ;
352
352
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 ) ;
354
355
debug_assert ! ( !required_region_bounds. is_empty( ) ) ;
355
356
356
357
for required_region in required_region_bounds {
@@ -1133,7 +1134,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
1133
1134
1134
1135
debug ! ( "instantiate_opaque_types: bounds={:?}" , bounds) ;
1135
1136
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 ( ) ) ;
1137
1138
debug ! ( "instantiate_opaque_types: required_region_bounds={:?}" , required_region_bounds) ;
1138
1139
1139
1140
// 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
1228
1229
) ;
1229
1230
res
1230
1231
}
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