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;
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)
}
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;
#[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),
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>),
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);
});
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);
})
}
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));
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 {
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
/// 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
.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);
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;
}
break;
}
- EarlyScope(_, lifetimes, s) |
+ EarlyScope(lifetimes, s) |
LateScope(lifetimes, s) => {
search_result = search_lifetimes(lifetimes, lifetime_ref);
if search_result.is_some() {
return;
}
- EarlyScope(_, lifetimes, s) |
+ EarlyScope(lifetimes, s) |
LateScope(lifetimes, s) => {
if let Some((_, lifetime_def)) = search_lifetimes(lifetimes, lifetime) {
signal_shadowing_problem(
}
}
}
-
-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"),
- }
- }
-}
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;
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);
// 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;
}
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;
// 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) => {
} 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;
}
// 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() {
// 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);
/// 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:
///
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};
}
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> {
}
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);
}
}
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;
#[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![],
}
}
}
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>>,
pub struct RegionParameterDef {
pub name: Name,
pub def_id: DefId,
- pub space: subst::ParamSpace,
pub index: u32,
pub bounds: Vec<ty::Region>,
}
impl RegionParameterDef {
pub fn to_early_bound_region(&self) -> ty::Region {
ty::ReEarlyBound(ty::EarlyBoundRegion {
- space: self.space,
index: self.index,
name: self.name,
})
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
/// 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),
}
}
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> {
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()
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))
}
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>] {
// 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
}
}
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 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 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 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))
}
}
(&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)
}
// 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};
}
}
-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 {
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,
ty::RegionParameterDef {
name: self.name,
def_id: self.def_id,
- space: self.space,
index: self.index,
bounds: self.bounds.fold_with(folder),
}
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;
/// 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.
// 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
}
}
#[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 {
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub struct EarlyBoundRegion {
- pub space: subst::ParamSpace,
pub index: u32,
pub name: Name,
}
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,
}
}
}
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(_) |
// 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>,
-> &'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,
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);
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);
}
}
}
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`
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)
}
}
}
}
-///////////////////////////////////////////////////////////////////////////
-// 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`
// 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)
}
span,
"Region parameter out of range \
when substituting in region {} (root type={:?}) \
- (space={:?}, index={})",
+ (index={})",
data.name,
self.root_ty,
- data.space,
data.index);
}
}
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);
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,
-> 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,
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,
self.hash(tys.len());
}
TyParam(p) => {
- self.hash(p.space);
self.hash(p.idx);
self.hash(p.name.as_str());
}
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))
}
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());
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) => {
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(),
}
/// Namespace of the path given to parameterized to print.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Ns {
Type,
Value
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;
}
}
- 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);
}
}
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, "<", ", ")?;
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)?;
}
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)
}
}
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)
}
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)
}
}
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 {
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};
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,
})
// 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)
// 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))
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());
// 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)
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;
}
}
- 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(), ']');
+ pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
+ let mut regions = vec![];
+ let mut types = vec![];
+ assert_eq!(self.next(), '[');
+ while self.peek() != '|' {
+ regions.push(self.parse_region());
}
- VecPerParamSpace::new(a, b)
- }
+ assert_eq!(self.next(), '|');
+ while self.peek() != ']' {
+ types.push(self.parse_ty());
+ }
+ assert_eq!(self.next(), ']');
- 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());
Substs::new(self.tcx, types, regions)
}
let parent_types = self.parse_u32();
let mut regions = vec![];
+ let mut types = vec![];
assert_eq!(self.next(), '[');
- while self.peek() != ']' {
+ while self.peek() != '|' {
regions.push(self.parse_region_param_def());
}
- assert_eq!(self.next(), ']');
-
- let mut types = vec![];
- assert_eq!(self.next(), '[');
+ assert_eq!(self.next(), '|');
while self.peek() != ']' {
types.push(self.parse_type_param_def());
}
}
'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
})
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()),
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 == ']');
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();
ty::TypeParameterDef {
name: name,
def_id: def_id,
- space: space,
index: index,
default_def_id: default_def_id,
default: default,
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![];
ty::RegionParameterDef {
name: name,
def_id: def_id,
- space: space,
index: index,
bounds: bounds,
}
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;
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));
}
}
-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>,
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);
}
write!(w, "]");
}
ty::ReEarlyBound(ref data) => {
- write!(w, "B[{}|{}|{}]",
- data.space.to_uint(),
+ write!(w, "B[{}|{}]",
data.index,
data.name);
}
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);
-> 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,
// 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())
// 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('<');
name_to_append_suffix_to: &mut String)
-> DIArray
{
- let actual_types = param_substs.types.as_full_slice();
+ let actual_types = ¶m_substs.types;
if actual_types.is_empty() {
return create_DIArray(DIB(cx), &[]);
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(", ");
}
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::*;
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);
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]);
}
}
(_, "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]);
}
}
(_, "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 {
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);
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))
}
copy_intrinsic(bcx,
false,
false,
- *substs.types.get(FnSpace, 0),
+ substs.types[0],
llargs[1],
llargs[0],
llargs[2],
copy_intrinsic(bcx,
true,
false,
- *substs.types.get(FnSpace, 0),
+ substs.types[0],
llargs[1],
llargs[0],
llargs[2],
(_, "write_bytes") => {
memset_intrinsic(bcx,
false,
- *substs.types.get(FnSpace, 0),
+ substs.types[0],
llargs[0],
llargs[1],
llargs[2],
copy_intrinsic(bcx,
false,
true,
- *substs.types.get(FnSpace, 0),
+ substs.types[0],
llargs[0],
llargs[1],
llargs[2],
copy_intrinsic(bcx,
true,
true,
- *substs.types.get(FnSpace, 0),
+ substs.types[0],
llargs[0],
llargs[1],
llargs[2],
(_, "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());
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]));
},
(_, "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)
}
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],
}
"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 {
}
"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 {
_ => 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 {
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> {
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;
// 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));
}
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};
}
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() {
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(", ");
}
// 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")
}
// 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[..])
}
}
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;
issue_32330))
}
- Some(&rl::DefEarlyBoundRegion(space, index, _)) => {
+ Some(&rl::DefEarlyBoundRegion(index, _)) => {
ty::ReEarlyBound(ty::EarlyBoundRegion {
- space: space,
index: index,
name: lifetime.name
})
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.
// 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)
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;
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);
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.
//
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;
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)
}
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};
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;
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;
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};
//
// 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()]
}
})
}
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};
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 {
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};
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
// 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;
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)
}
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};
.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
/// 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);
}
}
// 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[..],
}
}, |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[..],
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 {
// 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) {
/// 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)>) {
// 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
let origin = infer::ParameterInScope(origin, expr_span);
- for ®ion in substs.regions.as_full_slice() {
+ for ®ion 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);
}
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);
}
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))
{
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};
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();
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;
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;
}
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
}
// 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 => {
}
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,
});
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};
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);
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};
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(..) |
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 {
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);
// 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,
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.
//
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),
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();
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)
// 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();
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());
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());
}
}
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>>,
-> 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![]);
// 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,
¶m.bounds,
// 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
});
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)
}
let def = ty::TypeParameterDef {
- space: space,
index: index,
name: param.name,
def_id: ccx.tcx.map.local_def_id(param.id),
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
}
.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(®ion) && // (*)
!input_parameters.contains(&ctp::Parameter::Region(region))
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;
let tcx = self.terms_cx.tcx;
assert!(is_lifetime(&tcx.map, param_id));
match tcx.named_region_map.defs.get(¶m_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"),
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);
// 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)
}
}
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) {
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={:?}",
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);
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) {
//! 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::*;
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);
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;
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>,
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,
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,
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
}
}
}
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 {
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;
}
}
-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)
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
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
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)));
fn fold_lifetime(&mut self, lt: hir::Lifetime) -> hir::Lifetime {
let def = self.tcx.named_region_map.defs.get(<.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() {
}
#[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
}
// 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>
}
#![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;
}
// 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
// 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),
// 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,
}
// 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),
}
// 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
}
// 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),
#![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]),
}
#[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>
}
// 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
}
trait T { fn foo(&self); }
#[rustc_variance]
-struct TOption<'a> { //~ ERROR regions=[[-];[]]
+struct TOption<'a> { //~ ERROR regions=[-]
v: Option<Box<T + 'a>>,
}
#![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
}
#[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>,
}
// 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>)
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// ignore-tidy-linelength
+
fn main() {
let a = 0;
{
// 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