|
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