Skip to content

Commit c7953bb

Browse files
nikomatsakissgrif
authored andcommitted
obtain UnificationTable and snapshot_vec from ena instead
The ena version has an improved interface. I suspect `librustc_data_structures` should start migrating out to crates.io in general.
1 parent b680b12 commit c7953bb

File tree

9 files changed

+88
-65
lines changed

9 files changed

+88
-65
lines changed

src/librustc/infer/combine.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
132132
{
133133
self.int_unification_table
134134
.borrow_mut()
135-
.unify_var_value(vid, val)
135+
.unify_var_value(vid, Some(val))
136136
.map_err(|e| int_unification_error(vid_is_expected, e))?;
137137
match val {
138138
IntType(v) => Ok(self.tcx.mk_mach_int(v)),
@@ -148,7 +148,7 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
148148
{
149149
self.float_unification_table
150150
.borrow_mut()
151-
.unify_var_value(vid, val)
151+
.unify_var_value(vid, Some(ty::FloatVarValue(val)))
152152
.map_err(|e| float_unification_error(vid_is_expected, e))?;
153153
Ok(self.tcx.mk_mach_float(val))
154154
}
@@ -518,9 +518,9 @@ fn int_unification_error<'tcx>(a_is_expected: bool, v: (ty::IntVarValue, ty::Int
518518
}
519519

520520
fn float_unification_error<'tcx>(a_is_expected: bool,
521-
v: (ast::FloatTy, ast::FloatTy))
521+
v: (ty::FloatVarValue, ty::FloatVarValue))
522522
-> TypeError<'tcx>
523523
{
524-
let (a, b) = v;
524+
let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
525525
TypeError::FloatMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b))
526526
}

