rustc: use accessors for Substs::{types,regions}.

This commit is contained in:
Eduard Burtescu 2016-08-18 08:32:50 +03:00
parent eaf71f8d10
commit 5222fa58a1
43 changed files with 251 additions and 230 deletions

View file

@ -95,7 +95,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
if self.tcx.trait_of_item(def.def_id()).is_some() => {
if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
match substs.substs.types[0].sty {
match substs.substs.type_at(0).sty {
TyEnum(tyid, _) | TyStruct(tyid, _) => {
self.check_def_id(tyid.did)
}

View file

@ -232,8 +232,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
if let Ok(..) = self.can_equate(&trait_self_ty, &impl_self_ty) {
self_match_impls.push(def_id);
if trait_ref.substs.types[1..].iter()
.zip(&impl_trait_ref.substs.types[1..])
if trait_ref.substs.types().skip(1)
.zip(impl_trait_ref.substs.types().skip(1))
.all(|(u,v)| self.fuzzy_match_tys(u, v))
{
fuzzy_match_impls.push(def_id);
@ -738,8 +738,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
ty::Predicate::Trait(ref data) => {
let trait_ref = data.to_poly_trait_ref();
let self_ty = trait_ref.self_ty();
let all_types = &trait_ref.substs().types;
if all_types.references_error() {
if predicate.references_error() {
} else {
// Typically, this ambiguity should only happen if
// there are unresolved type inference variables

View file

@ -142,7 +142,7 @@ impl<'a, 'gcx, 'tcx> DeferredObligation<'tcx> {
// Auto trait obligations on `impl Trait`.
if tcx.trait_has_default_impl(predicate.def_id()) {
let substs = predicate.skip_binder().trait_ref.substs;
if substs.types.len() == 1 && substs.regions.is_empty() {
if substs.types().count() == 1 && substs.regions().next().is_none() {
if let ty::TyAnon(..) = predicate.skip_binder().self_ty().sty {
return true;
}
@ -440,7 +440,6 @@ fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 't
{
t.skip_binder() // ok b/c this check doesn't care about regions
.input_types()
.iter()
.map(|t| selcx.infcx().resolve_type_vars_if_possible(t))
.filter(|t| t.has_infer_types())
.flat_map(|t| t.walk())

View file

@ -145,7 +145,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
match predicate {
ty::Predicate::Trait(ref data) => {
// In the case of a trait predicate, we can skip the "self" type.
data.0.trait_ref.input_types()[1..].iter().any(|t| t.has_self_ty())
data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty())
}
ty::Predicate::Projection(..) |
ty::Predicate::WellFormed(..) |

View file

@ -644,8 +644,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// This suffices to allow chains like `FnMut` implemented in
// terms of `Fn` etc, but we could probably make this more
// precise still.
let input_types = stack.fresh_trait_ref.0.input_types();
let unbound_input_types = input_types.iter().any(|ty| ty.is_fresh());
let unbound_input_types = stack.fresh_trait_ref.input_types().any(|ty| ty.is_fresh());
if unbound_input_types && self.intercrate {
debug!("evaluate_stack({:?}) --> unbound argument, intercrate --> ambiguous",
stack.fresh_trait_ref);
@ -1064,9 +1063,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
match *candidate {
Ok(Some(_)) | Err(_) => true,
Ok(None) => {
cache_fresh_trait_pred.0.trait_ref.substs.types.has_infer_types()
}
Ok(None) => cache_fresh_trait_pred.has_infer_types()
}
}
@ -1603,7 +1600,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
return;
}
};
let target = obligation.predicate.skip_binder().input_types()[1];
let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
debug!("assemble_candidates_for_unsizing(source={:?}, target={:?})",
source, target);
@ -1936,7 +1933,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// for `PhantomData<T>`, we pass `T`
ty::TyStruct(def, substs) if def.is_phantom_data() => {
substs.types.to_vec()
substs.types().cloned().collect()
}
ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => {
@ -2180,12 +2177,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
match self_ty.sty {
ty::TyTrait(ref data) => {
// OK to skip the binder, it is reintroduced below
let input_types = data.principal.skip_binder().input_types();
let input_types = data.principal.input_types();
let assoc_types = data.projection_bounds.iter()
.map(|pb| pb.skip_binder().ty);
let all_types: Vec<_> = input_types.iter().cloned()
.chain(assoc_types)
.collect();
let all_types: Vec<_> = input_types.cloned()
.chain(assoc_types)
.collect();
// reintroduce the two binding levels we skipped, then flatten into one
let all_types = ty::Binder(ty::Binder(all_types));
@ -2476,7 +2473,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// regions here. See the comment there for more details.
let source = self.infcx.shallow_resolve(
tcx.no_late_bound_regions(&obligation.self_ty()).unwrap());
let target = obligation.predicate.skip_binder().input_types()[1];
let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
let target = self.infcx.shallow_resolve(target);
debug!("confirm_builtin_unsize_candidate(source={:?}, target={:?})",
@ -2585,7 +2582,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
} else {
return Err(Unimplemented);
};
let mut ty_params = BitVector::new(substs_a.types.len());
let mut ty_params = BitVector::new(substs_a.types().count());
let mut found = false;
for ty in field.walk() {
if let ty::TyParam(p) = ty.sty {
@ -2601,14 +2598,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// TyError and ensure they do not affect any other fields.
// This could be checked after type collection for any struct
// with a potentially unsized trailing field.
let types = substs_a.types.iter().enumerate().map(|(i, ty)| {
let types = substs_a.types().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());
let substs = Substs::new(tcx, types, substs_a.regions().cloned().collect());
for &ty in fields.split_last().unwrap().1 {
if ty.subst(tcx, substs).references_error() {
return Err(Unimplemented);
@ -2621,14 +2618,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// Check that the source structure with the target's
// type parameters is a subtype of the target.
let types = substs_a.types.iter().enumerate().map(|(i, ty)| {
let types = substs_a.types().enumerate().map(|(i, ty)| {
if ty_params.contains(i) {
substs_b.types[i]
substs_b.type_at(i)
} else {
ty
}
}).collect();
let substs = Substs::new(tcx, types, substs_a.regions.clone());
let substs = Substs::new(tcx, types, substs_a.regions().cloned().collect());
let new_struct = tcx.mk_struct(def, substs);
let origin = TypeOrigin::Misc(obligation.cause.span);
let InferOk { obligations, .. } =
@ -2753,7 +2750,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// substitution if we find that any of the input types, when
// simplified, do not match.
obligation.predicate.0.input_types().iter()
obligation.predicate.skip_binder().input_types()
.zip(impl_trait_ref.input_types())
.any(|(&obligation_ty, &impl_ty)| {
let simplified_obligation_ty =

View file

@ -1152,7 +1152,7 @@ fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
impl_interners!('tcx,
type_list: mk_type_list(Vec<Ty<'tcx>>, keep_local) -> [Ty<'tcx>],
substs: mk_substs(Substs<'tcx>, |substs: &Substs| {
keep_local(&substs.types) || keep_local(&substs.regions)
substs.types().any(keep_local) || substs.regions().any(keep_local)
}) -> Substs<'tcx>,
bare_fn: mk_bare_fn(BareFnTy<'tcx>, |fty: &BareFnTy| {
keep_local(&fty.sig)

View file

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

View file

@ -264,7 +264,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
match self_ty.sty {
ty::TyStruct(adt_def, substs) |
ty::TyEnum(adt_def, substs) => {
if substs.types.is_empty() { // ignore regions
if substs.types().next().is_none() { // ignore regions
self.push_item_path(buffer, adt_def.did);
} else {
buffer.push(&format!("<{}>", self_ty));

View file

@ -951,7 +951,6 @@ impl<'tcx> TraitPredicate<'tcx> {
// leads to more recompilation.
let def_ids: Vec<_> =
self.input_types()
.iter()
.flat_map(|t| t.walk())
.filter_map(|t| match t.sty {
ty::TyStruct(adt_def, _) |
@ -964,8 +963,8 @@ impl<'tcx> TraitPredicate<'tcx> {
DepNode::TraitSelect(self.def_id(), def_ids)
}
pub fn input_types(&self) -> &[Ty<'tcx>] {
&self.trait_ref.substs.types
pub fn input_types(&self) -> slice::Iter<Ty<'tcx>> {
self.trait_ref.input_types()
}
pub fn self_ty(&self) -> Ty<'tcx> {
@ -1107,7 +1106,7 @@ impl<'tcx> Predicate<'tcx> {
pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
let vec: Vec<_> = match *self {
ty::Predicate::Trait(ref data) => {
data.0.trait_ref.input_types().to_vec()
data.skip_binder().input_types().cloned().collect()
}
ty::Predicate::Rfc1592(ref data) => {
return data.walk_tys()
@ -1123,8 +1122,7 @@ impl<'tcx> Predicate<'tcx> {
}
ty::Predicate::Projection(ref data) => {
let trait_inputs = data.0.projection_ty.trait_ref.input_types();
trait_inputs.iter()
.cloned()
trait_inputs.cloned()
.chain(Some(data.0.ty))
.collect()
}
@ -1206,15 +1204,15 @@ impl<'tcx> TraitRef<'tcx> {
}
pub fn self_ty(&self) -> Ty<'tcx> {
self.substs.types[0]
self.substs.type_at(0)
}
pub fn input_types(&self) -> &[Ty<'tcx>] {
pub fn input_types(&self) -> slice::Iter<Ty<'tcx>> {
// Select only the "input types" from a trait-reference. For
// now this is all the types that appear in the
// trait-reference, but it should eventually exclude
// associated types.
&self.substs.types
self.substs.types()
}
}

View file

@ -147,14 +147,12 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
{
let tcx = relation.tcx();
let types = a_subst.types.iter().enumerate().map(|(i, a_ty)| {
let b_ty = &b_subst.types[i];
let types = a_subst.types().zip(b_subst.types()).enumerate().map(|(i, (a_ty, b_ty))| {
let variance = variances.map_or(ty::Invariant, |v| v.types[i]);
relation.relate_with_variance(variance, a_ty, b_ty)
}).collect::<Result<_, _>>()?;
let regions = a_subst.regions.iter().enumerate().map(|(i, a_r)| {
let b_r = &b_subst.regions[i];
let regions = a_subst.regions().zip(b_subst.regions()).enumerate().map(|(i, (a_r, b_r))| {
let variance = variances.map_or(ty::Invariant, |v| v.regions[i]);
relation.relate_with_variance(variance, a_r, b_r)
}).collect::<Result<_, _>>()?;

View file

@ -9,7 +9,6 @@
// except according to those terms.
use infer::type_variable;
use ty::subst::Substs;
use ty::{self, Lift, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@ -692,22 +691,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region {
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
let types = self.types.fold_with(folder);
let regions = self.regions.fold_with(folder);
Substs::new(folder.tcx(), types, regions)
}
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
folder.fold_substs(self)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.types.visit_with(visitor) || self.regions.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::ClosureSubsts {

View file

@ -19,8 +19,9 @@ use util::common::ErrorReported;
use collections::enum_set::{self, EnumSet, CLike};
use std::fmt;
use std::ops;
use std::mem;
use std::ops;
use std::slice;
use syntax::abi;
use syntax::ast::{self, Name};
use syntax::parse::token::keywords;
@ -335,7 +336,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
self.0.substs
}
pub fn input_types(&self) -> &[Ty<'tcx>] {
pub fn input_types(&self) -> slice::Iter<Ty<'tcx>> {
// FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
self.0.input_types()
}
@ -360,12 +361,12 @@ pub struct ExistentialTraitRef<'tcx> {
}
impl<'tcx> ExistentialTraitRef<'tcx> {
pub fn input_types(&self) -> &[Ty<'tcx>] {
pub fn input_types(&self) -> slice::Iter<Ty<'tcx>>{
// Select only the "input types" from a trait-reference. For
// now this is all the types that appear in the
// trait-reference, but it should eventually exclude
// associated types.
&self.substs.types
self.substs.types()
}
}
@ -376,7 +377,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
self.0.def_id
}
pub fn input_types(&self) -> &[Ty<'tcx>] {
pub fn input_types(&self) -> slice::Iter<Ty<'tcx>> {
// FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
self.0.input_types()
}
@ -1213,19 +1214,19 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
TyTrait(ref obj) => {
let mut v = vec![obj.region_bound];
v.extend_from_slice(&obj.principal.skip_binder().substs.regions);
v.extend(obj.principal.skip_binder().substs.regions());
v
}
TyEnum(_, substs) |
TyStruct(_, substs) |
TyAnon(_, substs) => {
substs.regions.to_vec()
substs.regions().cloned().collect()
}
TyClosure(_, ref substs) => {
substs.func_substs.regions.to_vec()
substs.func_substs.regions().cloned().collect()
}
TyProjection(ref data) => {
data.trait_ref.substs.regions.to_vec()
data.trait_ref.substs.regions().cloned().collect()
}
TyFnDef(..) |
TyFnPtr(_) |

View file

@ -13,18 +13,20 @@
use middle::cstore;
use hir::def_id::DefId;
use ty::{self, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use serialize::{Encodable, Encoder, Decodable, Decoder};
use syntax_pos::{Span, DUMMY_SP};
use std::slice;
///////////////////////////////////////////////////////////////////////////
/// A substitution mapping type/region parameters to new values.
#[derive(Clone, PartialEq, Eq, Hash)]
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct Substs<'tcx> {
pub types: Vec<Ty<'tcx>>,
pub regions: Vec<ty::Region>,
types: Vec<Ty<'tcx>>,
regions: Vec<ty::Region>,
}
impl<'a, 'gcx, 'tcx> Substs<'tcx> {
@ -104,12 +106,34 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
self.regions.is_empty() && self.types.is_empty()
}
pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> {
self.types[ty_param_def.index as usize]
#[inline]
pub fn types(&self) -> slice::Iter<Ty<'tcx>> {
self.types.iter()
}
#[inline]
pub fn regions(&self) -> slice::Iter<ty::Region> {
self.regions.iter()
}
#[inline]
pub fn type_at(&self, i: usize) -> Ty<'tcx> {
self.types[i]
}
#[inline]
pub fn region_at(&self, i: usize) -> ty::Region {
self.regions[i]
}
#[inline]
pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> {
self.type_at(ty_param_def.index as usize)
}
#[inline]
pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> ty::Region {
self.regions[def.index as usize]
self.region_at(def.index as usize)
}
/// Transform from substitutions for a child of `source_ancestor`
@ -130,6 +154,22 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
let types = self.types.fold_with(folder);
let regions = self.regions.fold_with(folder);
Substs::new(folder.tcx(), types, regions)
}
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
folder.fold_substs(self)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.types.visit_with(visitor) || self.regions.visit_with(visitor)
}
}
impl<'tcx> Encodable for &'tcx Substs<'tcx> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
cstore::tls::with_encoding_context(s, |ecx, rbml_w| {

View file

@ -693,10 +693,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
return false;
}
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))
substs_a.types().zip(substs_b.types()).all(|(&a, &b)| same_type(a, b))
}
_ => {
a == b

View file

@ -79,7 +79,7 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
stack.push(mt.ty);
}
ty::TyProjection(ref data) => {
push_reversed(stack, &data.trait_ref.substs.types);
push_reversed(stack, data.trait_ref.substs.types());
}
ty::TyTrait(ref obj) => {
push_reversed(stack, obj.principal.input_types());
@ -90,17 +90,17 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
ty::TyEnum(_, ref substs) |
ty::TyStruct(_, ref substs) |
ty::TyAnon(_, ref substs) => {
push_reversed(stack, &substs.types);
push_reversed(stack, substs.types());
}
ty::TyClosure(_, ref substs) => {
push_reversed(stack, &substs.func_substs.types);
push_reversed(stack, &substs.upvar_tys);
push_reversed(stack, substs.func_substs.types());
push_reversed(stack, substs.upvar_tys);
}
ty::TyTuple(ref ts) => {
ty::TyTuple(ts) => {
push_reversed(stack, ts);
}
ty::TyFnDef(_, substs, ref ft) => {
push_reversed(stack, &substs.types);
push_reversed(stack, substs.types());
push_sig_subtypes(stack, &ft.sig);
}
ty::TyFnPtr(ref ft) => {
@ -114,14 +114,17 @@ fn push_sig_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, sig: &ty::PolyFnSig<'tcx>)
push_reversed(stack, &sig.0.inputs);
}
fn push_reversed<'tcx>(stack: &mut Vec<Ty<'tcx>>, tys: &[Ty<'tcx>]) {
fn push_reversed<'a, 'tcx: 'a, I>(stack: &mut Vec<Ty<'tcx>>, tys: I)
where I: IntoIterator<Item=&'a Ty<'tcx>>,
I::IntoIter: DoubleEndedIterator
{
// We push slices on the stack in reverse order so as to
// maintain a pre-order traversal. As of the time of this
// writing, the fact that the traversal is pre-order is not
// known to be significant to any code, but it seems like the
// natural order one would expect (basically, the order of the
// types as they are written).
for &ty in tys.iter().rev() {
for &ty in tys.into_iter().rev() {
stack.push(ty);
}
}

View file

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

View file

@ -22,6 +22,8 @@ use ty::fold::{TypeFolder, TypeVisitor};
use std::cell::Cell;
use std::fmt;
use std::usize;
use syntax::abi::Abi;
use syntax::parse::token;
use syntax::ast::CRATE_NODE_ID;
@ -80,15 +82,17 @@ pub fn parameterized(f: &mut fmt::Formatter,
verbose = tcx.sess.verbose();
has_self = generics.has_self;
let mut child_types = 0;
if let Some(def_id) = generics.parent {
// Methods.
assert_eq!(ns, Ns::Value);
child_types = generics.types.len();
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])?;
write!(f, "<{} as ", substs.type_at(0))?;
}
item_name = Some(tcx.item_name(did));
@ -107,8 +111,8 @@ pub fn parameterized(f: &mut fmt::Formatter,
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[..num_types];
for (def, actual) in generics.types.iter().zip(tps).rev() {
let tps = substs.types().rev().skip(child_types);
for (def, actual) in generics.types.iter().rev().zip(tps) {
if def.default.subst(tcx, substs) != Some(actual) {
break;
}
@ -124,7 +128,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
let projection_ty = projections[0].ty;
if let TyTuple(ref args) = substs.types[1].sty {
if let TyTuple(ref args) = substs.type_at(1).sty {
return fn_sig(f, args, false, projection_ty);
}
}
@ -139,13 +143,15 @@ pub fn parameterized(f: &mut fmt::Formatter,
}
};
let print_regions = |f: &mut fmt::Formatter, start: &str, regions: &[ty::Region]| {
let print_regions = |f: &mut fmt::Formatter, start: &str, regions| {
// Don't print any regions if they're all erased.
if regions.iter().all(|r| *r == ty::ReErased) {
if Iterator::all(&mut Clone::clone(&regions),
|r: &ty::Region| *r == ty::ReErased) {
return Ok(());
}
for region in regions {
let region: &ty::Region = region;
start_or_continue(f, start, ", ")?;
if verbose {
write!(f, "{:?}", region)?;
@ -167,11 +173,12 @@ pub fn parameterized(f: &mut fmt::Formatter,
Ok(())
};
print_regions(f, "<", &substs.regions[..num_regions])?;
print_regions(f, "<", substs.regions().take(num_regions).skip(0))?;
let tps = &substs.types[..num_types];
let tps = substs.types().take(num_types - num_supplied_defaults)
.skip(has_self as usize);
for &ty in &tps[has_self as usize..tps.len() - num_supplied_defaults] {
for &ty in tps {
start_or_continue(f, "<", ", ")?;
write!(f, "{}", ty)?;
}
@ -197,10 +204,10 @@ pub fn parameterized(f: &mut fmt::Formatter,
write!(f, "::{}", item_name)?;
}
print_regions(f, "::<", &substs.regions[num_regions..])?;
print_regions(f, "::<", substs.regions().take(usize::MAX).skip(num_regions))?;
// FIXME: consider being smart with defaults here too
for ty in &substs.types[num_types..] {
for ty in substs.types().skip(num_types) {
start_or_continue(f, "::<", ", ")?;
write!(f, "{}", ty)?;
}
@ -368,13 +375,6 @@ impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
}
}
impl<'tcx> fmt::Debug for Substs<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Substs[types={:?}, regions={:?}]",
self.types, self.regions)
}
}
impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ItemSubsts({:?})", self.substs)

View file

@ -251,11 +251,11 @@ fn enc_opt<T, F>(w: &mut Cursor<Vec<u8>>, t: Option<T>, enc_f: F) where
pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
substs: &Substs<'tcx>) {
write!(w, "[");
for &r in &substs.regions {
for &r in substs.regions() {
enc_region(w, cx, r);
}
write!(w, "|");
for &ty in &substs.types {
for &ty in substs.types() {
enc_ty(w, cx, ty);
}
write!(w, "]");

View file

@ -543,7 +543,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
if let Literal::Item { def_id, substs } = constant.literal {
// Don't peek inside generic (associated) constants.
if !substs.types.is_empty() {
if substs.types().next().is_some() {
self.add_type(constant.ty);
} else {
let qualif = qualify_const_item_cached(self.tcx,

View file

@ -104,8 +104,9 @@ use util::sha2::{Digest, Sha256};
use rustc::middle::{cstore, weak_lang_items};
use rustc::hir::def_id::DefId;
use rustc::hir::map as hir_map;
use rustc::ty::{self, TyCtxt, TypeFoldable};
use rustc::ty::{Ty, TyCtxt, TypeFoldable};
use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
use rustc::ty::subst::Substs;
use rustc::hir::map::definitions::{DefPath, DefPathData};
use syntax::attr;
@ -126,14 +127,14 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
// parameters substituted; this is
// included in the hash as a kind of
// safeguard.
item_type: ty::Ty<'tcx>,
item_type: Ty<'tcx>,
// values for generic type parameters,
// if any.
parameters: &[ty::Ty<'tcx>])
substs: Option<&Substs<'tcx>>)
-> String {
debug!("get_symbol_hash(def_path={:?}, parameters={:?})",
def_path, parameters);
def_path, substs);
let tcx = scx.tcx();
@ -154,11 +155,13 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
hash_state.input(&encoded_item_type[..]);
// also include any type parameters (for generic items)
for t in parameters {
assert!(!t.has_erasable_regions());
assert!(!t.needs_subst());
let encoded_type = tcx.sess.cstore.encode_type(tcx, t, def_id_to_string);
hash_state.input(&encoded_type[..]);
if let Some(substs) = substs {
for t in substs.types() {
assert!(!t.has_erasable_regions());
assert!(!t.needs_subst());
let encoded_type = tcx.sess.cstore.encode_type(tcx, t, def_id_to_string);
hash_state.input(&encoded_type[..]);
}
}
return format!("h{}", truncated_hash_result(&mut *hash_state));
@ -252,7 +255,7 @@ impl<'a, 'tcx> Instance<'tcx> {
// and should not matter anyhow.
let instance_ty = scx.tcx().erase_regions(&instance_ty.ty);
let hash = get_symbol_hash(scx, &def_path, instance_ty, &substs.types);
let hash = get_symbol_hash(scx, &def_path, instance_ty, Some(substs));
let mut buffer = SymbolPathBuffer {
names: Vec::with_capacity(def_path.data.len())
@ -282,14 +285,14 @@ impl ItemPathBuffer for SymbolPathBuffer {
}
pub fn exported_name_from_type_and_prefix<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
t: ty::Ty<'tcx>,
t: Ty<'tcx>,
prefix: &str)
-> String {
let empty_def_path = DefPath {
data: vec![],
krate: cstore::LOCAL_CRATE,
};
let hash = get_symbol_hash(scx, &empty_def_path, t, &[]);
let hash = get_symbol_hash(scx, &empty_def_path, t, None);
let path = [token::intern_and_get_ident(prefix)];
mangle(path.iter().cloned(), Some(&hash[..]))
}
@ -297,7 +300,7 @@ pub fn exported_name_from_type_and_prefix<'a, 'tcx>(scx: &SharedCrateContext<'a,
/// Only symbols that are invisible outside their compilation unit should use a
/// name generated by this function.
pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
t: ty::Ty<'tcx>,
t: Ty<'tcx>,
suffix: &str)
-> String {
let path = [token::intern(&t.to_string()).as_str(),
@ -306,7 +309,7 @@ pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>
data: vec![],
krate: cstore::LOCAL_CRATE,
};
let hash = get_symbol_hash(ccx.shared(), &def_path, t, &[]);
let hash = get_symbol_hash(ccx.shared(), &def_path, t, None);
mangle(path.iter().cloned(), Some(&hash[..]))
}

View file

@ -400,9 +400,9 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
debug!("get_fn(def_id={:?}, substs={:?})", def_id, substs);
assert!(!substs.types.needs_infer());
assert!(!substs.types.has_escaping_regions());
assert!(!substs.types.has_param_types());
assert!(!substs.needs_infer());
assert!(!substs.has_escaping_regions());
assert!(!substs.has_param_types());
let substs = tcx.normalize_associated_type(&substs);
let instance = Instance::new(def_id, substs);

View file

@ -265,7 +265,7 @@ pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
}
pub fn validate_substs(substs: &Substs) {
assert!(!substs.types.needs_infer());
assert!(!substs.needs_infer());
}
// Function context. Every LLVM function we create will have one of

View file

@ -342,11 +342,10 @@ impl<'tcx> TypeMap<'tcx> {
// Add the def-index as the second part
output.push_str(&format!("{:x}", def_id.index.as_usize()));
let tps = &substs.types;
if !tps.is_empty() {
if substs.types().next().is_some() {
output.push('<');
for &type_parameter in tps {
for &type_parameter in substs.types() {
let param_type_id =
type_map.get_unique_type_id_of_type(cx, type_parameter);
let param_type_id =

View file

@ -344,36 +344,34 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
generics: &ty::Generics<'tcx>,
param_substs: &Substs<'tcx>,
substs: &Substs<'tcx>,
file_metadata: DIFile,
name_to_append_suffix_to: &mut String)
-> DIArray
{
let actual_types = &param_substs.types;
if actual_types.is_empty() {
if substs.types().next().is_none() {
return create_DIArray(DIB(cx), &[]);
}
name_to_append_suffix_to.push('<');
for (i, &actual_type) in actual_types.iter().enumerate() {
for (i, &actual_type) in substs.types().enumerate() {
if i != 0 {
name_to_append_suffix_to.push_str(",");
}
let actual_type = cx.tcx().normalize_associated_type(&actual_type);
// Add actual type name to <...> clause of function name
let actual_type_name = compute_debuginfo_type_name(cx,
actual_type,
true);
name_to_append_suffix_to.push_str(&actual_type_name[..]);
if i != actual_types.len() - 1 {
name_to_append_suffix_to.push_str(",");
}
}
name_to_append_suffix_to.push('>');
// Again, only create type information if full debuginfo is enabled
let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo {
let names = get_type_parameter_names(cx, generics);
actual_types.iter().zip(names).map(|(ty, name)| {
substs.types().zip(names).map(|(ty, name)| {
let actual_type = cx.tcx().normalize_associated_type(ty);
let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
let name = CString::new(name.as_str().as_bytes()).unwrap();

View file

@ -175,13 +175,13 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
substs: &Substs<'tcx>,
output: &mut String) {
if substs.types.is_empty() {
if substs.types().next().is_none() {
return;
}
output.push('<');
for &type_parameter in &substs.types {
for &type_parameter in substs.types() {
push_debuginfo_type_name(cx, type_parameter, true, output);
output.push_str(", ");
}

View file

@ -146,12 +146,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
Call(bcx, llfn, &[], call_debug_location)
}
(_, "size_of") => {
let tp_ty = substs.types[0];
let tp_ty = substs.type_at(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[0];
let tp_ty = substs.type_at(0);
if !type_is_sized(tcx, tp_ty) {
let (llsize, _) =
glue::size_and_align_of_dst(&bcx.build(), tp_ty, llargs[1]);
@ -162,11 +162,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
}
(_, "min_align_of") => {
let tp_ty = substs.types[0];
let tp_ty = substs.type_at(0);
C_uint(ccx, type_of::align_of(ccx, tp_ty))
}
(_, "min_align_of_val") => {
let tp_ty = substs.types[0];
let tp_ty = substs.type_at(0);
if !type_is_sized(tcx, tp_ty) {
let (_, llalign) =
glue::size_and_align_of_dst(&bcx.build(), tp_ty, llargs[1]);
@ -176,12 +176,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
}
(_, "pref_align_of") => {
let tp_ty = substs.types[0];
let tp_ty = substs.type_at(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[0];
let tp_ty = substs.type_at(0);
let is_sized = type_is_sized(tcx, tp_ty);
let ptr = if is_sized {
llargs[0]
@ -199,15 +199,15 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
C_nil(ccx)
}
(_, "type_name") => {
let tp_ty = substs.types[0];
let tp_ty = substs.type_at(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[0]))
C_u64(ccx, ccx.tcx().type_id_hash(substs.type_at(0)))
}
(_, "init") => {
let tp_ty = substs.types[0];
let tp_ty = substs.type_at(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);
@ -219,7 +219,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
C_nil(ccx)
}
(_, "needs_drop") => {
let tp_ty = substs.types[0];
let tp_ty = substs.type_at(0);
C_bool(ccx, bcx.fcx.type_needs_drop(tp_ty))
}
@ -238,7 +238,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
copy_intrinsic(bcx,
false,
false,
substs.types[0],
substs.type_at(0),
llargs[1],
llargs[0],
llargs[2],
@ -248,7 +248,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
copy_intrinsic(bcx,
true,
false,
substs.types[0],
substs.type_at(0),
llargs[1],
llargs[0],
llargs[2],
@ -257,7 +257,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
(_, "write_bytes") => {
memset_intrinsic(bcx,
false,
substs.types[0],
substs.type_at(0),
llargs[0],
llargs[1],
llargs[2],
@ -268,7 +268,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
copy_intrinsic(bcx,
false,
true,
substs.types[0],
substs.type_at(0),
llargs[0],
llargs[1],
llargs[2],
@ -278,7 +278,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
copy_intrinsic(bcx,
true,
true,
substs.types[0],
substs.type_at(0),
llargs[0],
llargs[1],
llargs[2],
@ -287,14 +287,14 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
(_, "volatile_set_memory") => {
memset_intrinsic(bcx,
true,
substs.types[0],
substs.type_at(0),
llargs[0],
llargs[1],
llargs[2],
call_debug_location)
}
(_, "volatile_load") => {
let tp_ty = substs.types[0];
let tp_ty = substs.type_at(0);
let mut ptr = llargs[0];
if let Some(ty) = fn_ty.ret.cast {
ptr = PointerCast(bcx, ptr, ty.ptr_to());
@ -306,7 +306,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
to_immediate(bcx, load, tp_ty)
},
(_, "volatile_store") => {
let tp_ty = substs.types[0];
let tp_ty = substs.type_at(0);
if type_is_fat_ptr(bcx.tcx(), tp_ty) {
VolatileStore(bcx, llargs[1], get_dataptr(bcx, llargs[0]));
VolatileStore(bcx, llargs[2], get_meta(bcx, llargs[0]));
@ -406,7 +406,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
},
(_, "discriminant_value") => {
let val_ty = substs.types[0];
let val_ty = substs.type_at(0);
match val_ty.sty {
ty::TyEnum(..) => {
let repr = adt::represent_type(ccx, val_ty);
@ -458,7 +458,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
match split[1] {
"cxchg" | "cxchgweak" => {
let sty = &substs.types[0].sty;
let sty = &substs.type_at(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],
@ -477,7 +477,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
"load" => {
let sty = &substs.types[0].sty;
let sty = &substs.type_at(0).sty;
if int_type_width_signed(sty, ccx).is_some() {
AtomicLoad(bcx, llargs[0], order)
} else {
@ -490,7 +490,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
"store" => {
let sty = &substs.types[0].sty;
let sty = &substs.type_at(0).sty;
if int_type_width_signed(sty, ccx).is_some() {
AtomicStore(bcx, llargs[1], llargs[0], order);
} else {
@ -529,7 +529,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
_ => ccx.sess().fatal("unknown atomic operation")
};
let sty = &substs.types[0].sty;
let sty = &substs.type_at(0).sty;
if int_type_width_signed(sty, ccx).is_some() {
AtomicRMW(bcx, atom_op, llargs[0], llargs[1], order)
} else {

View file

@ -307,7 +307,7 @@ pub fn get_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
name: Name)
-> ImplMethod<'tcx>
{
assert!(!substs.types.needs_infer());
assert!(!substs.needs_infer());
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
let trait_def = tcx.lookup_trait_def(trait_def_id);

View file

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

View file

@ -342,7 +342,7 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
TransItem::DropGlue(..) => unreachable!(),
// Is there any benefit to using ExternalLinkage?:
TransItem::Fn(ref instance) => {
if instance.substs.types.is_empty() {
if instance.substs.types().next().is_none() {
// This is a non-generic functions, we always
// make it visible externally on the chance that
// it might be used in another codegen unit.
@ -487,7 +487,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// DefId, we use the location of the impl after all.
if tcx.trait_of_item(instance.def).is_some() {
let self_ty = instance.substs.types[0];
let self_ty = instance.substs.type_at(0);
// This is an implementation of a trait method.
return characteristic_def_id_of_type(self_ty).or(Some(instance.def));
}

View file

@ -171,8 +171,8 @@ impl<'a, 'tcx> TransItem<'tcx> {
instance: Instance<'tcx>,
linkage: llvm::Linkage,
symbol_name: &str) {
assert!(!instance.substs.types.needs_infer() &&
!instance.substs.types.has_param_types());
assert!(!instance.substs.needs_infer() &&
!instance.substs.has_param_types());
let item_ty = ccx.tcx().lookup_item_type(instance.def).ty;
let item_ty = ccx.tcx().erase_regions(&item_ty);
@ -244,7 +244,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
pub fn requests_inline(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
match *self {
TransItem::Fn(ref instance) => {
!instance.substs.types.is_empty() || {
instance.substs.types().next().is_some() || {
let attributes = tcx.get_attrs(instance.def);
attr::requests_inline(&attributes[..])
}
@ -264,8 +264,9 @@ impl<'a, 'tcx> TransItem<'tcx> {
pub fn is_instantiated_only_on_demand(&self) -> bool {
match *self {
TransItem::Fn(ref instance) => !instance.def.is_local() ||
!instance.substs.types.is_empty(),
TransItem::Fn(ref instance) => {
!instance.def.is_local() || instance.substs.types().next().is_some()
}
TransItem::DropGlue(..) => true,
TransItem::Static(..) => false,
}
@ -273,7 +274,9 @@ impl<'a, 'tcx> TransItem<'tcx> {
pub fn is_generic_fn(&self) -> bool {
match *self {
TransItem::Fn(ref instance) => !instance.substs.types.is_empty(),
TransItem::Fn(ref instance) => {
instance.substs.types().next().is_some()
}
TransItem::DropGlue(..) |
TransItem::Static(..) => false,
}
@ -374,7 +377,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
/// Same as `unique_type_name()` but with the result pushed onto the given
/// `output` parameter.
pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
t: ty::Ty<'tcx>,
t: Ty<'tcx>,
output: &mut String) {
match t.sty {
ty::TyBool => output.push_str("bool"),
@ -396,7 +399,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty::TyStruct(adt_def, substs) |
ty::TyEnum(adt_def, substs) => {
push_item_name(tcx, adt_def.did, output);
push_type_params(tcx, &substs.types, &[], output);
push_type_params(tcx, substs, &[], output);
},
ty::TyTuple(component_types) => {
output.push('(');
@ -446,7 +449,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty::TyTrait(ref trait_data) => {
push_item_name(tcx, trait_data.principal.def_id(), output);
push_type_params(tcx,
&trait_data.principal.skip_binder().substs.types,
trait_data.principal.skip_binder().substs,
&trait_data.projection_bounds,
output);
},
@ -494,7 +497,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
output.push_str("{");
output.push_str(&format!("{}:{}", def_id.krate, def_id.index.as_usize()));
output.push_str("}");
push_type_params(tcx, &closure_substs.func_substs.types, &[], output);
push_type_params(tcx, closure_substs.func_substs, &[], output);
}
ty::TyError |
ty::TyInfer(_) |
@ -529,16 +532,16 @@ fn push_item_name(tcx: TyCtxt,
}
fn push_type_params<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
types: &[Ty<'tcx>],
substs: &Substs<'tcx>,
projections: &[ty::PolyExistentialProjection<'tcx>],
output: &mut String) {
if types.is_empty() && projections.is_empty() {
if substs.types().next().is_none() && projections.is_empty() {
return;
}
output.push('<');
for &type_parameter in types {
for &type_parameter in substs.types() {
push_unique_type_name(tcx, type_parameter, output);
output.push_str(", ");
}
@ -562,7 +565,7 @@ fn push_instance_as_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
instance: Instance<'tcx>,
output: &mut String) {
push_item_name(tcx, instance.def, output);
push_type_params(tcx, &instance.substs.types, &[], output);
push_type_params(tcx, instance.substs, &[], output);
}
pub fn def_id_to_string(tcx: TyCtxt, def_id: DefId) -> String {
@ -572,7 +575,7 @@ pub fn def_id_to_string(tcx: TyCtxt, def_id: DefId) -> String {
}
pub fn type_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty: ty::Ty<'tcx>)
ty: Ty<'tcx>)
-> String {
let mut output = String::new();
push_unique_type_name(tcx, ty, &mut output);

View file

@ -17,6 +17,7 @@ use common::*;
use machine;
use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::subst::Substs;
use type_::Type;
@ -256,7 +257,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
// avoids creating more than one copy of the enum when one
// of the enum's variants refers to the enum itself.
let repr = adt::represent_type(cx, t);
let name = llvm_type_name(cx, def.did, &substs.types);
let name = llvm_type_name(cx, def.did, substs);
adt::incomplete_type_of(cx, &repr, &name[..])
}
ty::TyClosure(..) => {
@ -330,7 +331,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
// in *after* placing it into the type cache. This prevents
// infinite recursion with recursive struct types.
let repr = adt::represent_type(cx, t);
let name = llvm_type_name(cx, def.did, &substs.types);
let name = llvm_type_name(cx, def.did, substs);
adt::incomplete_type_of(cx, &repr, &name[..])
}
}
@ -367,10 +368,10 @@ pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
did: DefId,
tps: &[Ty<'tcx>])
substs: &Substs<'tcx>)
-> String {
let base = cx.tcx().item_path_str(did);
let strings: Vec<String> = tps.iter().map(|t| t.to_string()).collect();
let strings: Vec<String> = substs.types().map(|t| t.to_string()).collect();
let tstr = if strings.is_empty() {
base
} else {

View file

@ -937,8 +937,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
// FIXME(#12938): This is a hack until we have full support for DST.
if Some(did) == self.tcx().lang_items.owned_box() {
assert_eq!(substs.types.len(), 1);
return self.tcx().mk_box(substs.types[0]);
assert_eq!(substs.types().count(), 1);
return self.tcx().mk_box(substs.type_at(0));
}
decl_ty.subst(self.tcx(), substs)

View file

@ -203,7 +203,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
return None;
}
let arg_param_ty = trait_ref.substs().types[1];
let arg_param_ty = trait_ref.substs().type_at(1);
let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
debug!("deduce_sig_from_projection: arg_param_ty {:?}", arg_param_ty);

View file

@ -438,7 +438,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>(
ty::TyStruct(def, substs) if def.is_phantom_data() => {
// PhantomData<T> - behaves identically to T
let ity = substs.types[0];
let ity = substs.type_at(0);
iterate_over_potentially_unsafe_regions_in_type(
cx, context, ity, depth+1)
}

View file

@ -328,18 +328,20 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
//
// FIXME -- permit users to manually specify lifetimes
Substs::for_item(self.tcx, method.def_id, |def, _| {
if let Some(&r) = substs.regions.get(def.index as usize) {
r
let i = def.index as usize;
if i < substs.regions().count() {
substs.region_at(i)
} else {
self.region_var_for_def(self.span, def)
}
}, |def, cur_substs| {
if let Some(&ty) = substs.types.get(def.index as usize) {
ty
let i = def.index as usize;
if i < substs.types().count() {
substs.type_at(i)
} 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 - substs.types.len()]
supplied_method_types[i - substs.types().count()]
}
})
}

View file

@ -519,9 +519,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
trait_ref.substs,
m);
assert_eq!(m.generics.parent_types as usize,
trait_ref.substs.types.len());
trait_ref.substs.types().count());
assert_eq!(m.generics.parent_regions as usize,
trait_ref.substs.regions.len());
trait_ref.substs.regions().count());
}
// Because this trait derives from a where-clause, it
@ -529,7 +529,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
// artifacts. This means it is safe to put into the
// `WhereClauseCandidate` and (eventually) into the
// `WhereClausePick`.
assert!(!trait_ref.substs.types.needs_infer());
assert!(!trait_ref.substs.needs_infer());
this.inherent_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
@ -1220,8 +1220,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
// are given do not include type/lifetime parameters for the
// method yet. So create fresh variables here for those too,
// if there are any.
assert_eq!(substs.types.len(), method.generics.parent_types as usize);
assert_eq!(substs.regions.len(), method.generics.parent_regions as usize);
assert_eq!(substs.types().count(), method.generics.parent_types as usize);
assert_eq!(substs.regions().count(), method.generics.parent_regions as usize);
if self.mode == Mode::Path {
return impl_ty;
@ -1236,16 +1236,18 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
xform_self_ty.subst(self.tcx, substs)
} else {
let substs = Substs::for_item(self.tcx, method.def_id, |def, _| {
if let Some(&r) = substs.regions.get(def.index as usize) {
r
let i = def.index as usize;
if i < substs.regions().count() {
substs.region_at(i)
} else {
// In general, during probe we erase regions. See
// `impl_self_ty()` for an explanation.
ty::ReErased
}
}, |def, cur_substs| {
if let Some(&ty) = substs.types.get(def.index as usize) {
ty
let i = def.index as usize;
if i < substs.types().count() {
substs.type_at(i)
} else {
self.type_var_for_def(self.span, def, cur_substs)
}
@ -1324,7 +1326,7 @@ impl<'tcx> Candidate<'tcx> {
// inference variables or other artifacts. This
// means they are safe to put into the
// `WhereClausePick`.
assert!(!trait_ref.substs().types.needs_infer());
assert!(!trait_ref.substs().needs_infer());
WhereClausePick(trait_ref.clone())
}

View file

@ -1899,7 +1899,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
/// Registers obligations that all types appearing in `substs` are well-formed.
pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
{
for &ty in &substs.types {
for &ty in substs.types() {
self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
}
}

View file

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

View file

@ -597,7 +597,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Trait impl: take implied bounds from all types that
// appear in the trait reference.
let trait_ref = self.instantiate_type_scheme(span, free_substs, trait_ref);
trait_ref.substs.types.to_vec()
trait_ref.substs.types().cloned().collect()
}
None => {

View file

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

View file

@ -386,7 +386,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
let source = tcx.lookup_item_type(impl_did).ty;
let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap();
let target = trait_ref.substs.types[1];
let target = trait_ref.substs.type_at(1);
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)",
source, target);

View file

@ -172,7 +172,7 @@ fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
node_id,
item_substs);
assert!(!item_substs.substs.types.needs_infer());
assert!(!item_substs.substs.needs_infer());
ccx.tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
}

View file

@ -642,8 +642,8 @@ impl Clean<TyParamBound> for hir::TyParamBound {
fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: bool,
bindings: Vec<TypeBinding>, substs: &Substs) -> PathParameters {
let lifetimes = substs.regions.iter().filter_map(|v| v.clean(cx)).collect();
let types = substs.types[has_self as usize..].to_vec();
let lifetimes = substs.regions().filter_map(|v| v.clean(cx)).collect();
let types = substs.types().skip(has_self as usize).cloned().collect::<Vec<_>>();
match (trait_did, cx.tcx_opt()) {
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
@ -737,12 +737,11 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
let path = external_path(cx, &tcx.item_name(self.def_id).as_str(),
Some(self.def_id), true, vec![], self.substs);
debug!("ty::TraitRef\n substs.types: {:?}\n",
&self.input_types()[1..]);
debug!("ty::TraitRef\n subst: {:?}\n", self.substs);
// collect any late bound regions
let mut late_bounds = vec![];
for &ty_s in &self.input_types()[1..] {
for &ty_s in self.input_types().skip(1) {
if let ty::TyTuple(ts) = ty_s.sty {
for &ty_s in ts {
if let ty::TyRef(ref reg, _) = ty_s.sty {
@ -775,9 +774,9 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
impl<'tcx> Clean<Option<Vec<TyParamBound>>> for Substs<'tcx> {
fn clean(&self, cx: &DocContext) -> Option<Vec<TyParamBound>> {
let mut v = Vec::new();
v.extend(self.regions.iter().filter_map(|r| r.clean(cx))
v.extend(self.regions().filter_map(|r| r.clean(cx))
.map(RegionBound));
v.extend(self.types.iter().map(|t| TraitBound(PolyTrait {
v.extend(self.types().map(|t| TraitBound(PolyTrait {
trait_: t.clean(cx),
lifetimes: vec![]
}, hir::TraitBoundModifier::None)));