@@ -68,6 +68,7 @@ use crate::infer::{
6868} ;
6969use crate :: traits:: { ObligationCause , ObligationCauseCode } ;
7070use rustc_data_structures:: undo_log:: UndoLogs ;
71+ use rustc_hir:: def_id:: DefId ;
7172use rustc_hir:: def_id:: LocalDefId ;
7273use rustc_middle:: mir:: ConstraintCategory ;
7374use rustc_middle:: ty:: subst:: GenericArgKind ;
@@ -324,6 +325,29 @@ where
324325 origin : infer:: SubregionOrigin < ' tcx > ,
325326 region : ty:: Region < ' tcx > ,
326327 projection_ty : ty:: ProjectionTy < ' tcx > ,
328+ ) {
329+ self . generic_must_outlive (
330+ origin,
331+ region,
332+ GenericKind :: Projection ( projection_ty) ,
333+ projection_ty. item_def_id ,
334+ projection_ty. substs ,
335+ |ty| match ty. kind ( ) {
336+ ty:: Projection ( projection_ty) => ( projection_ty. item_def_id , projection_ty. substs ) ,
337+ _ => bug ! ( "expected only projection types from env, not {:?}" , ty) ,
338+ } ,
339+ ) ;
340+ }
341+
342+ #[ instrument( level = "debug" , skip( self , filter) ) ]
343+ fn generic_must_outlive (
344+ & mut self ,
345+ origin : infer:: SubregionOrigin < ' tcx > ,
346+ region : ty:: Region < ' tcx > ,
347+ generic : GenericKind < ' tcx > ,
348+ def_id : DefId ,
349+ substs : SubstsRef < ' tcx > ,
350+ filter : impl Fn ( Ty < ' tcx > ) -> ( DefId , SubstsRef < ' tcx > ) ,
327351 ) {
328352 // This case is thorny for inference. The fundamental problem is
329353 // that there are many cases where we have choice, and inference
@@ -342,13 +366,10 @@ where
342366 // Compute the bounds we can derive from the trait definition.
343367 // These are guaranteed to apply, no matter the inference
344368 // results.
345- let trait_bounds: Vec < _ > =
346- self . verify_bound . bounds ( projection_ty. item_def_id , projection_ty. substs ) . collect ( ) ;
369+ let trait_bounds: Vec < _ > = self . verify_bound . bounds ( def_id, substs) . collect ( ) ;
347370
348371 debug ! ( ?trait_bounds) ;
349372
350- let generic = GenericKind :: Projection ( projection_ty) ;
351-
352373 // Compute the bounds we can derive from the environment. This
353374 // is an "approximate" match -- in some cases, these bounds
354375 // may not apply.
@@ -367,14 +388,8 @@ where
367388 // If the declaration is `trait Trait<'b> { type Item: 'b; }`, then `projection_declared_bounds_from_trait`
368389 // will be invoked with `['b => ^1]` and so we will get `^1` returned.
369390 let bound = bound_outlives. skip_binder ( ) ;
370- match * bound. 0 . kind ( ) {
371- ty:: Projection ( projection_ty) => self
372- . verify_bound
373- . bounds ( projection_ty. item_def_id , projection_ty. substs )
374- . all ( |r| r != bound. 1 ) ,
375-
376- _ => panic ! ( "expected only projection types from env, not {:?}" , bound. 0 ) ,
377- }
391+ let ( def_id, substs) = filter ( bound. 0 ) ;
392+ self . verify_bound . bounds ( def_id, substs) . all ( |r| r != bound. 1 )
378393 } ) ;
379394
380395 // If declared bounds list is empty, the only applicable rule is
@@ -391,11 +406,11 @@ where
391406 // the problem is to add `T: 'r`, which isn't true. So, if there are no
392407 // inference variables, we use a verify constraint instead of adding
393408 // edges, which winds up enforcing the same condition.
394- let needs_infer = projection_ty . needs_infer ( ) ;
409+ let needs_infer = substs . needs_infer ( ) ;
395410 if approx_env_bounds. is_empty ( ) && trait_bounds. is_empty ( ) && needs_infer {
396411 debug ! ( "no declared bounds" ) ;
397412
398- self . substs_must_outlive ( projection_ty . substs , origin, region) ;
413+ self . substs_must_outlive ( substs, origin, region) ;
399414
400415 return ;
401416 }
0 commit comments