make RegionVid
implement Idx
and use IndexVec
This commit is contained in:
parent
bea6b94273
commit
524e23ae2e
4 changed files with 49 additions and 25 deletions
|
@ -17,6 +17,7 @@ use infer::region_constraints::GenericKind;
|
||||||
use infer::region_constraints::RegionConstraintData;
|
use infer::region_constraints::RegionConstraintData;
|
||||||
use infer::region_constraints::VerifyBound;
|
use infer::region_constraints::VerifyBound;
|
||||||
use middle::free_region::RegionRelations;
|
use middle::free_region::RegionRelations;
|
||||||
|
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING};
|
use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -29,7 +30,7 @@ use ty::{ReLateBound, ReScope, ReSkolemized, ReVar};
|
||||||
mod graphviz;
|
mod graphviz;
|
||||||
|
|
||||||
pub struct LexicalRegionResolutions<'tcx> {
|
pub struct LexicalRegionResolutions<'tcx> {
|
||||||
values: Vec<VarValue<'tcx>>,
|
values: IndexVec<RegionVid, VarValue<'tcx>>,
|
||||||
error_region: ty::Region<'tcx>,
|
error_region: ty::Region<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +115,7 @@ impl<'tcx> RegionConstraintData<'tcx> {
|
||||||
|
|
||||||
(&ReVar(v_id), _) | (_, &ReVar(v_id)) => {
|
(&ReVar(v_id), _) | (_, &ReVar(v_id)) => {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
self.var_origins[v_id.index as usize].span(),
|
self.var_origins[v_id].span(),
|
||||||
"lub_concrete_regions invoked with non-concrete \
|
"lub_concrete_regions invoked with non-concrete \
|
||||||
regions: {:?}, {:?}",
|
regions: {:?}, {:?}",
|
||||||
a,
|
a,
|
||||||
|
@ -211,7 +212,7 @@ impl<'tcx> RegionConstraintData<'tcx> {
|
||||||
fn construct_var_data(&self, tcx: TyCtxt<'_, '_, 'tcx>) -> LexicalRegionResolutions<'tcx> {
|
fn construct_var_data(&self, tcx: TyCtxt<'_, '_, 'tcx>) -> LexicalRegionResolutions<'tcx> {
|
||||||
LexicalRegionResolutions {
|
LexicalRegionResolutions {
|
||||||
error_region: tcx.types.re_static,
|
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))
|
.map(|_| VarValue::Value(tcx.types.re_empty))
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
|
@ -240,11 +241,20 @@ impl<'tcx> RegionConstraintData<'tcx> {
|
||||||
|
|
||||||
let seeds: Vec<_> = self.givens.iter().cloned().collect();
|
let seeds: Vec<_> = self.givens.iter().cloned().collect();
|
||||||
for (r, vid) in seeds {
|
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);
|
let seed_index = NodeIndex(vid.index as usize);
|
||||||
for succ_index in graph.depth_traverse(seed_index, OUTGOING) {
|
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() {
|
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));
|
self.givens.insert((r, succ_vid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,11 +452,10 @@ impl<'tcx> RegionConstraintData<'tcx> {
|
||||||
// idea is to report errors that derive from independent
|
// idea is to report errors that derive from independent
|
||||||
// regions of the graph, but not those that derive from
|
// regions of the graph, but not those that derive from
|
||||||
// overlapping locations.
|
// 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() {
|
for (node_vid, value) in var_data.values.iter_enumerated() {
|
||||||
let node_vid = RegionVid { index };
|
match *value {
|
||||||
match var_data.value(node_vid) {
|
|
||||||
VarValue::Value(_) => { /* Inference successful */ }
|
VarValue::Value(_) => { /* Inference successful */ }
|
||||||
VarValue::ErrorValue => {
|
VarValue::ErrorValue => {
|
||||||
/* Inference impossible, this value contains
|
/* Inference impossible, this value contains
|
||||||
|
@ -560,7 +569,7 @@ impl<'tcx> RegionConstraintData<'tcx> {
|
||||||
for lower_bound in &lower_bounds {
|
for lower_bound in &lower_bounds {
|
||||||
for upper_bound in &upper_bounds {
|
for upper_bound in &upper_bounds {
|
||||||
if !region_rels.is_subregion_of(lower_bound.region, upper_bound.region) {
|
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!(
|
debug!(
|
||||||
"region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
|
"region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
|
||||||
sup: {:?}",
|
sup: {:?}",
|
||||||
|
@ -582,7 +591,7 @@ impl<'tcx> RegionConstraintData<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
span_bug!(
|
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 \
|
"collect_error_for_expanding_node() could not find \
|
||||||
error for var {:?}, lower_bounds={:?}, \
|
error for var {:?}, lower_bounds={:?}, \
|
||||||
upper_bounds={:?}",
|
upper_bounds={:?}",
|
||||||
|
@ -741,15 +750,15 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value(&self, rid: RegionVid) -> &VarValue<'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> {
|
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> {
|
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::Value(r) => r,
|
||||||
VarValue::ErrorValue => self.error_region,
|
VarValue::ErrorValue => self.error_region,
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@ use self::CombineMapType::*;
|
||||||
use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin};
|
use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin};
|
||||||
use super::unify_key;
|
use super::unify_key;
|
||||||
|
|
||||||
|
use rustc_data_structures::indexed_vec::IndexVec;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::unify::{self, UnificationTable};
|
use rustc_data_structures::unify::{self, UnificationTable};
|
||||||
use ty::{self, Ty, TyCtxt};
|
use ty::{self, Ty, TyCtxt};
|
||||||
|
@ -51,6 +52,8 @@ pub struct RegionConstraintCollector<'tcx> {
|
||||||
unification_table: UnificationTable<ty::RegionVid>,
|
unification_table: UnificationTable<ty::RegionVid>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type VarOrigins = IndexVec<RegionVid, RegionVariableOrigin>;
|
||||||
|
|
||||||
/// The full set of region constraints gathered up by the collector.
|
/// The full set of region constraints gathered up by the collector.
|
||||||
/// Describes a set of region variables ranging from 0..N (where N is
|
/// Describes a set of region variables ranging from 0..N (where N is
|
||||||
/// the length of the `var_origins` vector), and various constraints
|
/// the length of the `var_origins` vector), and various constraints
|
||||||
|
@ -58,7 +61,7 @@ pub struct RegionConstraintCollector<'tcx> {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RegionConstraintData<'tcx> {
|
pub struct RegionConstraintData<'tcx> {
|
||||||
/// For each `RegionVid`, the corresponding `RegionVariableOrigin`.
|
/// 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
|
/// Constraints of the form `A <= B`, where either `A` or `B` can
|
||||||
/// be a region variable (or neither, as it happens).
|
/// 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 {
|
pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid {
|
||||||
let vid = RegionVid {
|
let vid = self.data.var_origins.push(origin.clone());
|
||||||
index: self.data.num_vars(),
|
|
||||||
};
|
|
||||||
self.data.var_origins.push(origin.clone());
|
|
||||||
|
|
||||||
let u_vid = self.unification_table
|
let u_vid = self.unification_table
|
||||||
.new_key(unify_key::RegionVidKey { min_vid: vid });
|
.new_key(unify_key::RegionVidKey { min_vid: vid });
|
||||||
|
@ -364,7 +364,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
|
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
|
/// Creates a new skolemized region. Skolemized regions are fresh
|
||||||
|
@ -862,10 +862,7 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> RegionConstraintData<'tcx> {
|
impl<'tcx> RegionConstraintData<'tcx> {
|
||||||
pub fn num_vars(&self) -> u32 {
|
pub fn num_vars(&self) -> usize {
|
||||||
let len = self.var_origins.len();
|
self.var_origins.len()
|
||||||
// enforce no overflow
|
|
||||||
assert!(len as u32 as usize == len);
|
|
||||||
len as u32
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use hir::def_id::DefId;
|
||||||
|
|
||||||
use middle::const_val::ConstVal;
|
use middle::const_val::ConstVal;
|
||||||
use middle::region;
|
use middle::region;
|
||||||
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
use ty::subst::{Substs, Subst};
|
use ty::subst::{Substs, Subst};
|
||||||
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
|
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
|
||||||
use ty::{Slice, TyS};
|
use ty::{Slice, TyS};
|
||||||
|
@ -898,6 +899,18 @@ pub struct RegionVid {
|
||||||
pub index: u32,
|
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)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
|
||||||
pub struct SkolemizedRegionVid {
|
pub struct SkolemizedRegionVid {
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
|
|
|
@ -384,6 +384,11 @@ impl<I: Idx, T> IndexVec<I, T> {
|
||||||
idx
|
idx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn pop(&mut self) -> Option<T> {
|
||||||
|
self.raw.pop()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.raw.len()
|
self.raw.len()
|
||||||
|
|
Loading…
Reference in a new issue