about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-07-16 07:07:51 -0400
committerSean Griffin <sean@seantheprogrammer.com>2018-03-01 08:04:26 -0700
commitc7953bb6d67dead45033434161be2ed8cdd6cd31 (patch)
tree10e1b41ae54fb0bb43b63654954f89adac1e507c
parentb680b12e949097602dd6d39009fee8c95d86a261 (diff)
downloadrust-c7953bb6d67dead45033434161be2ed8cdd6cd31.tar.gz
rust-c7953bb6d67dead45033434161be2ed8cdd6cd31.zip
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.
-rw-r--r--src/librustc/infer/combine.rs8
-rw-r--r--src/librustc/infer/freshen.rs4
-rw-r--r--src/librustc/infer/mod.rs65
-rw-r--r--src/librustc/infer/type_variable.rs15
-rw-r--r--src/librustc/infer/unify_key.rs44
-rw-r--r--src/librustc/ty/mod.rs5
-rw-r--r--src/librustc/util/ppaux.rs6
-rw-r--r--src/librustc_data_structures/Cargo.toml1
-rw-r--r--src/librustc_data_structures/lib.rs5
9 files changed, 88 insertions, 65 deletions
diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs
index bd175c510fb..8997e7d99da 100644
--- a/src/librustc/infer/combine.rs
+++ b/src/librustc/infer/combine.rs
@@ -132,7 +132,7 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
     {
         self.int_unification_table
             .borrow_mut()
-            .unify_var_value(vid, val)
+            .unify_var_value(vid, Some(val))
             .map_err(|e| int_unification_error(vid_is_expected, e))?;
         match val {
             IntType(v) => Ok(self.tcx.mk_mach_int(v)),
@@ -148,7 +148,7 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
     {
         self.float_unification_table
             .borrow_mut()
-            .unify_var_value(vid, val)
+            .unify_var_value(vid, Some(ty::FloatVarValue(val)))
             .map_err(|e| float_unification_error(vid_is_expected, e))?;
         Ok(self.tcx.mk_mach_float(val))
     }
@@ -518,9 +518,9 @@ fn int_unification_error<'tcx>(a_is_expected: bool, v: (ty::IntVarValue, ty::Int
 }
 
 fn float_unification_error<'tcx>(a_is_expected: bool,
-                                 v: (ast::FloatTy, ast::FloatTy))
+                                 v: (ty::FloatVarValue, ty::FloatVarValue))
                                  -> TypeError<'tcx>
 {
-    let (a, b) = v;
+    let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
     TypeError::FloatMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b))
 }
diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs
index 8b61fcff233..25300eed548 100644
--- a/src/librustc/infer/freshen.rs
+++ b/src/librustc/infer/freshen.rs
@@ -143,7 +143,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
             ty::TyInfer(ty::IntVar(v)) => {
                 self.freshen(
                     self.infcx.int_unification_table.borrow_mut()
-                                                    .probe(v)
+                                                    .probe_value(v)
                                                     .map(|v| v.to_type(tcx)),
                     ty::IntVar(v),
                     ty::FreshIntTy)
@@ -152,7 +152,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
             ty::TyInfer(ty::FloatVar(v)) => {
                 self.freshen(
                     self.infcx.float_unification_table.borrow_mut()
-                                                      .probe(v)
+                                                      .probe_value(v)
                                                       .map(|v| v.to_type(tcx)),
                     ty::FloatVar(v),
                     ty::FreshFloatTy)
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 42928457925..72a4dfbb7e0 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -29,7 +29,7 @@ use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use ty::relate::RelateResult;
 use traits::{self, ObligationCause, PredicateObligations, Reveal};
-use rustc_data_structures::unify::{self, UnificationTable};
+use rustc_data_structures::unify as ut;
 use std::cell::{Cell, RefCell, Ref, RefMut};
 use std::collections::BTreeMap;
 use std::fmt;
@@ -99,10 +99,10 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     pub type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
 
     // Map from integral variable to the kind of integer it represents
-    int_unification_table: RefCell<UnificationTable<ty::IntVid>>,
+    int_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::IntVid>>>,
 
     // Map from floating variable to the kind of float it represents
-    float_unification_table: RefCell<UnificationTable<ty::FloatVid>>,
+    float_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::FloatVid>>>,
 
     // Tracks the set of region variables and the constraints between
     // them.  This is initially `Some(_)` but when
@@ -441,8 +441,8 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
             in_progress_tables,
             projection_cache: RefCell::new(traits::ProjectionCache::new()),
             type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
-            int_unification_table: RefCell::new(UnificationTable::new()),
-            float_unification_table: RefCell::new(UnificationTable::new()),
+            int_unification_table: RefCell::new(ut::UnificationTable::new()),
+            float_unification_table: RefCell::new(ut::UnificationTable::new()),
             region_constraints: RefCell::new(Some(RegionConstraintCollector::new())),
             lexical_region_resolutions: RefCell::new(None),
             selection_cache: traits::SelectionCache::new(),
@@ -476,8 +476,8 @@ impl<'tcx, T> InferOk<'tcx, T> {
 pub struct CombinedSnapshot<'a, 'tcx:'a> {
     projection_cache_snapshot: traits::ProjectionCacheSnapshot,
     type_snapshot: type_variable::Snapshot,
-    int_snapshot: unify::Snapshot<ty::IntVid>,
-    float_snapshot: unify::Snapshot<ty::FloatVid>,
+    int_snapshot: ut::Snapshot<ut::InPlace<ty::IntVid>>,
+    float_snapshot: ut::Snapshot<ut::InPlace<ty::FloatVid>>,
     region_constraints_snapshot: RegionSnapshot,
     region_obligations_snapshot: usize,
     was_in_snapshot: bool,
@@ -678,14 +678,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         use ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
         match ty.sty {
             ty::TyInfer(ty::IntVar(vid)) => {
-                if self.int_unification_table.borrow_mut().has_value(vid) {
+                if self.int_unification_table.borrow_mut().probe_value(vid).is_some() {
                     Neither
                 } else {
                     UnconstrainedInt
                 }
             },
             ty::TyInfer(ty::FloatVar(vid)) => {
-                if self.float_unification_table.borrow_mut().has_value(vid) {
+                if self.float_unification_table.borrow_mut().probe_value(vid).is_some() {
                     Neither
                 } else {
                     UnconstrainedFloat
@@ -698,27 +698,32 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> {
         let mut variables = Vec::new();
 
-        let unbound_ty_vars = self.type_variables
-                                  .borrow_mut()
-                                  .unsolved_variables()
-                                  .into_iter()
-                                  .map(|t| self.tcx.mk_var(t));
-
-        let unbound_int_vars = self.int_unification_table
-                                   .borrow_mut()
-                                   .unsolved_variables()
-                                   .into_iter()
-                                   .map(|v| self.tcx.mk_int_var(v));
+        {
+            let mut type_variables = self.type_variables.borrow_mut();
+            variables.extend(
+                type_variables
+                    .unsolved_variables()
+                    .into_iter()
+                    .map(|t| self.tcx.mk_var(t)));
+        }
 
-        let unbound_float_vars = self.float_unification_table
-                                     .borrow_mut()
-                                     .unsolved_variables()
-                                     .into_iter()
-                                     .map(|v| self.tcx.mk_float_var(v));
+        {
+            let mut int_unification_table = self.int_unification_table.borrow_mut();
+            variables.extend(
+                (0..int_unification_table.len())
+                    .map(|i| ty::IntVid { index: i as u32 })
+                    .filter(|&vid| int_unification_table.probe_value(vid).is_none())
+                    .map(|v| self.tcx.mk_int_var(v)));
+        }
 
-        variables.extend(unbound_ty_vars);
-        variables.extend(unbound_int_vars);
-        variables.extend(unbound_float_vars);
+        {
+            let mut float_unification_table = self.float_unification_table.borrow_mut();
+            variables.extend(
+                (0..float_unification_table.len())
+                    .map(|i| ty::FloatVid { index: i as u32 })
+                    .filter(|&vid| float_unification_table.probe_value(vid).is_none())
+                    .map(|v| self.tcx.mk_float_var(v)));
+        }
 
         return variables;
     }
@@ -1262,7 +1267,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             ty::TyInfer(ty::IntVar(v)) => {
                 self.int_unification_table
                     .borrow_mut()
-                    .probe(v)
+                    .probe_value(v)
                     .map(|v| v.to_type(self.tcx))
                     .unwrap_or(typ)
             }
@@ -1270,7 +1275,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             ty::TyInfer(ty::FloatVar(v)) => {
                 self.float_unification_table
                     .borrow_mut()
-                    .probe(v)
+                    .probe_value(v)
                     .map(|v| v.to_type(self.tcx))
                     .unwrap_or(typ)
             }
diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs
index e07cc92ec21..423b18823b1 100644
--- a/src/librustc/infer/type_variable.rs
+++ b/src/librustc/infer/type_variable.rs
@@ -26,7 +26,7 @@ pub struct TypeVariableTable<'tcx> {
 
     /// Two variables are unified in `eq_relations` when we have a
     /// constraint `?X == ?Y`.
-    eq_relations: ut::UnificationTable<ty::TyVid>,
+    eq_relations: ut::UnificationTable<ut::InPlace<ty::TyVid>>,
 
     /// Two variables are unified in `eq_relations` when we have a
     /// constraint `?X <: ?Y` *or* a constraint `?Y <: ?X`. This second
@@ -45,7 +45,7 @@ pub struct TypeVariableTable<'tcx> {
     /// This is reasonable because, in Rust, subtypes have the same
     /// "skeleton" and hence there is no possible type such that
     /// (e.g.)  `Box<?3> <: ?3` for any `?3`.
-    sub_relations: ut::UnificationTable<ty::TyVid>,
+    sub_relations: ut::UnificationTable<ut::InPlace<ty::TyVid>>,
 }
 
 /// Reasons to create a type inference variable
@@ -86,8 +86,8 @@ enum TypeVariableValue<'tcx> {
 
 pub struct Snapshot {
     snapshot: sv::Snapshot,
-    eq_snapshot: ut::Snapshot<ty::TyVid>,
-    sub_snapshot: ut::Snapshot<ty::TyVid>,
+    eq_snapshot: ut::Snapshot<ut::InPlace<ty::TyVid>>,
+    sub_snapshot: ut::Snapshot<ut::InPlace<ty::TyVid>>,
 }
 
 struct Instantiate {
@@ -354,3 +354,10 @@ impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
         values[vid.index as usize].value = Unknown;
     }
 }
+
+impl ut::UnifyKey for ty::TyVid {
+    type Value = ();
+    fn index(&self) -> u32 { self.index }
+    fn from_index(i: u32) -> ty::TyVid { ty::TyVid { index: i } }
+    fn tag() -> &'static str { "TyVid" }
+}
diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs
index 99b11794cc5..a1145572b79 100644
--- a/src/librustc/infer/unify_key.rs
+++ b/src/librustc/infer/unify_key.rs
@@ -8,9 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syntax::ast;
-use ty::{self, IntVarValue, Ty, TyCtxt};
-use rustc_data_structures::unify::{Combine, UnifyKey};
+use ty::{self, FloatVarValue, IntVarValue, Ty, TyCtxt};
+use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue};
 
 pub trait ToType {
     fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx>;
@@ -20,7 +19,10 @@ impl UnifyKey for ty::IntVid {
     type Value = Option<IntVarValue>;
     fn index(&self) -> u32 { self.index }
     fn from_index(i: u32) -> ty::IntVid { ty::IntVid { index: i } }
-    fn tag(_: Option<ty::IntVid>) -> &'static str { "IntVid" }
+    fn tag() -> &'static str { "IntVid" }
+}
+
+impl EqUnifyValue for IntVarValue {
 }
 
 #[derive(PartialEq, Copy, Clone, Debug)]
@@ -31,15 +33,17 @@ pub struct RegionVidKey {
     pub min_vid: ty::RegionVid
 }
 
-impl Combine for RegionVidKey {
-    fn combine(&self, other: &RegionVidKey) -> RegionVidKey {
-        let min_vid = if self.min_vid.index() < other.min_vid.index() {
-            self.min_vid
+impl UnifyValue for RegionVidKey {
+    type Error = NoError;
+
+    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> {
+        let min_vid = if value1.min_vid.index() < value2.min_vid.index() {
+            value1.min_vid
         } else {
-            other.min_vid
+            value2.min_vid
         };
 
-        RegionVidKey { min_vid: min_vid }
+        Ok(RegionVidKey { min_vid: min_vid })
     }
 }
 
@@ -47,7 +51,7 @@ impl UnifyKey for ty::RegionVid {
     type Value = RegionVidKey;
     fn index(&self) -> u32 { self.0 }
     fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid(i) }
-    fn tag(_: Option<ty::RegionVid>) -> &'static str { "RegionVid" }
+    fn tag() -> &'static str { "RegionVid" }
 }
 
 impl ToType for IntVarValue {
@@ -62,21 +66,17 @@ impl ToType for IntVarValue {
 // Floating point type keys
 
 impl UnifyKey for ty::FloatVid {
-    type Value = Option<ast::FloatTy>;
+    type Value = Option<FloatVarValue>;
     fn index(&self) -> u32 { self.index }
     fn from_index(i: u32) -> ty::FloatVid { ty::FloatVid { index: i } }
-    fn tag(_: Option<ty::FloatVid>) -> &'static str { "FloatVid" }
+    fn tag() -> &'static str { "FloatVid" }
 }
 
-impl ToType for ast::FloatTy {
-    fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
-        tcx.mk_mach_float(*self)
-    }
+impl EqUnifyValue for FloatVarValue {
 }
 
-impl UnifyKey for ty::TyVid {
-    type Value = ();
-    fn index(&self) -> u32 { self.index }
-    fn from_index(i: u32) -> ty::TyVid { ty::TyVid { index: i } }
-    fn tag(_: Option<ty::TyVid>) -> &'static str { "TyVid" }
+impl ToType for FloatVarValue {
+    fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
+        tcx.mk_mach_float(self.0)
+    }
 }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 856c53d19c9..4315d1f2c8c 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -685,12 +685,15 @@ pub struct ClosureUpvar<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
-#[derive(Clone, Copy, PartialEq)]
+#[derive(Clone, Copy, PartialEq, Eq)]
 pub enum IntVarValue {
     IntType(ast::IntTy),
     UintType(ast::UintTy),
 }
 
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct FloatVarValue(pub ast::FloatTy);
+
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
 pub struct TypeParameterDef {
     pub name: Name,
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 37d1c568515..d390d1c15e2 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -916,6 +916,12 @@ impl fmt::Debug for ty::IntVarValue {
     }
 }
 
+impl fmt::Debug for ty::FloatVarValue {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
 // The generic impl doesn't work yet because projections are not
 // normalized under HRTB.
 /*impl<T> fmt::Display for ty::Binder<T>
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index 23e42f6a672..40d557ee5e0 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -9,6 +9,7 @@ path = "lib.rs"
 crate-type = ["dylib"]
 
 [dependencies]
+ena = "0.8.0"
 log = "0.4"
 serialize = { path = "../libserialize" }
 cfg-if = "0.1.2"
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 33d760d0a14..265c6485830 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -39,6 +39,7 @@
 #![cfg_attr(test, feature(test))]
 
 extern crate core;
+extern crate ena;
 #[macro_use]
 extern crate log;
 extern crate serialize as rustc_serialize; // used by deriving
@@ -63,10 +64,10 @@ pub mod indexed_vec;
 pub mod obligation_forest;
 pub mod sip128;
 pub mod snapshot_map;
-pub mod snapshot_vec;
+pub use ena::snapshot_vec;
 pub mod stable_hasher;
 pub mod transitive_relation;
-pub mod unify;
+pub use ena::unify;
 pub mod fx;
 pub mod tuple_slice;
 pub mod control_flow_graph;