@@ -10,6 +10,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
1010use rustc_hir:: def_id:: { DefId , LocalDefId } ;
1111use rustc_hir:: intravisit:: Visitor ;
1212use rustc_hir:: { ItemKind , Node , PathSegment } ;
13+ use rustc_infer:: infer:: opaque_types:: ConstrainOpaqueTypeRegionVisitor ;
1314use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
1415use rustc_infer:: infer:: { DefiningAnchor , RegionVariableOrigin , TyCtxtInferExt } ;
1516use rustc_infer:: traits:: Obligation ;
@@ -254,100 +255,11 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
254255 let item = tcx. hir ( ) . expect_item ( def_id) ;
255256 debug ! ( ?item, ?span) ;
256257
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-
347258 struct ProhibitOpaqueVisitor < ' tcx > {
348259 tcx : TyCtxt < ' tcx > ,
349260 opaque_identity_ty : Ty < ' tcx > ,
350- generics : & ' tcx ty:: Generics ,
261+ parent_count : u32 ,
262+ references_parent_regions : bool ,
351263 selftys : Vec < ( Span , Option < String > ) > ,
352264 }
353265
@@ -359,11 +271,21 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
359271 if t == self . opaque_identity_ty {
360272 ControlFlow :: CONTINUE
361273 } else {
362- t. visit_with ( & mut FindParentLifetimeVisitor {
274+ t. visit_with ( & mut ConstrainOpaqueTypeRegionVisitor {
363275 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+ }
367289 }
368290 }
369291 }
@@ -408,7 +330,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
408330 } ;
409331 let mut visitor = ProhibitOpaqueVisitor {
410332 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 ,
412335 tcx,
413336 selftys : vec ! [ ] ,
414337 } ;
0 commit comments