@@ -10,6 +10,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
10
10
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
11
11
use rustc_hir:: intravisit:: Visitor ;
12
12
use rustc_hir:: { ItemKind , Node , PathSegment } ;
13
+ use rustc_infer:: infer:: opaque_types:: ConstrainOpaqueTypeRegionVisitor ;
13
14
use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
14
15
use rustc_infer:: infer:: { DefiningAnchor , RegionVariableOrigin , TyCtxtInferExt } ;
15
16
use rustc_infer:: traits:: Obligation ;
@@ -254,100 +255,11 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
254
255
let item = tcx. hir ( ) . expect_item ( def_id) ;
255
256
debug ! ( ?item, ?span) ;
256
257
257
- #[ derive( Debug ) ]
258
- struct FoundParentLifetime ;
259
- struct FindParentLifetimeVisitor < ' tcx > {
260
- tcx : TyCtxt < ' tcx > ,
261
- parent_count : u32 ,
262
- }
263
- impl < ' tcx > ty:: visit:: TypeVisitor < ' tcx > for FindParentLifetimeVisitor < ' tcx > {
264
- type BreakTy = FoundParentLifetime ;
265
-
266
- #[ instrument( level = "trace" , skip( self ) , ret) ]
267
- fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
268
- if let ty:: ReEarlyBound ( ty:: EarlyBoundRegion { index, .. } ) = * r {
269
- if index < self . parent_count {
270
- return ControlFlow :: Break ( FoundParentLifetime ) ;
271
- } else {
272
- return ControlFlow :: CONTINUE ;
273
- }
274
- }
275
-
276
- r. super_visit_with ( self )
277
- }
278
-
279
- #[ instrument( level = "trace" , skip( self ) , ret) ]
280
- fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
281
- // We're only interested in types involving regions
282
- if !ty. flags ( ) . intersects ( ty:: TypeFlags :: HAS_FREE_REGIONS ) {
283
- return ControlFlow :: CONTINUE ;
284
- }
285
-
286
- match ty. kind ( ) {
287
- ty:: Closure ( _, ref substs) => {
288
- // Skip lifetime parameters of the enclosing item(s)
289
-
290
- substs. as_closure ( ) . tupled_upvars_ty ( ) . visit_with ( self ) ?;
291
- substs. as_closure ( ) . sig_as_fn_ptr_ty ( ) . visit_with ( self ) ?;
292
- }
293
-
294
- ty:: Generator ( _, ref substs, _) => {
295
- // Skip lifetime parameters of the enclosing item(s)
296
- // Also skip the witness type, because that has no free regions.
297
-
298
- substs. as_generator ( ) . tupled_upvars_ty ( ) . visit_with ( self ) ?;
299
- substs. as_generator ( ) . return_ty ( ) . visit_with ( self ) ?;
300
- substs. as_generator ( ) . yield_ty ( ) . visit_with ( self ) ?;
301
- substs. as_generator ( ) . resume_ty ( ) . visit_with ( self ) ?;
302
- }
303
-
304
- ty:: Opaque ( def_id, ref substs) => {
305
- // Skip lifetime paramters that are not captures.
306
- let variances = self . tcx . variances_of ( * def_id) ;
307
-
308
- for ( v, s) in std:: iter:: zip ( variances, substs. iter ( ) ) {
309
- if * v != ty:: Variance :: Bivariant {
310
- s. visit_with ( self ) ?;
311
- }
312
- }
313
- }
314
-
315
- ty:: Projection ( proj)
316
- if self . tcx . def_kind ( proj. item_def_id ) == DefKind :: ImplTraitPlaceholder =>
317
- {
318
- // Skip lifetime paramters that are not captures.
319
- let variances = self . tcx . variances_of ( proj. item_def_id ) ;
320
-
321
- for ( v, s) in std:: iter:: zip ( variances, proj. substs . iter ( ) ) {
322
- if * v != ty:: Variance :: Bivariant {
323
- s. visit_with ( self ) ?;
324
- }
325
- }
326
- }
327
-
328
- _ => {
329
- ty. super_visit_with ( self ) ?;
330
- }
331
- }
332
-
333
- ControlFlow :: CONTINUE
334
- }
335
-
336
- fn visit_const ( & mut self , c : ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
337
- if let ty:: ConstKind :: Unevaluated ( ..) = c. kind ( ) {
338
- // FIXME(#72219) We currently don't detect lifetimes within substs
339
- // which would violate this check. Even though the particular substitution is not used
340
- // within the const, this should still be fixed.
341
- return ControlFlow :: CONTINUE ;
342
- }
343
- c. super_visit_with ( self )
344
- }
345
- }
346
-
347
258
struct ProhibitOpaqueVisitor < ' tcx > {
348
259
tcx : TyCtxt < ' tcx > ,
349
260
opaque_identity_ty : Ty < ' tcx > ,
350
- generics : & ' tcx ty:: Generics ,
261
+ parent_count : u32 ,
262
+ references_parent_regions : bool ,
351
263
selftys : Vec < ( Span , Option < String > ) > ,
352
264
}
353
265
@@ -359,11 +271,21 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
359
271
if t == self . opaque_identity_ty {
360
272
ControlFlow :: CONTINUE
361
273
} else {
362
- t. visit_with ( & mut FindParentLifetimeVisitor {
274
+ t. visit_with ( & mut ConstrainOpaqueTypeRegionVisitor {
363
275
tcx : self . tcx ,
364
- parent_count : self . generics . parent_count as u32 ,
365
- } )
366
- . map_break ( |FoundParentLifetime | t)
276
+ op : |region| {
277
+ if let ty:: ReEarlyBound ( ty:: EarlyBoundRegion { index, .. } ) = * region
278
+ && index < self . parent_count
279
+ {
280
+ self . references_parent_regions = true ;
281
+ }
282
+ } ,
283
+ } ) ;
284
+ if self . references_parent_regions {
285
+ ControlFlow :: Break ( t)
286
+ } else {
287
+ ControlFlow :: CONTINUE
288
+ }
367
289
}
368
290
}
369
291
}
@@ -408,7 +330,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
408
330
} ;
409
331
let mut visitor = ProhibitOpaqueVisitor {
410
332
opaque_identity_ty,
411
- generics : tcx. generics_of ( def_id) ,
333
+ parent_count : tcx. generics_of ( def_id) . parent_count as u32 ,
334
+ references_parent_regions : false ,
412
335
tcx,
413
336
selftys : vec ! [ ] ,
414
337
} ;
0 commit comments