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) 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 = generic_args.args =
self.elided_path_lifetimes(path_span, expected_lifetimes) self.elided_path_lifetimes(path_span, expected_lifetimes)
.into_iter() .into_iter()
@ -1763,7 +1767,7 @@ impl<'a> LoweringContext<'a> {
bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(), bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
parenthesized: false, parenthesized: false,
}, },
has_types && param_mode == ParamMode::Optional) !has_types && param_mode == ParamMode::Optional)
} }
fn lower_parenthesized_parameter_data( fn lower_parenthesized_parameter_data(

View file

@ -400,34 +400,20 @@ impl GenericArgs {
pub fn inputs(&self) -> &[P<Ty>] { pub fn inputs(&self) -> &[P<Ty>] {
if self.parenthesized { if self.parenthesized {
if let Some(ref ty) = self.types().next() { for arg in &self.args {
match arg {
GenericArg::Lifetime(_) => {}
GenericArg::Type(ref ty) => {
if let TyTup(ref tys) = ty.node { if let TyTup(ref tys) = ty.node {
return tys; return tys;
} }
break;
}
}
} }
} }
bug!("GenericArgs::inputs: not a `Fn(T) -> U`"); 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. /// The AST represents all type param bounds as types.

View file

@ -1731,7 +1731,20 @@ 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 { if !elide_lifetimes {
start_or_comma(self)?; start_or_comma(self)?;
self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| { self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| {
@ -1740,11 +1753,9 @@ impl<'a> State<'a> {
GenericArg::Type(ty) => s.print_type(ty), GenericArg::Type(ty) => s.print_type(ty),
} }
})?; })?;
} else if generic_args.types().count() != 0 { } else if !types.is_empty() {
start_or_comma(self)?; start_or_comma(self)?;
self.commasep(Inconsistent, self.commasep(Inconsistent, &types, |s, ty| s.print_type(&ty))?;
&generic_args.types().collect::<Vec<_>>(),
|s, ty| s.print_type(&ty))?;
} }
// FIXME(eddyb) This would leak into error messages, e.g.: // FIXME(eddyb) This would leak into error messages, e.g.:

View file

@ -18,8 +18,7 @@
use hir::def::Def; use hir::def::Def;
use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use hir::map::Map; use hir::map::Map;
use hir::ItemLocalId; use hir::{GenericArg, ItemLocalId, LifetimeName};
use hir::LifetimeName;
use ty::{self, TyCtxt, GenericParamDefKind}; use ty::{self, TyCtxt, GenericParamDefKind};
use errors::DiagnosticBuilder; use errors::DiagnosticBuilder;
@ -533,8 +532,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
0 0
}; };
let mut type_count = 0; let mut type_count = 0;
let lifetimes = generics.params.iter().filter_map(|param| { let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => { GenericParamKind::Lifetime { .. } => {
Some(Region::early(&self.tcx.hir, &mut index, param)) Some(Region::early(&self.tcx.hir, &mut index, param))
} }
@ -542,7 +540,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
type_count += 1; type_count += 1;
None None
} }
}
}).collect(); }).collect();
let scope = Scope::Binder { let scope = Scope::Binder {
lifetimes, lifetimes,
@ -585,13 +582,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
let scope = Scope::Binder { let scope = Scope::Binder {
lifetimes: c.generic_params lifetimes: c.generic_params
.iter() .iter()
.filter_map(|param| { .filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => { GenericParamKind::Lifetime { .. } => {
Some(Region::late(&self.tcx.hir, param)) Some(Region::late(&self.tcx.hir, param))
} }
_ => None, _ => None,
}
}) })
.collect(), .collect(),
s: self.scope, s: self.scope,
@ -777,8 +772,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
let mut type_count = 0; let mut type_count = 0;
let lifetimes = generics.params let lifetimes = generics.params
.iter() .iter()
.filter_map(|param| { .filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => { GenericParamKind::Lifetime { .. } => {
Some(Region::early(&self.tcx.hir, &mut index, param)) Some(Region::early(&self.tcx.hir, &mut index, param))
} }
@ -786,7 +780,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
type_count += 1; type_count += 1;
None None
} }
}
}) })
.collect(); .collect();
@ -834,8 +827,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
debug!("visit_ty: index = {}", index); debug!("visit_ty: index = {}", index);
let lifetimes = generics.params let lifetimes = generics.params
.iter() .iter()
.filter_map(|param| { .filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => { GenericParamKind::Lifetime { .. } => {
Some(Region::early(&self.tcx.hir, &mut index, param)) Some(Region::early(&self.tcx.hir, &mut index, param))
} }
@ -843,7 +835,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
next_early_index += 1; next_early_index += 1;
None None
} }
}
}) })
.collect(); .collect();
@ -899,11 +890,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_generics(&mut self, generics: &'tcx hir::Generics) { fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
check_mixed_explicit_and_in_band_defs( check_mixed_explicit_and_in_band_defs(
self.tcx, self.tcx,
&generics.params.iter().filter_map(|param| { &generics.params.iter().filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => Some(param.clone()), GenericParamKind::Lifetime { .. } => Some(param.clone()),
_ => None, _ => None,
}
}).collect::<Vec<_>>() }).collect::<Vec<_>>()
); );
for param in &generics.params { 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() let lifetimes: FxHashMap<_, _> = bound_generic_params.iter()
.filter_map(|param| { .filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => { GenericParamKind::Lifetime { .. } => {
Some(Region::late(&self.tcx.hir, param)) Some(Region::late(&self.tcx.hir, param))
} }
_ => None, _ => None,
}
}) })
.collect(); .collect();
if !lifetimes.is_empty() { if !lifetimes.is_empty() {
@ -990,11 +977,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|| trait_ref || trait_ref
.bound_generic_params .bound_generic_params
.iter() .iter()
.any(|param| { .any(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => true, GenericParamKind::Lifetime { .. } => true,
_ => false, _ => false,
}
}) })
{ {
if self.trait_ref_hack { if self.trait_ref_hack {
@ -1010,13 +995,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
lifetimes: trait_ref lifetimes: trait_ref
.bound_generic_params .bound_generic_params
.iter() .iter()
.filter_map(|param| { .filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => { GenericParamKind::Lifetime { .. } => {
Some(Region::late(&self.tcx.hir, param)) Some(Region::late(&self.tcx.hir, param))
} }
_ => None, _ => None,
}
}) })
.collect(), .collect(),
s: self.scope, s: self.scope,
@ -1087,11 +1070,9 @@ fn check_mixed_explicit_and_in_band_defs(
tcx: TyCtxt<'_, '_, '_>, tcx: TyCtxt<'_, '_, '_>,
params: &[hir::GenericParam], params: &[hir::GenericParam],
) { ) {
let in_bands: Vec<_> = params.iter().map(|param| { let in_bands: Vec<_> = params.iter().map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { in_band, .. } => (in_band, param.span), GenericParamKind::Lifetime { in_band, .. } => (in_band, param.span),
_ => bug!("expected lifetime param"), _ => bug!("expected lifetime param"),
}
}).collect(); }).collect();
let out_of_band = in_bands.iter().find(|(in_band, _)| !in_band); let out_of_band = in_bands.iter().find(|(in_band, _)| !in_band);
let in_band = in_bands.iter().find(|(in_band, _)| *in_band); let in_band = in_bands.iter().find(|(in_band, _)| *in_band);
@ -1262,17 +1243,15 @@ fn compute_object_lifetime_defaults(
Set1::One(Region::Static) => "'static".to_string(), Set1::One(Region::Static) => "'static".to_string(),
Set1::One(Region::EarlyBound(i, _, _)) => { Set1::One(Region::EarlyBound(i, _, _)) => {
let mut j = 0; let mut j = 0;
generics.params.iter().find(|param| { generics.params.iter().find(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => { GenericParamKind::Lifetime { .. } => {
if i == j { if i == j {
return true; return true;
} }
j += 1; j += 1;
}
_ => {}
}
false false
}
_ => false,
}).unwrap() }).unwrap()
.name() .name()
.to_string() .to_string()
@ -1308,8 +1287,7 @@ fn object_lifetime_defaults_for_item(
} }
} }
generics.params.iter().filter_map(|param| { generics.params.iter().filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => None, GenericParamKind::Lifetime { .. } => None,
GenericParamKind::Type { ref bounds, .. } => { GenericParamKind::Type { ref bounds, .. } => {
let mut set = Set1::Empty; let mut set = Set1::Empty;
@ -1346,13 +1324,11 @@ fn object_lifetime_defaults_for_item(
if name == hir::LifetimeName::Static { if name == hir::LifetimeName::Static {
Set1::One(Region::Static) Set1::One(Region::Static)
} else { } else {
generics.params.iter().filter_map(|param| { generics.params.iter().filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { name, in_band, .. } => { GenericParamKind::Lifetime { name, in_band, .. } => {
Some((param.id, name, in_band)) Some((param.id, name, in_band))
} }
_ => None, _ => None,
}
}) })
.enumerate() .enumerate()
.find(|&(_, (_, lt_name, _))| lt_name == name) .find(|&(_, (_, lt_name, _))| lt_name == name)
@ -1366,7 +1342,6 @@ fn object_lifetime_defaults_for_item(
Set1::Many => Set1::Many, Set1::Many => Set1::Many,
}) })
} }
}
}) })
.collect() .collect()
} }
@ -1541,8 +1516,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
} }
let mut type_count = 0; let mut type_count = 0;
let lifetimes = generics.params.iter().filter_map(|param| { let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => { GenericParamKind::Lifetime { .. } => {
if self.map.late_bound.contains(&param.id) { if self.map.late_bound.contains(&param.id) {
Some(Region::late(&self.tcx.hir, param)) Some(Region::late(&self.tcx.hir, param))
@ -1554,7 +1528,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
type_count += 1; type_count += 1;
None None
} }
}
}).collect(); }).collect();
let next_early_index = index + type_count; let next_early_index = index + type_count;
@ -1721,11 +1694,21 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
return; return;
} }
if generic_args.lifetimes().all(|l| l.is_elided()) { let mut elide_lifetimes = true;
self.resolve_elided_lifetimes(generic_args.lifetimes().collect(), 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 { } else {
for l in generic_args.lifetimes() { for lt in lifetimes {
self.visit_lifetime(l); self.visit_lifetime(lt);
} }
} }
@ -1788,21 +1771,30 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}).collect() }).collect()
}) })
}; };
unsubst unsubst.iter()
.iter()
.map(|set| match *set { .map(|set| match *set {
Set1::Empty => if in_body { Set1::Empty => if in_body {
None None
} else { } else {
Some(Region::Static) Some(Region::Static)
}, },
Set1::One(r) => r.subst(generic_args.lifetimes(), map), 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, Set1::Many => None,
}) })
.collect() .collect()
}); });
for (i, ty) in generic_args.types().enumerate() { 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) { if let Some(&lt) = object_lifetime_defaults.get(i) {
let scope = Scope::ObjectLifetimeDefault { let scope = Scope::ObjectLifetimeDefault {
lifetime: lt, lifetime: lt,
@ -1812,6 +1804,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
} else { } else {
self.visit_ty(ty); self.visit_ty(ty);
} }
i += 1;
}
}
} }
for b in &generic_args.bindings { for b in &generic_args.bindings {
@ -2269,11 +2264,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
} }
fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) { fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) {
let lifetimes: Vec<_> = params.iter().filter_map(|param| { let lifetimes: Vec<_> = params.iter().filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { name, .. } => Some((param, name)), GenericParamKind::Lifetime { name, .. } => Some((param, name)),
_ => None, _ => None,
}
}).collect(); }).collect();
for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() { for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() {
match lifetime_i_name { match lifetime_i_name {

View file

@ -224,11 +224,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
let names_map: FxHashSet<String> = generics let names_map: FxHashSet<String> = generics
.params .params
.iter() .iter()
.filter_map(|param| { .filter_map(|param| match param.kind {
match param.kind {
ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()), ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
_ => None _ => None
}
}) })
.collect(); .collect();

View file

@ -336,13 +336,11 @@ impl PrintContext {
if !verbose { if !verbose {
let mut type_params = let mut type_params =
generics.params.iter().rev().filter_map(|param| { generics.params.iter().rev().filter_map(|param| match param.kind {
match param.kind {
GenericParamDefKind::Type { has_default, .. } => { GenericParamDefKind::Type { has_default, .. } => {
Some((param.def_id, has_default)) Some((param.def_id, has_default))
} }
GenericParamDefKind::Lifetime => None, GenericParamDefKind::Lifetime => None,
}
}).peekable(); }).peekable();
let has_default = { let has_default = {
let has_default = type_params.peek().map(|(_, has_default)| 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::ItemConst(..) => self.encode_optimized_mir(def_id),
hir::ItemFn(_, _, constness, _, ref generics, _) => { hir::ItemFn(_, _, constness, _, ref generics, _) => {
let has_types = generics.params.iter().find(|param| { let has_types = generics.params.iter().any(|param| match param.kind {
match param.kind {
hir::GenericParamKind::Type { .. } => true, hir::GenericParamKind::Type { .. } => true,
_ => false, _ => false,
} });
}).is_some();
let needs_inline = let needs_inline =
(has_types || tcx.codegen_fn_attrs(def_id).requests_inline()) && (has_types || tcx.codegen_fn_attrs(def_id).requests_inline()) &&
!self.metadata_output_only(); !self.metadata_output_only();

View file

@ -13,7 +13,7 @@
//! is parameterized by an instance of `AstConv`. //! is parameterized by an instance of `AstConv`.
use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::accumulate_vec::AccumulateVec;
use hir; use hir::{self, GenericArg};
use hir::def::Def; use hir::def::Def;
use hir::def_id::DefId; use hir::def_id::DefId;
use middle::resolve_lifetime as rl; 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 // If the type is parameterized by this region, then replace this
// region with the current anon region binding (in other words, // region with the current anon region binding (in other words,
// whatever & would get replaced with). // whatever & would get replaced with).
let decl_generics = tcx.generics_of(def_id); let mut lt_provided = 0;
let ty_provided = generic_args.types().count(); let mut ty_provided = 0;
let lt_provided = generic_args.lifetimes().count(); 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 lt_accepted = 0;
let mut ty_params = ParamRange { required: 0, accepted: 0 }; let mut ty_params = ParamRange { required: 0, accepted: 0 };
for param in &decl_generics.params { for param in &decl_generics.params {
@ -269,11 +275,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
match param.kind { match param.kind {
GenericParamDefKind::Lifetime => { GenericParamDefKind::Lifetime => {
let i = param.index as usize - own_self; let i = param.index as usize - own_self;
if let Some(lifetime) = generic_args.lifetimes().nth(i) { let mut j = 0;
self.ast_region_to_region(lifetime, Some(param)).into() for arg in &generic_args.args {
} else { match arg {
tcx.types.re_static.into() 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, .. } => { GenericParamDefKind::Type { has_default, .. } => {
let i = param.index as usize; 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); let i = i - (lt_accepted + own_self);
if i < ty_provided { if i < ty_provided {
// A provided type parameter. // 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 { } else if infer_types {
// No type parameters were provided, we can infer all. // No type parameters were provided, we can infer all.
if !default_needs_object_self(param) { 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 mut error_found = false;
let impl_m_generics = tcx.generics_of(impl_m.def_id); let impl_m_generics = tcx.generics_of(impl_m.def_id);
let trait_m_generics = tcx.generics_of(trait_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| { let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind {
match param.kind {
GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)), GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
GenericParamDefKind::Lifetime => None, GenericParamDefKind::Lifetime => None,
}
}); });
let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| { let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| {
match param.kind { match param.kind {

View file

@ -12,6 +12,7 @@ use super::{probe, MethodCallee};
use astconv::AstConv; use astconv::AstConv;
use check::{FnCtxt, PlaceOp, callee, Needs}; use check::{FnCtxt, PlaceOp, callee, Needs};
use hir::GenericArg;
use hir::def_id::DefId; use hir::def_id::DefId;
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
use rustc::traits; use rustc::traits;
@ -330,16 +331,40 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
} else { } else {
match param.kind { match param.kind {
GenericParamDefKind::Lifetime => { GenericParamDefKind::Lifetime => {
if let Some(lifetime) = provided.as_ref().and_then(|p| { if let Some(lifetime) = provided.as_ref().and_then(|data| {
p.lifetimes().nth(i - parent_substs.len()) 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( return AstConv::ast_region_to_region(
self.fcx, lifetime, Some(param)).into(); self.fcx, lifetime, Some(param)).into();
} }
} }
GenericParamDefKind::Type {..} => { GenericParamDefKind::Type {..} => {
if let Some(ast_ty) = provided.as_ref().and_then(|p| { if let Some(ast_ty) = provided.as_ref().and_then(|data| {
p.types().nth(i - parent_substs.len() - own_counts.lifetimes) 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(); return self.to_ty(ast_ty).into();
} }

View file

@ -85,6 +85,7 @@ use self::method::MethodCallee;
use self::TupleArgumentsFlag::*; use self::TupleArgumentsFlag::*;
use astconv::AstConv; use astconv::AstConv;
use hir::GenericArg;
use hir::def::Def; use hir::def::Def;
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use std::slice; use std::slice;
@ -4834,7 +4835,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
match param.kind { match param.kind {
GenericParamDefKind::Lifetime => { GenericParamDefKind::Lifetime => {
let lifetimes = segment.map_or(vec![], |(s, _)| { 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) { if let Some(lifetime) = lifetimes.get(i) {
@ -4845,8 +4851,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
} }
GenericParamDefKind::Type {..} => { GenericParamDefKind::Type {..} => {
let (types, infer_types) = segment.map_or((vec![], true), |(s, _)| { let (types, infer_types) = segment.map_or((vec![], true), |(s, _)| {
(s.args.as_ref().map_or(vec![], |arg| { (s.args.as_ref().map_or(vec![], |data| {
arg.types().collect() data.args.iter().filter_map(|arg| match arg {
GenericArg::Type(ty) => Some(ty),
_ => None,
}).collect()
}), s.infer_types) }), s.infer_types)
}); });
@ -4967,11 +4976,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|(s, _)| { |(s, _)| {
s.args.as_ref().map_or( s.args.as_ref().map_or(
(vec![], vec![], s.infer_types, &[][..]), (vec![], vec![], s.infer_types, &[][..]),
|arg| { |data| {
(arg.lifetimes().collect(), let mut lifetimes = vec![];
arg.types().collect(), let mut types = vec![];
s.infer_types, for arg in &data.args {
&arg.bindings[..]) 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 { -> bool {
let segment = segment.map(|(path_segment, generics)| { let segment = segment.map(|(path_segment, generics)| {
let explicit = !path_segment.infer_types; let explicit = !path_segment.infer_types;
let impl_trait = generics.params.iter().any(|param| { let impl_trait = generics.params.iter().any(|param| match param.kind {
match param.kind {
ty::GenericParamDefKind::Type { ty::GenericParamDefKind::Type {
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), .. synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
} => true, } => true,
_ => false, _ => false,
}
}); });
if explicit && impl_trait { 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| { let types = generics.params.iter().filter(|param| match param.kind {
match param.kind {
hir::GenericParamKind::Type { .. } => true, hir::GenericParamKind::Type { .. } => true,
_ => false, _ => false,
}
}); });
for (&used, param) in types_used.iter().zip(types) { for (&used, param) in types_used.iter().zip(types) {
if !used { 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 parent = tcx.generics_of(generics.parent.unwrap());
let impl_params: FxHashMap<_, _> = let impl_params: FxHashMap<_, _> =
parent.params.iter() parent.params.iter()
.flat_map(|param| { .flat_map(|param| match param.kind {
match param.kind {
GenericParamDefKind::Lifetime => None, GenericParamDefKind::Lifetime => None,
GenericParamDefKind::Type {..} => Some((param.name, param.def_id)), GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
}
}) })
.collect(); .collect();

View file

@ -315,17 +315,14 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
{ {
let from_ty_params = let from_ty_params =
ast_generics.params.iter() ast_generics.params.iter()
.filter_map(|param| { .filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Type { ref bounds, .. } => { GenericParamKind::Type { ref bounds, .. } => {
if param.id == param_id { if param.id == param_id {
Some(bounds) return Some(bounds);
} else { }
None None
} }
}
_ => None _ => None
}
}) })
.flat_map(|bounds| bounds.iter()) .flat_map(|bounds| bounds.iter())
.flat_map(|b| predicates_from_bound(self, ty, b)); .flat_map(|b| predicates_from_bound(self, ty, b));
@ -921,8 +918,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Now create the real type parameters. // Now create the real type parameters.
let type_start = own_start - has_self as u32 + params.len() as u32; let type_start = own_start - has_self as u32 + params.len() as u32;
let mut i = 0; let mut i = 0;
params.extend(ast_generics.params.iter().filter_map(|param| { params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
match param.kind {
GenericParamKind::Type { ref default, synthetic, .. } => { GenericParamKind::Type { ref default, synthetic, .. } => {
if param.name() == keywords::SelfType.name() { if param.name() == keywords::SelfType.name() {
span_bug!(param.span, span_bug!(param.span,
@ -956,7 +952,6 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Some(ty_param) Some(ty_param)
} }
_ => None, _ => None,
}
})); }));
// provide junk type parameter defs - the only place that // 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) generics: &'a hir::Generics)
-> impl Iterator<Item=&'a hir::GenericParam> + Captures<'tcx> -> impl Iterator<Item=&'a hir::GenericParam> + Captures<'tcx>
{ {
generics.params.iter().filter(move |param| { generics.params.iter().filter(move |param| match param.kind {
match param.kind {
GenericParamKind::Lifetime { .. } => { GenericParamKind::Lifetime { .. } => {
let hir_id = tcx.hir.node_to_hir_id(param.id); let hir_id = tcx.hir.node_to_hir_id(param.id);
!tcx.is_late_bound(hir_id) !tcx.is_late_bound(hir_id)
} }
_ => false, _ => false,
}
}) })
} }

View file

@ -36,7 +36,7 @@ use rustc::middle::resolve_lifetime as rl;
use rustc::ty::fold::TypeFolder; use rustc::ty::fold::TypeFolder;
use rustc::middle::lang_items; use rustc::middle::lang_items;
use rustc::mir::interpret::GlobalId; 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::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::hir::def_id::DefIndexAddressSpace; 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 // Bounds in the type_params and lifetimes fields are repeated in the
// predicates field (see rustc_typeck::collect::ty_generics), so remove // predicates field (see rustc_typeck::collect::ty_generics), so remove
// them. // them.
let stripped_typarams = gens.params.iter().filter_map(|param| { let stripped_typarams = gens.params.iter().filter_map(|param| match param.kind {
if let ty::GenericParamDefKind::Type {..} = param.kind { ty::GenericParamDefKind::Lifetime => None,
ty::GenericParamDefKind::Type { .. } => {
if param.name == keywords::SelfType.name().as_str() { if param.name == keywords::SelfType.name().as_str() {
assert_eq!(param.index, 0); assert_eq!(param.index, 0);
None return None;
} else {
Some(param.clean(cx))
} }
} else { Some(param.clean(cx))
None
} }
}).collect::<Vec<TyParam>>(); }).collect::<Vec<TyParam>>();
@ -2034,12 +2032,11 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
Generics { Generics {
params: gens.params params: gens.params
.iter() .iter()
.flat_map(|param| { .flat_map(|param| match param.kind {
if let ty::GenericParamDefKind::Lifetime = param.kind { ty::GenericParamDefKind::Lifetime => {
Some(GenericParamDef::Lifetime(param.clean(cx))) Some(GenericParamDef::Lifetime(param.clean(cx)))
} else {
None
} }
ty::GenericParamDefKind::Type { .. } => None,
}).chain( }).chain(
simplify::ty_params(stripped_typarams) simplify::ty_params(stripped_typarams)
.into_iter() .into_iter()
@ -2870,8 +2867,20 @@ impl Clean<Type> for hir::Ty {
for param in generics.params.iter() { for param in generics.params.iter() {
match param.kind { match param.kind {
hir::GenericParamKind::Lifetime { .. } => { hir::GenericParamKind::Lifetime { .. } => {
if let Some(lt) = generic_args.lifetimes() let mut j = 0;
.nth(indices.lifetimes).cloned() { 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() { if !lt.is_elided() {
let lt_def_id = let lt_def_id =
cx.tcx.hir.local_def_id(param.id); cx.tcx.hir.local_def_id(param.id);
@ -2883,8 +2892,20 @@ impl Clean<Type> for hir::Ty {
hir::GenericParamKind::Type { ref default, .. } => { hir::GenericParamKind::Type { ref default, .. } => {
let ty_param_def = let ty_param_def =
Def::TyParam(cx.tcx.hir.local_def_id(param.id)); Def::TyParam(cx.tcx.hir.local_def_id(param.id));
if let Some(ty) = generic_args.types() let mut j = 0;
.nth(indices.types).cloned() { 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)); ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
} else if let Some(default) = default.clone() { } else if let Some(default) = default.clone() {
ty_substs.insert(ty_param_def, 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 } output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
} }
} else { } 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 { GenericArgs::AngleBracketed {
lifetimes: if self.lifetimes().all(|lt| lt.is_elided()) { lifetimes,
vec![] types,
} else {
self.lifetimes().map(|lt| lt.clean(cx)).collect()
},
types: self.types().map(|ty| ty.clean(cx)).collect(),
bindings: self.bindings.clean(cx), bindings: self.bindings.clean(cx),
} }
} }

View file

@ -18,6 +18,7 @@
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(fs_read_write)] #![feature(fs_read_write)]
#![feature(iterator_find_map)]
#![feature(set_stdio)] #![feature(set_stdio)]
#![feature(slice_sort_by_cached_key)] #![feature(slice_sort_by_cached_key)]
#![feature(test)] #![feature(test)]

View file

@ -549,8 +549,7 @@ impl<'a> TraitDef<'a> {
.to_generics(cx, self.span, type_ident, generics); .to_generics(cx, self.span, type_ident, generics);
// Create the generic parameters // Create the generic parameters
params.extend(generics.params.iter().map(|param| { params.extend(generics.params.iter().map(|param| match param.kind {
match param.kind {
GenericParamKindAST::Lifetime { .. } => param.clone(), GenericParamKindAST::Lifetime { .. } => param.clone(),
GenericParamKindAST::Type { bounds: ref ty_bounds, .. } => { GenericParamKindAST::Type { bounds: ref ty_bounds, .. } => {
// I don't think this can be moved out of the loop, since // I don't think this can be moved out of the loop, since
@ -573,7 +572,6 @@ impl<'a> TraitDef<'a> {
cx.typaram(self.span, param.ident, vec![], bounds, None) cx.typaram(self.span, param.ident, vec![], bounds, None)
} }
}
})); }));
// and similarly for where clauses // and similarly for where clauses