Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ErasedRegions from substs #32346

Merged
merged 3 commits into from
Mar 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 28 additions & 98 deletions src/librustc/middle/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// Type substitutions.

pub use self::ParamSpace::*;
pub use self::RegionSubsts::*;

use middle::cstore;
use middle::def_id::DefId;
Expand All @@ -34,24 +33,15 @@ use syntax::codemap::{Span, DUMMY_SP};
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Substs<'tcx> {
pub types: VecPerParamSpace<Ty<'tcx>>,
pub regions: RegionSubsts,
}

/// Represents the values to use when substituting lifetime parameters.
/// If the value is `ErasedRegions`, then this subst is occurring during
/// trans, and all region parameters will be replaced with `ty::ReStatic`.
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum RegionSubsts {
ErasedRegions,
NonerasedRegions(VecPerParamSpace<ty::Region>)
pub regions: VecPerParamSpace<ty::Region>,
}

impl<'tcx> Substs<'tcx> {
pub fn new(t: VecPerParamSpace<Ty<'tcx>>,
r: VecPerParamSpace<ty::Region>)
-> Substs<'tcx>
{
Substs { types: t, regions: NonerasedRegions(r) }
Substs { types: t, regions: r }
}

pub fn new_type(t: Vec<Ty<'tcx>>,
Expand All @@ -71,32 +61,15 @@ impl<'tcx> Substs<'tcx> {
VecPerParamSpace::new(r, Vec::new(), Vec::new()))
}

pub fn erased(t: VecPerParamSpace<Ty<'tcx>>) -> Substs<'tcx>
{
Substs { types: t, regions: ErasedRegions }
}

pub fn empty() -> Substs<'tcx> {
Substs {
types: VecPerParamSpace::empty(),
regions: NonerasedRegions(VecPerParamSpace::empty()),
}
}

pub fn trans_empty() -> Substs<'tcx> {
Substs {
types: VecPerParamSpace::empty(),
regions: ErasedRegions
regions: VecPerParamSpace::empty(),
}
}

pub fn is_noop(&self) -> bool {
let regions_is_noop = match self.regions {
ErasedRegions => false, // may be used to canonicalize
NonerasedRegions(ref regions) => regions.is_empty(),
};

regions_is_noop && self.types.is_empty()
self.regions.is_empty() && self.types.is_empty()
}

pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> {
Expand All @@ -115,26 +88,9 @@ impl<'tcx> Substs<'tcx> {
}

pub fn erase_regions(self) -> Substs<'tcx> {
let Substs { types, regions: _ } = self;
Substs { types: types, regions: ErasedRegions }
}

/// Since ErasedRegions are only to be used in trans, most of the compiler can use this method
/// to easily access the set of region substitutions.
pub fn regions<'a>(&'a self) -> &'a VecPerParamSpace<ty::Region> {
match self.regions {
ErasedRegions => panic!("Erased regions only expected in trans"),
NonerasedRegions(ref r) => r
}
}

/// Since ErasedRegions are only to be used in trans, most of the compiler can use this method
/// to easily access the set of region substitutions.
pub fn mut_regions<'a>(&'a mut self) -> &'a mut VecPerParamSpace<ty::Region> {
match self.regions {
ErasedRegions => panic!("Erased regions only expected in trans"),
NonerasedRegions(ref mut r) => r
}
let Substs { types, regions } = self;
let regions = regions.map(|_| ty::ReStatic);
Substs { types: types, regions: regions }
}

