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;
mod graphviz;
pub struct LexicalRegionResolutions<'tcx> {
- values: Vec<VarValue<'tcx>>,
+ values: IndexVec<RegionVid, VarValue<'tcx>>,
error_region: ty::Region<'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,
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(),
}
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));
}
}
// 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
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: {:?}",
}
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={:?}",
}
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,
};
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};
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
#[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).
}
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 });
}
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
}
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()
}
}
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};
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,