}
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);
}
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::<Vec<_>>()
+ generics.params.clone()
}
- _ => Vec::new(),
+ _ => HirVec::new(),
};
self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
// 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<Item = &'l GenericParamAST>,
- f: F,
- ) -> T
+ fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &Vec<GenericParamAST>, 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);
// 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<T, F>(&mut self, params: &[hir::GenericParam], f: F) -> T
- where
+ fn with_parent_impl_lifetime_defs<T, F>(&mut self,
+ params: &HirVec<hir::GenericParam>,
+ 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);
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| {
}
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)),
}
}
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,
}
}
+ fn lower_generic_params(
+ &mut self,
+ params: &Vec<GenericParamAST>,
+ add_bounds: &NodeMap<Vec<TyParamBound>>,
+ itctx: ImplTraitContext,
+ ) -> hir::HirVec<hir::GenericParam> {
+ params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect()
+ }
+
fn lower_generic_param(&mut self,
param: &GenericParamAST,
add_bounds: &NodeMap<Vec<TyParamBound>>,
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 {
synthetic: param.attrs.iter()
.filter(|attr| attr.check_name("rustc_synthetic"))
.map(|_| hir::SyntheticTyParamKind::ImplTrait)
- .nth(0),
+ .next(),
attrs: self.lower_attrs(¶m.attrs),
}
}
}
}
- fn lower_generic_params(
- &mut self,
- params: &Vec<GenericParamAST>,
- add_bounds: &NodeMap<Vec<TyParamBound>>,
- itctx: ImplTraitContext,
- ) -> hir::HirVec<hir::GenericParam> {
- params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect()
- }
-
fn lower_generics(
&mut self,
generics: &Generics,
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(
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::<Vec<_>>(),
+ &bound_generic_params,
|this| this.lower_trait_ref(&p.trait_ref, itctx),
);
);
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()
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);
}
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.
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)
}
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)
})?;
}
// 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()
} else {
sp
};
- (sp, has_lifetimes)
+ (sp, has_bounds)
})
} else {
None
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,
) -> (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,
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,
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,
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,
}
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::<Vec<_>>()
- );
+ check_mixed_explicit_and_in_band_defs(self.tcx, &generics.params);
for param in &generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
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();
}
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,
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);
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,
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);
.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
}
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) {
item: &'tcx hir::Item,
output: &mut Vec<MonoItem<'tcx>>) {
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 { .. } => {}
fn check_late_bound_lifetime_defs(&self, params: &Vec<GenericParamAST>) {
// 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");
}
}
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");
}
}
}
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()
}
}
}
- 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) {
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<Item=Debug>`
// are allowed to contain nested `impl Trait`.
}
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) => {
.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
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);
}
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);
}
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 {
// 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),
+ _ => {}
+ });
}
}
}
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) {
|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[..])
}
)
// 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),
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<T=Foo>'
- 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<T=Foo>`.
+ 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 => {}
}
}
}
}
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
-pub struct TyParam {
- pub name: String,
- pub did: DefId,
- pub bounds: Vec<TyParamBound>,
- pub default: Option<Type>,
- pub synthetic: Option<hir::SyntheticTyParamKind>,
-}
-
-impl Clean<TyParam> 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<TyParam> 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),
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,
+ });
}
}
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
-pub enum GenericParamDef {
- Lifetime(Lifetime),
- Type(TyParam),
+pub enum GenericParamDefKind {
+ Lifetime,
+ Type {
+ did: DefId,
+ bounds: Vec<TyParamBound>,
+ default: Option<Type>,
+ synthetic: Option<hir::SyntheticTyParamKind>,
+ },
+}
+
+#[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<GenericParamDef> 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<GenericParamDef> 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 { 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,
+ })
}
- hir::GenericParamKind::Type { .. } => GenericParamDef::Type(self.clean(cx)),
+ };
+
+ GenericParamDef {
+ name,
+ kind,
}
}
}
}
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::<Vec<_>>();
}
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
+ }
}
}
}
_ => continue,
}
}
- g
+ generics
}
}
}
Some(param.clean(cx))
}
- }).collect::<Vec<TyParam>>();
+ }).collect::<Vec<GenericParamDef>>();
let mut where_predicates = preds.predicates.to_vec().clean(cx);
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),
}
clauses
}
-pub fn ty_params(mut params: Vec<clean::TyParam>) -> Vec<clean::TyParam> {
+pub fn ty_params(mut params: Vec<clean::GenericParamDef>) -> Vec<clean::GenericParamDef> {
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
}
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 {
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(_) => {}
}
}
}