Skip to content

Commit 13efaf0

Browse files
nikomatsakissgrif
authored andcommitted
add universes to type inference variables
1 parent 44d9929 commit 13efaf0

File tree

21 files changed

+132
-55
lines changed

21 files changed

+132
-55
lines changed

src/librustc/infer/anon_types/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,8 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
600600
return anon_defn.concrete_ty;
601601
}
602602
let span = tcx.def_span(def_id);
603-
let ty_var = infcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
603+
let ty_var = infcx.next_ty_var(ty::UniverseIndex::ROOT,
604+
TypeVariableOrigin::TypeInference(span));
604605

605606
let predicates_of = tcx.predicates_of(def_id);
606607
let bounds = predicates_of.instantiate(tcx, substs);

src/librustc/infer/combine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
407407
drop(variables);
408408
self.relate(&u, &u)
409409
}
410-
TypeVariableValue::Unknown { .. } => {
410+
TypeVariableValue::Unknown { universe } => {
411411
match self.ambient_variance {
412412
// Invariant: no need to make a fresh type variable.
413413
ty::Invariant => return Ok(t),
@@ -424,7 +424,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
424424
}
425425

426426
let origin = *variables.var_origin(vid);
427-
let new_var_id = variables.new_var(false, origin);
427+
let new_var_id = variables.new_var(universe, false, origin);
428428
let u = self.tcx().mk_var(new_var_id);
429429
debug!("generalize: replacing original vid={:?} with new={:?}",
430430
vid, u);

src/librustc/infer/fudge.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,11 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFudger<'a, 'gcx, 'tcx> {
141141
// This variable was created during the
142142
// fudging. Recreate it with a fresh variable
143143
// here.
144-
self.infcx.next_ty_var(origin)
144+
//
145+
// The ROOT universe is fine because we only
146+
// ever invoke this routine at the
147+
// "item-level" of inference.
148+
self.infcx.next_ty_var(ty::UniverseIndex::ROOT, origin)
145149
}
146150
}
147151
}

src/librustc/infer/lattice.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,17 @@ pub fn super_lattice_tys<'a, 'gcx, 'tcx, L>(this: &mut L,
8888
// is (e.g.) `Box<i32>`. A more obvious solution might be to
8989
// iterate on the subtype obligations that are returned, but I
9090
// think this suffices. -nmatsakis
91-
(&ty::TyInfer(TyVar(..)), _) => {
92-
let v = infcx.next_ty_var(TypeVariableOrigin::LatticeVariable(this.cause().span));
91+
(&ty::TyInfer(TyVar(a_vid)), _) => {
92+
let universe = infcx.type_variables.borrow_mut().probe(a_vid).universe().unwrap();
93+
let v = infcx.next_ty_var(universe,
94+
TypeVariableOrigin::LatticeVariable(this.cause().span));
9395
this.relate_bound(v, b, a)?;
9496
Ok(v)
9597
}
96-
(_, &ty::TyInfer(TyVar(..))) => {
97-
let v = infcx.next_ty_var(TypeVariableOrigin::LatticeVariable(this.cause().span));
98+
(_, &ty::TyInfer(TyVar(b_vid))) => {
99+
let universe = infcx.type_variables.borrow_mut().probe(b_vid).universe().unwrap();
100+
let v = infcx.next_ty_var(universe,
101+
TypeVariableOrigin::LatticeVariable(this.cause().span));
98102
this.relate_bound(v, a, b)?;
99103
Ok(v)
100104
}

src/librustc/infer/mod.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,18 +1015,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10151015
})
10161016
}
10171017

1018-
pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid {
1018+
pub fn next_ty_var_id(&self,
1019+
universe: ty::UniverseIndex,
1020+
diverging: bool,
1021+
origin: TypeVariableOrigin)
1022+
-> TyVid {
10191023
self.type_variables
10201024
.borrow_mut()
1021-
.new_var(diverging, origin)
1025+
.new_var(universe, diverging, origin)
10221026
}
10231027

1024-
pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
1025-
self.tcx.mk_var(self.next_ty_var_id(false, origin))
1028+
pub fn next_ty_var(&self, universe: ty::UniverseIndex, origin: TypeVariableOrigin) -> Ty<'tcx> {
1029+
self.tcx.mk_var(self.next_ty_var_id(universe, false, origin))
10261030
}
10271031

