diff options
| author | Jonas Platte <jplatte+git@posteo.de> | 2017-10-16 21:07:26 +0200 |
|---|---|---|
| committer | Jonas Platte <jplatte+git@posteo.de> | 2017-12-21 13:38:10 +0100 |
| commit | 78493ed21aaeb20a8d5f7bd08f26c0c9fd496ed4 (patch) | |
| tree | 628b8d1cc99f88db6f47d5f07e1ff3d10b8adb3c /src/libsyntax | |
| parent | ab7abfcf3457ebc67ac7fef5c3028a6ae4402156 (diff) | |
| download | rust-78493ed21aaeb20a8d5f7bd08f26c0c9fd496ed4.tar.gz rust-78493ed21aaeb20a8d5f7bd08f26c0c9fd496ed4.zip | |
Add GenericParam, refactor Generics in ast, hir, rustdoc
The Generics now contain one Vec of an enum for the generic parameters, rather than two separate Vec's for lifetime and type parameters. Additionally, places that previously used Vec<LifetimeDef> now use Vec<GenericParam> instead.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 61 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 25 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 37 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 49 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 111 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/util/node_count.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 42 |
10 files changed, 184 insertions, 161 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 461cb0480d2..2c9ea44de5e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -302,30 +302,56 @@ pub struct TyParam { pub span: Span, } -/// Represents lifetimes and type parameters attached to a declaration -/// of a function, enum, trait, etc. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum GenericParam { + Lifetime(LifetimeDef), + Type(TyParam), +} + +impl GenericParam { + pub fn is_lifetime_param(&self) -> bool { + match *self { + GenericParam::Lifetime(_) => true, + _ => false, + } + } + + pub fn is_type_param(&self) -> bool { + match *self { + GenericParam::Type(_) => true, + _ => false, + } + } +} + +/// Represents lifetime, type and const parameters attached to a declaration of +/// a function, enum, trait, etc. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct Generics { - pub lifetimes: Vec<LifetimeDef>, - pub ty_params: Vec<TyParam>, + pub params: Vec<GenericParam>, pub where_clause: WhereClause, pub span: Span, } impl Generics { pub fn is_lt_parameterized(&self) -> bool { - !self.lifetimes.is_empty() + self.params.iter().any(|param| param.is_lifetime_param()) } + pub fn is_type_parameterized(&self) -> bool { - !self.ty_params.is_empty() + self.params.iter().any(|param| param.is_type_param()) } + pub fn is_parameterized(&self) -> bool { - self.is_lt_parameterized() || self.is_type_parameterized() + !self.params.is_empty() } + pub fn span_for_name(&self, name: &str) -> Option<Span> { - for t in &self.ty_params { - if t.ident.name == name { - return Some(t.span); + for param in &self.params { + if let GenericParam::Type(ref t) = *param { + if t.ident.name == name { + return Some(t.span); + } } } None @@ -336,8 +362,7 @@ impl Default for Generics { /// Creates an instance of `Generics`. fn default() -> Generics { Generics { - lifetimes: Vec::new(), - ty_params: Vec::new(), + params: Vec::new(), where_clause: WhereClause { id: DUMMY_NODE_ID, predicates: Vec::new(), @@ -373,8 +398,8 @@ pub enum WherePredicate { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct WhereBoundPredicate { pub span: Span, - /// Any lifetimes from a `for` binding - pub bound_lifetimes: Vec<LifetimeDef>, + /// Any generics from a `for` binding + pub bound_generic_params: Vec<GenericParam>, /// The type being bounded pub bounded_ty: P<Ty>, /// Trait and lifetime bounds (`Clone+Send+'static`) @@ -1492,7 +1517,7 @@ impl fmt::Debug for Ty { pub struct BareFnTy { pub unsafety: Unsafety, pub abi: Abi, - pub lifetimes: Vec<LifetimeDef>, + pub generic_params: Vec<GenericParam>, pub decl: P<FnDecl> } @@ -1851,7 +1876,7 @@ pub struct TraitRef { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct PolyTraitRef { /// The `'a` in `<'a> Foo<&'a T>` - pub bound_lifetimes: Vec<LifetimeDef>, + pub bound_generic_params: Vec<GenericParam>, /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` pub trait_ref: TraitRef, @@ -1860,9 +1885,9 @@ pub struct PolyTraitRef { } impl PolyTraitRef { - pub fn new(lifetimes: Vec<LifetimeDef>, path: Path, span: Span) -> Self { + pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self { PolyTraitRef { - bound_lifetimes: lifetimes, + bound_generic_params: generic_params, trait_ref: TraitRef { path: path, ref_id: DUMMY_NODE_ID }, span, } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 9a96432f11d..0b3272fc1db 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -462,7 +462,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { ast::PolyTraitRef { - bound_lifetimes: Vec::new(), + bound_generic_params: Vec::new(), trait_ref: self.trait_ref(path), span, } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 1f398ff155c..2d47382ac0f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1748,22 +1748,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_vis(self, vis); } - fn visit_generics(&mut self, g: &'a ast::Generics) { - for t in &g.ty_params { - if !t.attrs.is_empty() { - gate_feature_post!(&self, generic_param_attrs, t.attrs[0].span, - "attributes on type parameter bindings are experimental"); - } + fn visit_generic_param(&mut self, param: &'a ast::GenericParam) { + let (attrs, explain) = match *param { + ast::GenericParam::Lifetime(ref ld) => + (&ld.attrs, "attributes on lifetime bindings are experimental"), + ast::GenericParam::Type(ref t) => + (&t.attrs, "attributes on type parameter bindings are experimental"), + }; + + if !attrs.is_empty() { + gate_feature_post!(&self, generic_param_attrs, attrs[0].span, explain); } - visit::walk_generics(self, g) - } - fn visit_lifetime_def(&mut self, lifetime_def: &'a ast::LifetimeDef) { - if !lifetime_def.attrs.is_empty() { - gate_feature_post!(&self, generic_param_attrs, lifetime_def.attrs[0].span, - "attributes on lifetime bindings are experimental"); - } - visit::walk_lifetime_def(self, lifetime_def) + visit::walk_generic_param(self, param) } fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 6f973e2bcfa..d1aef0c5042 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -237,8 +237,12 @@ pub trait Folder : Sized { noop_fold_ty_param(tp, self) } - fn fold_ty_params(&mut self, tps: Vec<TyParam>) -> Vec<TyParam> { - noop_fold_ty_params(tps, self) + fn fold_generic_param(&mut self, param: GenericParam) -> GenericParam { + noop_fold_generic_param(param, self) + } + + fn fold_generic_params(&mut self, params: Vec<GenericParam>) -> Vec<GenericParam> { + noop_fold_generic_params(params, self) } fn fold_tt(&mut self, tt: TokenTree) -> TokenTree { @@ -363,8 +367,8 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { TyKind::Rptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt)) } TyKind::BareFn(f) => { - TyKind::BareFn(f.map(|BareFnTy {lifetimes, unsafety, abi, decl}| BareFnTy { - lifetimes: fld.fold_lifetime_defs(lifetimes), + TyKind::BareFn(f.map(|BareFnTy {generic_params, unsafety, abi, decl}| BareFnTy { + generic_params: fld.fold_generic_params(generic_params), unsafety, abi, decl: fld.fold_fn_decl(decl) @@ -677,8 +681,18 @@ pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam { } } -pub fn noop_fold_ty_params<T: Folder>(tps: Vec<TyParam>, fld: &mut T) -> Vec<TyParam> { - tps.move_map(|tp| fld.fold_ty_param(tp)) +pub fn noop_fold_generic_param<T: Folder>(param: GenericParam, fld: &mut T) -> GenericParam { + match param { + GenericParam::Lifetime(l) => GenericParam::Lifetime(fld.fold_lifetime_def(l)), + GenericParam::Type(t) => GenericParam::Type(fld.fold_ty_param(t)), + } +} + +pub fn noop_fold_generic_params<T: Folder>( + params: Vec<GenericParam>, + fld: &mut T +) -> Vec<GenericParam> { + params.move_map(|p| fld.fold_generic_param(p)) } pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime { @@ -716,11 +730,10 @@ pub fn noop_fold_opt_lifetime<T: Folder>(o_lt: Option<Lifetime>, fld: &mut T) o_lt.map(|lt| fld.fold_lifetime(lt)) } -pub fn noop_fold_generics<T: Folder>(Generics {ty_params, lifetimes, where_clause, span}: Generics, +pub fn noop_fold_generics<T: Folder>(Generics { params, where_clause, span }: Generics, fld: &mut T) -> Generics { Generics { - ty_params: fld.fold_ty_params(ty_params), - lifetimes: fld.fold_lifetime_defs(lifetimes), + params: fld.fold_generic_params(params), where_clause: fld.fold_where_clause(where_clause), span: fld.new_span(span), } @@ -744,12 +757,12 @@ pub fn noop_fold_where_predicate<T: Folder>( fld: &mut T) -> WherePredicate { match pred { - ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bound_lifetimes, + ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bound_generic_params, bounded_ty, bounds, span}) => { ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { - bound_lifetimes: fld.fold_lifetime_defs(bound_lifetimes), + bound_generic_params: fld.fold_generic_params(bound_generic_params), bounded_ty: fld.fold_ty(bounded_ty), bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)), span: fld.new_span(span) @@ -806,7 +819,7 @@ pub fn noop_fold_trait_ref<T: Folder>(p: TraitRef, fld: &mut T) -> TraitRef { pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef { ast::PolyTraitRef { - bound_lifetimes: fld.fold_lifetime_defs(p.bound_lifetimes), + bound_generic_params: fld.fold_generic_params(p.bound_generic_params), trait_ref: fld.fold_trait_ref(p.trait_ref), span: fld.new_span(p.span), } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 89a54989f96..17bccfc2d0f 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -905,9 +905,8 @@ mod tests { node: ast::Constness::NotConst, }, Abi::Rust, - ast::Generics{ // no idea on either of these: - lifetimes: Vec::new(), - ty_params: Vec::new(), + ast::Generics{ + params: Vec::new(), where_clause: ast::WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2aac7ef39f2..565e2191c00 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -21,6 +21,7 @@ use ast::EnumDef; use ast::{Expr, ExprKind, RangeLimits}; use ast::{Field, FnDecl}; use ast::{ForeignItem, ForeignItemKind, FunctionRetTy}; +use ast::GenericParam; use ast::{Ident, ImplItem, IsAuto, Item, ItemKind}; use ast::{Lifetime, LifetimeDef, Lit, LitKind, UintTy}; use ast::Local; @@ -1261,7 +1262,7 @@ impl<'a> Parser<'a> { } /// parse a TyKind::BareFn type: - pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec<LifetimeDef>) + pub fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a, TyKind> { /* @@ -1293,7 +1294,7 @@ impl<'a> Parser<'a> { Ok(TyKind::BareFn(P(BareFnTy { abi, unsafety, - lifetimes: lifetime_defs, + generic_params, decl, }))) } @@ -1582,9 +1583,9 @@ impl<'a> Parser<'a> { Ok(P(ty)) } - fn parse_remaining_bounds(&mut self, lifetime_defs: Vec<LifetimeDef>, path: ast::Path, + fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: ast::Path, lo: Span, parse_plus: bool) -> PResult<'a, TyKind> { - let poly_trait_ref = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span)); + let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span)); let mut bounds = vec![TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)]; if parse_plus { self.bump(); // `+` @@ -4550,9 +4551,8 @@ impl<'a> Parser<'a> { /// Parses (possibly empty) list of lifetime and type parameters, possibly including /// trailing comma and erroneous trailing attributes. - pub fn parse_generic_params(&mut self) -> PResult<'a, (Vec<LifetimeDef>, Vec<TyParam>)> { - let mut lifetime_defs = Vec::new(); - let mut ty_params = Vec::new(); + pub fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> { + let mut params = Vec::new(); let mut seen_ty_param = false; loop { let attrs = self.parse_outer_attributes()?; @@ -4564,18 +4564,18 @@ impl<'a> Parser<'a> { } else { Vec::new() }; - lifetime_defs.push(LifetimeDef { + params.push(ast::GenericParam::Lifetime(LifetimeDef { attrs: attrs.into(), lifetime, bounds, - }); + })); if seen_ty_param { self.span_err(self.prev_span, "lifetime parameters must be declared prior to type parameters"); } } else if self.check_ident() { // Parse type parameter. - ty_params.push(self.parse_ty_param(attrs)?); + params.push(ast::GenericParam::Type(self.parse_ty_param(attrs)?)); seen_ty_param = true; } else { // Check for trailing attributes and stop parsing. @@ -4591,7 +4591,7 @@ impl<'a> Parser<'a> { break } } - Ok((lifetime_defs, ty_params)) + Ok(params) } /// Parse a set of optional generic type parameter declarations. Where @@ -4606,11 +4606,10 @@ impl<'a> Parser<'a> { let span_lo = self.span; if self.eat_lt() { - let (lifetime_defs, ty_params) = self.parse_generic_params()?; + let params = self.parse_generic_params()?; self.expect_gt()?; Ok(ast::Generics { - lifetimes: lifetime_defs, - ty_params, + params, where_clause: WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), @@ -4738,7 +4737,7 @@ impl<'a> Parser<'a> { where_clause.predicates.push(ast::WherePredicate::BoundPredicate( ast::WhereBoundPredicate { span: lo.to(self.prev_span), - bound_lifetimes: lifetime_defs, + bound_generic_params: lifetime_defs, bounded_ty: ty, bounds, } @@ -5363,16 +5362,24 @@ impl<'a> Parser<'a> { } } - fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<LifetimeDef>> { + fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> { if self.eat_keyword(keywords::For) { self.expect_lt()?; - let (lifetime_defs, ty_params) = self.parse_generic_params()?; + let params = self.parse_generic_params()?; self.expect_gt()?; - if !ty_params.is_empty() { - self.span_err(ty_params[0].span, - "only lifetime parameters can be used in this context"); + + let first_non_lifetime_param_span = params.iter() + .filter_map(|param| match *param { + ast::GenericParam::Lifetime(_) => None, + ast::GenericParam::Type(ref t) => Some(t.span), + }) + .next(); + + if let Some(span) = first_non_lifetime_param_span { + self.span_err(span, "only lifetime parameters can be used in this context"); } - Ok(lifetime_defs) + + Ok(params) } else { Ok(Vec::new()) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index da4d5f5f676..8f619e8af76 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -275,7 +275,7 @@ pub fn token_to_string(tok: &Token) -> String { token::NtArm(ref e) => arm_to_string(e), token::NtImplItem(ref e) => impl_item_to_string(e), token::NtTraitItem(ref e) => trait_item_to_string(e), - token::NtGenerics(ref e) => generics_to_string(e), + token::NtGenerics(ref e) => generic_params_to_string(&e.params), token::NtWhereClause(ref e) => where_clause_to_string(e), token::NtArg(ref e) => arg_to_string(e), token::NtVis(ref e) => vis_to_string(e), @@ -339,8 +339,8 @@ pub fn trait_item_to_string(i: &ast::TraitItem) -> String { to_string(|s| s.print_trait_item(i)) } -pub fn generics_to_string(generics: &ast::Generics) -> String { - to_string(|s| s.print_generics(generics)) +pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String { + to_string(|s| s.print_generic_params(generic_params)) } pub fn where_clause_to_string(i: &ast::WhereClause) -> String { @@ -1043,21 +1043,11 @@ impl<'a> State<'a> { self.pclose()?; } ast::TyKind::BareFn(ref f) => { - let generics = ast::Generics { - lifetimes: f.lifetimes.clone(), - ty_params: Vec::new(), - where_clause: ast::WhereClause { - id: ast::DUMMY_NODE_ID, - predicates: Vec::new(), - span: syntax_pos::DUMMY_SP, - }, - span: syntax_pos::DUMMY_SP, - }; self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, - &generics)?; + &f.generic_params)?; } ast::TyKind::Path(None, ref path) => { self.print_path(path, false, 0, false)?; @@ -1271,15 +1261,15 @@ impl<'a> State<'a> { self.s.word(&ga.asm.as_str())?; self.end()?; } - ast::ItemKind::Ty(ref ty, ref params) => { + ast::ItemKind::Ty(ref ty, ref generics) => { self.ibox(INDENT_UNIT)?; self.ibox(0)?; self.word_nbsp(&visibility_qualified(&item.vis, "type"))?; self.print_ident(item.ident)?; - self.print_generics(params)?; + self.print_generic_params(&generics.params)?; self.end()?; // end the inner ibox - self.print_where_clause(¶ms.where_clause)?; + self.print_where_clause(&generics.where_clause)?; self.s.space()?; self.word_space("=")?; self.print_type(ty)?; @@ -1329,7 +1319,7 @@ impl<'a> State<'a> { self.word_nbsp("impl")?; if generics.is_parameterized() { - self.print_generics(generics)?; + self.print_generic_params(&generics.params)?; self.s.space()?; } @@ -1361,7 +1351,7 @@ impl<'a> State<'a> { self.print_is_auto(is_auto)?; self.word_nbsp("trait")?; self.print_ident(item.ident)?; - self.print_generics(generics)?; + self.print_generic_params(&generics.params)?; let mut real_bounds = Vec::with_capacity(bounds.len()); for b in bounds.iter() { if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b { @@ -1386,7 +1376,7 @@ impl<'a> State<'a> { self.print_visibility(&item.vis)?; self.word_nbsp("trait")?; self.print_ident(item.ident)?; - self.print_generics(generics)?; + self.print_generic_params(&generics.params)?; let mut real_bounds = Vec::with_capacity(bounds.len()); // FIXME(durka) this seems to be some quite outdated syntax for b in bounds.iter() { @@ -1432,26 +1422,20 @@ impl<'a> State<'a> { self.print_path(&t.path, false, 0, false) } - fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> { - if !lifetimes.is_empty() { - self.s.word("for<")?; - let mut comma = false; - for lifetime_def in lifetimes { - if comma { - self.word_space(",")? - } - self.print_outer_attributes_inline(&lifetime_def.attrs)?; - self.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)?; - comma = true; - } - self.s.word(">")?; + fn print_formal_generic_params( + &mut self, + generic_params: &[ast::GenericParam] + ) -> io::Result<()> { + if !generic_params.is_empty() { + self.s.word("for")?; + self.print_generic_params(generic_params)?; self.nbsp()?; } Ok(()) } fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> { - self.print_formal_lifetime_list(&t.bound_lifetimes)?; + self.print_formal_generic_params(&t.bound_generic_params)?; self.print_trait_ref(&t.trait_ref) } @@ -1461,7 +1445,7 @@ impl<'a> State<'a> { visibility: &ast::Visibility) -> io::Result<()> { self.head(&visibility_qualified(visibility, "enum"))?; self.print_ident(ident)?; - self.print_generics(generics)?; + self.print_generic_params(&generics.params)?; self.print_where_clause(&generics.where_clause)?; self.s.space()?; self.print_variants(&enum_definition.variants, span) @@ -1517,7 +1501,7 @@ impl<'a> State<'a> { span: syntax_pos::Span, print_finalizer: bool) -> io::Result<()> { self.print_ident(ident)?; - self.print_generics(generics)?; + self.print_generic_params(&generics.params)?; if !struct_def.is_struct() { if struct_def.is_tuple() { self.popen()?; @@ -2764,7 +2748,7 @@ impl<'a> State<'a> { self.nbsp()?; self.print_ident(name)?; } - self.print_generics(generics)?; + self.print_generic_params(&generics.params)?; self.print_fn_args_and_ret(decl)?; self.print_where_clause(&generics.where_clause) } @@ -2870,31 +2854,23 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_generics(&mut self, - generics: &ast::Generics) - -> io::Result<()> - { - let total = generics.lifetimes.len() + generics.ty_params.len(); - if total == 0 { + pub fn print_generic_params( + &mut self, + generic_params: &[ast::GenericParam] + ) -> io::Result<()> { + if generic_params.is_empty() { return Ok(()); } self.s.word("<")?; - let mut ints = Vec::new(); - for i in 0..total { - ints.push(i); - } - - self.commasep(Inconsistent, &ints[..], |s, &idx| { - if idx < generics.lifetimes.len() { - let lifetime_def = &generics.lifetimes[idx]; - s.print_outer_attributes_inline(&lifetime_def.attrs)?; - s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds) - } else { - let idx = idx - generics.lifetimes.len(); - let param = &generics.ty_params[idx]; - s.print_ty_param(param) + self.commasep(Inconsistent, &generic_params, |s, param| { + match *param { + ast::GenericParam::Lifetime(ref lifetime_def) => { + s.print_outer_attributes_inline(&lifetime_def.attrs)?; + s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds) + }, + ast::GenericParam::Type(ref ty_param) => s.print_ty_param(ty_param), } })?; @@ -2931,11 +2907,13 @@ impl<'a> State<'a> { } match *predicate { - ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bound_lifetimes, - ref bounded_ty, - ref bounds, - ..}) => { - self.print_formal_lifetime_list(bound_lifetimes)?; + ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { + ref bound_generic_params, + ref bounded_ty, + ref bounds, + .. + }) => { + self.print_formal_generic_params(bound_generic_params)?; self.print_type(bounded_ty)?; self.print_bounds(":", bounds)?; } @@ -3057,16 +3035,15 @@ impl<'a> State<'a> { unsafety: ast::Unsafety, decl: &ast::FnDecl, name: Option<ast::Ident>, - generics: &ast::Generics) + generic_params: &Vec<ast::GenericParam>) -> io::Result<()> { self.ibox(INDENT_UNIT)?; - if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() { + if !generic_params.is_empty() { self.s.word("for")?; - self.print_generics(generics)?; + self.print_generic_params(generic_params)?; } let generics = ast::Generics { - lifetimes: Vec::new(), - ty_params: Vec::new(), + params: Vec::new(), where_clause: ast::WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 694a9c1f472..1a0f4e9278d 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -363,7 +363,10 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true, _ => false }; - let tparm_cnt = generics.ty_params.len(); + let tparm_cnt = generics.params.iter() + .filter(|param| param.is_type_param()) + .count(); + // NB: inadequate check, but we're running // well before resolve, can't get too deep. input_cnt == 1 diff --git a/src/libsyntax/util/node_count.rs b/src/libsyntax/util/node_count.rs index ac5642e53cf..da238be85e0 100644 --- a/src/libsyntax/util/node_count.rs +++ b/src/libsyntax/util/node_count.rs @@ -71,6 +71,10 @@ impl<'ast> Visitor<'ast> for NodeCounter { self.count += 1; walk_ty(self, t) } + fn visit_generic_param(&mut self, param: &GenericParam) { + self.count += 1; + walk_generic_param(self, param) + } fn visit_generics(&mut self, g: &Generics) { self.count += 1; walk_generics(self, g) @@ -121,10 +125,6 @@ impl<'ast> Visitor<'ast> for NodeCounter { self.count += 1; walk_lifetime(self, lifetime) } - fn visit_lifetime_def(&mut self, lifetime: &LifetimeDef) { - self.count += 1; - walk_lifetime_def(self, lifetime) - } fn visit_mac(&mut self, _mac: &Mac) { self.count += 1; walk_mac(self, _mac) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 9266cc28097..bd68d7cf8f5 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -72,6 +72,7 @@ pub trait Visitor<'ast>: Sized { fn visit_expr(&mut self, ex: &'ast Expr) { walk_expr(self, ex) } fn visit_expr_post(&mut self, _ex: &'ast Expr) { } fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) } + fn visit_generic_param(&mut self, param: &'ast GenericParam) { walk_generic_param(self, param) } fn visit_generics(&mut self, g: &'ast Generics) { walk_generics(self, g) } fn visit_where_predicate(&mut self, p: &'ast WherePredicate) { walk_where_predicate(self, p) @@ -103,9 +104,6 @@ pub trait Visitor<'ast>: Sized { fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { walk_lifetime(self, lifetime) } - fn visit_lifetime_def(&mut self, lifetime: &'ast LifetimeDef) { - walk_lifetime_def(self, lifetime) - } fn visit_mac(&mut self, _mac: &'ast Mac) { panic!("visit_mac disabled by default"); // NB: see note about macros above. @@ -210,18 +208,12 @@ pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime visitor.visit_ident(lifetime.span, lifetime.ident); } -pub fn walk_lifetime_def<'a, V: Visitor<'a>>(visitor: &mut V, lifetime_def: &'a LifetimeDef) { - visitor.visit_lifetime(&lifetime_def.lifetime); - walk_list!(visitor, visit_lifetime, &lifetime_def.bounds); - walk_list!(visitor, visit_attribute, &*lifetime_def.attrs); -} - pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef, _: &TraitBoundModifier) where V: Visitor<'a>, { - walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes); + walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params); visitor.visit_trait_ref(&trait_ref.trait_ref); } @@ -339,7 +331,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { } TyKind::BareFn(ref function_declaration) => { walk_fn_decl(visitor, &function_declaration.decl); - walk_list!(visitor, visit_lifetime_def, &function_declaration.lifetimes); + walk_list!(visitor, visit_generic_param, &function_declaration.generic_params); } TyKind::Path(ref maybe_qself, ref path) => { if let Some(ref qself) = *maybe_qself { @@ -499,14 +491,24 @@ pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyPar } } -pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) { - for param in &generics.ty_params { - visitor.visit_ident(param.span, param.ident); - walk_list!(visitor, visit_ty_param_bound, ¶m.bounds); - walk_list!(visitor, visit_ty, ¶m.default); - walk_list!(visitor, visit_attribute, &*param.attrs); +pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a GenericParam) { + match *param { + GenericParam::Lifetime(ref l) => { + visitor.visit_lifetime(&l.lifetime); + walk_list!(visitor, visit_lifetime, &l.bounds); + walk_list!(visitor, visit_attribute, &*l.attrs); + } + GenericParam::Type(ref t) => { + visitor.visit_ident(t.span, t.ident); + walk_list!(visitor, visit_ty_param_bound, &t.bounds); + walk_list!(visitor, visit_ty, &t.default); + walk_list!(visitor, visit_attribute, &*t.attrs); + } } - walk_list!(visitor, visit_lifetime_def, &generics.lifetimes); +} + +pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) { + walk_list!(visitor, visit_generic_param, &generics.params); walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates); } @@ -514,11 +516,11 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a match *predicate { WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty, ref bounds, - ref bound_lifetimes, + ref bound_generic_params, ..}) => { visitor.visit_ty(bounded_ty); walk_list!(visitor, visit_ty_param_bound, bounds); - walk_list!(visitor, visit_lifetime_def, bound_lifetimes); + walk_list!(visitor, visit_generic_param, bound_generic_params); } WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime, ref bounds, |
