|
10 | 10 |
|
11 | 11 | use hir::def_id::DefId; |
12 | 12 | use infer::InferCtxt; |
13 | | -use ty::outlives::Component; |
14 | 13 | use ty::subst::Substs; |
15 | 14 | use traits; |
16 | 15 | use ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; |
@@ -107,133 +106,6 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, |
107 | 106 | wf.normalize() |
108 | 107 | } |
109 | 108 |
|
110 | | -/// Implied bounds are region relationships that we deduce |
111 | | -/// automatically. The idea is that (e.g.) a caller must check that a |
112 | | -/// function's argument types are well-formed immediately before |
113 | | -/// calling that fn, and hence the *callee* can assume that its |
114 | | -/// argument types are well-formed. This may imply certain relationships |
115 | | -/// between generic parameters. For example: |
116 | | -/// |
117 | | -/// fn foo<'a,T>(x: &'a T) |
118 | | -/// |
119 | | -/// can only be called with a `'a` and `T` such that `&'a T` is WF. |
120 | | -/// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`. |
121 | | -#[derive(Debug)] |
122 | | -pub enum ImpliedBound<'tcx> { |
123 | | - RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>), |
124 | | - RegionSubParam(ty::Region<'tcx>, ty::ParamTy), |
125 | | - RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>), |
126 | | -} |
127 | | - |
128 | | -/// Compute the implied bounds that a callee/impl can assume based on |
129 | | -/// the fact that caller/projector has ensured that `ty` is WF. See |
130 | | -/// the `ImpliedBound` type for more details. |
131 | | -pub fn implied_bounds<'a, 'gcx, 'tcx>( |
132 | | - infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, |
133 | | - param_env: ty::ParamEnv<'tcx>, |
134 | | - body_id: ast::NodeId, |
135 | | - ty: Ty<'tcx>, |
136 | | - span: Span) |
137 | | - -> Vec<ImpliedBound<'tcx>> |
138 | | -{ |
139 | | - // Sometimes when we ask what it takes for T: WF, we get back that |
140 | | - // U: WF is required; in that case, we push U onto this stack and |
141 | | - // process it next. Currently (at least) these resulting |
142 | | - // predicates are always guaranteed to be a subset of the original |
143 | | - // type, so we need not fear non-termination. |
144 | | - let mut wf_types = vec![ty]; |
145 | | - |
146 | | - let mut implied_bounds = vec![]; |
147 | | - |
148 | | - while let Some(ty) = wf_types.pop() { |
149 | | - // Compute the obligations for `ty` to be well-formed. If `ty` is |
150 | | - // an unresolved inference variable, just substituted an empty set |
151 | | - // -- because the return type here is going to be things we *add* |
152 | | - // to the environment, it's always ok for this set to be smaller |
153 | | - // than the ultimate set. (Note: normally there won't be |
154 | | - // unresolved inference variables here anyway, but there might be |
155 | | - // during typeck under some circumstances.) |
156 | | - let obligations = obligations(infcx, param_env, body_id, ty, span).unwrap_or(vec![]); |
157 | | - |
158 | | - // From the full set of obligations, just filter down to the |
159 | | - // region relationships. |
160 | | - implied_bounds.extend( |
161 | | - obligations |
162 | | - .into_iter() |
163 | | - .flat_map(|obligation| { |
164 | | - assert!(!obligation.has_escaping_regions()); |
165 | | - match obligation.predicate { |
166 | | - ty::Predicate::Trait(..) | |
167 | | - ty::Predicate::Equate(..) | |
168 | | - ty::Predicate::Subtype(..) | |
169 | | - ty::Predicate::Projection(..) | |
170 | | - ty::Predicate::ClosureKind(..) | |
171 | | - ty::Predicate::ObjectSafe(..) => |
172 | | - vec![], |
173 | | - |
174 | | - ty::Predicate::WellFormed(subty) => { |
175 | | - wf_types.push(subty); |
176 | | - vec![] |
177 | | - } |
178 | | - |
179 | | - ty::Predicate::RegionOutlives(ref data) => |
180 | | - match infcx.tcx.no_late_bound_regions(data) { |
181 | | - None => |
182 | | - vec![], |
183 | | - Some(ty::OutlivesPredicate(r_a, r_b)) => |
184 | | - vec![ImpliedBound::RegionSubRegion(r_b, r_a)], |
185 | | - }, |
186 | | - |
187 | | - ty::Predicate::TypeOutlives(ref data) => |
188 | | - match infcx.tcx.no_late_bound_regions(data) { |
189 | | - None => vec![], |
190 | | - Some(ty::OutlivesPredicate(ty_a, r_b)) => { |
191 | | - let ty_a = infcx.resolve_type_vars_if_possible(&ty_a); |
192 | | - let components = infcx.tcx.outlives_components(ty_a); |
193 | | - implied_bounds_from_components(r_b, components) |
194 | | - } |
195 | | - }, |
196 | | - }})); |
197 | | - } |
198 | | - |
199 | | - implied_bounds |
200 | | -} |
201 | | - |
202 | | -/// When we have an implied bound that `T: 'a`, we can further break |
203 | | -/// this down to determine what relationships would have to hold for |
204 | | -/// `T: 'a` to hold. We get to assume that the caller has validated |
205 | | -/// those relationships. |
206 | | -fn implied_bounds_from_components<'tcx>(sub_region: ty::Region<'tcx>, |
207 | | - sup_components: Vec<Component<'tcx>>) |
208 | | - -> Vec<ImpliedBound<'tcx>> |
209 | | -{ |
210 | | - sup_components |
211 | | - .into_iter() |
212 | | - .flat_map(|component| { |
213 | | - match component { |
214 | | - Component::Region(r) => |
215 | | - vec![ImpliedBound::RegionSubRegion(sub_region, r)], |
216 | | - Component::Param(p) => |
217 | | - vec![ImpliedBound::RegionSubParam(sub_region, p)], |
218 | | - Component::Projection(p) => |
219 | | - vec![ImpliedBound::RegionSubProjection(sub_region, p)], |
220 | | - Component::EscapingProjection(_) => |
221 | | - // If the projection has escaping regions, don't |
222 | | - // try to infer any implied bounds even for its |
223 | | - // free components. This is conservative, because |
224 | | - // the caller will still have to prove that those |
225 | | - // free components outlive `sub_region`. But the |
226 | | - // idea is that the WAY that the caller proves |
227 | | - // that may change in the future and we want to |
228 | | - // give ourselves room to get smarter here. |
229 | | - vec![], |
230 | | - Component::UnresolvedInferenceVariable(..) => |
231 | | - vec![], |
232 | | - } |
233 | | - }) |
234 | | - .collect() |
235 | | -} |
236 | | - |
237 | 109 | struct WfPredicates<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { |
238 | 110 | infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, |
239 | 111 | param_env: ty::ParamEnv<'tcx>, |
|
0 commit comments