rustc: use accessors for Substs::{types,regions}.
This commit is contained in:
parent
eaf71f8d10
commit
5222fa58a1
43 changed files with 251 additions and 230 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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(..) |
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<_, _>>()?;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(_) |
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))));
|
||||
|
|
|
|||
|
|
@ -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(®ions),
|
||||
|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)
|
||||
|
|
|
|||
|
|
@ -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, "]");
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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[..]))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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 = ¶m_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();
|
||||
|
|
|
|||
|
|
@ -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(", ");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1445,11 +1445,11 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
let origin = infer::ParameterInScope(origin, expr_span);
|
||||
|
||||
for ®ion in &substs.regions {
|
||||
for ®ion 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;
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
|
|
@ -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, _), ..
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue