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.
This commit is contained in:
Niko Matsakis 2017-07-16 07:07:51 -04:00 committed by Sean Griffin
parent b680b12e94
commit c7953bb6d6
9 changed files with 88 additions and 65 deletions

View File

@ -132,7 +132,7 @@ fn unify_integral_variable(&self,
{ {
self.int_unification_table self.int_unification_table
.borrow_mut() .borrow_mut()
.unify_var_value(vid, val) .unify_var_value(vid, Some(val))
.map_err(|e| int_unification_error(vid_is_expected, e))?; .map_err(|e| int_unification_error(vid_is_expected, e))?;
match val { match val {
IntType(v) => Ok(self.tcx.mk_mach_int(v)), IntType(v) => Ok(self.tcx.mk_mach_int(v)),
@ -148,7 +148,7 @@ fn unify_float_variable(&self,
{ {
self.float_unification_table self.float_unification_table
.borrow_mut() .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))?; .map_err(|e| float_unification_error(vid_is_expected, e))?;
Ok(self.tcx.mk_mach_float(val)) 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, fn float_unification_error<'tcx>(a_is_expected: bool,
v: (ast::FloatTy, ast::FloatTy)) v: (ty::FloatVarValue, ty::FloatVarValue))
-> TypeError<'tcx> -> 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)) TypeError::FloatMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b))
} }

View File

@ -143,7 +143,7 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
ty::TyInfer(ty::IntVar(v)) => { ty::TyInfer(ty::IntVar(v)) => {
self.freshen( self.freshen(
self.infcx.int_unification_table.borrow_mut() self.infcx.int_unification_table.borrow_mut()
.probe(v) .probe_value(v)
.map(|v| v.to_type(tcx)), .map(|v| v.to_type(tcx)),
ty::IntVar(v), ty::IntVar(v),
ty::FreshIntTy) ty::FreshIntTy)
@ -152,7 +152,7 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
ty::TyInfer(ty::FloatVar(v)) => { ty::TyInfer(ty::FloatVar(v)) => {
self.freshen( self.freshen(
self.infcx.float_unification_table.borrow_mut() self.infcx.float_unification_table.borrow_mut()
.probe(v) .probe_value(v)
.map(|v| v.to_type(tcx)), .map(|v| v.to_type(tcx)),
ty::FloatVar(v), ty::FloatVar(v),
ty::FreshFloatTy) ty::FreshFloatTy)

View File

@ -29,7 +29,7 @@
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use ty::relate::RelateResult; use ty::relate::RelateResult;
use traits::{self, ObligationCause, PredicateObligations, Reveal}; 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::cell::{Cell, RefCell, Ref, RefMut};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fmt; use std::fmt;
@ -99,10 +99,10 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
pub type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>, pub type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
// Map from integral variable to the kind of integer it represents // 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 // 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 // Tracks the set of region variables and the constraints between
// them. This is initially `Some(_)` but when // them. This is initially `Some(_)` but when
@ -441,8 +441,8 @@ pub fn enter<F, R>(&'tcx mut self, f: F) -> R
in_progress_tables, in_progress_tables,
projection_cache: RefCell::new(traits::ProjectionCache::new()), projection_cache: RefCell::new(traits::ProjectionCache::new()),
type_variables: RefCell::new(type_variable::TypeVariableTable::new()), type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
int_unification_table: RefCell::new(UnificationTable::new()), int_unification_table: RefCell::new(ut::UnificationTable::new()),
float_unification_table: RefCell::new(UnificationTable::new()), float_unification_table: RefCell::new(ut::UnificationTable::new()),
region_constraints: RefCell::new(Some(RegionConstraintCollector::new())), region_constraints: RefCell::new(Some(RegionConstraintCollector::new())),
lexical_region_resolutions: RefCell::new(None), lexical_region_resolutions: RefCell::new(None),
selection_cache: traits::SelectionCache::new(), selection_cache: traits::SelectionCache::new(),
@ -476,8 +476,8 @@ pub fn unit(self) -> InferOk<'tcx, ()> {
pub struct CombinedSnapshot<'a, 'tcx:'a> { pub struct CombinedSnapshot<'a, 'tcx:'a> {
projection_cache_snapshot: traits::ProjectionCacheSnapshot, projection_cache_snapshot: traits::ProjectionCacheSnapshot,
type_snapshot: type_variable::Snapshot, type_snapshot: type_variable::Snapshot,
int_snapshot: unify::Snapshot<ty::IntVid>, int_snapshot: ut::Snapshot<ut::InPlace<ty::IntVid>>,
float_snapshot: unify::Snapshot<ty::FloatVid>, float_snapshot: ut::Snapshot<ut::InPlace<ty::FloatVid>>,
region_constraints_snapshot: RegionSnapshot, region_constraints_snapshot: RegionSnapshot,
region_obligations_snapshot: usize, region_obligations_snapshot: usize,
was_in_snapshot: bool, was_in_snapshot: bool,
@ -678,14 +678,14 @@ pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
use ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat}; use ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
match ty.sty { match ty.sty {
ty::TyInfer(ty::IntVar(vid)) => { 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 Neither
} else { } else {
UnconstrainedInt UnconstrainedInt
} }
}, },
ty::TyInfer(ty::FloatVar(vid)) => { 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 Neither
} else { } else {
UnconstrainedFloat UnconstrainedFloat
@ -698,27 +698,32 @@ pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> { pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> {
let mut variables = Vec::new(); let mut variables = Vec::new();
let unbound_ty_vars = self.type_variables {
.borrow_mut() let mut type_variables = self.type_variables.borrow_mut();
.unsolved_variables() variables.extend(
.into_iter() type_variables
.map(|t| self.tcx.mk_var(t)); .unsolved_variables()
.into_iter()
.map(|t| self.tcx.mk_var(t)));
}
let unbound_int_vars = self.int_unification_table {
.borrow_mut() let mut int_unification_table = self.int_unification_table.borrow_mut();
.unsolved_variables() variables.extend(
.into_iter() (0..int_unification_table.len())
.map(|v| self.tcx.mk_int_var(v)); .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)));
}
let unbound_float_vars = self.float_unification_table {
.borrow_mut() let mut float_unification_table = self.float_unification_table.borrow_mut();
.unsolved_variables() variables.extend(
.into_iter() (0..float_unification_table.len())
.map(|v| self.tcx.mk_float_var(v)); .map(|i| ty::FloatVid { index: i as u32 })
.filter(|&vid| float_unification_table.probe_value(vid).is_none())
variables.extend(unbound_ty_vars); .map(|v| self.tcx.mk_float_var(v)));
variables.extend(unbound_int_vars); }
variables.extend(unbound_float_vars);
return variables; return variables;
} }
@ -1262,7 +1267,7 @@ pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
ty::TyInfer(ty::IntVar(v)) => { ty::TyInfer(ty::IntVar(v)) => {
self.int_unification_table self.int_unification_table
.borrow_mut() .borrow_mut()
.probe(v) .probe_value(v)
.map(|v| v.to_type(self.tcx)) .map(|v| v.to_type(self.tcx))
.unwrap_or(typ) .unwrap_or(typ)
} }
@ -1270,7 +1275,7 @@ pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
ty::TyInfer(ty::FloatVar(v)) => { ty::TyInfer(ty::FloatVar(v)) => {
self.float_unification_table self.float_unification_table
.borrow_mut() .borrow_mut()
.probe(v) .probe_value(v)
.map(|v| v.to_type(self.tcx)) .map(|v| v.to_type(self.tcx))
.unwrap_or(typ) .unwrap_or(typ)
} }

View File

@ -26,7 +26,7 @@ pub struct TypeVariableTable<'tcx> {
/// Two variables are unified in `eq_relations` when we have a /// Two variables are unified in `eq_relations` when we have a
/// constraint `?X == ?Y`. /// 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 /// Two variables are unified in `eq_relations` when we have a
/// constraint `?X <: ?Y` *or* a constraint `?Y <: ?X`. This second /// 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 /// This is reasonable because, in Rust, subtypes have the same
/// "skeleton" and hence there is no possible type such that /// "skeleton" and hence there is no possible type such that
/// (e.g.) `Box<?3> <: ?3` for any `?3`. /// (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 /// Reasons to create a type inference variable
@ -86,8 +86,8 @@ enum TypeVariableValue<'tcx> {
pub struct Snapshot { pub struct Snapshot {
snapshot: sv::Snapshot, snapshot: sv::Snapshot,
eq_snapshot: ut::Snapshot<ty::TyVid>, eq_snapshot: ut::Snapshot<ut::InPlace<ty::TyVid>>,
sub_snapshot: ut::Snapshot<ty::TyVid>, sub_snapshot: ut::Snapshot<ut::InPlace<ty::TyVid>>,
} }
struct Instantiate { struct Instantiate {
@ -354,3 +354,10 @@ fn reverse(values: &mut Vec<TypeVariableData<'tcx>>, action: Instantiate) {
values[vid.index as usize].value = Unknown; 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" }
}

View File

@ -8,9 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use syntax::ast; use ty::{self, FloatVarValue, IntVarValue, Ty, TyCtxt};
use ty::{self, IntVarValue, Ty, TyCtxt}; use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue};
use rustc_data_structures::unify::{Combine, UnifyKey};
pub trait ToType { pub trait ToType {
fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx>; 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>; type Value = Option<IntVarValue>;
fn index(&self) -> u32 { self.index } fn index(&self) -> u32 { self.index }
fn from_index(i: u32) -> ty::IntVid { ty::IntVid { index: i } } 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)] #[derive(PartialEq, Copy, Clone, Debug)]
@ -31,15 +33,17 @@ pub struct RegionVidKey {
pub min_vid: ty::RegionVid pub min_vid: ty::RegionVid
} }
impl Combine for RegionVidKey { impl UnifyValue for RegionVidKey {
fn combine(&self, other: &RegionVidKey) -> RegionVidKey { type Error = NoError;
let min_vid = if self.min_vid.index() < other.min_vid.index() {
self.min_vid 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 { } 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; type Value = RegionVidKey;
fn index(&self) -> u32 { self.0 } fn index(&self) -> u32 { self.0 }
fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid(i) } 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 { impl ToType for IntVarValue {
@ -62,21 +66,17 @@ fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
// Floating point type keys // Floating point type keys
impl UnifyKey for ty::FloatVid { impl UnifyKey for ty::FloatVid {
type Value = Option<ast::FloatTy>; type Value = Option<FloatVarValue>;
fn index(&self) -> u32 { self.index } fn index(&self) -> u32 { self.index }
fn from_index(i: u32) -> ty::FloatVid { ty::FloatVid { index: i } } 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 { impl EqUnifyValue for FloatVarValue {
}
impl ToType for FloatVarValue {
fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> { fn to_type<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
tcx.mk_mach_float(*self) tcx.mk_mach_float(self.0)
} }
} }
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" }
}

View File

@ -685,12 +685,15 @@ pub struct ClosureUpvar<'tcx> {
pub ty: Ty<'tcx>, pub ty: Ty<'tcx>,
} }
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq, Eq)]
pub enum IntVarValue { pub enum IntVarValue {
IntType(ast::IntTy), IntType(ast::IntTy),
UintType(ast::UintTy), UintType(ast::UintTy),
} }
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct FloatVarValue(pub ast::FloatTy);
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct TypeParameterDef { pub struct TypeParameterDef {
pub name: Name, pub name: Name,

View File

@ -916,6 +916,12 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
} }
} }
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 // The generic impl doesn't work yet because projections are not
// normalized under HRTB. // normalized under HRTB.
/*impl<T> fmt::Display for ty::Binder<T> /*impl<T> fmt::Display for ty::Binder<T>

View File

@ -9,6 +9,7 @@ path = "lib.rs"
crate-type = ["dylib"] crate-type = ["dylib"]
[dependencies] [dependencies]
ena = "0.8.0"
log = "0.4" log = "0.4"
serialize = { path = "../libserialize" } serialize = { path = "../libserialize" }
cfg-if = "0.1.2" cfg-if = "0.1.2"

View File

@ -39,6 +39,7 @@
#![cfg_attr(test, feature(test))] #![cfg_attr(test, feature(test))]
extern crate core; extern crate core;
extern crate ena;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate serialize as rustc_serialize; // used by deriving extern crate serialize as rustc_serialize; // used by deriving
@ -63,10 +64,10 @@
pub mod obligation_forest; pub mod obligation_forest;
pub mod sip128; pub mod sip128;
pub mod snapshot_map; pub mod snapshot_map;
pub mod snapshot_vec; pub use ena::snapshot_vec;
pub mod stable_hasher; pub mod stable_hasher;
pub mod transitive_relation; pub mod transitive_relation;
pub mod unify; pub use ena::unify;
pub mod fx; pub mod fx;
pub mod tuple_slice; pub mod tuple_slice;
pub mod control_flow_graph; pub mod control_flow_graph;