diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2017-11-05 14:06:46 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2017-11-16 05:57:44 -0500 |
| commit | 524e23ae2e842a6f52d5fc4d5819473b73a335ef (patch) | |
| tree | b6bc8a23bb4589efb3d6176049fd2b909e000108 | |
| parent | bea6b94273bc616f806b111c8f1f6b3d2e3e5380 (diff) | |
| download | rust-524e23ae2e842a6f52d5fc4d5819473b73a335ef.tar.gz rust-524e23ae2e842a6f52d5fc4d5819473b73a335ef.zip | |
make `RegionVid` implement `Idx` and use `IndexVec`
| -rw-r--r-- | src/librustc/infer/lexical_region_resolve/mod.rs | 37 | ||||
| -rw-r--r-- | src/librustc/infer/region_constraints/mod.rs | 19 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 13 | ||||
| -rw-r--r-- | src/librustc_data_structures/indexed_vec.rs | 5 |
4 files changed, 49 insertions, 25 deletions
diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 3522420a5dc..3aeecaf166a 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -17,6 +17,7 @@ use infer::region_constraints::GenericKind; use infer::region_constraints::RegionConstraintData; use infer::region_constraints::VerifyBound; use middle::free_region::RegionRelations; +use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING}; use std::fmt; @@ -29,7 +30,7 @@ use ty::{ReLateBound, ReScope, ReSkolemized, ReVar}; mod graphviz; pub struct LexicalRegionResolutions<'tcx> { - values: Vec<VarValue<'tcx>>, + values: IndexVec<RegionVid, VarValue<'tcx>>, error_region: ty::Region<'tcx>, } @@ -114,7 +115,7 @@ impl<'tcx> RegionConstraintData<'tcx> { (&ReVar(v_id), _) | (_, &ReVar(v_id)) => { span_bug!( - self.var_origins[v_id.index as usize].span(), + self.var_origins[v_id].span(), "lub_concrete_regions invoked with non-concrete \ regions: {:?}, {:?}", a, @@ -211,7 +212,7 @@ impl<'tcx> RegionConstraintData<'tcx> { fn construct_var_data(&self, tcx: TyCtxt<'_, '_, 'tcx>) -> LexicalRegionResolutions<'tcx> { LexicalRegionResolutions { error_region: tcx.types.re_static, - values: (0..self.num_vars() as usize) + values: (0..self.num_vars()) .map(|_| VarValue::Value(tcx.types.re_empty)) .collect(), } @@ -240,11 +241,20 @@ impl<'tcx> RegionConstraintData<'tcx> { let seeds: Vec<_> = self.givens.iter().cloned().collect(); for (r, vid) in seeds { + + // While all things transitively reachable in the graph + // from the variable (`'0` in the example above). let seed_index = NodeIndex(vid.index as usize); for succ_index in graph.depth_traverse(seed_index, OUTGOING) { - let succ_index = succ_index.0 as u32; + let succ_index = succ_index.0; + + // The first N nodes correspond to the region + // variables. Other nodes correspond to constant + // regions. if succ_index < self.num_vars() { - let succ_vid = RegionVid { index: succ_index }; + let succ_vid = RegionVid::new(succ_index); + + // Add `'c <= '1`. self.givens.insert((r, succ_vid)); } } @@ -442,11 +452,10 @@ impl<'tcx> RegionConstraintData<'tcx> { // idea is to report errors that derive from independent // regions of the graph, but not those that derive from // overlapping locations. - let mut dup_vec = vec![u32::MAX; self.num_vars() as usize]; + let mut dup_vec = vec![u32::MAX; self.num_vars()]; - for index in 0..self.num_vars() { - let node_vid = RegionVid { index }; - match var_data.value(node_vid) { + for (node_vid, value) in var_data.values.iter_enumerated() { + match *value { VarValue::Value(_) => { /* Inference successful */ } VarValue::ErrorValue => { /* Inference impossible, this value contains @@ -560,7 +569,7 @@ impl<'tcx> RegionConstraintData<'tcx> { for lower_bound in &lower_bounds { for upper_bound in &upper_bounds { if !region_rels.is_subregion_of(lower_bound.region, upper_bound.region) { - let origin = self.var_origins[node_idx.index as usize].clone(); + let origin = self.var_origins[node_idx].clone(); debug!( "region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \ sup: {:?}", @@ -582,7 +591,7 @@ impl<'tcx> RegionConstraintData<'tcx> { } span_bug!( - self.var_origins[node_idx.index as usize].span(), + self.var_origins[node_idx].span(), "collect_error_for_expanding_node() could not find \ error for var {:?}, lower_bounds={:?}, \ upper_bounds={:?}", @@ -741,15 +750,15 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { } fn value(&self, rid: RegionVid) -> &VarValue<'tcx> { - &self.values[rid.index as usize] + &self.values[rid] } fn value_mut(&mut self, rid: RegionVid) -> &mut VarValue<'tcx> { - &mut self.values[rid.index as usize] + &mut self.values[rid] } pub fn resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> { - let result = match self.values[rid.index as usize] { + let result = match self.values[rid] { VarValue::Value(r) => r, VarValue::ErrorValue => self.error_region, }; diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index d2cd52c73e2..634e4642600 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -16,6 +16,7 @@ use self::CombineMapType::*; use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin}; use super::unify_key; +use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::unify::{self, UnificationTable}; use ty::{self, Ty, TyCtxt}; @@ -51,6 +52,8 @@ pub struct RegionConstraintCollector<'tcx> { unification_table: UnificationTable<ty::RegionVid>, } +pub type VarOrigins = IndexVec<RegionVid, RegionVariableOrigin>; + /// The full set of region constraints gathered up by the collector. /// Describes a set of region variables ranging from 0..N (where N is /// the length of the `var_origins` vector), and various constraints @@ -58,7 +61,7 @@ pub struct RegionConstraintCollector<'tcx> { #[derive(Default)] pub struct RegionConstraintData<'tcx> { /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. - pub var_origins: Vec<RegionVariableOrigin>, + pub var_origins: IndexVec<RegionVid, RegionVariableOrigin>, /// Constraints of the form `A <= B`, where either `A` or `B` can /// be a region variable (or neither, as it happens). @@ -344,10 +347,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid { - let vid = RegionVid { - index: self.data.num_vars(), - }; - self.data.var_origins.push(origin.clone()); + let vid = self.data.var_origins.push(origin.clone()); let u_vid = self.unification_table .new_key(unify_key::RegionVidKey { min_vid: vid }); @@ -364,7 +364,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { - self.data.var_origins[vid.index as usize].clone() + self.data.var_origins[vid].clone() } /// Creates a new skolemized region. Skolemized regions are fresh @@ -862,10 +862,7 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { } impl<'tcx> RegionConstraintData<'tcx> { - pub fn num_vars(&self) -> u32 { - let len = self.var_origins.len(); - // enforce no overflow - assert!(len as u32 as usize == len); - len as u32 + pub fn num_vars(&self) -> usize { + self.var_origins.len() } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index a60cad0de9f..a73b234ffbe 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -14,6 +14,7 @@ use hir::def_id::DefId; use middle::const_val::ConstVal; use middle::region; +use rustc_data_structures::indexed_vec::Idx; use ty::subst::{Substs, Subst}; use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; use ty::{Slice, TyS}; @@ -898,6 +899,18 @@ pub struct RegionVid { pub index: u32, } +// TODO after rebasing, should be able to use `newtype_index!` +impl Idx for RegionVid { + fn new(value: usize) -> Self { + assert!(value < ::std::u32::MAX as usize); + RegionVid { index: value as u32 } + } + + fn index(self) -> usize { + self.index as usize + } +} + #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)] pub struct SkolemizedRegionVid { pub index: u32, diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index a733e9de5a1..622e8c51bee 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -385,6 +385,11 @@ impl<I: Idx, T> IndexVec<I, T> { } #[inline] + pub fn pop(&mut self) -> Option<T> { + self.raw.pop() + } + + #[inline] pub fn len(&self) -> usize { self.raw.len() } |