1028-
pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
1029-
self.tcx.mk_var(self.next_ty_var_id(true, origin))
1032+
pub fn next_diverging_ty_var(&self, universe: ty::UniverseIndex, origin: TypeVariableOrigin) -> Ty<'tcx> {
1033+
self.tcx.mk_var(self.next_ty_var_id(universe, true, origin))
10301034
}
10311035

10321036
pub fn next_int_var_id(&self) -> IntVid {
@@ -1081,12 +1085,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10811085
/// use an inference variable for `C` with `[T, U]`
10821086
/// as the substitutions for the default, `(T, U)`.
10831087
pub fn type_var_for_def(&self,
1088+
universe: ty::UniverseIndex,
10841089
span: Span,
10851090
def: &ty::TypeParameterDef)
10861091
-> Ty<'tcx> {
10871092
let ty_var_id = self.type_variables
10881093
.borrow_mut()
1089-
.new_var(false,
1094+
.new_var(universe,
1095+
false,
10901096
TypeVariableOrigin::TypeParameterDefinition(span, def.name));
10911097

10921098
self.tcx.mk_var(ty_var_id)
@@ -1095,13 +1101,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10951101
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
10961102
/// type/region parameter to a fresh inference variable.
10971103
pub fn fresh_substs_for_item(&self,
1104+
universe: ty::UniverseIndex,
10981105
span: Span,
10991106
def_id: DefId)
11001107
-> &'tcx Substs<'tcx> {
11011108
Substs::for_item(self.tcx, def_id, |def, _| {
11021109
self.region_var_for_def(span, def)
11031110
}, |def, _| {
1104-
self.type_var_for_def(span, def)
1111+
self.type_var_for_def(universe, span, def)
11051112
})
11061113
}
11071114

src/librustc/infer/type_variable.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use syntax::ast;
1212
use syntax_pos::Span;
1313
use ty::{self, Ty};
1414

15+
use std::cmp;
1516
use std::marker::PhantomData;
1617
use std::u32;
1718
use rustc_data_structures::fx::FxHashMap;
@@ -81,17 +82,33 @@ struct TypeVariableData {
8182
#[derive(Copy, Clone, Debug)]
8283
pub enum TypeVariableValue<'tcx> {
8384
Known { value: Ty<'tcx> },
84-
Unknown,
85+
Unknown { universe: ty::UniverseIndex },
86+
}
87+
88+
#[derive(Copy, Clone, Debug)]
89+
pub enum ProbeTyValue<'tcx> {
90+
Ty(Ty<'tcx>),
91+
Vid(ty::TyVid),
8592
}
8693

8794
impl<'tcx> TypeVariableValue<'tcx> {
95+
/// If this value is known, returns the type it is known to be.
96+
/// Otherwise, `None`.
8897
pub fn known(&self) -> Option<Ty<'tcx>> {
8998
match *self {
9099
TypeVariableValue::Unknown { .. } => None,
91100
TypeVariableValue::Known { value } => Some(value),
92101
}
93102
}
94103

104+
/// If this value is unknown, returns the universe, otherwise `None`.
105+
pub fn universe(&self) -> Option<ty::UniverseIndex> {
106+
match *self {
107+
TypeVariableValue::Unknown { universe } => Some(universe),
108+
TypeVariableValue::Known { .. } => None,
109+
}
110+
}
111+
95112
pub fn is_unknown(&self) -> bool {
96113
match *self {
97114
TypeVariableValue::Unknown { .. } => true,
@@ -178,10 +195,11 @@ impl<'tcx> TypeVariableTable<'tcx> {
178195
/// The code in this module doesn't care, but it can be useful
179196
/// for improving error messages.
180197
pub fn new_var(&mut self,
198+
universe: ty::UniverseIndex,
181199
diverging: bool,
182200
origin: TypeVariableOrigin)
183201
-> ty::TyVid {
184-
let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown);
202+
let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown { universe });
185203

186204
let sub_key = self.sub_relations.new_key(());
187205
assert_eq!(eq_key.vid, sub_key);
@@ -388,8 +406,12 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> {
388406
(&TypeVariableValue::Known { .. }, &TypeVariableValue::Unknown { .. }) => Ok(*value1),
389407
(&TypeVariableValue::Unknown { .. }, &TypeVariableValue::Known { .. }) => Ok(*value2),
390408

391-
// If both sides are *unknown*, it hardly matters, does it?
392-
(&TypeVariableValue::Unknown, &TypeVariableValue::Unknown) => Ok(*value1),
409+
// If both sides are unknown, we need to pick the most restrictive universe.
410+
(&TypeVariableValue::Unknown { universe: universe1 },
411+
&TypeVariableValue::Unknown { universe: universe2 }) => {
412+
let universe = cmp::min(universe1, universe2);
413+
Ok(TypeVariableValue::Unknown { universe })
414+
}
393415
}
394416
}
395417
}

src/librustc/traits/coherence.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, '
9292
-> ty::ImplHeader<'tcx>
9393
{
9494
let tcx = selcx.tcx();
95-
let impl_substs = selcx.infcx().fresh_substs_for_item(DUMMY_SP, impl_def_id);
95+
let impl_substs = selcx.infcx().fresh_substs_for_item(param_env.universe,
96+
DUMMY_SP,
97+
impl_def_id);
9698

9799
let header = ty::ImplHeader {
98100
impl_def_id,

src/librustc/traits/error_reporting.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
292292

293293
self.tcx.for_each_relevant_impl(
294294
trait_ref.def_id, trait_self_ty, |def_id| {
295-
let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id);
295+
let impl_substs = self.fresh_substs_for_item(param_env.universe,
296+
obligation.cause.span,
297+
def_id);
296298
let impl_trait_ref = tcx
297299
.impl_trait_ref(def_id)
298300
.unwrap()
@@ -1194,6 +1196,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11941196
-> bool {
11951197
struct ParamToVarFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
11961198
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
1199+
param_env: ty::ParamEnv<'tcx>,
11971200
var_map: FxHashMap<Ty<'tcx>, Ty<'tcx>>
11981201
}
11991202

@@ -1203,9 +1206,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12031206
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
12041207
if let ty::TyParam(ty::ParamTy {name, ..}) = ty.sty {
12051208
let infcx = self.infcx;
1206-
self.var_map.entry(ty).or_insert_with(||
1207-
infcx.next_ty_var(
1208-
TypeVariableOrigin::TypeParameterDefinition(DUMMY_SP, name)))
1209+
let param_env = self.param_env;
1210+
self.var_map
1211+
.entry(ty)
1212+
.or_insert_with(|| {
1213+
let origin = TypeVariableOrigin::TypeParameterDefinition(DUMMY_SP,
1214+
name);
1215+
infcx.next_ty_var(param_env.universe, origin)
1216+
})
12091217
} else {
12101218
ty.super_fold_with(self)
12111219
}
@@ -1217,6 +1225,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12171225

12181226
let cleaned_pred = pred.fold_with(&mut ParamToVarFolder {
12191227
infcx: self,
1228+
param_env,
12201229
var_map: FxHashMap()
12211230
});
12221231

src/librustc/traits/project.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ pub fn normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
469469
let tcx = selcx.infcx().tcx;
470470
let def_id = projection_ty.item_def_id;
471471
let ty_var = selcx.infcx().next_ty_var(
472+
param_env.universe,
472473
TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id)));
473474
let projection = ty::Binder(ty::ProjectionPredicate {
474475
projection_ty,
@@ -789,6 +790,7 @@ fn normalize_to_error<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tc
789790
let tcx = selcx.infcx().tcx;
790791
let def_id = projection_ty.item_def_id;
791792
let new_value = selcx.infcx().next_ty_var(
793+
param_env.universe,
792794
TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id)));
793795
Normalized {
794796
value: new_value,

src/librustc/traits/select.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3111,7 +3111,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
31113111
snapshot);
31123112
let skol_obligation_trait_ref = skol_obligation.trait_ref;
31133113

3114-
let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span,
3114+
let impl_substs = self.infcx.fresh_substs_for_item(obligation.param_env.universe,
3115+
obligation.cause.span,
31153116
impl_def_id);
31163117

31173118
let impl_trait_ref = impl_trait_ref.subst(self.tcx(),

0 commit comments

Comments
 (0)