Skip to content

Commit 1cc7621

Browse files
committed
simplify code to remove now unused "stack" and fix comments
1 parent fa437f4 commit 1cc7621

File tree

2 files changed

+54
-92
lines changed

2 files changed

+54
-92
lines changed

src/librustc/infer/combine.rs

Lines changed: 51 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ use ty::relate::{RelateResult, TypeRelation};
4747
use traits::PredicateObligations;
4848

4949
use syntax::ast;
50-
use syntax::util::small_vector::SmallVector;
5150
use syntax_pos::Span;
5251

5352
#[derive(Clone)]
@@ -174,6 +173,15 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
174173
Glb::new(self, a_is_expected)
175174
}
176175

176+
/// Here dir is either EqTo, SubtypeOf, or SupertypeOf. The
177+
/// idea is that we should ensure that the type `a_ty` is equal
178+
/// to, a subtype of, or a supertype of (respectively) the type
179+
/// to which `b_vid` is bound.
180+
///
181+
/// Since `b_vid` has not yet been instantiated with a type, we
182+
/// will first instantiate `b_vid` with a *generalized* version
183+
/// of `a_ty`. Generalization introduces other inference
184+
/// variables wherever subtyping could occur.
177185
pub fn instantiate(&mut self,
178186
a_ty: Ty<'tcx>,
179187
dir: RelationDir,
@@ -183,109 +191,64 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
183191
{
184192
use self::RelationDir::*;
185193

186-
// We use SmallVector here instead of Vec because this code is hot and
187-
// it's rare that the stack length exceeds 1.
188-
let mut stack = SmallVector::new();
189-
stack.push((a_ty, dir, b_vid));
190-
loop {
191-
// For each turn of the loop, we extract a tuple
192-
//
193-
// (a_ty, dir, b_vid)
194-
//
195-
// to relate. Here dir is either SubtypeOf or
196-
// SupertypeOf. The idea is that we should ensure that
197-
// the type `a_ty` is a subtype or supertype (respectively) of the
198-
// type to which `b_vid` is bound.
199-
//
200-
// If `b_vid` has not yet been instantiated with a type
201-
// (which is always true on the first iteration, but not
202-
// necessarily true on later iterations), we will first
203-
// instantiate `b_vid` with a *generalized* version of
204-
// `a_ty`. Generalization introduces other inference
205-
// variables wherever subtyping could occur (at time of
206-
// this writing, this means replacing free regions with
207-
// region variables).
208-
let (a_ty, dir, b_vid) = match stack.pop() {
209-
None => break,
210-
Some(e) => e,
211-
};
212-
// Get the actual variable that b_vid has been inferred to
213-
let (b_vid, b_ty) = {
214-
let mut variables = self.infcx.type_variables.borrow_mut();
215-
let b_vid = variables.root_var(b_vid);
216-
(b_vid, variables.probe_root(b_vid))
217-
};
218-
219-
debug!("instantiate(a_ty={:?} dir={:?} b_vid={:?})",
220-
a_ty,
221-
dir,
222-
b_vid);
223-
224-
// Check whether `vid` has been instantiated yet. If not,
225-
// make a generalized form of `ty` and instantiate with
226-
// that.
227-
//
228-
// FIXME(#18653) -- we need to generalize nested type
229-
// variables too.
230-
let b_ty = match b_ty {
231-
Some(t) => t, // ...already instantiated.
232-
None => { // ...not yet instantiated:
233-
// Generalize type if necessary.
234-
let generalized_ty = match dir {
235-
EqTo => self.generalize(a_ty, b_vid, false),
236-
SupertypeOf | SubtypeOf => self.generalize(a_ty, b_vid, true),
237-
}?;
238-
debug!("instantiate(a_ty={:?}, dir={:?}, \
239-
b_vid={:?}, generalized_ty={:?})",
240-
a_ty, dir, b_vid,
241-
generalized_ty);
242-
self.infcx.type_variables
243-
.borrow_mut()
244-
.instantiate(b_vid, generalized_ty);
245-
generalized_ty
246-
}
247-
};
248-
249-
// The original triple was `(a_ty, dir, b_vid)` -- now we have
250-
// resolved `b_vid` to `b_ty`, so apply `(a_ty, dir, b_ty)`:
251-
//
252-
// FIXME(#16847): This code is non-ideal because all these subtype
253-
// relations wind up attributed to the same spans. We need
254-
// to associate causes/spans with each of the relations in
255-
// the stack to get this right.
256-
match dir {
257-
EqTo => self.equate(a_is_expected).relate(&a_ty, &b_ty),
258-
SubtypeOf => self.sub(a_is_expected).relate(&a_ty, &b_ty),
259-
SupertypeOf => self.sub(a_is_expected).relate_with_variance(
260-
ty::Contravariant, &a_ty, &b_ty),
261-
}?;
262-
}
194+
// Get the actual variable that b_vid has been inferred to
195+
debug_assert!(self.infcx.type_variables.borrow_mut().probe(b_vid).is_none());
196+
197+
debug!("instantiate(a_ty={:?} dir={:?} b_vid={:?})", a_ty, dir, b_vid);
198+
199+
// Generalize type of `a_ty` appropriately depending on the
200+
// direction. As an example, assume:
201+
//
202+
// - `a_ty == &'x ?1`, where `'x` is some free region and `?1` is an
203+
// inference variable,
204+
// - and `dir` == `SubtypeOf`.
205+
//
206+
// Then the generalized form `b_ty` would be `&'?2 ?3`, where
207+
// `'?2` and `?3` are fresh region/type inference
208+
// variables. (Down below, we will relate `a_ty <: b_ty`,
209+
// adding constraints like `'x: '?2` and `?1 <: ?3`.)
210+
let b_ty = self.generalize(a_ty, b_vid, dir == EqTo)?;
211+
debug!("instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})",
212+
a_ty, dir, b_vid, b_ty);
213+
self.infcx.type_variables.borrow_mut().instantiate(b_vid, b_ty);
214+
215+
// Finally, relate `b_ty` to `a_ty`, as described in previous comment.
216+
//
217+
// FIXME(#16847): This code is non-ideal because all these subtype
218+
// relations wind up attributed to the same spans. We need
219+
// to associate causes/spans with each of the relations in
220+
// the stack to get this right.
221+
match dir {
222+
EqTo => self.equate(a_is_expected).relate(&a_ty, &b_ty),
223+
SubtypeOf => self.sub(a_is_expected).relate(&a_ty, &b_ty),
224+
SupertypeOf => self.sub(a_is_expected).relate_with_variance(
225+
ty::Contravariant, &a_ty, &b_ty),
226+
}?;
263227

264228
Ok(())
265229
}
266230