src/librustc/infer/freshen.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
143143
ty::TyInfer(ty::IntVar(v)) => {
144144
self.freshen(
145145
self.infcx.int_unification_table.borrow_mut()
146-
.probe(v)
146+
.probe_value(v)
147147
.map(|v| v.to_type(tcx)),
148148
ty::IntVar(v),
149149
ty::FreshIntTy)
@@ -152,7 +152,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
152152
ty::TyInfer(ty::FloatVar(v)) => {
153153
self.freshen(
154154
self.infcx.float_unification_table.borrow_mut()
155-
.probe(v)
155+
.probe_value(v)
156156
.map(|v| v.to_type(tcx)),
157157
ty::FloatVar(v),
158158
ty::FreshFloatTy)

src/librustc/infer/mod.rs

+35-30
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
2929
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
3030
use ty::relate::RelateResult;
3131
use traits::{self, ObligationCause, PredicateObligations, Reveal};
32-
use rustc_data_structures::unify::{self, UnificationTable};
32+
use rustc_data_structures::unify as ut;
3333
use std::cell::{Cell, RefCell, Ref, RefMut};
3434
use std::collections::BTreeMap;
3535
use std::fmt;
@@ -99,10 +99,10 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
9999
pub type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
100100

101101
// Map from integral variable to the kind of integer it represents
102-
int_unification_table: RefCell<UnificationTable<ty::IntVid>>,
102+
int_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::IntVid>>>,
103103

104104
// Map from floating variable to the kind of float it represents
105-
float_unification_table: RefCell<UnificationTable<ty::FloatVid>>,
105+
float_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::FloatVid>>>,
106106

107107
// Tracks the set of region variables and the constraints between
108108
// them. This is initially `Some(_)` but when
@@ -441,8 +441,8 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
441441
in_progress_tables,
442442
projection_cache: RefCell::new(traits::ProjectionCache::new()),
443443
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
444-
int_unification_table: RefCell::new(UnificationTable::new()),
445-
float_unification_table: RefCell::new(UnificationTable::new()),
444+
int_unification_table: RefCell::new(ut::UnificationTable::new()),
445+
float_unification_table: RefCell::new(ut::UnificationTable::new()),
446446
region_constraints: RefCell::new(Some(RegionConstraintCollector::new())),
447447
lexical_region_resolutions: RefCell::new(None),
448448
selection_cache: traits::SelectionCache::new(),
@@ -476,8 +476,8 @@ impl<'tcx, T> InferOk<'tcx, T> {
476476
pub struct CombinedSnapshot<'a, 'tcx:'a> {
477477
projection_cache_snapshot: traits::ProjectionCacheSnapshot,
478478
type_snapshot: type_variable::Snapshot,
479-
int_snapshot: unify::Snapshot<ty::IntVid>,
480-
float_snapshot: unify::Snapshot<ty::FloatVid>,
479+
int_snapshot: ut::Snapshot<ut::InPlace<ty::IntVid>>,
480+
float_snapshot: ut::Snapshot<ut::InPlace<ty::FloatVid>>,
481481
region_constraints_snapshot: RegionSnapshot,
482482
region_obligations_snapshot: usize,
483483
was_in_snapshot: bool,
@@ -678,14 +678,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
678678
use ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
679679
match ty.sty {
680680
ty::TyInfer(ty::IntVar(vid)) => {
681-
if self.int_unification_table.borrow_mut().has_value(vid) {
681+
if self.int_unification_table.borrow_mut().probe_value(vid).is_some() {
682682
Neither
683683
} else {
684684
UnconstrainedInt
685685
}
686686
},
687687
ty::TyInfer(ty::FloatVar(vid)) => {
688-
if self.float_unification_table.borrow_mut().has_value(vid) {
688+
if self.float_unification_table.borrow_mut().probe_value(vid).is_some() {
689689
Neither
690690
} else {
691691
UnconstrainedFloat
@@ -698,27 +698,32 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
698698
pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> {
699699
let mut variables = Vec::new();
700700

701-
let unbound_ty_vars = self.type_variables
702-
.borrow_mut()
703-
.unsolved_variables()
704-
.into_iter()
705-
.map(|t| self.tcx.mk_var(t));
706-
707-
let unbound_int_vars = self.int_unification_table
708-
.borrow_mut()
709-
.unsolved_variables()
710-
.into_iter()
711-
.map(|v| self.tcx.mk_int_var(v));
701+
{
702+
let mut type_variables = self.type_variables.borrow_mut();
703+
variables.extend(
704+
type_variables
705+
.unsolved_variables()
706+
.into_iter()
707+
.map(|t| self.tcx.mk_var(t)));
708+
}
712709

713-
let unbound_float_vars = self.float_unification_table
714-
.borrow_mut()
715-
.unsolved_variables()
716-
.into_iter()
717-
.map(|v| self.tcx.mk_float_var(v));
710+
{
711+
let mut int_unification_table = self.int_unification_table.borrow_mut();
712+
variables.extend(
713+
(0..int_unification_table.len())
714+
.map(|i| ty::IntVid { index: i as u32 })
715+
.filter(|&vid| int_unification_table.probe_value(vid).is_none())
716+
.map(|v| self.tcx.mk_int_var(v)));
717+
}
718718

719-
variables.extend(unbound_ty_vars);
720-
variables.extend(unbound_int_vars);
721-
variables.extend(unbound_float_vars);
719+
{
720+
let mut float_unification_table = self.float_unification_table.borrow_mut();
721+
variables.extend(
722+
(0..float_unification_table.len())
723+
.map(|i| ty::FloatVid { index: i as u32 })
724+
.filter(|&vid| float_unification_table.probe_value(vid).is_none())
725+
.map(|v| self.tcx.mk_float_var(v)));
726+
}
722727

723728
return variables;
724729
}
@@ -1262,15 +1267,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12621267
ty::TyInfer(ty::IntVar(v)) => {
12631268
self.int_unification_table
12641269
.borrow_mut()
1265-
.probe(v)
1270+
.probe_value(v)
12661271
.map(|v| v.to_type(self.tcx))
12671272
.unwrap_or(typ)
12681273
}
12691274

12701275
ty::TyInfer(ty::FloatVar(v)) => {
12711276
self.float_unification_table
12721277
.borrow_mut()
1273-
.probe(v)
1278+
.probe_value(v)
12741279
.map(|v| v.to_type(self.tcx))
12751280
.unwrap_or(typ)
12761281
}

src/librustc/infer/type_variable.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct TypeVariableTable<'tcx> {
2626

2727
/// Two variables are unified in `eq_relations` when we have a
2828
/// constraint `?X == ?Y`.
29-
eq_relations: ut::UnificationTable<ty::TyVid>,
29+
eq_relations: ut::UnificationTable<ut::InPlace<ty::TyVid>>,
3030

3131
/// Two variables are unified in `eq_relations` when we have a
3232
/// constraint `?X <: ?Y` *or* a constraint `?Y <: ?X`. This second
@@ -45,7 +45,7 @@ pub struct TypeVariableTable<'tcx> {
4545
/// This is reasonable because, in Rust, subtypes have the same
4646
/// "skeleton" and hence there is no possible type such that
4747
/// (e.g.) `Box<?3> <: ?3` for any `?3`.
48-
sub_relations: ut::UnificationTable<ty::TyVid>,
48+
sub_relations: ut::UnificationTable<ut::InPlace<ty::TyVid>>,
4949
}
5050

5151
/// Reasons to create a type inference variable
@@ -86,8 +86,8 @@ enum TypeVariableValue<'tcx> {
8686

8787
pub struct Snapshot {
8888
snapshot: sv::Snapshot,
89-
eq_snapshot: ut::Snapshot<ty::TyVid>,
90-
sub_snapshot: ut::Snapshot<ty::TyVid>,
89+
eq_snapshot: ut::Snapshot<ut::InPlace<ty::TyVid>>,
90+
sub_snapshot: ut::Snapshot<ut::InPlace<ty::TyVid>>,
9191
}
9292

9393
struct Instantiate {
@@ -354,3 +354,10 @@ impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
354354
values[vid.index as usize].value = Unknown;
355355
}
356356
}
357+
358+
impl ut::UnifyKey for ty::TyVid {
359+
type Value = ();
360+
fn index(&self) -> u32 { self.index }
361+
fn from_index(i: u32) -> ty::TyVid { ty::TyVid { index: i } }
362+
fn tag() -> &'static str { "TyVid" }
363+
}

src/librustc/infer/unify_key.rs

+22-22
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use syntax::ast;
12-
use ty::{self, IntVarValue, Ty, TyCtxt};
13-
use rustc_data_structures::unify::{Combine, UnifyKey};
11+
use ty::{self, FloatVarValue, IntVarValue, Ty, TyCtxt};
12+
use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue};
1413

1514
pub trait ToType {
1615
fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx>;
@@ -20,7 +19,10 @@ impl UnifyKey for ty::IntVid {
2019
type Value = Option<IntVarValue>;
2120
fn index(&self) -> u32 { self.index }
2221
fn from_index(i: u32) -> ty::IntVid { ty::IntVid { index: i } }
23-
fn tag(_: Option<ty::IntVid>) -> &'static str { "IntVid" }
22+
fn tag() -> &'static str { "IntVid" }
23+
}
24+
25+
impl EqUnifyValue for IntVarValue {
2426
}
2527

2628
#[derive(PartialEq, Copy, Clone, Debug)]
@@ -31,23 +33,25 @@ pub struct RegionVidKey {
3133
pub min_vid: ty::RegionVid
3234
}
3335

34-
impl Combine for RegionVidKey {
35-
fn combine(&self, other: &RegionVidKey) -> RegionVidKey {
36-
let min_vid = if self.min_vid.index() < other.min_vid.index() {
37-
self.min_vid
36+
impl UnifyValue for RegionVidKey {
37+
type Error = NoError;
38+
39+
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> {
40+
let min_vid = if value1.min_vid.index() < value2.min_vid.index() {
41+
value1.min_vid
3842
} else {
39-
other.min_vid
43+
value2.min_vid
4044
};
4145

42-
RegionVidKey { min_vid: min_vid }
46+
Ok(RegionVidKey { min_vid: min_vid })
4347
}
4448
}
4549

4650
impl UnifyKey for ty::RegionVid {
4751
type Value = RegionVidKey;
4852
fn index(&self) -> u32 { self.0 }
4953
fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid(i) }
50-
fn tag(_: Option<ty::RegionVid>) -> &'static str { "RegionVid" }
54+
fn tag() -> &'static str { "RegionVid" }
5155
}
5256

5357
impl ToType for IntVarValue {
@@ -62,21 +66,17 @@ impl ToType for IntVarValue {
6266
// Floating point type keys
6367

6468
impl UnifyKey for ty::FloatVid {
65-
type Value = Option<ast::FloatTy>;
69+
type Value = Option<FloatVarValue>;
6670
fn index(&self) -> u32 { self.index }
6771
fn from_index(i: u32) -> ty::FloatVid { ty::FloatVid { index: i } }
68-
fn tag(_: Option<ty::FloatVid>) -> &'static str { "FloatVid" }
72+
fn tag() -> &'static str { "FloatVid" }
6973
}
7074

71-
impl ToType for ast::FloatTy {
72-
fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
73-
tcx.mk_mach_float(*self)
74-
}
75+
impl EqUnifyValue for FloatVarValue {
7576
}
7677

77-
impl UnifyKey for ty::TyVid {
78-
type Value = ();
79-
fn index(&self) -> u32 { self.index }
80-
fn from_index(i: u32) -> ty::TyVid { ty::TyVid { index: i } }
81-
fn tag(_: Option<ty::TyVid>) -> &'static str { "TyVid" }
78+
impl ToType for FloatVarValue {
79+
fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
80+
tcx.mk_mach_float(self.0)
81+
}
8282
}

src/librustc/ty/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -685,12 +685,15 @@ pub struct ClosureUpvar<'tcx> {
685685
pub ty: Ty<'tcx>,
686686
}
687687

688-
#[derive(Clone, Copy, PartialEq)]
688+
#[derive(Clone, Copy, PartialEq, Eq)]
689689
pub enum IntVarValue {
690690
IntType(ast::IntTy),
691691
UintType(ast::UintTy),
692692
}
693693

694+
#[derive(Clone, Copy, PartialEq, Eq)]
695+
pub struct FloatVarValue(pub ast::FloatTy);
696+
694697
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
695698
pub struct TypeParameterDef {
696699
pub name: Name,

src/librustc/util/ppaux.rs

+6
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,12 @@ impl fmt::Debug for ty::IntVarValue {
916916
}
917917
}
918918

919+
impl fmt::Debug for ty::FloatVarValue {
920+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
921+
self.0.fmt(f)
922+
}
923+
}
924+
919925
// The generic impl doesn't work yet because projections are not
920926
// normalized under HRTB.
921927
/*impl<T> fmt::Display for ty::Binder<T>

src/librustc_data_structures/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ path = "lib.rs"
99
crate-type = ["dylib"]
1010

1111
[dependencies]
12+
ena = "0.8.0"
1213
log = "0.4"
1314
serialize = { path = "../libserialize" }
1415
cfg-if = "0.1.2"

src/librustc_data_structures/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#![cfg_attr(test, feature(test))]
4040

4141
extern crate core;
42+
extern crate ena;
4243
#[macro_use]
4344
extern crate log;
4445
extern crate serialize as rustc_serialize; // used by deriving
@@ -63,10 +64,10 @@ pub mod indexed_vec;
6364
pub mod obligation_forest;
6465
pub mod sip128;
6566
pub mod snapshot_map;
66-
pub mod snapshot_vec;
67+
pub use ena::snapshot_vec;
6768
pub mod stable_hasher;
6869
pub mod transitive_relation;
69-
pub mod unify;
70+
pub use ena::unify;
7071
pub mod fx;
7172
pub mod tuple_slice;
7273
pub mod control_flow_graph;

0 commit comments

Comments
 (0)