self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx)
};
- if !generic_args.parenthesized && generic_args.lifetimes().count() == 0 {
+ let has_lifetimes = generic_args.args.iter().any(|arg| match arg {
+ GenericArg::Lifetime(_) => true,
+ _ => false,
+ });
+ if !generic_args.parenthesized && !has_lifetimes {
generic_args.args =
self.elided_path_lifetimes(path_span, expected_lifetimes)
.into_iter()
bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
parenthesized: false,
},
- has_types && param_mode == ParamMode::Optional)
+ !has_types && param_mode == ParamMode::Optional)
}
fn lower_parenthesized_parameter_data(
pub fn inputs(&self) -> &[P<Ty>] {
if self.parenthesized {
- if let Some(ref ty) = self.types().next() {
- if let TyTup(ref tys) = ty.node {
- return tys;
+ for arg in &self.args {
+ match arg {
+ GenericArg::Lifetime(_) => {}
+ GenericArg::Type(ref ty) => {
+ if let TyTup(ref tys) = ty.node {
+ return tys;
+ }
+ break;
+ }
}
}
}
bug!("GenericArgs::inputs: not a `Fn(T) -> U`");
}
-
- pub fn lifetimes(&self) -> impl DoubleEndedIterator<Item = &Lifetime> {
- self.args.iter().filter_map(|p| {
- if let GenericArg::Lifetime(lt) = p {
- Some(lt)
- } else {
- None
- }
- })
- }
-
- pub fn types(&self) -> impl DoubleEndedIterator<Item = &P<Ty>> {
- self.args.iter().filter_map(|p| {
- if let GenericArg::Type(ty) = p {
- Some(ty)
- } else {
- None
- }
- })
- }
}
/// The AST represents all type param bounds as types.
}
};
- let elide_lifetimes = generic_args.lifetimes().all(|lt| lt.is_elided());
+ let mut types = vec![];
+ let mut elide_lifetimes = true;
+ for arg in &generic_args.args {
+ match arg {
+ GenericArg::Lifetime(lt) => {
+ if !lt.is_elided() {
+ elide_lifetimes = false;
+ }
+ }
+ GenericArg::Type(ty) => {
+ types.push(ty);
+ }
+ }
+ }
if !elide_lifetimes {
start_or_comma(self)?;
self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| {
match generic_arg {
GenericArg::Lifetime(lt) => s.print_lifetime(lt),
GenericArg::Type(ty) => s.print_type(ty),
- }
+ }
})?;
- } else if generic_args.types().count() != 0 {
+ } else if !types.is_empty() {
start_or_comma(self)?;
- self.commasep(Inconsistent,
- &generic_args.types().collect::<Vec<_>>(),
- |s, ty| s.print_type(&ty))?;
+ self.commasep(Inconsistent, &types, |s, ty| s.print_type(&ty))?;
}
// FIXME(eddyb) This would leak into error messages, e.g.:
use hir::def::Def;
use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use hir::map::Map;
-use hir::ItemLocalId;
-use hir::LifetimeName;
+use hir::{GenericArg, ItemLocalId, LifetimeName};
use ty::{self, TyCtxt, GenericParamDefKind};
use errors::DiagnosticBuilder;
0
};
let mut type_count = 0;
- let lifetimes = generics.params.iter().filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::early(&self.tcx.hir, &mut index, param))
- }
- GenericParamKind::Type { .. } => {
- type_count += 1;
- None
- }
+ let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::early(&self.tcx.hir, &mut index, param))
+ }
+ GenericParamKind::Type { .. } => {
+ type_count += 1;
+ None
}
}).collect();
let scope = Scope::Binder {
let scope = Scope::Binder {
lifetimes: c.generic_params
.iter()
- .filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::late(&self.tcx.hir, param))
- }
- _ => None,
+ .filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::late(&self.tcx.hir, param))
}
+ _ => None,
})
.collect(),
s: self.scope,
let mut type_count = 0;
let lifetimes = generics.params
.iter()
- .filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::early(&self.tcx.hir, &mut index, param))
- }
- GenericParamKind::Type { .. } => {
- type_count += 1;
- None
- }
+ .filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::early(&self.tcx.hir, &mut index, param))
+ }
+ GenericParamKind::Type { .. } => {
+ type_count += 1;
+ None
}
})
.collect();
debug!("visit_ty: index = {}", index);
let lifetimes = generics.params
.iter()
- .filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::early(&self.tcx.hir, &mut index, param))
- }
- GenericParamKind::Type { .. } => {
- next_early_index += 1;
- None
- }
+ .filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::early(&self.tcx.hir, &mut index, param))
+ }
+ GenericParamKind::Type { .. } => {
+ next_early_index += 1;
+ None
}
})
.collect();
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
check_mixed_explicit_and_in_band_defs(
self.tcx,
- &generics.params.iter().filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => Some(param.clone()),
- _ => None,
- }
+ &generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => Some(param.clone()),
+ _ => None,
}).collect::<Vec<_>>()
);
for param in &generics.params {
..
}) => {
let lifetimes: FxHashMap<_, _> = bound_generic_params.iter()
- .filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::late(&self.tcx.hir, param))
- }
- _ => None,
+ .filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::late(&self.tcx.hir, param))
}
+ _ => None,
})
.collect();
if !lifetimes.is_empty() {
|| trait_ref
.bound_generic_params
.iter()
- .any(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => true,
- _ => false,
- }
+ .any(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => true,
+ _ => false,
})
{
if self.trait_ref_hack {
lifetimes: trait_ref
.bound_generic_params
.iter()
- .filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::late(&self.tcx.hir, param))
- }
- _ => None,
+ .filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::late(&self.tcx.hir, param))
}
+ _ => None,
})
.collect(),
s: self.scope,
tcx: TyCtxt<'_, '_, '_>,
params: &[hir::GenericParam],
) {
- let in_bands: Vec<_> = params.iter().map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { in_band, .. } => (in_band, param.span),
- _ => bug!("expected lifetime param"),
- }
+ let in_bands: Vec<_> = params.iter().map(|param| match param.kind {
+ GenericParamKind::Lifetime { in_band, .. } => (in_band, param.span),
+ _ => bug!("expected lifetime param"),
}).collect();
let out_of_band = in_bands.iter().find(|(in_band, _)| !in_band);
let in_band = in_bands.iter().find(|(in_band, _)| *in_band);
Set1::One(Region::Static) => "'static".to_string(),
Set1::One(Region::EarlyBound(i, _, _)) => {
let mut j = 0;
- generics.params.iter().find(|param| {
- match param.kind {
+ generics.params.iter().find(|param| match param.kind {
GenericParamKind::Lifetime { .. } => {
if i == j {
return true;
}
j += 1;
+ false
}
- _ => {}
- }
- false
- }).unwrap()
+ _ => false,
+ }).unwrap()
.name()
.to_string()
}
}
}
- generics.params.iter().filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => None,
- GenericParamKind::Type { ref bounds, .. } => {
- let mut set = Set1::Empty;
-
- add_bounds(&mut set, &bounds);
-
- let param_def_id = tcx.hir.local_def_id(param.id);
- for predicate in &generics.where_clause.predicates {
- // Look for `type: ...` where clauses.
- let data = match *predicate {
- hir::WherePredicate::BoundPredicate(ref data) => data,
- _ => continue,
- };
+ generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => None,
+ GenericParamKind::Type { ref bounds, .. } => {
+ let mut set = Set1::Empty;
- // Ignore `for<'a> type: ...` as they can change what
- // lifetimes mean (although we could "just" handle it).
- if !data.bound_generic_params.is_empty() {
- continue;
- }
+ add_bounds(&mut set, &bounds);
- let def = match data.bounded_ty.node {
- hir::TyPath(hir::QPath::Resolved(None, ref path)) => path.def,
- _ => continue,
- };
+ let param_def_id = tcx.hir.local_def_id(param.id);
+ for predicate in &generics.where_clause.predicates {
+ // Look for `type: ...` where clauses.
+ let data = match *predicate {
+ hir::WherePredicate::BoundPredicate(ref data) => data,
+ _ => continue,
+ };
- if def == Def::TyParam(param_def_id) {
- add_bounds(&mut set, &data.bounds);
- }
+ // Ignore `for<'a> type: ...` as they can change what
+ // lifetimes mean (although we could "just" handle it).
+ if !data.bound_generic_params.is_empty() {
+ continue;
}
- Some(match set {
- Set1::Empty => Set1::Empty,
- Set1::One(name) => {
- if name == hir::LifetimeName::Static {
- Set1::One(Region::Static)
- } else {
- generics.params.iter().filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { name, in_band, .. } => {
- Some((param.id, name, in_band))
- }
- _ => None,
- }
- })
- .enumerate()
- .find(|&(_, (_, lt_name, _))| lt_name == name)
- .map_or(Set1::Many, |(i, (id, _, in_band))| {
- let def_id = tcx.hir.local_def_id(id);
- let origin = LifetimeDefOrigin::from_is_in_band(in_band);
- Set1::One(Region::EarlyBound(i as u32, def_id, origin))
- })
- }
- }
- Set1::Many => Set1::Many,
- })
+ let def = match data.bounded_ty.node {
+ hir::TyPath(hir::QPath::Resolved(None, ref path)) => path.def,
+ _ => continue,
+ };
+
+ if def == Def::TyParam(param_def_id) {
+ add_bounds(&mut set, &data.bounds);
+ }
}
+
+ Some(match set {
+ Set1::Empty => Set1::Empty,
+ Set1::One(name) => {
+ if name == hir::LifetimeName::Static {
+ Set1::One(Region::Static)
+ } else {
+ generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { name, in_band, .. } => {
+ Some((param.id, name, in_band))
+ }
+ _ => None,
+ })
+ .enumerate()
+ .find(|&(_, (_, lt_name, _))| lt_name == name)
+ .map_or(Set1::Many, |(i, (id, _, in_band))| {
+ let def_id = tcx.hir.local_def_id(id);
+ let origin = LifetimeDefOrigin::from_is_in_band(in_band);
+ Set1::One(Region::EarlyBound(i as u32, def_id, origin))
+ })
+ }
+ }
+ Set1::Many => Set1::Many,
+ })
}
})
.collect()
}
let mut type_count = 0;
- let lifetimes = generics.params.iter().filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => {
- if self.map.late_bound.contains(¶m.id) {
- Some(Region::late(&self.tcx.hir, param))
- } else {
- Some(Region::early(&self.tcx.hir, &mut index, param))
- }
- }
- GenericParamKind::Type { .. } => {
- type_count += 1;
- None
+ let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ if self.map.late_bound.contains(¶m.id) {
+ Some(Region::late(&self.tcx.hir, param))
+ } else {
+ Some(Region::early(&self.tcx.hir, &mut index, param))
}
}
+ GenericParamKind::Type { .. } => {
+ type_count += 1;
+ None
+ }
}).collect();
let next_early_index = index + type_count;
return;
}
- if generic_args.lifetimes().all(|l| l.is_elided()) {
- self.resolve_elided_lifetimes(generic_args.lifetimes().collect(), true);
+ let mut elide_lifetimes = true;
+ let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
+ hir::GenericArg::Lifetime(lt) => {
+ if !lt.is_elided() {
+ elide_lifetimes = false;
+ }
+ Some(lt)
+ }
+ _ => None,
+ }).collect();
+ if elide_lifetimes {
+ self.resolve_elided_lifetimes(lifetimes, true);
} else {
- for l in generic_args.lifetimes() {
- self.visit_lifetime(l);
+ for lt in lifetimes {
+ self.visit_lifetime(lt);
}
}
}).collect()
})
};
- unsubst
- .iter()
- .map(|set| match *set {
- Set1::Empty => if in_body {
- None
- } else {
- Some(Region::Static)
- },
- Set1::One(r) => r.subst(generic_args.lifetimes(), map),
- Set1::Many => None,
- })
- .collect()
+ unsubst.iter()
+ .map(|set| match *set {
+ Set1::Empty => if in_body {
+ None
+ } else {
+ Some(Region::Static)
+ },
+ Set1::One(r) => {
+ let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
+ GenericArg::Lifetime(lt) => Some(lt),
+ _ => None,
+ });
+ r.subst(lifetimes, map)
+ }
+ Set1::Many => None,
+ })
+ .collect()
});
- for (i, ty) in generic_args.types().enumerate() {
- if let Some(<) = object_lifetime_defaults.get(i) {
- let scope = Scope::ObjectLifetimeDefault {
- lifetime: lt,
- s: self.scope,
- };
- self.with(scope, |_, this| this.visit_ty(ty));
- } else {
- self.visit_ty(ty);
+ let mut i = 0;
+ for arg in &generic_args.args {
+ match arg {
+ GenericArg::Lifetime(_) => {}
+ GenericArg::Type(ty) => {
+ if let Some(<) = object_lifetime_defaults.get(i) {
+ let scope = Scope::ObjectLifetimeDefault {
+ lifetime: lt,
+ s: self.scope,
+ };
+ self.with(scope, |_, this| this.visit_ty(ty));
+ } else {
+ self.visit_ty(ty);
+ }
+ i += 1;
+ }
}
}
}
fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) {
- let lifetimes: Vec<_> = params.iter().filter_map(|param| {
- match param.kind {
- GenericParamKind::Lifetime { name, .. } => Some((param, name)),
- _ => None,
- }
+ let lifetimes: Vec<_> = params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { name, .. } => Some((param, name)),
+ _ => None,
}).collect();
for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() {
match lifetime_i_name {
let names_map: FxHashSet<String> = generics
.params
.iter()
- .filter_map(|param| {
- match param.kind {
- ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
- _ => None
- }
+ .filter_map(|param| match param.kind {
+ ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
+ _ => None
})
.collect();
if !verbose {
let mut type_params =
- generics.params.iter().rev().filter_map(|param| {
- match param.kind {
- GenericParamDefKind::Type { has_default, .. } => {
- Some((param.def_id, has_default))
- }
- GenericParamDefKind::Lifetime => None,
+ generics.params.iter().rev().filter_map(|param| match param.kind {
+ GenericParamDefKind::Type { has_default, .. } => {
+ Some((param.def_id, has_default))
}
+ GenericParamDefKind::Lifetime => None,
}).peekable();
let has_default = {
let has_default = type_params.peek().map(|(_, has_default)| has_default);
}
hir::ItemConst(..) => self.encode_optimized_mir(def_id),
hir::ItemFn(_, _, constness, _, ref generics, _) => {
- let has_types = generics.params.iter().find(|param| {
- match param.kind {
- hir::GenericParamKind::Type { .. } => true,
- _ => false,
- }
- }).is_some();
+ let has_types = generics.params.iter().any(|param| match param.kind {
+ hir::GenericParamKind::Type { .. } => true,
+ _ => false,
+ });
let needs_inline =
(has_types || tcx.codegen_fn_attrs(def_id).requests_inline()) &&
!self.metadata_output_only();
//! is parameterized by an instance of `AstConv`.
use rustc_data_structures::accumulate_vec::AccumulateVec;
-use hir;
+use hir::{self, GenericArg};
use hir::def::Def;
use hir::def_id::DefId;
use middle::resolve_lifetime as rl;
// If the type is parameterized by this region, then replace this
// region with the current anon region binding (in other words,
// whatever & would get replaced with).
- let decl_generics = tcx.generics_of(def_id);
- let ty_provided = generic_args.types().count();
- let lt_provided = generic_args.lifetimes().count();
+ let mut lt_provided = 0;
+ let mut ty_provided = 0;
+ for arg in &generic_args.args {
+ match arg {
+ GenericArg::Lifetime(_) => lt_provided += 1,
+ GenericArg::Type(_) => ty_provided += 1,
+ }
+ }
+ let decl_generics = tcx.generics_of(def_id);
let mut lt_accepted = 0;
let mut ty_params = ParamRange { required: 0, accepted: 0 };
for param in &decl_generics.params {
match param.kind {
GenericParamDefKind::Lifetime => {
let i = param.index as usize - own_self;
- if let Some(lifetime) = generic_args.lifetimes().nth(i) {
- self.ast_region_to_region(lifetime, Some(param)).into()
- } else {
- tcx.types.re_static.into()
+ let mut j = 0;
+ for arg in &generic_args.args {
+ match arg {
+ GenericArg::Lifetime(lt) => {
+ if i == j {
+ return self.ast_region_to_region(lt, Some(param)).into();
+ }
+ j += 1;
+ }
+ _ => {}
+ }
}
+ tcx.types.re_static.into()
}
GenericParamDefKind::Type { has_default, .. } => {
let i = param.index as usize;
let i = i - (lt_accepted + own_self);
if i < ty_provided {
// A provided type parameter.
- self.ast_ty_to_ty(&generic_args.types().nth(i).unwrap()).into()
+ let mut j = 0;
+ for arg in &generic_args.args {
+ match arg {
+ GenericArg::Type(ty) => {
+ if i == j {
+ return self.ast_ty_to_ty(ty).into();
+ }
+ j += 1;
+ }
+ _ => {}
+ }
+ }
+ bug!()
} else if infer_types {
// No type parameters were provided, we can infer all.
if !default_needs_object_self(param) {
let mut error_found = false;
let impl_m_generics = tcx.generics_of(impl_m.def_id);
let trait_m_generics = tcx.generics_of(trait_m.def_id);
- let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| {
- match param.kind {
- GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
- GenericParamDefKind::Lifetime => None,
- }
+ let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
+ GenericParamDefKind::Lifetime => None,
});
let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| {
match param.kind {
use astconv::AstConv;
use check::{FnCtxt, PlaceOp, callee, Needs};
+use hir::GenericArg;
use hir::def_id::DefId;
use rustc::ty::subst::Substs;
use rustc::traits;
} else {
match param.kind {
GenericParamDefKind::Lifetime => {
- if let Some(lifetime) = provided.as_ref().and_then(|p| {
- p.lifetimes().nth(i - parent_substs.len())
+ if let Some(lifetime) = provided.as_ref().and_then(|data| {
+ let mut j = 0;
+ for arg in &data.args {
+ match arg {
+ GenericArg::Lifetime(lt) => {
+ if i - parent_substs.len() == j {
+ return Some(lt);
+ }
+ j += 1;
+ }
+ _ => {}
+ }
+ }
+ None
}) {
return AstConv::ast_region_to_region(
self.fcx, lifetime, Some(param)).into();
}
}
GenericParamDefKind::Type {..} => {
- if let Some(ast_ty) = provided.as_ref().and_then(|p| {
- p.types().nth(i - parent_substs.len() - own_counts.lifetimes)
+ if let Some(ast_ty) = provided.as_ref().and_then(|data| {
+ let mut j = 0;
+ for arg in &data.args {
+ match arg {
+ GenericArg::Type(ty) => {
+ if i - parent_substs.len() - own_counts.lifetimes == j {
+ return Some(ty);
+ }
+ j += 1;
+ }
+ _ => {}
+ }
+ }
+ None
}) {
return self.to_ty(ast_ty).into();
}
use self::TupleArgumentsFlag::*;
use astconv::AstConv;
+use hir::GenericArg;
use hir::def::Def;
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use std::slice;
match param.kind {
GenericParamDefKind::Lifetime => {
let lifetimes = segment.map_or(vec![], |(s, _)| {
- s.args.as_ref().map_or(vec![], |arg| arg.lifetimes().collect())
+ s.args.as_ref().map_or(vec![], |data| {
+ data.args.iter().filter_map(|arg| match arg {
+ GenericArg::Lifetime(lt) => Some(lt),
+ _ => None,
+ }).collect()
+ })
});
if let Some(lifetime) = lifetimes.get(i) {
}
GenericParamDefKind::Type {..} => {
let (types, infer_types) = segment.map_or((vec![], true), |(s, _)| {
- (s.args.as_ref().map_or(vec![], |arg| {
- arg.types().collect()
+ (s.args.as_ref().map_or(vec![], |data| {
+ data.args.iter().filter_map(|arg| match arg {
+ GenericArg::Type(ty) => Some(ty),
+ _ => None,
+ }).collect()
}), s.infer_types)
});
|(s, _)| {
s.args.as_ref().map_or(
(vec![], vec![], s.infer_types, &[][..]),
- |arg| {
- (arg.lifetimes().collect(),
- arg.types().collect(),
- s.infer_types,
- &arg.bindings[..])
+ |data| {
+ let mut lifetimes = vec![];
+ let mut types = vec![];
+ for arg in &data.args {
+ match arg {
+ GenericArg::Lifetime(lt) => lifetimes.push(lt),
+ GenericArg::Type(ty) => types.push(ty),
+ }
+ }
+ (lifetimes, types, s.infer_types, &data.bindings[..])
}
)
});
-> bool {
let segment = segment.map(|(path_segment, generics)| {
let explicit = !path_segment.infer_types;
- let impl_trait = generics.params.iter().any(|param| {
- match param.kind {
- ty::GenericParamDefKind::Type {
- synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
- } => true,
- _ => false,
- }
+ let impl_trait = generics.params.iter().any(|param| match param.kind {
+ ty::GenericParamDefKind::Type {
+ synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
+ } => true,
+ _ => false,
});
if explicit && impl_trait {
}
}
- let types = generics.params.iter().filter(|param| {
- match param.kind {
- hir::GenericParamKind::Type { .. } => true,
- _ => false,
- }
+ let types = generics.params.iter().filter(|param| match param.kind {
+ hir::GenericParamKind::Type { .. } => true,
+ _ => false,
});
for (&used, param) in types_used.iter().zip(types) {
if !used {
let parent = tcx.generics_of(generics.parent.unwrap());
let impl_params: FxHashMap<_, _> =
parent.params.iter()
- .flat_map(|param| {
- match param.kind {
- GenericParamDefKind::Lifetime => None,
- GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
- }
+ .flat_map(|param| match param.kind {
+ GenericParamDefKind::Lifetime => None,
+ GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
})
.collect();
{
let from_ty_params =
ast_generics.params.iter()
- .filter_map(|param| {
- match param.kind {
- GenericParamKind::Type { ref bounds, .. } => {
- if param.id == param_id {
- Some(bounds)
- } else {
- None
- }
+ .filter_map(|param| match param.kind {
+ GenericParamKind::Type { ref bounds, .. } => {
+ if param.id == param_id {
+ return Some(bounds);
}
- _ => None
+ None
}
+ _ => None
})
.flat_map(|bounds| bounds.iter())
.flat_map(|b| predicates_from_bound(self, ty, b));
// Now create the real type parameters.
let type_start = own_start - has_self as u32 + params.len() as u32;
let mut i = 0;
- params.extend(ast_generics.params.iter().filter_map(|param| {
- match param.kind {
- GenericParamKind::Type { ref default, synthetic, .. } => {
- if param.name() == keywords::SelfType.name() {
- span_bug!(param.span,
- "`Self` should not be the name of a regular parameter");
- }
+ params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Type { ref default, synthetic, .. } => {
+ if param.name() == keywords::SelfType.name() {
+ span_bug!(param.span,
+ "`Self` should not be the name of a regular parameter");
+ }
- if !allow_defaults && default.is_some() {
- if !tcx.features().default_type_parameter_fallback {
- tcx.lint_node(
- lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
- param.id,
- param.span,
- &format!("defaults for type parameters are only allowed in \
- `struct`, `enum`, `type`, or `trait` definitions."));
- }
+ if !allow_defaults && default.is_some() {
+ if !tcx.features().default_type_parameter_fallback {
+ tcx.lint_node(
+ lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
+ param.id,
+ param.span,
+ &format!("defaults for type parameters are only allowed in \
+ `struct`, `enum`, `type`, or `trait` definitions."));
}
-
- let ty_param = ty::GenericParamDef {
- index: type_start + i as u32,
- name: param.name().as_interned_str(),
- def_id: tcx.hir.local_def_id(param.id),
- pure_wrt_drop: param.pure_wrt_drop,
- kind: ty::GenericParamDefKind::Type {
- has_default: default.is_some(),
- object_lifetime_default:
- object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]),
- synthetic,
- },
- };
- i += 1;
- Some(ty_param)
}
- _ => None,
+
+ let ty_param = ty::GenericParamDef {
+ index: type_start + i as u32,
+ name: param.name().as_interned_str(),
+ def_id: tcx.hir.local_def_id(param.id),
+ pure_wrt_drop: param.pure_wrt_drop,
+ kind: ty::GenericParamDefKind::Type {
+ has_default: default.is_some(),
+ object_lifetime_default:
+ object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]),
+ synthetic,
+ },
+ };
+ i += 1;
+ Some(ty_param)
}
+ _ => None,
}));
// provide junk type parameter defs - the only place that
generics: &'a hir::Generics)
-> impl Iterator<Item=&'a hir::GenericParam> + Captures<'tcx>
{
- generics.params.iter().filter(move |param| {
- match param.kind {
- GenericParamKind::Lifetime { .. } => {
- let hir_id = tcx.hir.node_to_hir_id(param.id);
- !tcx.is_late_bound(hir_id)
- }
- _ => false,
+ generics.params.iter().filter(move |param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ let hir_id = tcx.hir.node_to_hir_id(param.id);
+ !tcx.is_late_bound(hir_id)
}
+ _ => false,
})
}
use rustc::ty::fold::TypeFolder;
use rustc::middle::lang_items;
use rustc::mir::interpret::GlobalId;
-use rustc::hir::{self, HirVec};
+use rustc::hir::{self, GenericArg, HirVec};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::hir::def_id::DefIndexAddressSpace;
// Bounds in the type_params and lifetimes fields are repeated in the
// predicates field (see rustc_typeck::collect::ty_generics), so remove
// them.
- let stripped_typarams = gens.params.iter().filter_map(|param| {
- if let ty::GenericParamDefKind::Type {..} = param.kind {
+ let stripped_typarams = gens.params.iter().filter_map(|param| match param.kind {
+ ty::GenericParamDefKind::Lifetime => None,
+ ty::GenericParamDefKind::Type { .. } => {
if param.name == keywords::SelfType.name().as_str() {
assert_eq!(param.index, 0);
- None
- } else {
- Some(param.clean(cx))
+ return None;
}
- } else {
- None
+ Some(param.clean(cx))
}
}).collect::<Vec<TyParam>>();
Generics {
params: gens.params
.iter()
- .flat_map(|param| {
- if let ty::GenericParamDefKind::Lifetime = param.kind {
+ .flat_map(|param| match param.kind {
+ ty::GenericParamDefKind::Lifetime => {
Some(GenericParamDef::Lifetime(param.clean(cx)))
- } else {
- None
}
+ ty::GenericParamDefKind::Type { .. } => None,
}).chain(
simplify::ty_params(stripped_typarams)
.into_iter()
for param in generics.params.iter() {
match param.kind {
hir::GenericParamKind::Lifetime { .. } => {
- if let Some(lt) = generic_args.lifetimes()
- .nth(indices.lifetimes).cloned() {
+ let mut j = 0;
+ let lifetime = generic_args.args.iter().find_map(|arg| {
+ match arg {
+ GenericArg::Lifetime(lt) => {
+ if indices.lifetimes == j {
+ return Some(lt);
+ }
+ j += 1;
+ None
+ }
+ _ => None,
+ }
+ });
+ if let Some(lt) = lifetime.cloned() {
if !lt.is_elided() {
let lt_def_id =
cx.tcx.hir.local_def_id(param.id);
hir::GenericParamKind::Type { ref default, .. } => {
let ty_param_def =
Def::TyParam(cx.tcx.hir.local_def_id(param.id));
- if let Some(ty) = generic_args.types()
- .nth(indices.types).cloned() {
+ let mut j = 0;
+ let type_ = generic_args.args.iter().find_map(|arg| {
+ match arg {
+ GenericArg::Type(ty) => {
+ if indices.types == j {
+ return Some(ty);
+ }
+ j += 1;
+ None
+ }
+ _ => None,
+ }
+ });
+ if let Some(ty) = type_.cloned() {
ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
} else if let Some(default) = default.clone() {
ty_substs.insert(ty_param_def,
output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
}
} else {
+ let mut lifetimes = vec![];
+ let mut types = vec![];
+ let mut elided_lifetimes = true;
+ for arg in &self.args {
+ match arg {
+ GenericArg::Lifetime(lt) if elided_lifetimes => {
+ if lt.is_elided() {
+ elided_lifetimes = false;
+ lifetimes = vec![];
+ continue;
+ }
+ lifetimes.push(lt.clean(cx));
+ }
+ GenericArg::Lifetime(_) => {}
+ GenericArg::Type(ty) => {
+ types.push(ty.clean(cx));
+ }
+ }
+ }
GenericArgs::AngleBracketed {
- lifetimes: if self.lifetimes().all(|lt| lt.is_elided()) {
- vec![]
- } else {
- self.lifetimes().map(|lt| lt.clean(cx)).collect()
- },
- types: self.types().map(|ty| ty.clean(cx)).collect(),
+ lifetimes,
+ types,
bindings: self.bindings.clean(cx),
}
}
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(fs_read_write)]
+#![feature(iterator_find_map)]
#![feature(set_stdio)]
#![feature(slice_sort_by_cached_key)]
#![feature(test)]
.to_generics(cx, self.span, type_ident, generics);
// Create the generic parameters
- params.extend(generics.params.iter().map(|param| {
- match param.kind {
- GenericParamKindAST::Lifetime { .. } => param.clone(),
- GenericParamKindAST::Type { bounds: ref ty_bounds, .. } => {
- // I don't think this can be moved out of the loop, since
- // a TyParamBound requires an ast id
- let mut bounds: Vec<_> =
- // extra restrictions on the generics parameters to the
- // type being derived upon
- self.additional_bounds.iter().map(|p| {
- cx.typarambound(p.to_path(cx, self.span,
- type_ident, generics))
- }).collect();
-
- // require the current trait
- bounds.push(cx.typarambound(trait_path.clone()));
-
- // also add in any bounds from the declaration
- for declared_bound in ty_bounds {
- bounds.push((*declared_bound).clone());
- }
-
- cx.typaram(self.span, param.ident, vec![], bounds, None)
+ params.extend(generics.params.iter().map(|param| match param.kind {
+ GenericParamKindAST::Lifetime { .. } => param.clone(),
+ GenericParamKindAST::Type { bounds: ref ty_bounds, .. } => {
+ // I don't think this can be moved out of the loop, since
+ // a TyParamBound requires an ast id
+ let mut bounds: Vec<_> =
+ // extra restrictions on the generics parameters to the
+ // type being derived upon
+ self.additional_bounds.iter().map(|p| {
+ cx.typarambound(p.to_path(cx, self.span,
+ type_ident, generics))
+ }).collect();
+
+ // require the current trait
+ bounds.push(cx.typarambound(trait_path.clone()));
+
+ // also add in any bounds from the declaration
+ for declared_bound in ty_bounds {
+ bounds.push((*declared_bound).clone());
}
+
+ cx.typaram(self.span, param.ident, vec![], bounds, None)
}
}));