rustc: remove ParamSpace from Substs.

This commit is contained in:
Eduard Burtescu 2016-08-17 06:32:00 +03:00
parent 6f5e455c2d
commit 9453d9b8ad
60 changed files with 462 additions and 857 deletions

View File

@ -18,7 +18,7 @@ use hir::{self, pat_util, PatKind};
use hir::intravisit::{self, Visitor};
use middle::privacy;
use ty::{self, subst, TyCtxt};
use ty::{self, TyCtxt};
use hir::def::Def;
use hir::def_id::{DefId};
use lint;
@ -95,7 +95,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
if self.tcx.trait_of_item(def.def_id()).is_some() => {
if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
match substs.substs.types.get(subst::TypeSpace, 0).sty {
match substs.substs.types[0].sty {
TyEnum(tyid, _) | TyStruct(tyid, _) => {
self.check_def_id(tyid.did)
}

View File

@ -24,9 +24,7 @@ use session::Session;
use hir::def::{Def, DefMap};
use hir::def_id::DefId;
use middle::region;
use ty::subst;
use ty;
use std::fmt;
use std::mem::replace;
use syntax::ast;
use syntax::parse::token::keywords;
@ -41,8 +39,7 @@ use hir::intravisit::{self, Visitor, FnKind};
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub enum DefRegion {
DefStaticRegion,
DefEarlyBoundRegion(/* space */ subst::ParamSpace,
/* index */ u32,
DefEarlyBoundRegion(/* index */ u32,
/* lifetime decl */ ast::NodeId),
DefLateBoundRegion(ty::DebruijnIndex,
/* lifetime decl */ ast::NodeId),
@ -90,10 +87,11 @@ struct LifetimeContext<'a, 'tcx: 'a> {
labels_in_fn: Vec<(ast::Name, Span)>,
}
#[derive(PartialEq, Debug)]
enum ScopeChain<'a> {
/// EarlyScope(i, ['a, 'b, ...], s) extends s with early-bound
/// lifetimes, assigning indexes 'a => i, 'b => i+1, ... etc.
EarlyScope(subst::ParamSpace, &'a [hir::LifetimeDef], Scope<'a>),
/// EarlyScope(['a, 'b, ...], s) extends s with early-bound
/// lifetimes.
EarlyScope(&'a [hir::LifetimeDef], Scope<'a>),
/// LateScope(['a, 'b, ...], s) extends s with late-bound
/// lifetimes introduced by the declaration binder_id.
LateScope(&'a [hir::LifetimeDef], Scope<'a>),
@ -159,8 +157,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
hir::ItemImpl(_, _, ref generics, _, _, _) => {
// These kinds of items have only early bound lifetime parameters.
let lifetimes = &generics.lifetimes;
let early_scope = EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE);
this.with(early_scope, |old_scope, this| {
this.with(EarlyScope(lifetimes, &ROOT_SCOPE), |old_scope, this| {
this.check_lifetime_defs(old_scope, lifetimes);
intravisit::walk_item(this, item);
});
@ -181,11 +178,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
self.with(RootScope, |_, this| {
match item.node {
hir::ForeignItemFn(ref decl, ref generics) => {
this.visit_early_late(item.id,
subst::FnSpace,
decl,
generics,
|this| {
this.visit_early_late(item.id, decl, generics, |this| {
intravisit::walk_foreign_item(this, item);
})
}
@ -203,14 +196,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
b: &'v hir::Block, s: Span, fn_id: ast::NodeId) {
match fk {
FnKind::ItemFn(_, generics, _, _, _, _, _) => {
self.visit_early_late(fn_id, subst::FnSpace, decl, generics, |this| {
self.visit_early_late(fn_id,decl, generics, |this| {
this.add_scope_and_walk_fn(fk, decl, b, s, fn_id)
})
}
FnKind::Method(_, sig, _, _) => {
self.visit_early_late(
fn_id,
subst::FnSpace,
decl,
&sig.generics,
|this| this.add_scope_and_walk_fn(fk, decl, b, s, fn_id));
@ -263,7 +255,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
if let hir::MethodTraitItem(ref sig, None) = trait_item.node {
self.visit_early_late(
trait_item.id, subst::FnSpace,
trait_item.id,
&sig.decl, &sig.generics,
|this| intravisit::walk_trait_item(this, trait_item))
} else {
@ -469,7 +461,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: &hir::Block) {
FnScope { s, .. } => { scope = s; }
RootScope => { return; }
EarlyScope(_, lifetimes, s) |
EarlyScope(lifetimes, s) |
LateScope(lifetimes, s) => {
for lifetime_def in lifetimes {
// FIXME (#24278): non-hygienic comparison
@ -557,7 +549,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
/// ordering is not important there.
fn visit_early_late<F>(&mut self,
fn_id: ast::NodeId,
early_space: subst::ParamSpace,
decl: &hir::FnDecl,
generics: &hir::Generics,
walk: F) where
@ -576,7 +567,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
.partition(|l| self.map.late_bound.contains_key(&l.lifetime.id));
let this = self;
this.with(EarlyScope(early_space, &early, this.scope), move |old_scope, this| {
this.with(EarlyScope(&early, this.scope), move |old_scope, this| {
this.with(LateScope(&late, this.scope), move |_, this| {
this.check_lifetime_defs(old_scope, &generics.lifetimes);
walk(this);
@ -606,11 +597,19 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
break;
}
EarlyScope(space, lifetimes, s) => {
EarlyScope(lifetimes, s) => {
match search_lifetimes(lifetimes, lifetime_ref) {
Some((index, lifetime_def)) => {
Some((mut index, lifetime_def)) => {
// Adjust for nested early scopes, e.g. in methods.
let mut parent = s;
while let EarlyScope(lifetimes, s) = *parent {
index += lifetimes.len() as u32;
parent = s;
}
assert_eq!(*parent, RootScope);
let decl_id = lifetime_def.id;
let def = DefEarlyBoundRegion(space, index, decl_id);
let def = DefEarlyBoundRegion(index, decl_id);
self.insert_lifetime(lifetime_ref, def);
return;
}
@ -672,7 +671,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
break;
}
EarlyScope(_, lifetimes, s) |
EarlyScope(lifetimes, s) |
LateScope(lifetimes, s) => {
search_result = search_lifetimes(lifetimes, lifetime_ref);
if search_result.is_some() {
@ -768,7 +767,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
return;
}
EarlyScope(_, lifetimes, s) |
EarlyScope(lifetimes, s) |
LateScope(lifetimes, s) => {
if let Some((_, lifetime_def)) = search_lifetimes(lifetimes, lifetime) {
signal_shadowing_problem(
@ -963,14 +962,3 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
}
}
}
impl<'a> fmt::Debug for ScopeChain<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
EarlyScope(space, defs, _) => write!(fmt, "EarlyScope({:?}, {:?})", space, defs),
LateScope(defs, _) => write!(fmt, "LateScope({:?})", defs),
FnScope { fn_id, body_id, s: _ } => write!(fmt, "FnScope({:?}, {:?})", fn_id, body_id),
RootScope => write!(fmt, "RootScope"),
}
}
}

View File

@ -31,7 +31,7 @@ use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
use ty::error::ExpectedFound;
use ty::fast_reject;
use ty::fold::TypeFolder;
use ty::subst::{Subst, TypeSpace};
use ty::subst::Subst;
use util::nodemap::{FnvHashMap, FnvHashSet};
use std::cmp;
@ -232,8 +232,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
if let Ok(..) = self.can_equate(&trait_self_ty, &impl_self_ty) {
self_match_impls.push(def_id);
if trait_ref.substs.types.get_slice(TypeSpace)[1..].iter()
.zip(&impl_trait_ref.substs.types.get_slice(TypeSpace)[1..])
if trait_ref.substs.types[1..].iter()
.zip(&impl_trait_ref.substs.types[1..])
.all(|(u,v)| self.fuzzy_match_tys(u, v))
{
fuzzy_match_impls.push(def_id);

View File

@ -142,7 +142,7 @@ impl<'a, 'gcx, 'tcx> DeferredObligation<'tcx> {
// Auto trait obligations on `impl Trait`.
if tcx.trait_has_default_impl(predicate.def_id()) {
let substs = predicate.skip_binder().trait_ref.substs;
if substs.types.as_full_slice().len() == 1 && substs.regions.is_empty() {
if substs.types.len() == 1 && substs.regions.is_empty() {
if let ty::TyAnon(..) = predicate.skip_binder().self_ty().sty {
return true;
}

View File

@ -36,7 +36,7 @@ use super::util;
use hir::def_id::DefId;
use infer;
use infer::{InferCtxt, InferOk, TypeFreshener, TypeOrigin};
use ty::subst::{Subst, Substs, TypeSpace};
use ty::subst::{Subst, Substs};
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
use traits;
use ty::fast_reject;
@ -1936,7 +1936,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// for `PhantomData<T>`, we pass `T`
ty::TyStruct(def, substs) if def.is_phantom_data() => {
substs.types.as_full_slice().to_vec()
substs.types.to_vec()
}
ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => {
@ -2585,11 +2585,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
} else {
return Err(Unimplemented);
};
let mut ty_params = BitVector::new(substs_a.types.len(TypeSpace));
let mut ty_params = BitVector::new(substs_a.types.len());
let mut found = false;
for ty in field.walk() {
if let ty::TyParam(p) = ty.sty {
assert!(p.space == TypeSpace);
ty_params.insert(p.idx as usize);
found = true;
}
@ -2602,13 +2601,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// TyError and ensure they do not affect any other fields.
// This could be checked after type collection for any struct
// with a potentially unsized trailing field.
let types = substs_a.types.map_enumerated(|(_, i, ty)| {
let types = substs_a.types.iter().enumerate().map(|(i, ty)| {
if ty_params.contains(i) {
tcx.types.err
} else {
ty
}
});
}).collect();
let substs = Substs::new(tcx, types, substs_a.regions.clone());
for &ty in fields.split_last().unwrap().1 {
if ty.subst(tcx, substs).references_error() {
@ -2622,13 +2621,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// Check that the source structure with the target's
// type parameters is a subtype of the target.
let types = substs_a.types.map_enumerated(|(_, i, ty)| {
let types = substs_a.types.iter().enumerate().map(|(i, ty)| {
if ty_params.contains(i) {
*substs_b.types.get(TypeSpace, i)
substs_b.types[i]
} else {
ty
}
});
}).collect();
let substs = Substs::new(tcx, types, substs_a.regions.clone());
let new_struct = tcx.mk_struct(def, substs);
let origin = TypeOrigin::Misc(obligation.cause.span);

View File

@ -44,11 +44,10 @@ pub struct OverlapError {
/// When we have selected one impl, but are actually using item definitions from
/// a parent impl providing a default, we need a way to translate between the
/// type parameters of the two impls. Here the `source_impl` is the one we've
/// selected, and `source_substs` is a substitution of its generics (and
/// possibly some relevant `FnSpace` variables as well). And `target_node` is
/// the impl/trait we're actually going to get the definition from. The resulting
/// substitution will map from `target_node`'s generics to `source_impl`'s
/// generics as instantiated by `source_subst`.
/// selected, and `source_substs` is a substitution of its generics.
/// And `target_node` is the impl/trait we're actually going to get the
/// definition from. The resulting substitution will map from `target_node`'s
/// generics to `source_impl`'s generics as instantiated by `source_subst`.
///
/// For example, consider the following scenario:
///

View File

@ -23,7 +23,7 @@ use middle::free_region::FreeRegionMap;
use middle::region::RegionMaps;
use middle::resolve_lifetime;
use middle::stability;
use ty::subst::{self, Substs};
use ty::subst::Substs;
use traits;
use ty::{self, TraitRef, Ty, TypeAndMut};
use ty::{TyS, TypeVariants};
@ -1346,18 +1346,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
pub fn mk_param(self,
space: subst::ParamSpace,
index: u32,
name: Name) -> Ty<'tcx> {
self.mk_ty(TyParam(ParamTy { space: space, idx: index, name: name }))
self.mk_ty(TyParam(ParamTy { idx: index, name: name }))
}
pub fn mk_self_type(self) -> Ty<'tcx> {
self.mk_param(subst::TypeSpace, 0, keywords::SelfType.name())
self.mk_param(0, keywords::SelfType.name())
}
pub fn mk_param_from_def(self, def: &ty::TypeParameterDef) -> Ty<'tcx> {
self.mk_param(def.space, def.index, def.name)
self.mk_param(def.index, def.name)
}
pub fn mk_anon(self, def_id: DefId, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {

View File

@ -208,8 +208,8 @@ impl FlagComputation {
}
fn add_substs(&mut self, substs: &Substs) {
self.add_tys(substs.types.as_full_slice());
for &r in substs.regions.as_full_slice() {
self.add_tys(&substs.types);
for &r in &substs.regions {
self.add_region(r);
}
}

View File

@ -28,7 +28,7 @@ use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangIte
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
use traits;
use ty;
use ty::subst::{Subst, Substs, VecPerParamSpace};
use ty::subst::{Subst, Substs};
use ty::walk::TypeWalker;
use util::common::MemoizationMap;
use util::nodemap::NodeSet;
@ -426,15 +426,15 @@ pub struct AssociatedType<'tcx> {
#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
pub struct ItemVariances {
pub types: VecPerParamSpace<Variance>,
pub regions: VecPerParamSpace<Variance>,
pub types: Vec<Variance>,
pub regions: Vec<Variance>,
}
impl ItemVariances {
pub fn empty() -> ItemVariances {
ItemVariances {
types: VecPerParamSpace::empty(),
regions: VecPerParamSpace::empty(),
types: vec![],
regions: vec![],
}
}
}
@ -723,7 +723,6 @@ pub enum ObjectLifetimeDefault {
pub struct TypeParameterDef<'tcx> {
pub name: Name,
pub def_id: DefId,
pub space: subst::ParamSpace,
pub index: u32,
pub default_def_id: DefId, // for use in error reporing about defaults
pub default: Option<Ty<'tcx>>,
@ -734,7 +733,6 @@ pub struct TypeParameterDef<'tcx> {
pub struct RegionParameterDef {
pub name: Name,
pub def_id: DefId,
pub space: subst::ParamSpace,
pub index: u32,
pub bounds: Vec<ty::Region>,
}
@ -742,7 +740,6 @@ pub struct RegionParameterDef {
impl RegionParameterDef {
pub fn to_early_bound_region(&self) -> ty::Region {
ty::ReEarlyBound(ty::EarlyBoundRegion {
space: self.space,
index: self.index,
name: self.name,
})
@ -812,7 +809,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
pub enum Predicate<'tcx> {
/// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
/// would be the parameters in the `TypeSpace`.
/// would be the type parameters.
Trait(PolyTraitPredicate<'tcx>),
/// A predicate created by RFC1592
@ -837,9 +834,9 @@ pub enum Predicate<'tcx> {
/// trait must be object-safe
ObjectSafe(DefId),
/// No direct syntax. May be thought of as `where T : FnFoo<...>` for some 'TypeSpace'
/// substitutions `...` and T being a closure type. Satisfied (or refuted) once we know the
/// closure's kind.
/// No direct syntax. May be thought of as `where T : FnFoo<...>`
/// for some substitutions `...` and T being a closure type.
/// Satisfied (or refuted) once we know the closure's kind.
ClosureKind(DefId, ClosureKind),
}
@ -975,7 +972,7 @@ impl<'tcx> TraitPredicate<'tcx> {
}
pub fn input_types(&self) -> &[Ty<'tcx>] {
self.trait_ref.substs.types.as_full_slice()
&self.trait_ref.substs.types
}
pub fn self_ty(&self) -> Ty<'tcx> {
@ -1117,7 +1114,7 @@ impl<'tcx> Predicate<'tcx> {
pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
let vec: Vec<_> = match *self {
ty::Predicate::Trait(ref data) => {
data.0.trait_ref.substs.types.as_full_slice().to_vec()
data.0.trait_ref.input_types().to_vec()
}
ty::Predicate::Rfc1592(ref data) => {
return data.walk_tys()
@ -1132,8 +1129,7 @@ impl<'tcx> Predicate<'tcx> {
vec![]
}
ty::Predicate::Projection(ref data) => {
let trait_inputs = data.0.projection_ty.trait_ref.substs
.types.as_full_slice();
let trait_inputs = data.0.projection_ty.trait_ref.input_types();
trait_inputs.iter()
.cloned()
.chain(Some(data.0.ty))
@ -1217,7 +1213,7 @@ impl<'tcx> TraitRef<'tcx> {
}
pub fn self_ty(&self) -> Ty<'tcx> {
*self.substs.types.get(subst::TypeSpace, 0)
self.substs.types[0]
}
pub fn input_types(&self) -> &[Ty<'tcx>] {
@ -1225,7 +1221,7 @@ impl<'tcx> TraitRef<'tcx> {
// now this is all the types that appear in the
// trait-reference, but it should eventually exclude
// associated types.
self.substs.types.as_full_slice()
&self.substs.types
}
}

View File

@ -146,41 +146,18 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{
let tcx = relation.tcx();
let mut result = Ok(());
let types = a_subst.types.map_enumerated(|(space, i, a_ty)| {
if result.is_err() { return tcx.types.err; }
let types = a_subst.types.iter().enumerate().map(|(i, a_ty)| {
let b_ty = &b_subst.types[i];
let variance = variances.map_or(ty::Invariant, |v| v.types[i]);
relation.relate_with_variance(variance, a_ty, b_ty)
}).collect()?;
let b_ty = b_subst.types.get(space, i);
let variance = variances.map_or(ty::Invariant, |v| {
*v.types.get(space, i)
});
match relation.relate_with_variance(variance, a_ty, b_ty) {
Ok(ty) => ty,
Err(e) => {
result = Err(e);
tcx.types.err
}
}
});
result?;
let regions = a_subst.regions.map_enumerated(|(space, i, a_r)| {
if result.is_err() { return ty::ReStatic; }
let b_r = b_subst.regions.get(space, i);
let variance = variances.map_or(ty::Invariant, |v| {
*v.regions.get(space, i)
});
match relation.relate_with_variance(variance, a_r, b_r) {
Ok(r) => r,
Err(e) => {
result = Err(e);
ty::ReStatic
}
}
});
result?;
let regions = a_subst.regions.iter().enumerate().map(|(i, a_r)| {
let b_r = &b_subst.regions[i];
let variance = variances.map_or(ty::Invariant, |v| v.regions[i]);
relation.relate_with_variance(variance, a_r, b_r)
}).collect()?;
Ok(Substs::new(tcx, types, regions))
}
@ -433,7 +410,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
}
(&ty::TyParam(ref a_p), &ty::TyParam(ref b_p))
if a_p.idx == b_p.idx && a_p.space == b_p.space =>
if a_p.idx == b_p.idx =>
{
Ok(a)
}

View File

@ -9,7 +9,7 @@
// except according to those terms.
use infer::type_variable;
use ty::subst::{Substs, VecPerParamSpace};
use ty::subst::Substs;
use ty::{self, Lift, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@ -450,16 +450,6 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for P<[T]> {
}
}
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for VecPerParamSpace<T> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
self.map(|elem| elem.fold_with(folder))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.as_full_slice().iter().any(|elem| elem.visit_with(visitor))
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::TraitObject<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::TraitObject {
@ -780,7 +770,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
ty::TypeParameterDef {
name: self.name,
def_id: self.def_id,
space: self.space,
index: self.index,
default: self.default.fold_with(folder),
default_def_id: self.default_def_id,
@ -821,7 +810,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef {
ty::RegionParameterDef {
name: self.name,
def_id: self.def_id,
space: self.space,
index: self.index,
bounds: self.bounds.fold_with(folder),
}

View File

@ -13,7 +13,7 @@
use middle::cstore;
use hir::def_id::DefId;
use middle::region;
use ty::subst::{self, Substs};
use ty::subst::Substs;
use ty::{self, AdtDef, ToPredicate, TypeFlags, Ty, TyCtxt, TyS, TypeFoldable};
use util::common::ErrorReported;
@ -304,8 +304,8 @@ pub struct TraitObject<'tcx> {
/// T : Foo<U>
///
/// This would be represented by a trait-reference where the def-id is the
/// def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the
/// `TypeSpace` and `U` as parameter 1 in the `TypeSpace`.
/// def-id for the trait `Foo` and the substs define `T` as parameter 0,
/// and `U` as parameter 1.
///
/// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the substitutions.
@ -365,7 +365,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
// now this is all the types that appear in the
// trait-reference, but it should eventually exclude
// associated types.
self.substs.types.as_full_slice()
&self.substs.types
}
}
@ -498,34 +498,29 @@ impl<'tcx> PolyFnSig<'tcx> {
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct ParamTy {
pub space: subst::ParamSpace,
pub idx: u32,
pub name: Name,
}
impl<'a, 'gcx, 'tcx> ParamTy {
pub fn new(space: subst::ParamSpace,
index: u32,
name: Name)
-> ParamTy {
ParamTy { space: space, idx: index, name: name }
pub fn new(index: u32, name: Name) -> ParamTy {
ParamTy { idx: index, name: name }
}
pub fn for_self() -> ParamTy {
ParamTy::new(subst::TypeSpace, 0, keywords::SelfType.name())
ParamTy::new(0, keywords::SelfType.name())
}
pub fn for_def(def: &ty::TypeParameterDef) -> ParamTy {
ParamTy::new(def.space, def.index, def.name)
ParamTy::new(def.index, def.name)
}
pub fn to_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
tcx.mk_param(self.space, self.idx, self.name)
tcx.mk_param(self.idx, self.name)
}
pub fn is_self(&self) -> bool {
if self.name == keywords::SelfType.name() {
assert_eq!(self.space, subst::TypeSpace);
assert_eq!(self.idx, 0);
true
} else {
@ -682,7 +677,6 @@ pub enum Region {
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub struct EarlyBoundRegion {
pub space: subst::ParamSpace,
pub index: u32,
pub name: Name,
}
@ -951,9 +945,9 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
pub fn is_bool(&self) -> bool { self.sty == TyBool }
pub fn is_param(&self, space: subst::ParamSpace, index: u32) -> bool {
pub fn is_param(&self, index: u32) -> bool {
match self.sty {
ty::TyParam(ref data) => data.space == space && data.idx == index,
ty::TyParam(ref data) => data.idx == index,
_ => false,
}
}
@ -1219,19 +1213,19 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
TyTrait(ref obj) => {
let mut v = vec![obj.region_bound];
v.extend_from_slice(obj.principal.skip_binder().substs.regions.as_full_slice());
v.extend_from_slice(&obj.principal.skip_binder().substs.regions);
v
}
TyEnum(_, substs) |
TyStruct(_, substs) |
TyAnon(_, substs) => {
substs.regions.as_full_slice().to_vec()
substs.regions.to_vec()
}
TyClosure(_, ref substs) => {
substs.func_substs.regions.as_full_slice().to_vec()
substs.func_substs.regions.to_vec()
}
TyProjection(ref data) => {
data.trait_ref.substs.regions.as_full_slice().to_vec()
data.trait_ref.substs.regions.to_vec()
}
TyFnDef(..) |
TyFnPtr(_) |

View File

@ -10,56 +10,32 @@
// Type substitutions.
pub use self::ParamSpace::*;
use middle::cstore;
use hir::def_id::DefId;
use ty::{self, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder};
use serialize::{Encodable, Encoder, Decodable, Decoder};
use std::fmt;
use syntax_pos::{Span, DUMMY_SP};
///////////////////////////////////////////////////////////////////////////
/// A substitution mapping type/region parameters to new values. We
/// identify each in-scope parameter by an *index* and a *parameter
/// space* (which indices where the parameter is defined; see
/// `ParamSpace`).
/// A substitution mapping type/region parameters to new values.
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Substs<'tcx> {
pub types: VecPerParamSpace<Ty<'tcx>>,
pub regions: VecPerParamSpace<ty::Region>,
pub types: Vec<Ty<'tcx>>,
pub regions: Vec<ty::Region>,
}
impl<'a, 'gcx, 'tcx> Substs<'tcx> {
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
t: VecPerParamSpace<Ty<'tcx>>,
r: VecPerParamSpace<ty::Region>)
t: Vec<Ty<'tcx>>,
r: Vec<ty::Region>)
-> &'tcx Substs<'tcx>
{
tcx.mk_substs(Substs { types: t, regions: r })
}
pub fn new_fn(tcx: TyCtxt<'a, 'gcx, 'tcx>,
t: Vec<Ty<'tcx>>,
r: Vec<ty::Region>)
-> &'tcx Substs<'tcx>
{
Substs::new(tcx, VecPerParamSpace::new(vec![], t),
VecPerParamSpace::new(vec![], r))
}
pub fn new_type(tcx: TyCtxt<'a, 'gcx, 'tcx>,
t: Vec<Ty<'tcx>>,
r: Vec<ty::Region>)
-> &'tcx Substs<'tcx>
{
Substs::new(tcx, VecPerParamSpace::new(t, vec![]),
VecPerParamSpace::new(r, vec![]))
}
pub fn new_trait(tcx: TyCtxt<'a, 'gcx, 'tcx>,
mut t: Vec<Ty<'tcx>>,
r: Vec<ty::Region>,
@ -67,13 +43,11 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
-> &'tcx Substs<'tcx>
{
t.insert(0, s);
Substs::new(tcx, VecPerParamSpace::new(t, vec![]),
VecPerParamSpace::new(r, vec![]))
Substs::new(tcx, t, r)
}
pub fn empty(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx Substs<'tcx> {
Substs::new(tcx, VecPerParamSpace::empty(),
VecPerParamSpace::empty())
Substs::new(tcx, vec![], vec![])
}
/// Creates a Substs for generic parameter definitions,
@ -92,14 +66,8 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
let num_regions = defs.parent_regions as usize + defs.regions.len();
let num_types = defs.parent_types as usize + defs.types.len();
let mut substs = Substs {
regions: VecPerParamSpace {
type_limit: 0,
content: Vec::with_capacity(num_regions)
},
types: VecPerParamSpace {
type_limit: 0,
content: Vec::with_capacity(num_types)
}
regions: Vec::with_capacity(num_regions),
types: Vec::with_capacity(num_types)
};
substs.fill_item(tcx, defs, &mut mk_region, &mut mk_type);
@ -121,22 +89,14 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
for def in &defs.regions {
let region = mk_region(def, self);
self.regions.content.push(region);
if def.space == TypeSpace {
self.regions.type_limit += 1;
assert_eq!(self.regions.content.len(), self.regions.type_limit);
}
assert_eq!(def.index as usize, self.regions.len());
self.regions.push(region);
}
for def in &defs.types {
let ty = mk_type(def, self);
self.types.content.push(ty);
if def.space == TypeSpace {
self.types.type_limit += 1;
assert_eq!(self.types.content.len(), self.types.type_limit);
}
assert_eq!(def.index as usize, self.types.len());
self.types.push(ty);
}
}
@ -145,11 +105,11 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}
pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> {
*self.types.get(ty_param_def.space, ty_param_def.index as usize)
self.types[ty_param_def.index as usize]
}
pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> ty::Region {
*self.regions.get(def.space, def.index as usize)
self.regions[def.index as usize]
}
/// Transform from substitutions for a child of `source_ancestor`
@ -162,14 +122,10 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
target_substs: &Substs<'tcx>)
-> &'tcx Substs<'tcx> {
let defs = tcx.lookup_generics(source_ancestor);
assert_eq!(self.types.len(TypeSpace), defs.types.len());
assert_eq!(target_substs.types.len(FnSpace), 0);
assert_eq!(self.regions.len(TypeSpace), defs.regions.len());
assert_eq!(target_substs.regions.len(FnSpace), 0);
let Substs { mut types, mut regions } = target_substs.clone();
types.content.extend(&self.types.as_full_slice()[defs.types.len()..]);
regions.content.extend(&self.regions.as_full_slice()[defs.regions.len()..]);
let regions = target_substs.regions.iter()
.chain(&self.regions[defs.regions.len()..]).cloned().collect();
let types = target_substs.types.iter()
.chain(&self.types[defs.types.len()..]).cloned().collect();
Substs::new(tcx, types, regions)
}
}
@ -193,200 +149,6 @@ impl<'tcx> Decodable for &'tcx Substs<'tcx> {
}
}
///////////////////////////////////////////////////////////////////////////
// ParamSpace
#[derive(PartialOrd, Ord, PartialEq, Eq, Copy,
Clone, Hash, RustcEncodable, RustcDecodable, Debug)]
pub enum ParamSpace {
TypeSpace, // Type parameters attached to a type definition, trait, or impl
FnSpace, // Type parameters attached to a method or fn
}
impl ParamSpace {
pub fn all() -> [ParamSpace; 2] {
[TypeSpace, FnSpace]
}
pub fn to_uint(self) -> usize {
match self {
TypeSpace => 0,
FnSpace => 1,
}
}
pub fn from_uint(u: usize) -> ParamSpace {
match u {
0 => TypeSpace,
1 => FnSpace,
_ => bug!("Invalid ParamSpace: {}", u)
}
}
}
/// Vector of things sorted by param space. Used to keep
/// the set of things declared on the type, self, or method
/// distinct.
#[derive(PartialEq, Eq, Clone, Hash, RustcEncodable, RustcDecodable)]
pub struct VecPerParamSpace<T> {
// This was originally represented as a tuple with one Vec<T> for
// each variant of ParamSpace, and that remains the abstraction
// that it provides to its clients.
//
// Here is how the representation corresponds to the abstraction
// i.e. the "abstraction function" AF:
//
// AF(self) = (self.content[..self.type_limit],
// self.content[self.type_limit..])
type_limit: usize,
content: Vec<T>,
}
impl<T: fmt::Debug> fmt::Debug for VecPerParamSpace<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{:?};{:?}]",
self.get_slice(TypeSpace),
self.get_slice(FnSpace))
}
}
impl<T> VecPerParamSpace<T> {
fn limits(&self, space: ParamSpace) -> (usize, usize) {
match space {
TypeSpace => (0, self.type_limit),
FnSpace => (self.type_limit, self.content.len()),
}
}
pub fn empty() -> VecPerParamSpace<T> {
VecPerParamSpace {
type_limit: 0,
content: Vec::new()
}
}
/// `t` is the type space.
/// `f` is the fn space.
pub fn new(t: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
let type_limit = t.len();
let mut content = t;
content.extend(f);
VecPerParamSpace {
type_limit: type_limit,
content: content,
}
}
fn new_internal(content: Vec<T>, type_limit: usize) -> VecPerParamSpace<T> {
VecPerParamSpace {
type_limit: type_limit,
content: content,
}
}
pub fn len(&self, space: ParamSpace) -> usize {
self.get_slice(space).len()
}
pub fn is_empty_in(&self, space: ParamSpace) -> bool {
self.len(space) == 0
}
pub fn get_slice<'a>(&'a self, space: ParamSpace) -> &'a [T] {
let (start, limit) = self.limits(space);
&self.content[start.. limit]
}
pub fn get<'a>(&'a self, space: ParamSpace, index: usize) -> &'a T {
&self.get_slice(space)[index]
}
pub fn iter_enumerated<'a>(&'a self) -> EnumeratedItems<'a,T> {
EnumeratedItems::new(self)
}
pub fn as_full_slice(&self) -> &[T] {
&self.content
}
pub fn all<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool {
self.as_full_slice().iter().all(pred)
}
pub fn any<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool {
self.as_full_slice().iter().any(pred)
}
pub fn is_empty(&self) -> bool {
self.content.is_empty()
}
pub fn map<U, P>(&self, pred: P) -> VecPerParamSpace<U> where P: FnMut(&T) -> U {
let result = self.as_full_slice().iter().map(pred).collect();
VecPerParamSpace::new_internal(result, self.type_limit)
}
pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where
P: FnMut((ParamSpace, usize, &T)) -> U,
{
let result = self.iter_enumerated().map(pred).collect();
VecPerParamSpace::new_internal(result, self.type_limit)
}
}
#[derive(Clone)]
pub struct EnumeratedItems<'a,T:'a> {
vec: &'a VecPerParamSpace<T>,
space_index: usize,
elem_index: usize
}
impl<'a,T> EnumeratedItems<'a,T> {
fn new(v: &'a VecPerParamSpace<T>) -> EnumeratedItems<'a,T> {
let mut result = EnumeratedItems { vec: v, space_index: 0, elem_index: 0 };
result.adjust_space();
result
}
fn adjust_space(&mut self) {
let spaces = ParamSpace::all();
while
self.space_index < spaces.len() &&
self.elem_index >= self.vec.len(spaces[self.space_index])
{
self.space_index += 1;
self.elem_index = 0;
}
}
}
impl<'a,T> Iterator for EnumeratedItems<'a,T> {
type Item = (ParamSpace, usize, &'a T);
fn next(&mut self) -> Option<(ParamSpace, usize, &'a T)> {
let spaces = ParamSpace::all();
if self.space_index < spaces.len() {
let space = spaces[self.space_index];
let index = self.elem_index;
let item = self.vec.get(space, index);
self.elem_index += 1;
self.adjust_space();
Some((space, index, item))
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.vec.as_full_slice().len();
(size, Some(size))
}
}
///////////////////////////////////////////////////////////////////////////
// Public trait `Subst`
@ -461,7 +223,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
// the specialized routine `ty::replace_late_regions()`.
match r {
ty::ReEarlyBound(data) => {
match self.substs.regions.get_slice(data.space).get(data.index as usize) {
match self.substs.regions.get(data.index as usize) {
Some(&r) => {
self.shift_region_through_binders(r)
}
@ -471,10 +233,9 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
span,
"Region parameter out of range \
when substituting in region {} (root type={:?}) \
(space={:?}, index={})",
(index={})",
data.name,
self.root_ty,
data.space,
data.index);
}
}
@ -517,18 +278,17 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
// Look up the type in the substitutions. It really should be in there.
let opt_ty = self.substs.types.get_slice(p.space).get(p.idx as usize);
let opt_ty = self.substs.types.get(p.idx as usize);
let ty = match opt_ty {
Some(t) => *t,
None => {
let span = self.span.unwrap_or(DUMMY_SP);
span_bug!(
span,
"Type parameter `{:?}` ({:?}/{:?}/{}) out of range \
"Type parameter `{:?}` ({:?}/{}) out of range \
when substituting (root type={:?}) substs={:?}",
p,
source_ty,
p.space,
p.idx,
self.root_ty,
self.substs);
@ -606,10 +366,9 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
trait_id: DefId,
substs: &Substs<'tcx>)
-> ty::TraitRef<'tcx> {
let Substs { mut types, mut regions } = substs.clone();
let defs = tcx.lookup_generics(trait_id);
types.content.truncate(defs.types.len());
regions.content.truncate(defs.regions.len());
let regions = substs.regions[..defs.regions.len()].to_vec();
let types = substs.types[..defs.types.len()].to_vec();
ty::TraitRef {
def_id: trait_id,
@ -624,8 +383,7 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
-> ty::ExistentialTraitRef<'tcx> {
let Substs { mut types, regions } = trait_ref.substs.clone();
types.type_limit -= 1;
types.content.remove(0);
types.remove(0);
ty::ExistentialTraitRef {
def_id: trait_ref.def_id,
@ -648,8 +406,7 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
self.map_bound(|trait_ref| {
let Substs { mut types, regions } = trait_ref.substs.clone();
types.type_limit += 1;
types.content.insert(0, self_ty);
types.insert(0, self_ty);
ty::TraitRef {
def_id: trait_ref.def_id,

View File

@ -476,7 +476,6 @@ impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> {
self.hash(tys.len());
}
TyParam(p) => {
self.hash(p.space);
self.hash(p.idx);
self.hash(p.name.as_str());
}
@ -694,8 +693,8 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
return false;
}
let types_a = substs_a.types.as_full_slice();
let types_b = substs_b.types.as_full_slice();
let types_a = &substs_a.types;
let types_b = &substs_b.types;
types_a.iter().zip(types_b).all(|(&a, &b)| same_type(a, b))
}

View File

@ -79,7 +79,7 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
stack.push(mt.ty);
}
ty::TyProjection(ref data) => {
push_reversed(stack, data.trait_ref.substs.types.as_full_slice());
push_reversed(stack, &data.trait_ref.substs.types);
}
ty::TyTrait(ref obj) => {
push_reversed(stack, obj.principal.input_types());
@ -90,17 +90,17 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
ty::TyEnum(_, ref substs) |
ty::TyStruct(_, ref substs) |
ty::TyAnon(_, ref substs) => {
push_reversed(stack, substs.types.as_full_slice());
push_reversed(stack, &substs.types);
}
ty::TyClosure(_, ref substs) => {
push_reversed(stack, substs.func_substs.types.as_full_slice());
push_reversed(stack, &substs.func_substs.types);
push_reversed(stack, &substs.upvar_tys);
}
ty::TyTuple(ref ts) => {
push_reversed(stack, ts);
}
ty::TyFnDef(_, substs, ref ft) => {
push_reversed(stack, substs.types.as_full_slice());
push_reversed(stack, &substs.types);
push_sig_subtypes(stack, &ft.sig);
}
ty::TyFnPtr(ref ft) => {

View File

@ -261,7 +261,6 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
let cause = self.cause(traits::MiscObligation);
self.out.extend(
trait_ref.substs.types
.as_full_slice()
.iter()
.filter(|ty| !ty.has_escaping_regions())
.map(|ty| traits::Obligation::new(cause.clone(),

View File

@ -56,7 +56,7 @@ fn fn_sig(f: &mut fmt::Formatter,
}
/// Namespace of the path given to parameterized to print.
#[derive(Copy, Clone, PartialEq)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Ns {
Type,
Value
@ -71,16 +71,43 @@ pub fn parameterized(f: &mut fmt::Formatter,
let mut verbose = false;
let mut num_supplied_defaults = 0;
let mut has_self = false;
let (fn_trait_kind, item_name) = ty::tls::with(|tcx| {
verbose = tcx.sess.verbose();
let mut num_regions = 0;
let mut num_types = 0;
let mut item_name = None;
let fn_trait_kind = ty::tls::with(|tcx| {
let mut generics = tcx.lookup_generics(did);
let mut path_def_id = did;
verbose = tcx.sess.verbose();
has_self = generics.has_self;
if let Some(def_id) = generics.parent {
// Methods.
assert_eq!(ns, Ns::Value);
generics = tcx.lookup_generics(def_id);
num_regions = generics.regions.len();
num_types = generics.types.len();
if has_self {
write!(f, "<{} as ", substs.types[0])?;
}
item_name = Some(tcx.item_name(did));
path_def_id = def_id;
} else {
if ns == Ns::Value {
// Functions.
assert_eq!(has_self, false);
} else {
// Types and traits.
num_regions = generics.regions.len();
num_types = generics.types.len();
}
}
if !verbose {
if generics.types.last().map_or(false, |def| def.default.is_some()) {
if let Some(substs) = tcx.lift(&substs) {
let tps = substs.types.get_slice(subst::TypeSpace);
let tps = &substs.types[..num_types];
for (def, actual) in generics.types.iter().zip(tps).rev() {
if def.default.subst(tcx, substs) != Some(actual) {
break;
@ -91,31 +118,13 @@ pub fn parameterized(f: &mut fmt::Formatter,
}
}
has_self = generics.has_self;
if ns == Ns::Value && has_self {
write!(f, "<{} as ", substs.types.get(subst::TypeSpace, 0))?;
}
let (did, item_name) = if ns == Ns::Value {
// Try to get the impl/trait parent, if this is an
// associated value item (method or constant).
tcx.trait_of_item(did).or_else(|| {
// An impl could be a trait impl or an inherent one.
tcx.impl_of_method(did).map(|impl_def_id| {
tcx.trait_id_of_impl(impl_def_id)
.unwrap_or(impl_def_id)
})
}).map_or((did, None), |parent| (parent, Some(tcx.item_name(did))))
} else {
(did, None)
};
write!(f, "{}", tcx.item_path_str(did))?;
Ok((tcx.lang_items.fn_trait_kind(did), item_name))
write!(f, "{}", tcx.item_path_str(path_def_id))?;
Ok(tcx.lang_items.fn_trait_kind(path_def_id))
})?;
if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
let projection_ty = projections[0].ty;
if let TyTuple(ref args) = substs.types.get(subst::TypeSpace, 1).sty {
if let TyTuple(ref args) = substs.types[1].sty {
return fn_sig(f, args, false, projection_ty);
}
}
@ -158,9 +167,9 @@ pub fn parameterized(f: &mut fmt::Formatter,
Ok(())
};
print_regions(f, "<", substs.regions.get_slice(subst::TypeSpace))?;
print_regions(f, "<", &substs.regions[..num_regions])?;
let tps = substs.types.get_slice(subst::TypeSpace);
let tps = &substs.types[..num_types];
for &ty in &tps[has_self as usize..tps.len() - num_supplied_defaults] {
start_or_continue(f, "<", ", ")?;
@ -188,10 +197,10 @@ pub fn parameterized(f: &mut fmt::Formatter,
write!(f, "::{}", item_name)?;
}
print_regions(f, "::<", substs.regions.get_slice(subst::FnSpace))?;
print_regions(f, "::<", &substs.regions[num_regions..])?;
// FIXME: consider being smart with defaults here too
for ty in substs.types.get_slice(subst::FnSpace) {
for ty in &substs.types[num_types..] {
start_or_continue(f, "::<", ", ")?;
write!(f, "{}", ty)?;
}
@ -328,19 +337,19 @@ impl<'tcx> fmt::Display for ty::TraitObject<'tcx> {
impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TypeParameterDef({}, {:?}, {:?}/{})",
write!(f, "TypeParameterDef({}, {:?}, {})",
self.name,
self.def_id,
self.space, self.index)
self.index)
}
}
impl fmt::Debug for ty::RegionParameterDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "RegionParameterDef({}, {:?}, {:?}/{}, {:?})",
write!(f, "RegionParameterDef({}, {:?}, {}, {:?})",
self.name,
self.def_id,
self.space, self.index,
self.index,
self.bounds)
}
}
@ -526,8 +535,7 @@ impl fmt::Debug for ty::Region {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ty::ReEarlyBound(ref data) => {
write!(f, "ReEarlyBound({:?}, {}, {})",
data.space,
write!(f, "ReEarlyBound({}, {})",
data.index,
data.name)
}
@ -1011,7 +1019,7 @@ impl fmt::Display for ty::ParamTy {
impl fmt::Debug for ty::ParamTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}/{:?}.{}", self, self.space, self.idx)
write!(f, "{}/#{}", self, self.idx)
}
}

View File

@ -859,7 +859,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let unit_temp = Lvalue::Temp(self.patch.new_temp(tcx.mk_nil()));
let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
.unwrap_or_else(|e| tcx.sess.fatal(&e));
let substs = Substs::new_fn(tcx, vec![ty], vec![]);
let substs = Substs::new(tcx, vec![ty], vec![]);
let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs);
self.patch.new_block(BasicBlockData {

View File

@ -20,7 +20,6 @@ use rustc::middle::region::{self, CodeExtent};
use rustc::middle::region::CodeExtentData;
use rustc::middle::resolve_lifetime;
use rustc::middle::stability;
use rustc::ty::subst;
use rustc::ty::subst::{Subst, Substs};
use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
@ -276,19 +275,17 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
self.infcx.tcx.mk_tup(vec![ty1, ty2])
}
pub fn t_param(&self, space: subst::ParamSpace, index: u32) -> Ty<'tcx> {
pub fn t_param(&self, index: u32) -> Ty<'tcx> {
let name = format!("T{}", index);
self.infcx.tcx.mk_param(space, index, token::intern(&name[..]))
self.infcx.tcx.mk_param(index, token::intern(&name[..]))
}
pub fn re_early_bound(&self,
space: subst::ParamSpace,
index: u32,
name: &'static str)
-> ty::Region {
let name = token::intern(name);
ty::ReEarlyBound(ty::EarlyBoundRegion {
space: space,
index: index,
name: name,
})
@ -674,11 +671,11 @@ fn subst_ty_renumber_bound() {
// t_source = fn(A)
let t_source = {
let t_param = env.t_param(subst::TypeSpace, 0);
let t_param = env.t_param(0);
env.t_fn(&[t_param], env.t_nil())
};
let substs = Substs::new_type(env.infcx.tcx, vec![t_rptr_bound1], vec![]);
let substs = Substs::new(env.infcx.tcx, vec![t_rptr_bound1], vec![]);
let t_substituted = t_source.subst(env.infcx.tcx, substs);
// t_expected = fn(&'a isize)
@ -709,11 +706,11 @@ fn subst_ty_renumber_some_bounds() {
// t_source = (A, fn(A))
let t_source = {
let t_param = env.t_param(subst::TypeSpace, 0);
let t_param = env.t_param(0);
env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil()))
};
let substs = Substs::new_type(env.infcx.tcx, vec![t_rptr_bound1], vec![]);
let substs = Substs::new(env.infcx.tcx, vec![t_rptr_bound1], vec![]);
let t_substituted = t_source.subst(env.infcx.tcx, substs);
// t_expected = (&'a isize, fn(&'a isize))
@ -755,7 +752,7 @@ fn escaping() {
assert!(t_rptr_bound2.has_escaping_regions());
// t_fn = fn(A)
let t_param = env.t_param(subst::TypeSpace, 0);
let t_param = env.t_param(0);
assert!(!t_param.has_escaping_regions());
let t_fn = env.t_fn(&[t_param], env.t_nil());
assert!(!t_fn.has_escaping_regions());
@ -771,11 +768,11 @@ fn subst_region_renumber_region() {
// type t_source<'a> = fn(&'a isize)
let t_source = {
let re_early = env.re_early_bound(subst::TypeSpace, 0, "'a");
let re_early = env.re_early_bound(0, "'a");
env.t_fn(&[env.t_rptr(re_early)], env.t_nil())
};
let substs = Substs::new_type(env.infcx.tcx, vec![], vec![re_bound1]);
let substs = Substs::new(env.infcx.tcx, vec![], vec![re_bound1]);
let t_substituted = t_source.subst(env.infcx.tcx, substs);
// t_expected = fn(&'a isize)

View File

@ -20,7 +20,7 @@ use rustc::hir;
use rustc::hir::def_id::{DefId, DefIndex};
use middle::region;
use rustc::ty::subst::{self, Substs, VecPerParamSpace};
use rustc::ty::subst::Substs;
use rustc::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
use rbml;
@ -128,23 +128,19 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}
fn parse_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T,
{
let (mut a, mut b) = (vec![], vec![]);
for r in &mut [&mut a, &mut b] {
assert_eq!(self.next(), '[');
while self.peek() != ']' {
r.push(f(self));
}
assert_eq!(self.next(), ']');
}
VecPerParamSpace::new(a, b)
}
pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
let regions = self.parse_vec_per_param_space(|this| this.parse_region());
let types = self.parse_vec_per_param_space(|this| this.parse_ty());
let mut regions = vec![];
let mut types = vec![];
assert_eq!(self.next(), '[');
while self.peek() != '|' {
regions.push(self.parse_region());
}
assert_eq!(self.next(), '|');
while self.peek() != ']' {
types.push(self.parse_ty());
}
assert_eq!(self.next(), ']');
Substs::new(self.tcx, types, regions)
}
@ -155,14 +151,12 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
let parent_types = self.parse_u32();
let mut regions = vec![];
assert_eq!(self.next(), '[');
while self.peek() != ']' {
regions.push(self.parse_region_param_def());
}
assert_eq!(self.next(), ']');
let mut types = vec![];
assert_eq!(self.next(), '[');
while self.peek() != '|' {
regions.push(self.parse_region_param_def());
}
assert_eq!(self.next(), '|');
while self.peek() != ']' {
types.push(self.parse_type_param_def());
}
@ -225,13 +219,10 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
'B' => {
assert_eq!(self.next(), '[');
let space = self.parse_param_space();
assert_eq!(self.next(), '|');
let index = self.parse_u32();
assert_eq!(self.next(), '|');
let name = token::intern(&self.parse_str(']'));
ty::ReEarlyBound(ty::EarlyBoundRegion {
space: space,
index: index,
name: name
})
@ -406,10 +397,8 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
assert_eq!(self.next(), '[');
let index = self.parse_u32();
assert_eq!(self.next(), '|');
let space = self.parse_param_space();
assert_eq!(self.next(), '|');
let name = token::intern(&self.parse_str(']'));
return tcx.mk_param(space, index, name);
return tcx.mk_param(index, name);
}
'~' => return tcx.mk_box(self.parse_ty()),
'*' => return tcx.mk_ptr(self.parse_mt()),
@ -552,10 +541,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
m
}
fn parse_param_space(&mut self) -> subst::ParamSpace {
subst::ParamSpace::from_uint(self.parse_uint())
}
fn parse_abi_set(&mut self) -> abi::Abi {
assert_eq!(self.next(), '[');
let bytes = self.scan(|c| c == ']');
@ -656,8 +641,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
let name = self.parse_name(':');
let def_id = self.parse_def();
let space = self.parse_param_space();
assert_eq!(self.next(), '|');
let index = self.parse_u32();
assert_eq!(self.next(), '|');
let default_def_id = self.parse_def();
@ -667,7 +650,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
ty::TypeParameterDef {
name: name,
def_id: def_id,
space: space,
index: index,
default_def_id: default_def_id,
default: default,
@ -678,8 +660,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
let name = self.parse_name(':');
let def_id = self.parse_def();
let space = self.parse_param_space();
assert_eq!(self.next(), '|');
let index = self.parse_u32();
assert_eq!(self.next(), '|');
let mut bounds = vec![];
@ -695,7 +675,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
ty::RegionParameterDef {
name: name,
def_id: def_id,
space: space,
index: index,
bounds: bounds,
}

View File

@ -19,8 +19,7 @@ use std::io::prelude::*;
use rustc::hir::def_id::DefId;
use middle::region;
use rustc::ty::subst::{self, Substs, VecPerParamSpace};
use rustc::ty::ParamTy;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::util::nodemap::FnvHashMap;
@ -163,8 +162,8 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx
ty::TyInfer(_) => {
bug!("cannot encode inference variable types");
}
ty::TyParam(ParamTy {space, idx, name}) => {
write!(w, "p[{}|{}|{}]", idx, space.to_uint(), name);
ty::TyParam(p) => {
write!(w, "p[{}|{}]", p.idx, p.name);
}
ty::TyStruct(def, substs) => {
write!(w, "a[{}|", (cx.ds)(cx.tcx, def.did));
@ -249,27 +248,17 @@ fn enc_opt<T, F>(w: &mut Cursor<Vec<u8>>, t: Option<T>, enc_f: F) where
}
}
fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut Cursor<Vec<u8>>,
cx: &ctxt<'a, 'tcx>,
v: &VecPerParamSpace<T>,
mut op: F) where
F: FnMut(&mut Cursor<Vec<u8>>, &ctxt<'a, 'tcx>, &T),
{
for &space in &subst::ParamSpace::all() {
write!(w, "[");
for t in v.get_slice(space) {
op(w, cx, t);
}
write!(w, "]");
}
}
pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
substs: &Substs<'tcx>) {
enc_vec_per_param_space(w, cx, &substs.regions,
|w, cx, &r| enc_region(w, cx, r));
enc_vec_per_param_space(w, cx, &substs.types,
|w, cx, &ty| enc_ty(w, cx, ty));
write!(w, "[");
for &r in &substs.regions {
enc_region(w, cx, r);
}
write!(w, "|");
for &ty in &substs.types {
enc_ty(w, cx, ty);
}
write!(w, "]");
}
pub fn enc_generics<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
@ -284,7 +273,7 @@ pub fn enc_generics<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
for r in &generics.regions {
enc_region_param_def(w, cx, r)
}
write!(w, "][");
write!(w, "|");
for t in &generics.types {
enc_type_param_def(w, cx, t);
}
@ -305,8 +294,7 @@ pub fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: ty::Region) {
write!(w, "]");
}
ty::ReEarlyBound(ref data) => {
write!(w, "B[{}|{}|{}]",
data.space.to_uint(),
write!(w, "B[{}|{}]",
data.index,
data.name);
}
@ -446,18 +434,17 @@ fn enc_builtin_bounds(w: &mut Cursor<Vec<u8>>, _cx: &ctxt, bs: &ty::BuiltinBound
fn enc_type_param_def<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
write!(w, "{}:{}|{}|{}|{}|",
v.name, (cx.ds)(cx.tcx, v.def_id),
v.space.to_uint(), v.index, (cx.ds)(cx.tcx, v.default_def_id));
write!(w, "{}:{}|{}|{}|",
v.name, (cx.ds)(cx.tcx, v.def_id),
v.index, (cx.ds)(cx.tcx, v.default_def_id));
enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
enc_object_lifetime_default(w, cx, v.object_lifetime_default);
}
fn enc_region_param_def(w: &mut Cursor<Vec<u8>>, cx: &ctxt,
v: &ty::RegionParameterDef) {
write!(w, "{}:{}|{}|{}|",
v.name, (cx.ds)(cx.tcx, v.def_id),
v.space.to_uint(), v.index);
write!(w, "{}:{}|{}|",
v.name, (cx.ds)(cx.tcx, v.def_id), v.index);
for &r in &v.bounds {
write!(w, "R");
enc_region(w, cx, r);

View File

@ -750,7 +750,7 @@ fn build_free<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-> TerminatorKind<'tcx> {
let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
.unwrap_or_else(|e| tcx.sess.fatal(&e));
let substs = Substs::new_fn(tcx, vec![data.item_ty], vec![]);
let substs = Substs::new(tcx, vec![data.item_ty], vec![]);
TerminatorKind::Call {
func: Operand::Constant(Constant {
span: data.span,

View File

@ -252,7 +252,7 @@ impl<'a, 'tcx> Instance<'tcx> {
// and should not matter anyhow.
let instance_ty = scx.tcx().erase_regions(&instance_ty.ty);
let hash = get_symbol_hash(scx, &def_path, instance_ty, substs.types.as_full_slice());
let hash = get_symbol_hash(scx, &def_path, instance_ty, &substs.types);
let mut buffer = SymbolPathBuffer {
names: Vec::with_capacity(def_path.data.len())

View File

@ -346,7 +346,7 @@ impl<'tcx> TypeMap<'tcx> {
// Add the def-index as the second part
output.push_str(&format!("{:x}", def_id.index.as_usize()));
let tps = substs.types.as_full_slice();
let tps = &substs.types;
if !tps.is_empty() {
output.push('<');

View File

@ -358,7 +358,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
name_to_append_suffix_to: &mut String)
-> DIArray
{
let actual_types = param_substs.types.as_full_slice();
let actual_types = &param_substs.types;
if actual_types.is_empty() {
return create_DIArray(DIB(cx), &[]);

View File

@ -181,7 +181,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
output.push('<');
for &type_parameter in substs.types.as_full_slice() {
for &type_parameter in &substs.types {
push_debuginfo_type_name(cx, type_parameter, true, output);
output.push_str(", ");
}

View File

@ -15,7 +15,7 @@ use intrinsics::{self, Intrinsic};
use libc;
use llvm;
use llvm::{ValueRef, TypeKind};
use rustc::ty::subst::{FnSpace, Substs};
use rustc::ty::subst::Substs;
use abi::{Abi, FnType};
use adt;
use base::*;
@ -136,8 +136,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
callee::ArgExprs(arg_exprs) => {
assert_eq!(arg_exprs.len(), 1);
let (in_type, out_type) = (*substs.types.get(FnSpace, 0),
*substs.types.get(FnSpace, 1));
let (in_type, out_type) = (substs.types[0],
substs.types[1]);
let llintype = type_of::type_of(ccx, in_type);
let llouttype = type_of::type_of(ccx, out_type);
@ -346,12 +346,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
Call(bcx, llfn, &[], call_debug_location)
}
(_, "size_of") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
let lltp_ty = type_of::type_of(ccx, tp_ty);
C_uint(ccx, machine::llsize_of_alloc(ccx, lltp_ty))
}
(_, "size_of_val") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
if !type_is_sized(tcx, tp_ty) {
let (llsize, _) =
glue::size_and_align_of_dst(&bcx.build(), tp_ty, llargs[1]);
@ -362,11 +362,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
}
(_, "min_align_of") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
C_uint(ccx, type_of::align_of(ccx, tp_ty))
}
(_, "min_align_of_val") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
if !type_is_sized(tcx, tp_ty) {
let (_, llalign) =
glue::size_and_align_of_dst(&bcx.build(), tp_ty, llargs[1]);
@ -376,12 +376,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
}
(_, "pref_align_of") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
let lltp_ty = type_of::type_of(ccx, tp_ty);
C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty))
}
(_, "drop_in_place") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
let ptr = if type_is_sized(tcx, tp_ty) {
llargs[0]
} else {
@ -395,22 +395,22 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
C_nil(ccx)
}
(_, "type_name") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
let ty_name = token::intern_and_get_ident(&tp_ty.to_string());
C_str_slice(ccx, ty_name)
}
(_, "type_id") => {
C_u64(ccx, ccx.tcx().type_id_hash(*substs.types.get(FnSpace, 0)))
C_u64(ccx, ccx.tcx().type_id_hash(substs.types[0]))
}
(_, "init_dropped") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
if !type_is_zero_size(ccx, tp_ty) {
drop_done_fill_mem(bcx, llresult, tp_ty);
}
C_nil(ccx)
}
(_, "init") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
if !type_is_zero_size(ccx, tp_ty) {
// Just zero out the stack slot. (See comment on base::memzero for explanation)
init_zero_mem(bcx, llresult, tp_ty);
@ -422,7 +422,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
C_nil(ccx)
}
(_, "needs_drop") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
C_bool(ccx, bcx.fcx.type_needs_drop(tp_ty))
}
@ -441,7 +441,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
copy_intrinsic(bcx,
false,
false,
*substs.types.get(FnSpace, 0),
substs.types[0],
llargs[1],
llargs[0],
llargs[2],
@ -451,7 +451,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
copy_intrinsic(bcx,
true,
false,
*substs.types.get(FnSpace, 0),
substs.types[0],
llargs[1],
llargs[0],
llargs[2],
@ -460,7 +460,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
(_, "write_bytes") => {
memset_intrinsic(bcx,
false,
*substs.types.get(FnSpace, 0),
substs.types[0],
llargs[0],
llargs[1],
llargs[2],
@ -471,7 +471,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
copy_intrinsic(bcx,
false,
true,
*substs.types.get(FnSpace, 0),
substs.types[0],
llargs[0],
llargs[1],
llargs[2],
@ -481,7 +481,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
copy_intrinsic(bcx,
true,
true,
*substs.types.get(FnSpace, 0),
substs.types[0],
llargs[0],
llargs[1],
llargs[2],
@ -490,14 +490,14 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
(_, "volatile_set_memory") => {
memset_intrinsic(bcx,
true,
*substs.types.get(FnSpace, 0),
substs.types[0],
llargs[0],
llargs[1],
llargs[2],
call_debug_location)
}
(_, "volatile_load") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
let mut ptr = llargs[0];
if let Some(ty) = fn_ty.ret.cast {
ptr = PointerCast(bcx, ptr, ty.ptr_to());
@ -509,7 +509,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
to_immediate(bcx, load, tp_ty)
},
(_, "volatile_store") => {
let tp_ty = *substs.types.get(FnSpace, 0);
let tp_ty = substs.types[0];
if type_is_fat_ptr(bcx.tcx(), tp_ty) {
VolatileStore(bcx, llargs[1], expr::get_dataptr(bcx, llargs[0]));
VolatileStore(bcx, llargs[2], expr::get_meta(bcx, llargs[0]));
@ -609,10 +609,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
},
(_, "discriminant_value") => {
let val_ty = substs.types.get(FnSpace, 0);
let val_ty = substs.types[0];
match val_ty.sty {
ty::TyEnum(..) => {
let repr = adt::represent_type(ccx, *val_ty);
let repr = adt::represent_type(ccx, val_ty);
adt::trans_get_discr(bcx, &repr, llargs[0],
Some(llret_ty), true)
}
@ -663,7 +663,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
match split[1] {
"cxchg" | "cxchgweak" => {
let sty = &substs.types.get(FnSpace, 0).sty;
let sty = &substs.types[0].sty;
if int_type_width_signed(sty, ccx).is_some() {
let weak = if split[1] == "cxchgweak" { llvm::True } else { llvm::False };
let val = AtomicCmpXchg(bcx, llargs[0], llargs[1], llargs[2],
@ -682,7 +682,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
"load" => {
let sty = &substs.types.get(FnSpace, 0).sty;
let sty = &substs.types[0].sty;
if int_type_width_signed(sty, ccx).is_some() {
AtomicLoad(bcx, llargs[0], order)
} else {
@ -695,7 +695,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
"store" => {
let sty = &substs.types.get(FnSpace, 0).sty;
let sty = &substs.types[0].sty;
if int_type_width_signed(sty, ccx).is_some() {
AtomicStore(bcx, llargs[1], llargs[0], order);
} else {
@ -734,7 +734,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
_ => ccx.sess().fatal("unknown atomic operation")
};
let sty = &substs.types.get(FnSpace, 0).sty;
let sty = &substs.types[0].sty;
if int_type_width_signed(sty, ccx).is_some() {
AtomicRMW(bcx, atom_op, llargs[0], llargs[1], order)
} else {

View File

@ -180,7 +180,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
impl<'tcx> Instance<'tcx> {
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
-> Instance<'tcx> {
assert!(substs.regions.as_full_slice().iter().all(|&r| r == ty::ReErased));
assert!(substs.regions.iter().all(|&r| r == ty::ReErased));
Instance { def: def_id, substs: substs }
}
pub fn mono<'a>(scx: &SharedCrateContext<'a, 'tcx>, def_id: DefId) -> Instance<'tcx> {

View File

@ -125,7 +125,6 @@ use rustc::hir::map::DefPathData;
use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
use rustc::ty::TyCtxt;
use rustc::ty::item_path::characteristic_def_id_of_type;
use rustc::ty::subst;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher, SipHasher};
use std::sync::Arc;
@ -488,7 +487,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// DefId, we use the location of the impl after all.
if tcx.trait_of_item(instance.def).is_some() {
let self_ty = *instance.substs.types.get(subst::TypeSpace, 0);
let self_ty = instance.substs.types[0];
// This is an implementation of a trait method.
return characteristic_def_id_of_type(self_ty).or(Some(instance.def));
}

View File

@ -28,7 +28,7 @@ use rustc::hir;
use rustc::hir::map as hir_map;
use rustc::hir::def_id::DefId;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::subst::{Substs, VecPerParamSpace};
use rustc::ty::subst::Substs;
use rustc_const_eval::fatal_const_eval_err;
use std::hash::{Hash, Hasher};
use syntax::ast::{self, NodeId};
@ -560,7 +560,7 @@ fn push_item_name(tcx: TyCtxt,
}
fn push_type_params<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
types: &'tcx VecPerParamSpace<Ty<'tcx>>,
types: &[Ty<'tcx>],
projections: &[ty::PolyExistentialProjection<'tcx>],
output: &mut String) {
if types.is_empty() && projections.is_empty() {
@ -569,7 +569,7 @@ fn push_type_params<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
output.push('<');
for &type_parameter in types.as_full_slice() {
for &type_parameter in types {
push_unique_type_name(tcx, type_parameter, output);
output.push_str(", ");
}

View File

@ -256,18 +256,13 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
// avoids creating more than one copy of the enum when one
// of the enum's variants refers to the enum itself.
let repr = adt::represent_type(cx, t);
let tps = substs.types.as_full_slice();
let name = llvm_type_name(cx, def.did, tps);
let name = llvm_type_name(cx, def.did, &substs.types);
adt::incomplete_type_of(cx, &repr, &name[..])
}
ty::TyClosure(..) => {
// Only create the named struct, but don't fill it in. We
// fill it in *after* placing it into the type cache.
let repr = adt::represent_type(cx, t);
// Unboxed closures can have substitutions in all spaces
// inherited from their environment, so we use entire
// contents of the VecPerParamSpace to construct the llvm
// name
adt::incomplete_type_of(cx, &repr, "closure")
}
@ -335,8 +330,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
// in *after* placing it into the type cache. This prevents
// infinite recursion with recursive struct types.
let repr = adt::represent_type(cx, t);
let tps = substs.types.as_full_slice();
let name = llvm_type_name(cx, def.did, tps);
let name = llvm_type_name(cx, def.did, &substs.types);
adt::incomplete_type_of(cx, &repr, &name[..])
}
}

View File

@ -55,7 +55,7 @@ use hir::def_id::DefId;
use hir::print as pprust;
use middle::resolve_lifetime as rl;
use rustc::lint;
use rustc::ty::subst::{TypeSpace, Subst, Substs};
use rustc::ty::subst::{Subst, Substs};
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
use rustc::ty::wf::object_region_bounds;
@ -207,9 +207,8 @@ pub fn ast_region_to_region(tcx: TyCtxt, lifetime: &hir::Lifetime)
issue_32330))
}
Some(&rl::DefEarlyBoundRegion(space, index, _)) => {
Some(&rl::DefEarlyBoundRegion(index, _)) => {
ty::ReEarlyBound(ty::EarlyBoundRegion {
space: space,
index: index,
name: lifetime.name
})
@ -473,10 +472,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
let mut output_assoc_binding = None;
let substs = Substs::for_item(tcx, def_id, |def, _| {
assert_eq!(def.space, TypeSpace);
regions[def.index as usize]
}, |def, substs| {
assert!(def.space == TypeSpace);
let i = def.index as usize;
// Handle Self first, so we can adjust the index to match the AST.
@ -940,8 +937,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
// FIXME(#12938): This is a hack until we have full support for DST.
if Some(did) == self.tcx().lang_items.owned_box() {
assert_eq!(substs.types.len(TypeSpace), 1);
return self.tcx().mk_box(*substs.types.get(TypeSpace, 0));
assert_eq!(substs.types.len(), 1);
return self.tcx().mk_box(substs.types[0]);
}
decl_ty.subst(self.tcx(), substs)

View File

@ -13,7 +13,6 @@
use super::{check_fn, Expectation, FnCtxt};
use astconv::AstConv;
use rustc::ty::subst;
use rustc::ty::{self, ToPolyTraitRef, Ty};
use std::cmp;
use syntax::abi::Abi;
@ -204,7 +203,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
return None;
}
let arg_param_ty = *trait_ref.substs().types.get(subst::TypeSpace, 1);
let arg_param_ty = trait_ref.substs().types[1];
let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
debug!("deduce_sig_from_projection: arg_param_ty {:?}", arg_param_ty);

View File

@ -225,7 +225,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
debug!("compare_impl_method: impl_bounds={:?}", hybrid_preds);
// This is the only tricky bit of the new way we check implementation methods
// We need to build a set of predicates where only the FnSpace bounds
// We need to build a set of predicates where only the method-level bounds
// are from the trait and we assume all other bounds from the implementation
// to be previously satisfied.
//

View File

@ -15,7 +15,7 @@ use hir::def_id::DefId;
use middle::free_region::FreeRegionMap;
use rustc::infer;
use middle::region;
use rustc::ty::subst::{self, Subst, Substs};
use rustc::ty::subst::{Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::traits::{self, Reveal};
use util::nodemap::FnvHashSet;
@ -438,7 +438,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>(
ty::TyStruct(def, substs) if def.is_phantom_data() => {
// PhantomData<T> - behaves identically to T
let ity = *substs.types.get(subst::TypeSpace, 0);
let ity = substs.types[0];
iterate_over_potentially_unsafe_regions_in_type(
cx, context, ity, depth+1)
}

View File

@ -13,7 +13,7 @@
use intrinsics;
use rustc::infer::TypeOrigin;
use rustc::ty::subst::{self, Substs};
use rustc::ty::subst::Substs;
use rustc::ty::FnSig;
use rustc::ty::{self, Ty};
use {CrateCtxt, require_same_types};
@ -70,7 +70,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) {
fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
let name = token::intern(&format!("P{}", n));
ccx.tcx.mk_param(subst::FnSpace, n, name)
ccx.tcx.mk_param(n, name)
}
let tcx = ccx.tcx;
@ -316,7 +316,7 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
it: &hir::ForeignItem) {
let param = |n| {
let name = token::intern(&format!("P{}", n));
ccx.tcx.mk_param(subst::FnSpace, n, name)
ccx.tcx.mk_param(n, name)
};
let tcx = ccx.tcx;

View File

@ -12,7 +12,7 @@ use super::probe;
use check::{FnCtxt, callee};
use hir::def_id::DefId;
use rustc::ty::subst::{self, Substs};
use rustc::ty::subst::Substs;
use rustc::traits;
use rustc::ty::{self, LvaluePreference, NoPreference, PreferMutLvalue, Ty};
use rustc::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr};
@ -328,18 +328,18 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
//
// FIXME -- permit users to manually specify lifetimes
Substs::for_item(self.tcx, method.def_id, |def, _| {
if def.space != subst::FnSpace {
substs.region_for_def(def)
if let Some(&r) = substs.regions.get(def.index as usize) {
r
} else {
self.region_var_for_def(self.span, def)
}
}, |def, cur_substs| {
if def.space != subst::FnSpace {
substs.type_for_def(def)
if let Some(&ty) = substs.types.get(def.index as usize) {
ty
} else if supplied_method_types.is_empty() {
self.type_var_for_def(self.span, def, cur_substs)
} else {
supplied_method_types[def.index as usize]
supplied_method_types[def.index as usize - substs.types.len()]
}
})
}

View File

@ -13,7 +13,7 @@
use check::FnCtxt;
use hir::def::Def;
use hir::def_id::DefId;
use rustc::ty::subst::{self, Substs};
use rustc::ty::subst::Substs;
use rustc::traits;
use rustc::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable};
use rustc::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr};
@ -191,7 +191,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| {
self.region_var_for_def(span, def)
}, |def, substs| {
assert_eq!(def.space, subst::TypeSpace);
if def.index == 0 {
self_ty
} else if let Some(ref input_types) = opt_input_types {

View File

@ -16,7 +16,7 @@ use super::suggest;
use check::{FnCtxt};
use hir::def_id::DefId;
use hir::def::Def;
use rustc::ty::subst::{self, Subst, Substs};
use rustc::ty::subst::{Subst, Substs};
use rustc::traits;
use rustc::ty::{self, Ty, ToPolyTraitRef, TraitRef, TypeFoldable};
use rustc::infer::{InferOk, TypeOrigin};
@ -519,9 +519,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
trait_ref.substs,
m);
assert_eq!(m.generics.parent_types as usize,
trait_ref.substs.types.len(subst::TypeSpace));
trait_ref.substs.types.len());
assert_eq!(m.generics.parent_regions as usize,
trait_ref.substs.regions.len(subst::TypeSpace));
trait_ref.substs.regions.len());
}
// Because this trait derives from a where-clause, it
@ -1220,8 +1220,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
// are given do not include type/lifetime parameters for the
// method yet. So create fresh variables here for those too,
// if there are any.
assert_eq!(substs.types.len(subst::FnSpace), 0);
assert_eq!(substs.regions.len(subst::FnSpace), 0);
assert_eq!(substs.types.len(), method.generics.parent_types as usize);
assert_eq!(substs.regions.len(), method.generics.parent_regions as usize);
if self.mode == Mode::Path {
return impl_ty;
@ -1236,16 +1236,16 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
xform_self_ty.subst(self.tcx, substs)
} else {
let substs = Substs::for_item(self.tcx, method.def_id, |def, _| {
if def.space != subst::FnSpace {
substs.region_for_def(def)
if let Some(&r) = substs.regions.get(def.index as usize) {
r
} else {
// In general, during probe we erase regions. See
// `impl_self_ty()` for an explanation.
ty::ReErased
}
}, |def, cur_substs| {
if def.space != subst::FnSpace {
substs.type_for_def(def)
if let Some(&ty) = substs.types.get(def.index as usize) {
ty
} else {
self.type_var_for_def(self.span, def, cur_substs)
}

View File

@ -88,7 +88,7 @@ use hir::def::{Def, PathResolution};
use hir::def_id::DefId;
use hir::pat_util;
use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable};
use rustc::ty::subst::{self, Subst, Substs};
use rustc::ty::subst::{Subst, Substs};
use rustc::traits::{self, Reveal};
use rustc::ty::{ParamTy, ParameterEnvironment};
use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
@ -1333,7 +1333,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
.filter_map(|predicate| {
match *predicate {
ty::Predicate::Trait(ref data) => {
if data.0.self_ty().is_param(def.space, def.index) {
if data.0.self_ty().is_param(def.index) {
Some(data.to_poly_trait_ref())
} else {
None
@ -1887,7 +1887,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
/// Registers obligations that all types appearing in `substs` are well-formed.
pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
{
for &ty in substs.types.as_full_slice() {
for &ty in &substs.types {
self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
}
}
@ -4223,20 +4223,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// variables. If the user provided some types, we may still need
// to add defaults. If the user provided *too many* types, that's
// a problem.
self.check_path_parameter_count(subst::TypeSpace,
span,
!require_type_space,
&mut type_segment);
self.check_path_parameter_count(subst::FnSpace,
span,
true,
&mut fn_segment);
self.check_path_parameter_count(span, !require_type_space, &mut type_segment);
self.check_path_parameter_count(span, true, &mut fn_segment);
let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
let i = def.index as usize;
let segment = match def.space {
subst::TypeSpace => type_segment,
subst::FnSpace => fn_segment
let mut i = def.index as usize;
let type_regions = match (type_segment, fn_segment) {
(_, Some((_, generics))) => generics.parent_regions as usize,
(Some((_, generics)), None) => generics.regions.len(),
(None, None) => 0
};
let segment = if i < type_regions {
type_segment
} else {
i -= type_regions;
fn_segment
};
let lifetimes = match segment.map(|(s, _)| &s.parameters) {
Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
@ -4251,25 +4253,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
}, |def, substs| {
let mut i = def.index as usize;
let segment = match def.space {
subst::TypeSpace => {
// Handle Self first, so we can adjust the index to match the AST.
match (type_segment, fn_segment) {
(Some((_, generics)), _) | (_, Some((_, generics))) => {
if generics.has_self {
if i == 0 {
return opt_self_ty.unwrap_or_else(|| {
self.type_var_for_def(span, def, substs)
});
}
i -= 1;
}
}
_ => {}
}
type_segment
let (type_types, has_self) = match (type_segment, fn_segment) {
(_, Some((_, generics))) => {
(generics.parent_types as usize, generics.has_self)
}
subst::FnSpace => fn_segment
(Some((_, generics)), None) => {
(generics.types.len(), generics.has_self)
}
(None, None) => (0, false)
};
let can_omit = i >= type_types || !require_type_space;
let segment = if i < type_types {
// Handle Self first, so we can adjust the index to match the AST.
if has_self && i == 0 {
return opt_self_ty.unwrap_or_else(|| {
self.type_var_for_def(span, def, substs)
});
}
i -= has_self as usize;
type_segment
} else {
i -= type_types;
fn_segment
};
let types = match segment.map(|(s, _)| &s.parameters) {
Some(&hir::AngleBracketedParameters(ref data)) => &data.types[..],
@ -4277,16 +4283,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
None => &[]
};
let can_omit = def.space != subst::TypeSpace || !require_type_space;
let default = if can_omit && types.len() == 0 {
def.default
} else {
None
};
let omitted = can_omit && types.is_empty();
if let Some(ast_ty) = types.get(i) {
// A provided type parameter.
self.to_ty(ast_ty)
} else if let Some(default) = default {
} else if let (false, Some(default)) = (omitted, def.default) {
// No type parameter provided, but a default exists.
default.subst_spanned(self.tcx, substs, Some(span))
} else {
@ -4323,10 +4324,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// type parameters, which we can infer by unifying the provided `Self`
// with the substituted impl type.
let impl_scheme = self.tcx.lookup_item_type(impl_def_id);
assert_eq!(substs.types.len(subst::TypeSpace),
impl_scheme.generics.types.len());
assert_eq!(substs.regions.len(subst::TypeSpace),
impl_scheme.generics.regions.len());
let impl_ty = self.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
match self.sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) {
@ -4355,7 +4352,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
/// Report errors if the provided parameters are too few or too many.
fn check_path_parameter_count(&self,
space: subst::ParamSpace,
span: Span,
can_omit: bool,
segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
@ -4392,7 +4388,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Check provided type parameters.
let type_defs = segment.map_or(&[][..], |(_, generics)| {
if space == subst::TypeSpace {
if generics.parent.is_none() {
&generics.types[generics.has_self as usize..]
} else {
&generics.types

View File

@ -1445,11 +1445,11 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
let origin = infer::ParameterInScope(origin, expr_span);
for &region in substs.regions.as_full_slice() {
for &region in &substs.regions {
self.sub_regions(origin.clone(), expr_region, region);
}
for &ty in substs.types.as_full_slice() {
for &ty in &substs.types {
let ty = self.resolve_type(ty);
self.type_must_outlive(origin.clone(), ty, expr_region);
}
@ -1575,11 +1575,11 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
if env_bounds.is_empty() && needs_infer {
debug!("projection_must_outlive: no declared bounds");
for &component_ty in projection_ty.trait_ref.substs.types.as_full_slice() {
for &component_ty in &projection_ty.trait_ref.substs.types {
self.type_must_outlive(origin.clone(), component_ty, region);
}
for &r in projection_ty.trait_ref.substs.regions.as_full_slice() {
for &r in &projection_ty.trait_ref.substs.regions {
self.sub_regions(origin.clone(), region, r);
}
@ -1597,7 +1597,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
if !env_bounds.is_empty() && env_bounds[1..].iter().all(|b| *b == env_bounds[0]) {
let unique_bound = env_bounds[0];
debug!("projection_must_outlive: unique declared bound = {:?}", unique_bound);
if projection_ty.trait_ref.substs.regions.as_full_slice()
if projection_ty.trait_ref.substs.regions
.iter()
.any(|r| env_bounds.contains(r))
{

View File

@ -14,7 +14,6 @@ use CrateCtxt;
use hir::def_id::DefId;
use middle::region::{CodeExtent};
use rustc::infer::TypeOrigin;
use rustc::ty::subst;
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt};
@ -459,9 +458,9 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
let mut constrained_parameters: HashSet<_> =
variances.types
.iter_enumerated()
.filter(|&(_, _, &variance)| variance != ty::Bivariant)
.map(|(_, index, _)| self.param_ty(ast_generics, index))
.iter().enumerate()
.filter(|&(_, &variance)| variance != ty::Bivariant)
.map(|(index, _)| self.param_ty(ast_generics, index))
.map(|p| Parameter::Type(p))
.collect();
@ -469,9 +468,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
None,
&mut constrained_parameters);
for (space, index, _) in variances.types.iter_enumerated() {
assert_eq!(space, subst::TypeSpace);
for (index, _) in variances.types.iter().enumerate() {
let param_ty = self.param_ty(ast_generics, index);
if constrained_parameters.contains(&Parameter::Type(param_ty)) {
continue;
@ -480,9 +477,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
self.report_bivariance(span, param_ty.name);
}
for (space, index, &variance) in variances.regions.iter_enumerated() {
assert_eq!(space, subst::TypeSpace);
for (index, &variance) in variances.regions.iter().enumerate() {
if variance != ty::Bivariant {
continue;
}
@ -495,7 +490,6 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
fn param_ty(&self, ast_generics: &hir::Generics, index: usize) -> ty::ParamTy {
ty::ParamTy {
space: subst::TypeSpace,
idx: index as u32,
name: ast_generics.ty_params[index].name
}
@ -603,7 +597,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Trait impl: take implied bounds from all types that
// appear in the trait reference.
let trait_ref = self.instantiate_type_scheme(span, free_substs, trait_ref);
trait_ref.substs.types.as_full_slice().to_vec()
trait_ref.substs.types.to_vec()
}
None => {

View File

@ -103,13 +103,12 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}
let free_substs = fcx.parameter_environment.free_substs;
for (space, i, r) in free_substs.regions.iter_enumerated() {
for (i, r) in free_substs.regions.iter().enumerate() {
match *r {
ty::ReFree(ty::FreeRegion {
bound_region: ty::BoundRegion::BrNamed(def_id, name, _), ..
}) => {
let bound_region = ty::ReEarlyBound(ty::EarlyBoundRegion {
space: space,
index: i as u32,
name: name,
});

View File

@ -17,7 +17,7 @@
use hir::def_id::DefId;
use middle::lang_items::UnsizeTraitLangItem;
use rustc::ty::subst::{self, Subst};
use rustc::ty::subst::Subst;
use rustc::ty::{self, TyCtxt, TypeFoldable};
use rustc::traits::{self, Reveal};
use rustc::ty::{ImplOrTraitItemId, ConstTraitItemId};
@ -386,7 +386,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
let source = tcx.lookup_item_type(impl_did).ty;
let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap();
let target = *trait_ref.substs.types.get(subst::TypeSpace, 1);
let target = trait_ref.substs.types[1];
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)",
source, target);

View File

@ -65,7 +65,7 @@ use middle::lang_items::SizedTraitLangItem;
use middle::const_val::ConstVal;
use rustc_const_eval::EvalHint::UncheckedExprHint;
use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, TypeSpace};
use rustc::ty::subst::Substs;
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
use rustc::ty::{VariantKind};
@ -473,10 +473,10 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
results.extend(self.predicates.iter().filter(|predicate| {
match **predicate {
ty::Predicate::Trait(ref data) => {
data.skip_binder().self_ty().is_param(def.space, def.index)
data.skip_binder().self_ty().is_param(def.index)
}
ty::Predicate::TypeOutlives(ref data) => {
data.skip_binder().0.is_param(def.space, def.index)
data.skip_binder().0.is_param(def.index)
}
ty::Predicate::Rfc1592(..) |
ty::Predicate::Equate(..) |
@ -571,7 +571,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let ty_generics = generics_of_def_id(ccx, def_id);
let ty_generic_predicates =
ty_generic_predicates(ccx, FnSpace, &sig.generics, ty_generics.parent, vec![], false);
ty_generic_predicates(ccx, &sig.generics, ty_generics.parent, vec![], false);
let (fty, explicit_self_category) = {
let anon_scope = match container {
@ -752,7 +752,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
let def_id = ccx.tcx.map.local_def_id(it.id);
let ty_generics = generics_of_def_id(ccx, def_id);
let mut ty_predicates =
ty_generic_predicates(ccx, TypeSpace, generics, None, vec![], false);
ty_generic_predicates(ccx, generics, None, vec![], false);
debug!("convert: impl_bounds={:?}", ty_predicates);
@ -1346,7 +1346,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
// add in the explicit where-clauses
let mut trait_predicates =
ty_generic_predicates(ccx, TypeSpace, generics, None, base_predicates, true);
ty_generic_predicates(ccx, generics, None, base_predicates, true);
let assoc_predicates = predicates_for_associated_types(ccx,
generics,
@ -1419,31 +1419,33 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let mut allow_defaults = false;
let no_generics = hir::Generics::empty();
let (space, ast_generics) = match node {
let ast_generics = match node {
NodeTraitItem(item) => {
match item.node {
MethodTraitItem(ref sig, _) => (FnSpace, &sig.generics),
_ => (FnSpace, &no_generics)
MethodTraitItem(ref sig, _) => &sig.generics,
_ => &no_generics
}
}
NodeImplItem(item) => {
match item.node {
ImplItemKind::Method(ref sig, _) => (FnSpace, &sig.generics),
_ => (FnSpace, &no_generics)
ImplItemKind::Method(ref sig, _) => &sig.generics,
_ => &no_generics
}
}
NodeItem(item) => {
match item.node {
ItemFn(_, _, _, _, ref generics, _) => (FnSpace, generics),
ItemImpl(_, _, ref generics, _, _, _) => (TypeSpace, generics),
ItemFn(_, _, _, _, ref generics, _) |
ItemImpl(_, _, ref generics, _, _, _) => generics,
ItemTy(_, ref generics) |
ItemEnum(_, ref generics) |
ItemStruct(_, ref generics) => {
allow_defaults = true;
(TypeSpace, generics)
generics
}
ItemTrait(_, ref generics, _, _) => {
// Add in the self type parameter.
//
@ -1454,7 +1456,6 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let parent = ccx.tcx.map.get_parent(param_id);
let def = ty::TypeParameterDef {
space: TypeSpace,
index: 0,
name: keywords::SelfType.name(),
def_id: tcx.map.local_def_id(param_id),
@ -1466,20 +1467,21 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
opt_self = Some(def);
allow_defaults = true;
(TypeSpace, generics)
generics
}
_ => (TypeSpace, &no_generics)
_ => &no_generics
}
}
NodeForeignItem(item) => {
match item.node {
ForeignItemStatic(..) => (TypeSpace, &no_generics),
ForeignItemFn(_, ref generics) => (FnSpace, generics)
ForeignItemStatic(..) => &no_generics,
ForeignItemFn(_, ref generics) => generics
}
}
_ => (TypeSpace, &no_generics)
_ => &no_generics
};
let has_self = opt_self.is_some();
@ -1491,15 +1493,14 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
assert_eq!(generics.parent_types, 0);
assert_eq!(has_self, false);
parent_has_self = generics.has_self;
(generics.regions.len(), generics.types.len())
(generics.regions.len() as u32, generics.types.len() as u32)
});
let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
let regions = early_lifetimes.iter().enumerate().map(|(i, l)| {
ty::RegionParameterDef {
name: l.lifetime.name,
space: space,
index: i as u32,
index: parent_regions + i as u32,
def_id: tcx.map.local_def_id(l.lifetime.id),
bounds: l.bounds.iter().map(|l| {
ast_region_to_region(tcx, l)
@ -1509,8 +1510,8 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// Now create the real type parameters.
let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
let i = has_self as u32 + i as u32;
get_or_create_type_parameter_def(ccx, ast_generics, space, i, p, allow_defaults)
let i = parent_types + has_self as u32 + i as u32;
get_or_create_type_parameter_def(ccx, ast_generics, i, p, allow_defaults)
});
let types: Vec<_> = opt_self.into_iter().chain(types).collect();
@ -1631,15 +1632,15 @@ fn predicates_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let def_id = ccx.tcx.map.local_def_id(it.id);
let no_generics = hir::Generics::empty();
let (space, generics) = match it.node {
hir::ItemFn(_, _, _, _, ref generics, _) => (FnSpace, generics),
let generics = match it.node {
hir::ItemFn(_, _, _, _, ref generics, _) |
hir::ItemTy(_, ref generics) |
hir::ItemEnum(_, ref generics) |
hir::ItemStruct(_, ref generics) => (TypeSpace, generics),
_ => (TypeSpace, &no_generics)
hir::ItemStruct(_, ref generics) => generics,
_ => &no_generics
};
let predicates = ty_generic_predicates(ccx, space, generics, None, vec![], false);
let predicates = ty_generic_predicates(ccx, generics, None, vec![], false);
let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id,
predicates.clone());
assert!(prev_predicates.is_none());
@ -1658,12 +1659,12 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
type_scheme_of_def_id(ccx, def_id);
let no_generics = hir::Generics::empty();
let (space, generics) = match it.node {
hir::ForeignItemFn(_, ref generics) => (FnSpace, generics),
hir::ForeignItemStatic(..) => (TypeSpace, &no_generics)
let generics = match it.node {
hir::ForeignItemFn(_, ref generics) => generics,
hir::ForeignItemStatic(..) => &no_generics
};
let predicates = ty_generic_predicates(ccx, space, generics, None, vec![], false);
let predicates = ty_generic_predicates(ccx, generics, None, vec![], false);
let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id, predicates);
assert!(prev_predicates.is_none());
}
@ -1733,7 +1734,6 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx, 'hir>(
}
fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
space: ParamSpace,
ast_generics: &hir::Generics,
parent: Option<DefId>,
super_predicates: Vec<ty::Predicate<'tcx>>,
@ -1741,6 +1741,13 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
-> ty::GenericPredicates<'tcx>
{
let tcx = ccx.tcx;
let (parent_regions, parent_types) = parent.map_or((0, 0), |def_id| {
let generics = generics_of_def_id(ccx, def_id);
assert_eq!(generics.parent, None);
assert_eq!(generics.parent_regions, 0);
assert_eq!(generics.parent_types, 0);
(generics.regions.len() as u32, generics.types.len() as u32)
});
let ref base_predicates = match parent {
Some(def_id) => {
assert_eq!(super_predicates, vec![]);
@ -1758,8 +1765,8 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
// Collect the predicates that were written inline by the user on each
// type parameter (e.g., `<T:Foo>`).
for (index, param) in ast_generics.ty_params.iter().enumerate() {
let index = has_self as u32 + index as u32;
let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
let index = parent_types + has_self as u32 + index as u32;
let param_ty = ty::ParamTy::new(index, param.name).to_ty(ccx.tcx);
let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
param_ty,
&param.bounds,
@ -1774,10 +1781,9 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
// have to be careful to only iterate over early-bound regions.
let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
for (index, param) in early_lifetimes.iter().enumerate() {
let index = index as u32;
let index = parent_regions + index as u32;
let region =
ty::ReEarlyBound(ty::EarlyBoundRegion {
space: space,
index: index,
name: param.lifetime.name
});
@ -1852,7 +1858,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
ast_generics: &hir::Generics,
space: ParamSpace,
index: u32,
param: &hir::TyParam,
allow_defaults: bool)
@ -1885,7 +1890,6 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
}
let def = ty::TypeParameterDef {
space: space,
index: index,
name: param.name,
def_id: ccx.tcx.map.local_def_id(param.id),
@ -1900,8 +1904,7 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
debug!("get_or_create_type_parameter_def: def for type param: {:?}, {:?}",
def, space);
debug!("get_or_create_type_parameter_def: def for type param: {:?}", def);
def
}
@ -2190,9 +2193,10 @@ fn enforce_impl_lifetimes_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
.collect();
for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
let region = ty::EarlyBoundRegion { space: TypeSpace,
index: index as u32,
name: lifetime_def.lifetime.name };
let region = ty::EarlyBoundRegion {
index: index as u32,
name: lifetime_def.lifetime.name
};
if
lifetimes_in_associated_types.contains(&region) && // (*)
!input_parameters.contains(&ctp::Parameter::Region(region))

View File

@ -16,7 +16,7 @@
use dep_graph::DepTrackingMapConfig;
use hir::def_id::DefId;
use middle::resolve_lifetime as rl;
use rustc::ty::subst::{self, ParamSpace, Substs};
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::maps::ItemVariances;
use rustc::hir::map as hir_map;
@ -144,7 +144,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
let tcx = self.terms_cx.tcx;
assert!(is_lifetime(&tcx.map, param_id));
match tcx.named_region_map.defs.get(&param_id) {
Some(&rl::DefEarlyBoundRegion(_, _, lifetime_decl_id))
Some(&rl::DefEarlyBoundRegion(_, lifetime_decl_id))
=> lifetime_decl_id,
Some(_) => bug!("should not encounter non early-bound cases"),
@ -210,7 +210,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
param_def_id: DefId,
item_def_id: DefId,
kind: ParamKind,
space: ParamSpace,
index: usize)
-> VarianceTermPtr<'a> {
assert_eq!(param_def_id.krate, item_def_id.krate);
@ -226,8 +225,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// variance already inferred, just look it up.
let variances = self.tcx().item_variances(item_def_id);
let variance = match kind {
TypeParam => *variances.types.get(space, index),
RegionParam => *variances.regions.get(space, index),
TypeParam => variances.types[index],
RegionParam => variances.regions[index],
};
self.constant_term(variance)
}
@ -401,8 +400,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
ty::TyParam(ref data) => {
assert_eq!(data.space, subst::TypeSpace);
assert_eq!(generics.parent, None);
assert!((data.idx as usize) < generics.types.len());
let def_id = generics.types[data.idx as usize].def_id;
let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
match self.terms_cx.inferred_map.get(&node_id) {
@ -450,8 +449,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
for p in type_param_defs {
let variance_decl =
self.declared_variance(p.def_id, def_id, TypeParam,
p.space, p.index as usize);
self.declared_variance(p.def_id, def_id, TypeParam, p.index as usize);
let variance_i = self.xform(variance, variance_decl);
let substs_ty = substs.type_for_def(p);
debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
@ -461,8 +459,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
for p in region_param_defs {
let variance_decl =
self.declared_variance(p.def_id, def_id,
RegionParam, p.space, p.index as usize);
self.declared_variance(p.def_id, def_id, RegionParam, p.index as usize);
let variance_i = self.xform(variance, variance_decl);
let substs_r = substs.region_for_def(p);
self.add_constraints_from_region(generics, substs_r, variance_i);
@ -490,8 +487,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
variance: VarianceTermPtr<'a>) {
match region {
ty::ReEarlyBound(ref data) => {
assert_eq!(data.space, subst::TypeSpace);
assert_eq!(generics.parent, None);
assert!((data.index as usize) < generics.regions.len());
let def_id = generics.regions[data.index as usize].def_id;
let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
if self.is_to_be_inferred(node_id) {

View File

@ -16,7 +16,6 @@
//! inferred is then written into the `variance_map` in the tcx.
use rustc::ty;
use rustc::ty::subst;
use std::rc::Rc;
use super::constraints::*;
@ -110,41 +109,27 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
while index < num_inferred {
let item_id = inferred_infos[index].item_id;
let (mut rt, mut rf) = (vec![], vec![]);
let (mut tt, mut tf) = (vec![], vec![]);
let mut item_variances = ty::ItemVariances::empty();
while index < num_inferred && inferred_infos[index].item_id == item_id {
let info = &inferred_infos[index];
let variance = solutions[index];
debug!("Index {} Info {} / {:?} / {:?} Variance {:?}",
index, info.index, info.kind, info.space, variance);
debug!("Index {} Info {} / {:?} Variance {:?}",
index, info.index, info.kind, variance);
match info.kind {
TypeParam => {
let types = match info.space {
subst::TypeSpace => &mut tt,
subst::FnSpace => &mut tf
};
assert_eq!(types.len(), info.index);
types.push(variance);
assert_eq!(item_variances.types.len(), info.index);
item_variances.types.push(variance);
}
RegionParam => {
let regions = match info.space {
subst::TypeSpace => &mut rt,
subst::FnSpace => &mut rf
};
assert_eq!(regions.len(), info.index);
regions.push(variance);
assert_eq!(item_variances.regions.len(), info.index);
item_variances.regions.push(variance);
}
}
index += 1;
}
let item_variances = ty::ItemVariances {
regions: subst::VecPerParamSpace::new(rt, rf),
types: subst::VecPerParamSpace::new(tt, tf)
};
debug!("item_id={} item_variances={:?}",
item_id,
item_variances);

View File

@ -21,7 +21,6 @@
use arena::TypedArena;
use dep_graph::DepTrackingMapConfig;
use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
use rustc::ty::{self, TyCtxt};
use rustc::ty::maps::ItemVariances;
use std::fmt;
@ -86,7 +85,6 @@ pub enum ParamKind {
pub struct InferredInfo<'a> {
pub item_id: ast::NodeId,
pub kind: ParamKind,
pub space: ParamSpace,
pub index: usize,
pub param_id: ast::NodeId,
pub term: VarianceTermPtr<'a>,
@ -166,15 +164,15 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
for (i, p) in generics.lifetimes.iter().enumerate() {
let id = p.lifetime.id;
self.add_inferred(item_id, RegionParam, TypeSpace, i, id);
self.add_inferred(item_id, RegionParam, i, id);
}
if has_self {
self.add_inferred(item_id, TypeParam, TypeSpace, 0, item_id);
self.add_inferred(item_id, TypeParam, 0, item_id);
}
for (i, p) in generics.ty_params.iter().enumerate() {
let i = has_self as usize + i;
self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id);
self.add_inferred(item_id, TypeParam, i, p.id);
}
// If this item has no type or lifetime parameters,
@ -197,15 +195,13 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
fn add_inferred(&mut self,
item_id: ast::NodeId,
kind: ParamKind,
space: ParamSpace,
index: usize,
param_id: ast::NodeId) {
let inf_index = InferredIndex(self.inferred_infos.len());
let term = self.arena.alloc(InferredTerm(inf_index));
let initial_variance = self.pick_initial_variance(item_id, space, index);
let initial_variance = self.pick_initial_variance(item_id, index);
self.inferred_infos.push(InferredInfo { item_id: item_id,
kind: kind,
space: space,
index: index,
param_id: param_id,
term: term,
@ -216,33 +212,23 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
debug!("add_inferred(item_path={}, \
item_id={}, \
kind={:?}, \
space={:?}, \
index={}, \
param_id={}, \
inf_index={:?}, \
initial_variance={:?})",
self.tcx.item_path_str(self.tcx.map.local_def_id(item_id)),
item_id, kind, space, index, param_id, inf_index,
item_id, kind, index, param_id, inf_index,
initial_variance);
}
fn pick_initial_variance(&self,
item_id: ast::NodeId,
space: ParamSpace,
index: usize)
-> ty::Variance
{
match space {
FnSpace => {
ty::Bivariant
}
TypeSpace => {
match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
Some(&(_, ref variances)) => variances[index],
None => ty::Bivariant
}
}
match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
Some(&(_, ref variances)) => variances[index],
None => ty::Bivariant
}
}

View File

@ -388,8 +388,6 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
}
ty::TypeTraitItem(ref assoc_ty) => {
let did = assoc_ty.def_id;
// Not sure the choice of ParamSpace actually matters here,
// because an associated type won't have generics on the LHS
let typedef = clean::Typedef {
type_: assoc_ty.ty.unwrap().clean(cx),
generics: clean::Generics {

View File

@ -41,7 +41,7 @@ use rustc::hir::def::Def;
use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
use rustc::hir::fold::Folder;
use rustc::hir::print as pprust;
use rustc::ty::subst::{self, Substs, VecPerParamSpace};
use rustc::ty::subst::Substs;
use rustc::ty;
use rustc::middle::stability;
@ -82,12 +82,6 @@ impl<T: Clean<U>, U> Clean<Vec<U>> for [T] {
}
}
impl<T: Clean<U>, U> Clean<VecPerParamSpace<U>> for VecPerParamSpace<T> {
fn clean(&self, cx: &DocContext) -> VecPerParamSpace<U> {
self.map(|x| x.clean(cx))
}
}
impl<T: Clean<U>, U> Clean<U> for P<T> {
fn clean(&self, cx: &DocContext) -> U {
(**self).clean(cx)
@ -632,12 +626,8 @@ impl Clean<TyParamBound> for hir::TyParamBound {
fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: bool,
bindings: Vec<TypeBinding>, substs: &Substs) -> PathParameters {
let lifetimes = substs.regions.get_slice(subst::TypeSpace)
.iter()
.filter_map(|v| v.clean(cx))
.collect();
let types = substs.types.get_slice(subst::TypeSpace);
let types = types[has_self as usize..].to_vec();
let lifetimes = substs.regions.iter().filter_map(|v| v.clean(cx)).collect();
let types = substs.types[has_self as usize..].to_vec();
match (trait_did, cx.tcx_opt()) {
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
@ -731,7 +721,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
let path = external_path(cx, &tcx.item_name(self.def_id).as_str(),
Some(self.def_id), true, vec![], self.substs);
debug!("ty::TraitRef\n substs.types(TypeSpace): {:?}\n",
debug!("ty::TraitRef\n substs.types: {:?}\n",
&self.input_types()[1..]);
// collect any late bound regions
@ -769,9 +759,9 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
impl<'tcx> Clean<Option<Vec<TyParamBound>>> for Substs<'tcx> {
fn clean(&self, cx: &DocContext) -> Option<Vec<TyParamBound>> {
let mut v = Vec::new();
v.extend(self.regions.as_full_slice().iter().filter_map(|r| r.clean(cx))
v.extend(self.regions.iter().filter_map(|r| r.clean(cx))
.map(RegionBound));
v.extend(self.types.as_full_slice().iter().map(|t| TraitBound(PolyTrait {
v.extend(self.types.iter().map(|t| TraitBound(PolyTrait {
trait_: t.clean(cx),
lifetimes: vec![]
}, hir::TraitBoundModifier::None)));
@ -1637,7 +1627,7 @@ impl<'a, 'tcx: 'a, 'b: 'tcx> Folder for SubstAlias<'a, 'tcx> {
fn fold_lifetime(&mut self, lt: hir::Lifetime) -> hir::Lifetime {
let def = self.tcx.named_region_map.defs.get(&lt.id).cloned();
match def {
Some(DefEarlyBoundRegion(_, _, node_id)) |
Some(DefEarlyBoundRegion(_, node_id)) |
Some(DefLateBoundRegion(_, node_id)) |
Some(DefFreeRegion(_, node_id)) => {
if let Some(lt) = self.lt_substs.get(&node_id).cloned() {

View File

@ -20,12 +20,12 @@ trait Trait<'a> {
}
#[rustc_variance]
struct Foo<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[+];[]], regions=[[-];[]])
struct Foo<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[+], regions=[-])
field: (T, &'a ())
}
#[rustc_variance]
struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[o];[]], regions=[[o];[]])
struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[o], regions=[o])
field: <T as Trait<'a>>::Type
}

View File

@ -18,7 +18,7 @@ use std::cell::Cell;
// For better or worse, associated types are invariant, and hence we
// get an invariant result for `'a`.
#[rustc_variance]
struct Foo<'a> { //~ ERROR regions=[[o];[]]
struct Foo<'a> { //~ ERROR regions=[o]
x: Box<Fn(i32) -> &'a i32 + 'static>
}

View File

@ -13,11 +13,11 @@
#![feature(rustc_attrs)]
#[rustc_variance]
trait Foo: 'static { //~ ERROR types=[[o];[]]
trait Foo: 'static { //~ ERROR types=[o]
}
#[rustc_variance]
trait Bar<T> { //~ ERROR types=[[o, o];[]]
trait Bar<T> { //~ ERROR types=[o, o]
fn do_it(&self)
where T: 'static;
}

View File

@ -16,7 +16,7 @@
// Regions that just appear in normal spots are contravariant:
#[rustc_variance]
struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[]]
struct Test2<'a, 'b, 'c> { //~ ERROR regions=[-, -, -]
x: &'a isize,
y: &'b [isize],
c: &'c str
@ -25,7 +25,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[]]
// Those same annotations in function arguments become covariant:
#[rustc_variance]
struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[]]
struct Test3<'a, 'b, 'c> { //~ ERROR regions=[+, +, +]
x: extern "Rust" fn(&'a isize),
y: extern "Rust" fn(&'b [isize]),
c: extern "Rust" fn(&'c str),
@ -34,7 +34,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[]]
// Mutability induces invariance:
#[rustc_variance]
struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[]]
struct Test4<'a, 'b:'a> { //~ ERROR regions=[-, o]
x: &'a mut &'b isize,
}
@ -42,7 +42,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[]]
// contravariant context:
#[rustc_variance]
struct Test5<'a, 'b:'a> { //~ ERROR regions=[[+, o];[]]
struct Test5<'a, 'b:'a> { //~ ERROR regions=[+, o]
x: extern "Rust" fn(&'a mut &'b isize),
}
@ -52,14 +52,14 @@ struct Test5<'a, 'b:'a> { //~ ERROR regions=[[+, o];[]]
// argument list occurs in an invariant context.
#[rustc_variance]
struct Test6<'a, 'b:'a> { //~ ERROR regions=[[-, o];[]]
struct Test6<'a, 'b:'a> { //~ ERROR regions=[-, o]
x: &'a mut extern "Rust" fn(&'b isize),
}
// No uses at all is bivariant:
#[rustc_variance]
struct Test7<'a> { //~ ERROR regions=[[*];[]]
struct Test7<'a> { //~ ERROR regions=[*]
//~^ ERROR parameter `'a` is never used
x: isize
}
@ -67,7 +67,7 @@ struct Test7<'a> { //~ ERROR regions=[[*];[]]
// Try enums too.
#[rustc_variance]
enum Test8<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[]]
enum Test8<'a, 'b, 'c:'b> { //~ ERROR regions=[+, -, o]
Test8A(extern "Rust" fn(&'a isize)),
Test8B(&'b [isize]),
Test8C(&'b mut &'c str),

View File

@ -15,7 +15,7 @@
#![feature(rustc_attrs)]
#[rustc_variance]
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[]]
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[+, -, o, *]
//~^ ERROR parameter `'d` is never used
Test8A(extern "Rust" fn(&'a isize)),
Test8B(&'b [isize]),
@ -23,25 +23,25 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[]]
}
#[rustc_variance]
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[]]
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[*, o, -, +]
//~^ ERROR parameter `'w` is never used
f: Base<'z, 'y, 'x, 'w>
}
#[rustc_variance] // Combine - and + to yield o
struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[]]
struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[o, o, *]
//~^ ERROR parameter `'c` is never used
f: Base<'a, 'a, 'b, 'c>
}
#[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[]]
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[o, -, *]
//~^ ERROR parameter `'c` is never used
f: Base<'a, 'b, 'a, 'c>
}
#[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here)
struct Derived4<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[]]
struct Derived4<'a, 'b, 'c:'b> { //~ ERROR regions=[+, -, o]
f: Base<'a, 'b, 'c, 'a>
}

View File

@ -15,48 +15,48 @@
// influence variance.
#[rustc_variance]
trait Getter<T> { //~ ERROR types=[[o, o];[]]
trait Getter<T> { //~ ERROR types=[o, o]
fn get(&self) -> T;
}
#[rustc_variance]
trait Setter<T> { //~ ERROR types=[[o, o];[]]
trait Setter<T> { //~ ERROR types=[o, o]
fn get(&self, T);
}
#[rustc_variance]
struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[[+, +];[]]
struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[+, +]
t: T, u: U
}
#[rustc_variance]
enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[*, +];[]]
enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[*, +]
//~^ ERROR parameter `U` is never used
Foo(T)
}
#[rustc_variance]
trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[[o, o, o];[]]
trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[o, o, o]
fn getter(&self, u: U) -> T;
}
#[rustc_variance]
trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[o, o];[]]
trait TestTrait2<U> : Getter<U> { //~ ERROR types=[o, o]
}
#[rustc_variance]
trait TestTrait3<U> { //~ ERROR types=[[o, o];[]]
trait TestTrait3<U> { //~ ERROR types=[o, o]
fn getter<T:Getter<U>>(&self);
}
#[rustc_variance]
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[[*, +];[]]
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[*, +]
//~^ ERROR parameter `U` is never used
t: T
}
#[rustc_variance]
struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR types=[[*, +];[]]
struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR types=[*, +]
//~^ ERROR parameter `U` is never used
t: T
}

View File

@ -21,7 +21,7 @@ use std::mem;
trait T { fn foo(&self); }
#[rustc_variance]
struct TOption<'a> { //~ ERROR regions=[[-];[]]
struct TOption<'a> { //~ ERROR regions=[-]
v: Option<Box<T + 'a>>,
}

View File

@ -14,46 +14,46 @@
#![feature(rustc_attrs)]
#[rustc_variance]
struct TestImm<A, B> { //~ ERROR types=[[+, +];[]]
struct TestImm<A, B> { //~ ERROR types=[+, +]
x: A,
y: B,
}
#[rustc_variance]
struct TestMut<A, B:'static> { //~ ERROR types=[[+, o];[]]
struct TestMut<A, B:'static> { //~ ERROR types=[+, o]
x: A,
y: &'static mut B,
}
#[rustc_variance]
struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[[+, o];[]]
struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[+, o]
m: TestMut<A, B>
}
#[rustc_variance]
struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[[o, o];[]]
struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[o, o]
n: TestMut<A, B>,
m: TestMut<B, A>
}
#[rustc_variance]
trait Getter<A> { //~ ERROR types=[[o, o];[]]
trait Getter<A> { //~ ERROR types=[o, o]
fn get(&self) -> A;
}
#[rustc_variance]
trait Setter<A> { //~ ERROR types=[[o, o];[]]
trait Setter<A> { //~ ERROR types=[o, o]
fn set(&mut self, a: A);
}
#[rustc_variance]
trait GetterSetter<A> { //~ ERROR types=[[o, o];[]]
trait GetterSetter<A> { //~ ERROR types=[o, o]
fn get(&self) -> A;
fn set(&mut self, a: A);
}
#[rustc_variance]
trait GetterInTypeBound<A> { //~ ERROR types=[[o, o];[]]
trait GetterInTypeBound<A> { //~ ERROR types=[o, o]
// Here, the use of `A` in the method bound *does* affect
// variance. Think of it as if the method requested a dictionary
// for `T:Getter<A>`. Since this dictionary is an input, it is
@ -63,12 +63,12 @@ trait GetterInTypeBound<A> { //~ ERROR types=[[o, o];[]]
}
#[rustc_variance]
trait SetterInTypeBound<A> { //~ ERROR types=[[o, o];[]]
trait SetterInTypeBound<A> { //~ ERROR types=[o, o]
fn do_it<T:Setter<A>>(&self);
}
#[rustc_variance]
struct TestObject<A, R> { //~ ERROR types=[[o, o];[]]
struct TestObject<A, R> { //~ ERROR types=[o, o]
n: Box<Setter<A>+Send>,
m: Box<Getter<R>+Send>,
}

View File

@ -17,32 +17,32 @@ use std::cell::Cell;
// not considered bivariant.
#[rustc_variance]
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[o, o];[]], regions=[[-];[]]
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[o, o], regions=[-]
t: &'a mut (A,B)
}
#[rustc_variance]
struct InvariantCell<A> { //~ ERROR types=[[o];[]]
struct InvariantCell<A> { //~ ERROR types=[o]
t: Cell<A>
}
#[rustc_variance]
struct InvariantIndirect<A> { //~ ERROR types=[[o];[]]
struct InvariantIndirect<A> { //~ ERROR types=[o]
t: InvariantCell<A>
}
#[rustc_variance]
struct Covariant<A> { //~ ERROR types=[[+];[]]
struct Covariant<A> { //~ ERROR types=[+]
t: A, u: fn() -> A
}
#[rustc_variance]
struct Contravariant<A> { //~ ERROR types=[[-];[]]
struct Contravariant<A> { //~ ERROR types=[-]
t: fn(A)
}
#[rustc_variance]
enum Enum<A,B,C> { //~ ERROR types=[[+, -, o];[]]
enum Enum<A,B,C> { //~ ERROR types=[+, -, o]
Foo(Covariant<A>),
Bar(Contravariant<B>),
Zed(Covariant<C>,Contravariant<C>)

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-tidy-linelength
fn main() {
let a = 0;
{
@ -25,7 +27,7 @@ fn main() {
// StorageLive(tmp1); // scope 1 at storage_ranges.rs:14:18: 14:25
// StorageLive(tmp2); // scope 1 at storage_ranges.rs:14:23: 14:24
// tmp2 = var0; // scope 1 at storage_ranges.rs:14:23: 14:24
// tmp1 = std::prelude::v1::Some<i32>(tmp2,); // scope 1 at storage_ranges.rs:14:18: 14:25
// tmp1 = std::option::Option<i32>::Some(tmp2,); // scope 1 at storage_ranges.rs:14:18: 14:25
// var1 = &tmp1; // scope 1 at storage_ranges.rs:14:17: 14:25
// StorageDead(tmp2); // scope 1 at storage_ranges.rs:14:23: 14:24
// tmp0 = (); // scope 2 at storage_ranges.rs:13:5: 15:6