267231
/// Attempts to generalize `ty` for the type variable `for_vid`.
268232
/// This checks for cycle -- that is, whether the type `ty`
269-
/// references `for_vid`. If `make_region_vars` is true, it will
270-
/// also replace all regions with fresh variables. Returns
271-
/// `TyError` in the case of a cycle, `Ok` otherwise.
233+
/// references `for_vid`. If `is_eq_relation` is false, it will
234+
/// also replace all regions/unbound-type-variables with fresh
235+
/// variables. Returns `TyError` in the case of a cycle, `Ok`
236+
/// otherwise.
272237
///
273238
/// Preconditions:
274239
///
275240
/// - `for_vid` is a "root vid"
276241
fn generalize(&self,
277242
ty: Ty<'tcx>,
278243
for_vid: ty::TyVid,
279-
make_region_vars: bool)
244+
is_eq_relation: bool)
280245
-> RelateResult<'tcx, Ty<'tcx>>
281246
{
282-
debug_assert!(self.infcx.type_variables.borrow_mut().root_var(for_vid) == for_vid);
283-
284247
let mut generalize = Generalizer {
285248
infcx: self.infcx,
286249
span: self.trace.cause.span,
287250
for_vid_sub_root: self.infcx.type_variables.borrow_mut().sub_root_var(for_vid),
288-
make_region_vars: make_region_vars,
251+
is_eq_relation: is_eq_relation,
289252
cycle_detected: false
290253
};
291254
let u = ty.fold_with(&mut generalize);
@@ -301,7 +264,7 @@ struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
301264
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
302265
span: Span,
303266
for_vid_sub_root: ty::TyVid,
304-
make_region_vars: bool,
267+
is_eq_relation: bool,
305268
cycle_detected: bool,
306269
}
307270

@@ -332,7 +295,7 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
332295
self.fold_ty(u)
333296
}
334297
None => {
335-
if self.make_region_vars {
298+
if !self.is_eq_relation {
336299
let origin = variables.origin(vid);
337300
let new_var_id = variables.new_var(false, origin, None);
338301
let u = self.tcx().mk_var(new_var_id);
@@ -379,7 +342,7 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
379342
ty::ReScope(..) |
380343
ty::ReVar(..) |
381344
ty::ReFree(..) => {
382-
if !self.make_region_vars {
345+
if self.is_eq_relation {
383346
return r;
384347
}
385348
}

src/librustc/infer/type_variable.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,10 @@ impl<'tcx> TypeVariableTable<'tcx> {
151151

152152
/// Instantiates `vid` with the type `ty`.
153153
///
154-
/// Precondition: `vid` must be a root in the unification table
155-
/// and has not previously been instantiated.
154+
/// Precondition: `vid` must not have been previously instantiated.
156155
pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) {
157-
debug_assert!(self.root_var(vid) == vid);
158-
debug_assert!(self.probe(vid).is_none());
156+
let vid = self.root_var(vid);
157+
debug_assert!(self.probe_root(vid).is_none());
159158

160159
let old_value = {
161160
let vid_data = &mut self.values[vid.index as usize];

0 commit comments

Comments
 (0)