@@ -38,21 +38,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
38
38
Self { tcx, region_bound_pairs, implicit_region_bound, param_env }
39
39
}
40
40
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
-
54
41
#[ 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 > {
56
43
// Start with anything like `T: 'a` we can scrape from the
57
44
// environment. If the environment contains something like
58
45
// `for<'a> T: 'a`, then we know that `T` outlives everything.
@@ -116,20 +103,21 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
116
103
}
117
104
118
105
#[ instrument( level = "debug" , skip( self , visited) ) ]
119
- fn projection_bound (
106
+ pub fn projection_opaque_bounds (
120
107
& self ,
121
- projection_ty : ty:: ProjectionTy < ' tcx > ,
108
+ generic : GenericKind < ' tcx > ,
109
+ def_id : DefId ,
110
+ substs : SubstsRef < ' tcx > ,
122
111
visited : & mut SsoHashSet < GenericArg < ' tcx > > ,
123
112
) -> 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 ) ;
126
114
127
115
// 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 )
130
118
. into_iter ( )
131
119
. 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 {
133
121
// Micro-optimize if this is an exact match (this
134
122
// occurs often when there are no region variables
135
123
// involved).
@@ -139,35 +127,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
139
127
VerifyBound :: IfEq ( verify_if_eq_b)
140
128
}
141
129
} ) ;
142
-
143
130
// 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) ) ;
147
132
148
133
// see the extensive comment in projection_must_outlive
149
134
let recursive_bound = {
150
135
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) ;
153
137
self . bound_from_components ( & components, visited)
154
138
} ;
155
139
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)
171
142
}
172
143
173
144
fn bound_from_components (
@@ -199,8 +170,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
199
170
match * component {
200
171
Component :: Region ( lt) => VerifyBound :: OutlivedBy ( lt) ,
201
172
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
+ ) ,
204
185
Component :: EscapingProjection ( ref components) => {
205
186
self . bound_from_components ( components, visited)
206
187
}
0 commit comments