pub fn with_method(self,
Expand All @@ -144,7 +100,7 @@ impl<'tcx> Substs<'tcx> {
{
let Substs { types, regions } = self;
let types = types.with_slice(FnSpace, &m_types);
let regions = regions.map(|r| r.with_slice(FnSpace, &m_regions));
let regions = regions.with_slice(FnSpace, &m_regions);
Substs { types: types, regions: regions }
}

Expand All @@ -154,27 +110,23 @@ impl<'tcx> Substs<'tcx> {
{
let Substs { types, regions } = self.clone();
let types = types.with_slice(FnSpace, meth_substs.types.get_slice(FnSpace));
let regions = regions.map(|r| {
r.with_slice(FnSpace, meth_substs.regions().get_slice(FnSpace))
});
let regions = regions.with_slice(FnSpace, meth_substs.regions.get_slice(FnSpace));
Substs { types: types, regions: regions }
}

pub fn with_method_from_subst(self, other: &Substs<'tcx>) -> Substs<'tcx> {
let Substs { types, regions } = self;
let types = types.with_slice(FnSpace, other.types.get_slice(FnSpace));
let regions = regions.map(|r| {
r.with_slice(FnSpace, other.regions().get_slice(FnSpace))
});
let regions = regions.with_slice(FnSpace, other.regions.get_slice(FnSpace));
Substs { types: types, regions: regions }
}

/// Creates a trait-ref out of this substs, ignoring the FnSpace substs
pub fn to_trait_ref(&self, tcx: &TyCtxt<'tcx>, trait_id: DefId)
-> ty::TraitRef<'tcx> {
let Substs { mut types, regions } = self.clone();
let Substs { mut types, mut regions } = self.clone();
types.truncate(FnSpace, 0);
let regions = regions.map(|mut r| { r.truncate(FnSpace, 0); r });
regions.truncate(FnSpace, 0);

ty::TraitRef {
def_id: trait_id,
Expand Down Expand Up @@ -212,24 +164,6 @@ impl<'tcx> Decodable for &'tcx Substs<'tcx> {
}
}

impl RegionSubsts {
pub fn map<F>(self, op: F) -> RegionSubsts where
F: FnOnce(VecPerParamSpace<ty::Region>) -> VecPerParamSpace<ty::Region>,
{
match self {
ErasedRegions => ErasedRegions,
NonerasedRegions(r) => NonerasedRegions(op(r))
}
}

pub fn is_erased(&self) -> bool {
match *self {
ErasedRegions => true,
NonerasedRegions(_) => false,
}
}
}

///////////////////////////////////////////////////////////////////////////
// ParamSpace

Expand Down Expand Up @@ -664,26 +598,22 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
// the specialized routine `ty::replace_late_regions()`.
match r {
ty::ReEarlyBound(data) => {
match self.substs.regions {
ErasedRegions => ty::ReStatic,
NonerasedRegions(ref regions) =>
match regions.opt_get(data.space, data.index as usize) {
Some(&r) => {
self.shift_region_through_binders(r)
}
None => {
let span = self.span.unwrap_or(DUMMY_SP);
self.tcx().sess.span_bug(
span,
&format!("Type parameter out of range \
when substituting in region {} (root type={:?}) \
(space={:?}, index={})",
data.name,
self.root_ty,
data.space,
data.index));
}
}
match self.substs.regions.opt_get(data.space, data.index as usize) {
Some(&r) => {
self.shift_region_through_binders(r)
}
None => {
let span = self.span.unwrap_or(DUMMY_SP);
self.tcx().sess.span_bug(
span,
&format!("Region parameter out of range \
when substituting in region {} (root type={:?}) \
(space={:?}, index={})",
data.name,
self.root_ty,
data.space,
data.index));
}
}
}
_ => r
Expand Down
8 changes: 0 additions & 8 deletions src/librustc/middle/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,6 @@ pub fn translate_substs<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
specialization_graph::Node::Trait(..) => source_trait_ref.substs.clone(),
};

// retain erasure mode
// NB: this must happen before inheriting method generics below
let target_substs = if source_substs.regions.is_erased() {
target_substs.erase_regions()
} else {
target_substs
};

// directly inherent the method generics, since those do not vary across impls
infcx.tcx.mk_substs(target_substs.with_method_from_subst(source_substs))
}
Expand Down
9 changes: 2 additions & 7 deletions src/librustc/middle/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,8 @@ impl FlagComputation {

fn add_substs(&mut self, substs: &subst::Substs) {
self.add_tys(substs.types.as_slice());
match substs.regions {
subst::ErasedRegions => {}
subst::NonerasedRegions(ref regions) => {
for &r in regions {
self.add_region(r);
}
}
for &r in &substs.regions {
self.add_region(r);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ impl<'tcx> TyCtxt<'tcx> {
fn fold_substs(&mut self,
substs: &subst::Substs<'tcx>)
-> subst::Substs<'tcx> {
subst::Substs { regions: subst::ErasedRegions,
subst::Substs { regions: substs.regions.fold_with(self),
types: substs.types.fold_with(self) }
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2605,7 +2605,7 @@ impl<'tcx> TyCtxt<'tcx> {

Substs {
types: types,
regions: subst::NonerasedRegions(regions)
regions: regions,
}
}

Expand Down
28 changes: 10 additions & 18 deletions src/librustc/middle/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//! type equality, etc.

use middle::def_id::DefId;
use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs};
use middle::subst::{ParamSpace, Substs};
use middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use middle::ty::error::{ExpectedFound, TypeError};
use std::rc::Rc;
Expand Down Expand Up @@ -156,23 +156,15 @@ pub fn relate_substs<'a,'tcx:'a,R>(relation: &mut R,
substs.types.replace(space, tps);
}

match (&a_subst.regions, &b_subst.regions) {
(&ErasedRegions, _) | (_, &ErasedRegions) => {
substs.regions = ErasedRegions;
}

(&NonerasedRegions(ref a), &NonerasedRegions(ref b)) => {
for &space in &ParamSpace::all() {
let a_regions = a.get_slice(space);
let b_regions = b.get_slice(space);
let r_variances = variances.map(|v| v.regions.get_slice(space));
let regions = relate_region_params(relation,
r_variances,
a_regions,
b_regions)?;
substs.mut_regions().replace(space, regions);
}
}
for &space in &ParamSpace::all() {
let a_regions = a_subst.regions.get_slice(space);
let b_regions = b_subst.regions.get_slice(space);
let r_variances = variances.map(|v| v.regions.get_slice(space));
let regions = relate_region_params(relation,
r_variances,
a_regions,
b_regions)?;
substs.regions.replace(space, regions);
}

Ok(substs)
Expand Down
14 changes: 2 additions & 12 deletions src/librustc/middle/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,14 +487,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region {

impl<'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let regions = match self.regions {
subst::ErasedRegions => subst::ErasedRegions,
subst::NonerasedRegions(ref regions) => {
subst::NonerasedRegions(regions.fold_with(folder))
}
};

subst::Substs { regions: regions,
subst::Substs { regions: self.regions.fold_with(folder),
types: self.types.fold_with(folder) }
}

Expand All @@ -503,10 +496,7 @@ impl<'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> {
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.types.visit_with(visitor) || match self.regions {
subst::ErasedRegions => false,
subst::NonerasedRegions(ref regions) => regions.visit_with(visitor),
}
self.types.visit_with(visitor) || self.regions.visit_with(visitor)
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,18 +1204,18 @@ impl<'tcx> TyS<'tcx> {
TyTrait(ref obj) => {
let mut v = vec![obj.bounds.region_bound];
v.extend_from_slice(obj.principal.skip_binder()
.substs.regions().as_slice());
.substs.regions.as_slice());
v
}
TyEnum(_, substs) |
TyStruct(_, substs) => {
substs.regions().as_slice().to_vec()
substs.regions.as_slice().to_vec()
}
TyClosure(_, ref substs) => {
substs.func_substs.regions().as_slice().to_vec()
substs.func_substs.regions.as_slice().to_vec()
}
TyProjection(ref data) => {
data.trait_ref.substs.regions().as_slice().to_vec()
data.trait_ref.substs.regions.as_slice().to_vec()
}
TyFnDef(..) |
TyFnPtr(_) |
Expand Down
Loading