@@ -38,21 +38,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
3838 Self { tcx, region_bound_pairs, implicit_region_bound, param_env }
3939 }
4040
41- /// Returns a "verify bound" that encodes what we know about
42- /// `generic` and the regions it outlives.
43- pub fn generic_bound ( & self , generic : GenericKind < ' tcx > ) -> VerifyBound < ' tcx > {
44- let mut visited = SsoHashSet :: new ( ) ;
45- match generic {
46- GenericKind :: Param ( param_ty) => self . param_bound ( param_ty) ,
47- GenericKind :: Projection ( projection_ty) => {
48- self . projection_bound ( projection_ty, & mut visited)
49- }
50- GenericKind :: Opaque ( def_id, substs) => self . opaque_bound ( def_id, substs) ,
51- }
52- }
53-
5441 #[ instrument( level = "debug" , skip( self ) ) ]
55- fn param_bound ( & self , param_ty : ty:: ParamTy ) -> VerifyBound < ' tcx > {
42+ pub fn param_bound ( & self , param_ty : ty:: ParamTy ) -> VerifyBound < ' tcx > {
5643 // Start with anything like `T: 'a` we can scrape from the
5744 // environment. If the environment contains something like
5845 // `for<'a> T: 'a`, then we know that `T` outlives everything.
@@ -116,20 +103,21 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
116103 }
117104
118105 #[ instrument( level = "debug" , skip( self , visited) ) ]
119- fn projection_bound (
106+ pub fn projection_opaque_bounds (
120107 & self ,
121- projection_ty : ty:: ProjectionTy < ' tcx > ,
108+ generic : GenericKind < ' tcx > ,
109+ def_id : DefId ,
110+ substs : SubstsRef < ' tcx > ,
122111 visited : & mut SsoHashSet < GenericArg < ' tcx > > ,
123112 ) -> VerifyBound < ' tcx > {
124- let projection_ty_as_ty =
125- self . tcx . mk_projection ( projection_ty. item_def_id , projection_ty. substs ) ;
113+ let generic_ty = generic. to_ty ( self . tcx ) ;
126114
127115 // Search the env for where clauses like `P: 'a`.
128- let env_bounds = self
129- . approx_declared_bounds_from_env ( GenericKind :: Projection ( projection_ty ) )
116+ let projection_opaque_bounds = self
117+ . approx_declared_bounds_from_env ( generic )
130118 . into_iter ( )
131119 . map ( |binder| {
132- if let Some ( ty:: OutlivesPredicate ( ty, r) ) = binder. no_bound_vars ( ) && ty == projection_ty_as_ty {
120+ if let Some ( ty:: OutlivesPredicate ( ty, r) ) = binder. no_bound_vars ( ) && ty == generic_ty {
133121 // Micro-optimize if this is an exact match (this
134122 // occurs often when there are no region variables
135123 // involved).
@@ -139,35 +127,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
139127 VerifyBound :: IfEq ( verify_if_eq_b)
140128 }
141129 } ) ;
142-
143130 // Extend with bounds that we can find from the trait.
144- let trait_bounds = self
145- . bounds ( projection_ty. item_def_id , projection_ty. substs )
146- . map ( |r| VerifyBound :: OutlivedBy ( r) ) ;
131+ let trait_bounds = self . bounds ( def_id, substs) . map ( |r| VerifyBound :: OutlivedBy ( r) ) ;
147132
148133 // see the extensive comment in projection_must_outlive
149134 let recursive_bound = {
150135 let mut components = smallvec ! [ ] ;
151- let ty = self . tcx . mk_projection ( projection_ty. item_def_id , projection_ty. substs ) ;
152- compute_components_recursive ( self . tcx , ty. into ( ) , & mut components, visited) ;
136+ compute_components_recursive ( self . tcx , generic_ty. into ( ) , & mut components, visited) ;
153137 self . bound_from_components ( & components, visited)
154138 } ;
155139
156- VerifyBound :: AnyBound ( env_bounds. chain ( trait_bounds) . collect ( ) ) . or ( recursive_bound)
157- }
158-
159- fn opaque_bound ( & self , def_id : DefId , substs : SubstsRef < ' tcx > ) -> VerifyBound < ' tcx > {
160- let bounds: Vec < _ > =
161- self . bounds ( def_id, substs) . map ( |r| VerifyBound :: OutlivedBy ( r) ) . collect ( ) ;
162- trace ! ( "{:#?}" , bounds) ;
163- if bounds. is_empty ( ) {
164- // No bounds means the value must not have any lifetimes.
165- // FIXME: should we implicitly add 'static to `tcx.item_bounds` for opaque types, just
166- // like we add `Sized`?
167- VerifyBound :: OutlivedBy ( self . tcx . lifetimes . re_static )
168- } else {
169- VerifyBound :: AnyBound ( bounds)
170- }
140+ VerifyBound :: AnyBound ( projection_opaque_bounds. chain ( trait_bounds) . collect ( ) )
141+ . or ( recursive_bound)
171142 }
172143
173144 fn bound_from_components (
@@ -199,8 +170,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
199170 match * component {
200171 Component :: Region ( lt) => VerifyBound :: OutlivedBy ( lt) ,
201172 Component :: Param ( param_ty) => self . param_bound ( param_ty) ,
202- Component :: Opaque ( did, substs) => self . opaque_bound ( did, substs) ,
203- Component :: Projection ( projection_ty) => self . projection_bound ( projection_ty, visited) ,
173+ Component :: Opaque ( did, substs) => self . projection_opaque_bounds (
174+ GenericKind :: Opaque ( did, substs) ,
175+ did,
176+ substs,
177+ visited,
178+ ) ,
179+ Component :: Projection ( projection_ty) => self . projection_opaque_bounds (
180+ GenericKind :: Projection ( projection_ty) ,
181+ projection_ty. item_def_id ,
182+ projection_ty. substs ,
183+ visited,
184+ ) ,
204185 Component :: EscapingProjection ( ref components) => {
205186 self . bound_from_components ( components, visited)
206187 }
0 commit comments