1
Fork 0

Remove all traces of lifetimes() and types() methods

This commit is contained in:
varkor 2018-05-27 01:43:03 +01:00
parent 10229fd9d5
commit 80b381e041
16 changed files with 419 additions and 346 deletions

View file

@ -1731,7 +1731,11 @@ impl<'a> LoweringContext<'a> {
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()
@ -1763,7 +1767,7 @@ impl<'a> LoweringContext<'a> {
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(

View file

@ -400,34 +400,20 @@ impl GenericArgs {
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.

View file

@ -1731,20 +1731,31 @@ impl<'a> State<'a> {
}
};
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.:

View file

@ -18,8 +18,7 @@
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;
@ -533,15 +532,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
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 {
@ -585,13 +582,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
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,
@ -777,15 +772,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
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();
@ -834,15 +827,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
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();
@ -899,11 +890,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
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 {
@ -926,13 +915,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
..
}) => {
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() {
@ -990,11 +977,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|| 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 {
@ -1010,13 +995,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
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,
@ -1087,11 +1070,9 @@ fn check_mixed_explicit_and_in_band_defs(
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);
@ -1262,18 +1243,16 @@ fn compute_object_lifetime_defaults(
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()
}
@ -1308,64 +1287,60 @@ fn object_lifetime_defaults_for_item(
}
}
generics.params.iter().filter_map(|param| {
match param.kind {
GenericParamKind::Lifetime { .. } => None,
GenericParamKind::Type { ref bounds, .. } => {
let mut set = Set1::Empty;
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);
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,
};
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,
};
// 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;
}
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);
}
// 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()
@ -1541,20 +1516,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
let mut type_count = 0;
let lifetimes = generics.params.iter().filter_map(|param| {
match param.kind {
GenericParamKind::Lifetime { .. } => {
if self.map.late_bound.contains(&param.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(&param.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;
@ -1721,11 +1694,21 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
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);
}
}
@ -1788,29 +1771,41 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}).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(&lt) = 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(&lt) = 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;
}
}
}
@ -2269,11 +2264,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
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 {

View file

@ -224,11 +224,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
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();

View file

@ -336,13 +336,11 @@ impl PrintContext {
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);

View file

@ -1236,12 +1236,10 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
}
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();

View file

@ -13,7 +13,7 @@
//! 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;
@ -213,10 +213,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
// 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 {
@ -269,11 +275,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
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;
@ -286,7 +300,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
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) {

View file

@ -728,11 +728,9 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
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 {

View file

@ -12,6 +12,7 @@ use super::{probe, MethodCallee};
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;
@ -330,16 +331,40 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
} 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();
}

View file

@ -85,6 +85,7 @@ use self::method::MethodCallee;
use self::TupleArgumentsFlag::*;
use astconv::AstConv;
use hir::GenericArg;
use hir::def::Def;
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use std::slice;
@ -4834,7 +4835,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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) {
@ -4845,8 +4851,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
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)
});
@ -4967,11 +4976,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|(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[..])
}
)
});
@ -5097,13 +5111,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
-> 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 {
@ -5187,11 +5199,9 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
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 {

View file

@ -662,11 +662,9 @@ fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
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();

View file

@ -315,17 +315,14 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
{
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));
@ -921,42 +918,40 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// 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");
}
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)
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");
}
_ => None,
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,
}));
// provide junk type parameter defs - the only place that
@ -1313,14 +1308,12 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>(
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,
})
}

View file

@ -36,7 +36,7 @@ use rustc::middle::resolve_lifetime as rl;
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;
@ -1979,16 +1979,14 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
// 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>>();
@ -2034,12 +2032,11 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
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()
@ -2870,8 +2867,20 @@ impl Clean<Type> for hir::Ty {
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);
@ -2883,8 +2892,20 @@ impl Clean<Type> for hir::Ty {
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,
@ -3504,13 +3525,28 @@ impl Clean<GenericArgs> for hir::GenericArgs {
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),
}
}

View file

@ -18,6 +18,7 @@
#![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)]

View file

@ -549,30 +549,28 @@ impl<'a> TraitDef<'a> {
.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();
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()));
// 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)
// 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)
}
}));