From f457b3d10aa2db4104402e2d04f72fab64a3c62e Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 27 May 2018 16:56:01 +0100 Subject: [PATCH] Refactor generic parameters in rustdoc/clean --- src/librustc/hir/intravisit.rs | 4 +- src/librustc/hir/lowering.rs | 101 ++++------- src/librustc/hir/map/def_collector.rs | 7 +- src/librustc/hir/map/mod.rs | 8 +- src/librustc/hir/print.rs | 12 +- src/librustc/infer/error_reporting/mod.rs | 14 +- src/librustc/middle/resolve_lifetime.rs | 117 +++++-------- src/librustc/util/ppaux.rs | 2 +- src/librustc_lint/types.rs | 3 +- src/librustc_metadata/encoder.rs | 19 +-- src/librustc_mir/monomorphize/collector.rs | 7 +- src/librustc_passes/ast_validation.rs | 43 +++-- src/librustc_privacy/lib.rs | 14 +- src/librustc_resolve/lib.rs | 15 +- src/librustc_save_analysis/dump_visitor.rs | 42 ++--- src/librustc_typeck/check/mod.rs | 10 +- src/librustdoc/clean/auto_trait.rs | 23 +-- src/librustdoc/clean/mod.rs | 189 +++++++++++---------- src/librustdoc/clean/simplify.rs | 9 +- src/librustdoc/html/format.rs | 16 +- src/librustdoc/html/render.rs | 8 +- 21 files changed, 296 insertions(+), 367 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 4c24c7afd73..51ce134544d 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -654,8 +654,8 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, } pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V, - _path_span: Span, - generic_args: &'v GenericArgs) { + _path_span: Span, + generic_args: &'v GenericArgs) { walk_list!(visitor, visit_generic_arg, &generic_args.args); walk_list!(visitor, visit_assoc_type_binding, &generic_args.bindings); } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 1c62e5813ff..c0f94a138af 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -382,17 +382,9 @@ impl<'a> LoweringContext<'a> { let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node { hir::Item_::ItemImpl(_, _, _, ref generics, ..) | hir::Item_::ItemTrait(_, _, ref generics, ..) => { - generics.params - .iter() - .filter_map(|param| match param.kind { - hir::GenericParamKind::Lifetime { .. } => { - Some(param.clone()) - } - _ => None, - }) - .collect::>() + generics.params.clone() } - _ => Vec::new(), + _ => HirVec::new(), }; self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| { @@ -766,16 +758,15 @@ impl<'a> LoweringContext<'a> { // This is used to track which lifetimes have already been defined, and // which are new in-band lifetimes that need to have a definition created // for them. - fn with_in_scope_lifetime_defs<'l, T, F>( - &mut self, - params: impl Iterator, - f: F, - ) -> T + fn with_in_scope_lifetime_defs(&mut self, params: &Vec, f: F) -> T where F: FnOnce(&mut LoweringContext) -> T, { let old_len = self.in_scope_lifetimes.len(); - let lt_def_names = params.map(|param| param.ident.name); + let lt_def_names = params.iter().filter_map(|param| match param.kind { + GenericParamKindAST::Lifetime { .. } => Some(param.ident.name), + _ => None, + }); self.in_scope_lifetimes.extend(lt_def_names); let res = f(self); @@ -789,12 +780,17 @@ impl<'a> LoweringContext<'a> { // This should only be used with generics that have already had their // in-band lifetimes added. In practice, this means that this function is // only used when lowering a child item of a trait or impl. - fn with_parent_impl_lifetime_defs(&mut self, params: &[hir::GenericParam], f: F) -> T - where + fn with_parent_impl_lifetime_defs(&mut self, + params: &HirVec, + f: F + ) -> T where F: FnOnce(&mut LoweringContext) -> T, { let old_len = self.in_scope_lifetimes.len(); - let lt_def_names = params.iter().map(|param| param.name()); + let lt_def_names = params.iter().filter_map(|param| match param.kind { + hir::GenericParamKind::Lifetime { .. } => Some(param.name()), + _ => None, + }); self.in_scope_lifetimes.extend(lt_def_names); let res = f(self); @@ -820,10 +816,7 @@ impl<'a> LoweringContext<'a> { F: FnOnce(&mut LoweringContext) -> T, { let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs( - generics.params.iter().filter_map(|param| match param.kind { - GenericParamKindAST::Lifetime { .. } => Some(param), - _ => None, - }), + &generics.params, |this| { let itctx = ImplTraitContext::Universal(parent_id); this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| { @@ -1051,16 +1044,12 @@ impl<'a> LoweringContext<'a> { } fn lower_generic_arg(&mut self, - p: &ast::GenericArgAST, + arg: &ast::GenericArgAST, itctx: ImplTraitContext) -> hir::GenericArg { - match p { - ast::GenericArgAST::Lifetime(lt) => { - GenericArg::Lifetime(self.lower_lifetime(<)) - } - ast::GenericArgAST::Type(ty) => { - GenericArg::Type(self.lower_ty(&ty, itctx)) - } + match arg { + ast::GenericArgAST::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), + ast::GenericArgAST::Type(ty) => GenericArg::Type(self.lower_ty(&ty, itctx)), } } @@ -1079,10 +1068,7 @@ impl<'a> LoweringContext<'a> { hir::TyRptr(lifetime, self.lower_mt(mt, itctx)) } TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs( - f.generic_params.iter().filter_map(|param| match param.kind { - GenericParamKindAST::Lifetime { .. } => Some(param), - _ => None, - }), + &f.generic_params, |this| { this.with_anonymous_lifetime_mode( AnonymousLifetimeMode::PassThrough, @@ -1946,6 +1932,15 @@ impl<'a> LoweringContext<'a> { } } + fn lower_generic_params( + &mut self, + params: &Vec, + add_bounds: &NodeMap>, + itctx: ImplTraitContext, + ) -> hir::HirVec { + params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect() + } + fn lower_generic_param(&mut self, param: &GenericParamAST, add_bounds: &NodeMap>, @@ -1986,10 +1981,9 @@ impl<'a> LoweringContext<'a> { let mut bounds = self.lower_bounds(bounds, itctx); let add_bounds = add_bounds.get(¶m.id).map_or(&[][..], |x| &x); if !add_bounds.is_empty() { - bounds = bounds - .into_iter() - .chain(self.lower_bounds(add_bounds, itctx).into_iter()) - .collect(); + bounds = bounds.into_iter() + .chain(self.lower_bounds(add_bounds, itctx).into_iter()) + .collect(); } hir::GenericParam { @@ -2005,7 +1999,7 @@ impl<'a> LoweringContext<'a> { synthetic: param.attrs.iter() .filter(|attr| attr.check_name("rustc_synthetic")) .map(|_| hir::SyntheticTyParamKind::ImplTrait) - .nth(0), + .next(), attrs: self.lower_attrs(¶m.attrs), } } @@ -2013,15 +2007,6 @@ impl<'a> LoweringContext<'a> { } } - fn lower_generic_params( - &mut self, - params: &Vec, - add_bounds: &NodeMap>, - itctx: ImplTraitContext, - ) -> hir::HirVec { - params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect() - } - fn lower_generics( &mut self, generics: &Generics, @@ -2107,10 +2092,7 @@ impl<'a> LoweringContext<'a> { span, }) => { self.with_in_scope_lifetime_defs( - bound_generic_params.iter().filter_map(|param| match param.kind { - GenericParamKindAST::Lifetime { .. } => Some(param), - _ => None, - }), + &bound_generic_params, |this| { hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { bound_generic_params: this.lower_generic_params( @@ -2203,13 +2185,7 @@ impl<'a> LoweringContext<'a> { let bound_generic_params = self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx); let trait_ref = self.with_parent_impl_lifetime_defs( - &bound_generic_params - .iter() - .filter_map(|param| match param.kind { - hir::GenericParamKind::Lifetime { .. } => Some(param.clone()), - _ => None, - }) - .collect::>(), + &bound_generic_params, |this| this.lower_trait_ref(&p.trait_ref, itctx), ); @@ -2426,10 +2402,7 @@ impl<'a> LoweringContext<'a> { ); let new_impl_items = self.with_in_scope_lifetime_defs( - ast_generics.params.iter().filter_map(|param| match param.kind { - GenericParamKindAST::Lifetime { .. } => Some(param), - _ => None, - }), + &ast_generics.params, |this| { impl_items .iter() diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 6555be110d1..ab4a0826584 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -176,12 +176,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { GenericParamKindAST::Lifetime { .. } => DefPathData::LifetimeParam(name), GenericParamKindAST::Type { .. } => DefPathData::TypeParam(name), }; - self.create_def( - param.id, - def_path_data, - REGULAR_SPACE, - param.ident.span - ); + self.create_def(param.id, def_path_data, REGULAR_SPACE, param.ident.span); visit::walk_generic_param(self, param); } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index c46f5813754..1f958d3fe95 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -974,11 +974,9 @@ impl<'hir> Map<'hir> { Some(NodeField(ref f)) => Some(&f.attrs[..]), Some(NodeExpr(ref e)) => Some(&*e.attrs), Some(NodeStmt(ref s)) => Some(s.node.attrs()), - Some(NodeGenericParam(param)) => { - match param.kind { - GenericParamKind::Type { ref attrs, .. } => Some(&attrs[..]), - _ => bug!("unexpected non-type NodeGenericParam") - } + Some(NodeGenericParam(param)) => match param.kind { + GenericParamKind::Type { ref attrs, .. } => Some(&attrs[..]), + _ => bug!("unexpected non-type NodeGenericParam") } // unit/tuple structs take the attributes straight from // the struct definition. diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index dc5d9749227..eabf554bc53 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1270,13 +1270,10 @@ impl<'a> State<'a> { self.print_name(segment.name)?; segment.with_generic_args(|generic_args| { - if !generic_args.args.is_empty() || - !generic_args.bindings.is_empty() - { - self.print_generic_args(&generic_args, segment.infer_types, true) - } else { - Ok(()) + if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() { + return self.print_generic_args(&generic_args, segment.infer_types, true); } + Ok(()) })?; self.print_call_post(base_args) } @@ -1642,8 +1639,7 @@ impl<'a> State<'a> { segment.name != keywords::DollarCrate.name() { self.print_name(segment.name)?; segment.with_generic_args(|generic_args| { - self.print_generic_args(generic_args, - segment.infer_types, + self.print_generic_args(generic_args, segment.infer_types, colons_before_params) })?; } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index af38e8ba2d4..b30e5bab968 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1036,21 +1036,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Get the `hir::TyParam` to verify whether it already has any bounds. // We do this to avoid suggesting code that ends up as `T: 'a'b`, // instead we suggest `T: 'a + 'b` in that case. - let has_lifetimes = - if let hir_map::NodeGenericParam(ref param) = hir.get(id) { + let mut has_bounds = false; + if let hir_map::NodeGenericParam(ref param) = hir.get(id) { match param.kind { GenericParamKind::Type { ref bounds, .. } => { - !bounds.is_empty() + has_bounds = !bounds.is_empty(); } _ => bug!("unexpected non-type NodeGenericParam"), } - } else { - false - }; + } let sp = hir.span(id); // `sp` only covers `T`, change it so that it covers // `T:` when appropriate - let sp = if has_lifetimes { + let sp = if has_bounds { sp.to(self.tcx .sess .codemap() @@ -1058,7 +1056,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } else { sp }; - (sp, has_lifetimes) + (sp, has_bounds) }) } else { None diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 358df3a1733..67a5448babf 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -81,6 +81,18 @@ pub enum Region { Free(DefId, /* lifetime decl */ DefId), } +fn new_region(hir_map: &Map, param: &hir::GenericParam) + -> (hir::LifetimeName, DefId, LifetimeDefOrigin) { + let def_id = hir_map.local_def_id(param.id); + let (name, origin) = match param.kind { + GenericParamKind::Lifetime { name, in_band, .. } => { + (name, LifetimeDefOrigin::from_is_in_band(in_band)) + } + _ => bug!("expected a lifetime param"), + }; + (name, def_id, origin) +} + impl Region { fn early( hir_map: &Map, @@ -89,26 +101,14 @@ impl Region { ) -> (hir::LifetimeName, Region) { let i = *index; *index += 1; - let def_id = hir_map.local_def_id(param.id); - let (name, origin) = match param.kind { - GenericParamKind::Lifetime { name, in_band, .. } => { - (name, LifetimeDefOrigin::from_is_in_band(in_band)) - } - _ => bug!("expected a lifetime param"), - }; + let (name, def_id, origin) = new_region(hir_map, param); debug!("Region::early: index={} def_id={:?}", i, def_id); (name, Region::EarlyBound(i, def_id, origin)) } fn late(hir_map: &Map, param: &hir::GenericParam) -> (hir::LifetimeName, Region) { let depth = ty::INNERMOST; - let def_id = hir_map.local_def_id(param.id); - let (name, origin) = match param.kind { - GenericParamKind::Lifetime { name, in_band, .. } => { - (name, LifetimeDefOrigin::from_is_in_band(in_band)) - } - _ => bug!("expected a lifetime param"), - }; + let (name, def_id, origin) = new_region(hir_map, param); debug!( "Region::late: def={:?} depth={:?} def_id={:?} origin={:?}", def, @@ -580,15 +580,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let was_in_fn_syntax = self.is_in_fn_syntax; self.is_in_fn_syntax = true; 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, - }) - .collect(), + lifetimes: c.generic_params.iter().filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => { + Some(Region::late(&self.tcx.hir, param)) + } + _ => None, + }).collect(), s: self.scope, next_early_index, track_lifetime_uses: true, @@ -770,19 +767,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let mut index = self.next_early_index(); debug!("visit_ty: index = {}", index); 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 - } - }) - .collect(); - + 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 { lifetimes, next_early_index: index + type_count, @@ -825,19 +818,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let mut index = self.next_early_index(); let mut next_early_index = index; 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 - } - }) - .collect(); - + 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 + } + }).collect(); let scope = Scope::Binder { lifetimes, next_early_index, @@ -888,13 +877,7 @@ 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, - }).collect::>() - ); + check_mixed_explicit_and_in_band_defs(self.tcx, &generics.params); for param in &generics.params { match param.kind { GenericParamKind::Lifetime { .. } => {} @@ -920,8 +903,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { Some(Region::late(&self.tcx.hir, param)) } _ => None, - }) - .collect(); + }).collect(); if !lifetimes.is_empty() { self.trait_ref_hack = true; let next_early_index = self.next_early_index(); @@ -992,16 +974,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } let next_early_index = self.next_early_index(); let scope = Scope::Binder { - lifetimes: trait_ref - .bound_generic_params - .iter() + lifetimes: trait_ref.bound_generic_params.iter() .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { Some(Region::late(&self.tcx.hir, param)) } _ => None, - }) - .collect(), + }).collect(), s: self.scope, next_early_index, track_lifetime_uses: true, @@ -1068,11 +1047,11 @@ impl ShadowKind { fn check_mixed_explicit_and_in_band_defs( tcx: TyCtxt<'_, '_, '_>, - params: &[hir::GenericParam], + params: &P<[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().filter_map(|param| match param.kind { + GenericParamKind::Lifetime { in_band, .. } => Some((in_band, param.span)), + _ => None, }).collect(); let out_of_band = in_bands.iter().find(|(in_band, _)| !in_band); let in_band = in_bands.iter().find(|(in_band, _)| *in_band); @@ -1707,9 +1686,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if elide_lifetimes { self.resolve_elided_lifetimes(lifetimes, true); } else { - for lt in lifetimes { - self.visit_lifetime(lt); - } + lifetimes.iter().for_each(|lt| self.visit_lifetime(lt)); } // Figure out if this is a type/trait segment, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index bd19a575c79..3252a2cd6ab 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -337,10 +337,10 @@ impl PrintContext { if !verbose { let mut type_params = generics.params.iter().rev().filter_map(|param| match param.kind { + GenericParamDefKind::Lifetime => None, 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); diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 2149e654281..2d96c01a6df 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -836,8 +836,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { .zip(variants) .map(|(variant, variant_layout)| { // Subtract the size of the enum discriminant. - let bytes = variant_layout.size.bytes() - .saturating_sub(discr_size); + let bytes = variant_layout.size.bytes().saturating_sub(discr_size); debug!("- variant `{}` is {} bytes large", variant.node.name, bytes); bytes diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index e105c9cd3c2..ed3dab09df9 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1648,18 +1648,15 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { } fn encode_info_for_generics(&mut self, generics: &hir::Generics) { - for param in &generics.params { - match param.kind { - hir::GenericParamKind::Lifetime { .. } => {} - hir::GenericParamKind::Type { ref default, .. } => { - let def_id = self.tcx.hir.local_def_id(param.id); - let has_default = Untracked(default.is_some()); - self.record(def_id, - IsolatedEncoder::encode_info_for_ty_param, - (def_id, has_default)); - } + generics.params.iter().for_each(|param| match param.kind { + hir::GenericParamKind::Lifetime { .. } => {} + hir::GenericParamKind::Type { ref default, .. } => { + let def_id = self.tcx.hir.local_def_id(param.id); + let has_default = Untracked(default.is_some()); + let encode_info = IsolatedEncoder::encode_info_for_ty_param; + self.record(def_id, encode_info, (def_id, has_default)); } - } + }); } fn encode_info_for_ty(&mut self, ty: &hir::Ty) { diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 9f5b9d405a1..ef69cb574e0 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1099,12 +1099,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &'tcx hir::Item, output: &mut Vec>) { match item.node { - hir::ItemImpl(_, - _, - _, - ref generics, - .., - ref impl_item_refs) => { + hir::ItemImpl(_, _, _, ref generics, .., ref impl_item_refs) => { for param in &generics.params { match param.kind { hir::GenericParamKind::Lifetime { .. } => {} diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index a6ef83671a5..d9a69f09d34 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -141,20 +141,19 @@ impl<'a> AstValidator<'a> { fn check_late_bound_lifetime_defs(&self, params: &Vec) { // Check only lifetime parameters are present and that the lifetime // parameters that are present have no bounds. - let non_lifetime_param_spans: Vec<_> = params.iter() - .filter_map(|param| match param.kind { + let non_lt_param_spans: Vec<_> = params.iter().filter_map(|param| match param.kind { GenericParamKindAST::Lifetime { ref bounds, .. } => { if !bounds.is_empty() { let spans: Vec<_> = bounds.iter().map(|b| b.ident.span).collect(); - self.err_handler().span_err(spans, - "lifetime bounds cannot be used in this context"); + self.err_handler() + .span_err(spans, "lifetime bounds cannot be used in this context"); } None } _ => Some(param.ident.span), }).collect(); - if !non_lifetime_param_spans.is_empty() { - self.err_handler().span_err(non_lifetime_param_spans, + if !non_lt_param_spans.is_empty() { + self.err_handler().span_err(non_lt_param_spans, "only lifetime parameters can be used in this context"); } } @@ -333,16 +332,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> { GenericParamKindAST::Lifetime { .. } => {} GenericParamKindAST::Type { ref bounds, ref default, .. } => { if !bounds.is_empty() { - self.err_handler().span_err(param.ident.span, - "type parameters on the left side \ - of a trait alias cannot be \ - bounded"); + self.err_handler() + .span_err(param.ident.span, "type parameters on the left \ + side of a trait alias cannot be bounded"); } if !default.is_none() { - self.err_handler().span_err(param.ident.span, - "type parameters on the left side \ - of a trait alias cannot have \ - defaults"); + self.err_handler() + .span_err(param.ident.span, "type parameters on the left \ + side of a trait alias cannot have defaults"); } } } @@ -402,10 +399,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_vis(self, vis) } - fn visit_generics(&mut self, g: &'a Generics) { + fn visit_generics(&mut self, generics: &'a Generics) { let mut seen_non_lifetime_param = false; let mut seen_default = None; - for param in &g.params { + for param in &generics.params { match (¶m.kind, seen_non_lifetime_param) { (GenericParamKindAST::Lifetime { .. }, true) => { self.err_handler() @@ -424,13 +421,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - for predicate in &g.where_clause.predicates { + for predicate in &generics.where_clause.predicates { if let WherePredicate::EqPredicate(ref predicate) = *predicate { self.err_handler().span_err(predicate.span, "equality constraints are not yet \ supported in where clauses (#20041)"); } } - visit::walk_generics(self, g) + visit::walk_generics(self, generics) } fn visit_generic_param(&mut self, param: &'a GenericParam) { @@ -516,12 +513,10 @@ impl<'a> Visitor<'a> for NestedImplTraitVisitor<'a> { fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) { match *generic_args { GenericArgs::AngleBracketed(ref data) => { - for arg in &data.args { - match arg { - GenericArgAST::Type(ty) => self.visit_ty(ty), - _ => {} - } - } + data.args.iter().for_each(|arg| match arg { + GenericArgAST::Type(ty) => self.visit_ty(ty), + _ => {} + }); for type_binding in &data.bindings { // Type bindings such as `Item=impl Debug` in `Iterator` // are allowed to contain nested `impl Trait`. diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 19ed04a7968..388ac5cdb50 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1268,16 +1268,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } fn visit_generics(&mut self, generics: &'tcx hir::Generics) { - for param in &generics.params { - match param.kind { - GenericParamKind::Lifetime { .. } => {} - GenericParamKind::Type { ref bounds, .. } => { - for bound in bounds { - self.check_ty_param_bound(bound); - } + generics.params.iter().for_each(|param| match param.kind { + GenericParamKind::Lifetime { .. } => {} + GenericParamKind::Type { ref bounds, .. } => { + for bound in bounds { + self.check_ty_param_bound(bound); } } - } + }); for predicate in &generics.where_clause.predicates { match predicate { &hir::WherePredicate::BoundPredicate(ref bound_pred) => { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 37264eb3382..314eae8f338 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -802,10 +802,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { .filter_map(|param| match param.kind { GenericParamKindAST::Lifetime { .. } => None, GenericParamKindAST::Type { ref default, .. } => { - if default.is_some() { + if found_default || default.is_some() { found_default = true; - } - if found_default { return Some((Ident::with_empty_ctxt(param.ident.name), Def::Err)); } None @@ -2209,8 +2207,7 @@ impl<'a> Resolver<'a> { HasTypeParameters(generics, rib_kind) => { let mut function_type_rib = Rib::new(rib_kind); let mut seen_bindings = FxHashMap(); - for param in &generics.params { - match param.kind { + generics.params.iter().for_each(|param| match param.kind { GenericParamKindAST::Type { .. } => { let ident = param.ident.modern(); debug!("with_type_parameter_rib: {}", param.id); @@ -2225,15 +2222,13 @@ impl<'a> Resolver<'a> { } seen_bindings.entry(ident).or_insert(param.ident.span); - // plain insert (no renaming) - let def_id = self.definitions.local_def_id(param.id); - let def = Def::TyParam(def_id); + // Plain insert (no renaming). + let def = Def::TyParam(self.definitions.local_def_id(param.id)); function_type_rib.bindings.insert(ident, def); self.record_def(param.id, PathResolution::new(def)); } _ => {} - } - } + }); self.ribs[TypeNS].push(function_type_rib); } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 5faa3559c76..ea5f452199a 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -826,12 +826,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { if let Some(ref generic_args) = seg.args { match **generic_args { ast::GenericArgs::AngleBracketed(ref data) => { - for arg in &data.args { - match arg { - ast::GenericArgAST::Type(ty) => self.visit_ty(ty), - _ => {} - } - } + data.args.iter().for_each(|arg| match arg { + ast::GenericArgAST::Type(ty) => self.visit_ty(ty), + _ => {} + }); } ast::GenericArgs::Parenthesized(ref data) => { for t in &data.inputs { @@ -915,12 +913,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // Explicit types in the turbo-fish. if let Some(ref generic_args) = seg.args { if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args { - for arg in &data.args { - match arg { - ast::GenericArgAST::Type(ty) => self.visit_ty(ty), - _ => {} - } - } + data.args.iter().for_each(|arg| match arg { + ast::GenericArgAST::Type(ty) => self.visit_ty(ty), + _ => {} + }); } } @@ -1489,21 +1485,19 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc } fn visit_generics(&mut self, generics: &'l ast::Generics) { - for param in &generics.params { - match param.kind { - ast::GenericParamKindAST::Lifetime { .. } => {} - ast::GenericParamKindAST::Type { ref bounds, ref default, .. } => { - for bound in bounds { - if let ast::TraitTyParamBound(ref trait_ref, _) = *bound { - self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path) - } - } - if let Some(ref ty) = default { - self.visit_ty(&ty); + generics.params.iter().for_each(|param| match param.kind { + ast::GenericParamKindAST::Lifetime { .. } => {} + ast::GenericParamKindAST::Type { ref bounds, ref default, .. } => { + for bound in bounds { + if let ast::TraitTyParamBound(ref trait_ref, _) = *bound { + self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path) } } + if let Some(ref ty) = default { + self.visit_ty(&ty); + } } - } + }); } fn visit_ty(&mut self, t: &'l ast::Ty) { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4b731d5b883..6ac9a0fdfc0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4979,12 +4979,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { |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), - } - } + data.args.iter().for_each(|arg| match arg { + GenericArg::Lifetime(lt) => lifetimes.push(lt), + GenericArg::Type(ty) => types.push(ty), + }); (lifetimes, types, s.infer_types, &data.bindings[..]) } ) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 4418c107223..2a63b124866 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -521,7 +521,10 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // We only care about late bound regions, as we need to add them // to the 'for<>' section &ty::ReLateBound(_, ty::BoundRegion::BrNamed(_, name)) => { - Some(GenericParamDef::Lifetime(Lifetime(name.to_string()))) + Some(GenericParamDef { + name: name.to_string(), + kind: GenericParamDefKind::Lifetime, + }) } &ty::ReVar(_) | &ty::ReEarlyBound(_) => None, _ => panic!("Unexpected region type {:?}", r), @@ -867,19 +870,17 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { existing_predicates.extend(final_bounds); - for p in generic_params.iter_mut() { - match p { - &mut GenericParamDef::Type(ref mut ty) => { - // We never want something like 'impl' - ty.default.take(); - - let generic_ty = Type::Generic(ty.name.clone()); - + for param in generic_params.iter_mut() { + match param.kind { + GenericParamDefKind::Type { ref mut default, ref mut bounds, .. } => { + // We never want something like `impl`. + default.take(); + let generic_ty = Type::Generic(param.name.clone()); if !has_sized.contains(&generic_ty) { - ty.bounds.insert(0, TyParamBound::maybe_sized(self.cx)); + bounds.insert(0, TyParamBound::maybe_sized(self.cx)); } } - GenericParamDef::Lifetime(_) => {} + GenericParamDefKind::Lifetime => {} } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a2ae7afbc83..3a4e582622f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1457,53 +1457,6 @@ impl Clean for [ast::Attribute] { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] -pub struct TyParam { - pub name: String, - pub did: DefId, - pub bounds: Vec, - pub default: Option, - pub synthetic: Option, -} - -impl Clean for hir::GenericParam { - fn clean(&self, cx: &DocContext) -> TyParam { - match self.kind { - hir::GenericParamKind::Type { ref bounds, ref default, synthetic, .. } => { - TyParam { - name: self.name().clean(cx), - did: cx.tcx.hir.local_def_id(self.id), - bounds: bounds.clean(cx), - default: default.clean(cx), - synthetic: synthetic, - } - } - _ => panic!(), - } - } -} - -impl<'tcx> Clean for ty::GenericParamDef { - fn clean(&self, cx: &DocContext) -> TyParam { - cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx)); - let has_default = match self.kind { - ty::GenericParamDefKind::Type { has_default, .. } => has_default, - _ => panic!("tried to convert a non-type GenericParamDef as a type") - }; - TyParam { - name: self.name.clean(cx), - did: self.def_id, - bounds: vec![], // these are filled in from the where-clauses - default: if has_default { - Some(cx.tcx.type_of(self.def_id).clean(cx)) - } else { - None - }, - synthetic: None, - } - } -} - #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] pub enum TyParamBound { RegionBound(Lifetime), @@ -1634,8 +1587,11 @@ impl<'a, 'tcx> Clean for (&'a ty::TraitRef<'tcx>, Vec if let ty::TyRef(ref reg, _, _) = ty_s.sty { if let &ty::RegionKind::ReLateBound(..) = *reg { debug!(" hit an ReLateBound {:?}", reg); - if let Some(lt) = reg.clean(cx) { - late_bounds.push(GenericParamDef::Lifetime(lt)); + if let Some(Lifetime(name)) = reg.clean(cx) { + late_bounds.push(GenericParamDef { + name, + kind: GenericParamDefKind::Lifetime, + }); } } } @@ -1872,27 +1828,90 @@ impl<'tcx> Clean for ty::ProjectionTy<'tcx> { } #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] -pub enum GenericParamDef { - Lifetime(Lifetime), - Type(TyParam), +pub enum GenericParamDefKind { + Lifetime, + Type { + did: DefId, + bounds: Vec, + default: Option, + synthetic: Option, + }, +} + +#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +pub struct GenericParamDef { + pub name: String, + + pub kind: GenericParamDefKind, } impl GenericParamDef { pub fn is_synthetic_type_param(&self) -> bool { - match self { - GenericParamDef::Type(ty) => ty.synthetic.is_some(), - GenericParamDef::Lifetime(_) => false, + match self.kind { + GenericParamDefKind::Lifetime => false, + GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(), + } + } +} + +impl<'tcx> Clean for ty::GenericParamDef { + fn clean(&self, cx: &DocContext) -> GenericParamDef { + let (name, kind) = match self.kind { + ty::GenericParamDefKind::Lifetime => { + (self.name.to_string(), GenericParamDefKind::Lifetime) + } + ty::GenericParamDefKind::Type { has_default, .. } => { + cx.renderinfo.borrow_mut().external_typarams + .insert(self.def_id, self.name.clean(cx)); + let default = if has_default { + Some(cx.tcx.type_of(self.def_id).clean(cx)) + } else { + None + }; + (self.name.clean(cx), GenericParamDefKind::Type { + did: self.def_id, + bounds: vec![], // These are filled in from the where-clauses. + default, + synthetic: None, + }) + } + }; + + GenericParamDef { + name, + kind, } } } impl Clean for hir::GenericParam { fn clean(&self, cx: &DocContext) -> GenericParamDef { - match self.kind { - hir::GenericParamKind::Lifetime { .. } => { - GenericParamDef::Lifetime(self.clean(cx)) + let (name, kind) = match self.kind { + hir::GenericParamKind::Lifetime { ref bounds, .. } => { + let name = if bounds.len() > 0 { + let mut s = format!("{}: {}", self.name(), bounds[0].name.name()); + for bound in bounds.iter().skip(1) { + s.push_str(&format!(" + {}", bound.name.name())); + } + s + } else { + self.name().to_string() + }; + (name, GenericParamDefKind::Lifetime) } - hir::GenericParamKind::Type { .. } => GenericParamDef::Type(self.clean(cx)), + hir::GenericParamKind::Type { ref bounds, ref default, synthetic, .. } => { + (self.name().clean(cx), GenericParamDefKind::Type { + did: cx.tcx.hir.local_def_id(self.id), + bounds: bounds.clean(cx), + default: default.clean(cx), + synthetic: synthetic, + }) + } + }; + + GenericParamDef { + name, + kind, } } } @@ -1919,17 +1938,16 @@ impl Clean for hir::Generics { } let impl_trait_params = self.params .iter() - .filter(|p| is_impl_trait(p)) - .map(|p| { - let p = p.clean(cx); - if let GenericParamDef::Type(ref tp) = p { - cx.impl_trait_bounds - .borrow_mut() - .insert(tp.did, tp.bounds.clone()); - } else { - unreachable!() + .filter(|param| is_impl_trait(param)) + .map(|param| { + let param: GenericParamDef = param.clean(cx); + match param.kind { + GenericParamDefKind::Lifetime => unreachable!(), + GenericParamDefKind::Type { did, ref bounds, .. } => { + cx.impl_trait_bounds.borrow_mut().insert(did, bounds.clone()); + } } - p + param }) .collect::>(); @@ -1940,23 +1958,26 @@ impl Clean for hir::Generics { } params.extend(impl_trait_params); - let mut g = Generics { + let mut generics = Generics { params, - where_predicates: self.where_clause.predicates.clean(cx) + where_predicates: self.where_clause.predicates.clean(cx), }; // Some duplicates are generated for ?Sized bounds between type params and where // predicates. The point in here is to move the bounds definitions from type params // to where predicates when such cases occur. - for where_pred in &mut g.where_predicates { + for where_pred in &mut generics.where_predicates { match *where_pred { WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => { if bounds.is_empty() { - for param in &mut g.params { - if let GenericParamDef::Type(ref mut type_param) = *param { - if &type_param.name == name { - mem::swap(bounds, &mut type_param.bounds); - break + for param in &mut generics.params { + match param.kind { + GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => { + if ¶m.name == name { + mem::swap(bounds, ty_bounds); + break + } } } } @@ -1965,7 +1986,7 @@ impl Clean for hir::Generics { _ => continue, } } - g + generics } } @@ -1988,7 +2009,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, } Some(param.clean(cx)) } - }).collect::>(); + }).collect::>(); let mut where_predicates = preds.predicates.to_vec().clean(cx); @@ -2033,15 +2054,9 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, params: gens.params .iter() .flat_map(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => { - Some(GenericParamDef::Lifetime(param.clean(cx))) - } + ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)), ty::GenericParamDefKind::Type { .. } => None, - }).chain( - simplify::ty_params(stripped_typarams) - .into_iter() - .map(|tp| GenericParamDef::Type(tp)) - ) + }).chain(simplify::ty_params(stripped_typarams).into_iter()) .collect(), where_predicates: simplify::where_clauses(cx, where_predicates), } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index ac1952a4bab..95ceee85690 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -135,9 +135,14 @@ pub fn where_clauses(cx: &DocContext, clauses: Vec) -> Vec { clauses } -pub fn ty_params(mut params: Vec) -> Vec { +pub fn ty_params(mut params: Vec) -> Vec { for param in &mut params { - param.bounds = ty_bounds(mem::replace(&mut param.bounds, Vec::new())); + match param.kind { + clean::GenericParamDefKind::Type { ref mut bounds, .. } => { + *bounds = ty_bounds(mem::replace(bounds, Vec::new())); + } + _ => panic!("expected only type parameters"), + } } params } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index d2d068e5209..86c312275ff 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -119,20 +119,20 @@ impl<'a> fmt::Display for TyParamBounds<'a> { impl fmt::Display for clean::GenericParamDef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - clean::GenericParamDef::Lifetime(ref lp) => write!(f, "{}", lp), - clean::GenericParamDef::Type(ref tp) => { - f.write_str(&tp.name)?; + match self.kind { + clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name), + clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => { + f.write_str(&self.name)?; - if !tp.bounds.is_empty() { + if !bounds.is_empty() { if f.alternate() { - write!(f, ": {:#}", TyParamBounds(&tp.bounds))?; + write!(f, ": {:#}", TyParamBounds(bounds))?; } else { - write!(f, ": {}", TyParamBounds(&tp.bounds))?; + write!(f, ": {}", TyParamBounds(bounds))?; } } - if let Some(ref ty) = tp.default { + if let Some(ref ty) = default { if f.alternate() { write!(f, " = {:#}", ty)?; } else { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5c2ec2058ee..675d1097bda 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1453,11 +1453,11 @@ impl DocFolder for Cache { impl<'a> Cache { fn generics(&mut self, generics: &clean::Generics) { for param in &generics.params { - match *param { - clean::GenericParamDef::Type(ref typ) => { - self.typarams.insert(typ.did, typ.name.clone()); + match param.kind { + clean::GenericParamDefKind::Lifetime => {} + clean::GenericParamDefKind::Type { did, .. } => { + self.typarams.insert(did, param.name.clone()); } - clean::GenericParamDef::Lifetime(_) => {} } } }