diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2013-02-14 21:50:03 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2013-02-27 19:42:09 -0500 |
| commit | c623d21e388315df672951fcb8efb5000923ab3d (patch) | |
| tree | 8c7116e7df304166ccafcc30b21c19bf30788f75 /src/libsyntax/print | |
| parent | 061a2237230d3abcdb30ecb8987e5de17e67a58e (diff) | |
| download | rust-c623d21e388315df672951fcb8efb5000923ab3d.tar.gz rust-c623d21e388315df672951fcb8efb5000923ab3d.zip | |
Introduce lifetime declarations into the lists of type parameters.
Major changes are: - replace ~[ty_param] with Generics structure, which includes both OptVec<TyParam> and OptVec<Lifetime>; - the use of syntax::opt_vec to avoid allocation for empty lists; cc #4846
Diffstat (limited to 'src/libsyntax/print')
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 102 |
1 files changed, 63 insertions, 39 deletions
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d5a09e087a0..5eb40626437 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -14,6 +14,8 @@ use ast::{RegionTyParamBound, TraitTyParamBound, required, provided}; use ast; use ast_util; use ast_util::{operator_prec}; +use opt_vec; +use opt_vec::OptVec; use attr; use codemap::{CodeMap, BytePos}; use codemap; @@ -164,8 +166,9 @@ pub fn item_to_str(i: @ast::item, intr: @ident_interner) -> ~str { to_str(i, print_item, intr) } -pub fn typarams_to_str(tps: ~[ast::ty_param], intr: @ident_interner) -> ~str { - to_str(tps, print_type_params, intr) +pub fn generics_to_str(generics: &ast::Generics, + intr: @ident_interner) -> ~str { + to_str(generics, print_generics, intr) } pub fn path_to_str(&&p: @ast::path, intr: @ident_interner) -> ~str { @@ -173,10 +176,10 @@ pub fn path_to_str(&&p: @ast::path, intr: @ident_interner) -> ~str { } pub fn fun_to_str(decl: ast::fn_decl, name: ast::ident, - params: ~[ast::ty_param], intr: @ident_interner) -> ~str { + generics: &ast::Generics, intr: @ident_interner) -> ~str { do io::with_str_writer |wr| { let s = rust_printer(wr, intr); - print_fn(s, decl, None, name, params, None, ast::inherited); + print_fn(s, decl, None, name, generics, None, ast::inherited); end(s); // Close the head box end(s); // Close the outer box eof(s.s); @@ -300,7 +303,7 @@ pub fn synth_comment(s: @ps, text: ~str) { word(s.s, ~"*/"); } -pub fn commasep<IN>(s: @ps, b: breaks, elts: ~[IN], op: fn(@ps, IN)) { +pub fn commasep<IN>(s: @ps, b: breaks, elts: ~[IN], op: &fn(@ps, IN)) { box(s, 0u, b); let mut first = true; for elts.each |elt| { @@ -459,8 +462,8 @@ pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) { maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); match item.node { - ast::foreign_item_fn(decl, purity, typarams) => { - print_fn(s, decl, Some(purity), item.ident, typarams, None, + ast::foreign_item_fn(decl, purity, ref generics) => { + print_fn(s, decl, Some(purity), item.ident, generics, None, ast::inherited); end(s); // end head-ibox word(s.s, ~";"); @@ -505,7 +508,7 @@ pub fn print_item(s: @ps, &&item: @ast::item) { /* FIXME (#2543) */ copy *decl, Some(purity), item.ident, - /* FIXME (#2543) */ copy *typarams, + typarams, None, item.vis ); @@ -536,12 +539,12 @@ pub fn print_item(s: @ps, &&item: @ast::item) { print_foreign_mod(s, nmod, item.attrs); bclose(s, item.span); } - ast::item_ty(ty, params) => { + ast::item_ty(ty, ref params) => { ibox(s, indent_unit); ibox(s, 0u); word_nbsp(s, visibility_qualified(item.vis, ~"type")); print_ident(s, item.ident); - print_type_params(s, params); + print_generics(s, params); end(s); // end the inner ibox space(s.s); @@ -554,21 +557,21 @@ pub fn print_item(s: @ps, &&item: @ast::item) { print_enum_def( s, *enum_definition, - /* FIXME (#2543) */ copy *params, + params, item.ident, item.span, item.vis ); } - ast::item_struct(struct_def, tps) => { + ast::item_struct(struct_def, ref generics) => { head(s, visibility_qualified(item.vis, ~"struct")); - print_struct(s, struct_def, tps, item.ident, item.span); + print_struct(s, struct_def, generics, item.ident, item.span); } - ast::item_impl(tps, opt_trait, ty, methods) => { + ast::item_impl(ref generics, opt_trait, ty, methods) => { head(s, visibility_qualified(item.vis, ~"impl")); - if !tps.is_empty() { - print_type_params(s, tps); + if !generics.is_empty() { + print_generics(s, generics); space(s.s); } @@ -594,10 +597,10 @@ pub fn print_item(s: @ps, &&item: @ast::item) { bclose(s, item.span); } } - ast::item_trait(ref tps, ref traits, ref methods) => { + ast::item_trait(ref generics, ref traits, ref methods) => { head(s, visibility_qualified(item.vis, ~"trait")); print_ident(s, item.ident); - print_type_params(s, /* FIXME (#2543) */ copy *tps); + print_generics(s, generics); if traits.len() != 0u { word(s.s, ~":"); for traits.each |trait_| { @@ -629,7 +632,7 @@ pub fn print_item(s: @ps, &&item: @ast::item) { } pub fn print_enum_def(s: @ps, enum_definition: ast::enum_def, - params: ~[ast::ty_param], ident: ast::ident, + generics: &ast::Generics, ident: ast::ident, span: codemap::span, visibility: ast::visibility) { let mut newtype = vec::len(enum_definition.variants) == 1u && @@ -648,7 +651,7 @@ pub fn print_enum_def(s: @ps, enum_definition: ast::enum_def, } print_ident(s, ident); - print_type_params(s, params); + print_generics(s, generics); space(s.s); if newtype { word_space(s, ~"="); @@ -706,12 +709,12 @@ pub fn print_visibility(s: @ps, vis: ast::visibility) { pub fn print_struct(s: @ps, struct_def: @ast::struct_def, - tps: ~[ast::ty_param], + generics: &ast::Generics, ident: ast::ident, span: codemap::span) { print_ident(s, ident); nbsp(s); - print_type_params(s, tps); + print_generics(s, generics); if ast_util::struct_def_is_tuple_like(struct_def) { popen(s); let mut first = true; @@ -823,7 +826,8 @@ pub fn print_variant(s: @ps, v: ast::variant) { } ast::struct_variant_kind(struct_def) => { head(s, ~""); - print_struct(s, struct_def, ~[], v.node.name, v.span); + let generics = ast_util::empty_generics(); + print_struct(s, struct_def, &generics, v.node.name, v.span); } ast::enum_variant_kind(ref enum_definition) => { print_variants(s, (*enum_definition).variants, v.span); @@ -844,7 +848,7 @@ pub fn print_ty_method(s: @ps, m: ast::ty_method) { maybe_print_comment(s, m.span.lo); print_outer_attributes(s, m.attrs); print_ty_fn(s, None, None, None, m.purity, ast::Many, - m.decl, Some(m.ident), Some(m.tps), + m.decl, Some(m.ident), Some(&m.generics), Some(m.self_ty.node)); word(s.s, ~";"); } @@ -861,7 +865,7 @@ pub fn print_method(s: @ps, meth: @ast::method) { maybe_print_comment(s, meth.span.lo); print_outer_attributes(s, meth.attrs); print_fn(s, meth.decl, Some(meth.purity), - meth.ident, meth.tps, Some(meth.self_ty.node), + meth.ident, &meth.generics, Some(meth.self_ty.node), meth.vis); word(s.s, ~" "); print_block_with_attrs(s, meth.body, meth.attrs); @@ -1714,14 +1718,14 @@ pub fn print_fn(s: @ps, decl: ast::fn_decl, purity: Option<ast::purity>, name: ast::ident, - typarams: ~[ast::ty_param], + generics: &ast::Generics, opt_self_ty: Option<ast::self_ty_>, vis: ast::visibility) { head(s, ~""); print_fn_header_info(s, opt_self_ty, purity, ast::Many, None, vis); nbsp(s); print_ident(s, name); - print_type_params(s, typarams); + print_generics(s, generics); print_fn_args_and_ret(s, decl, opt_self_ty); } @@ -1791,11 +1795,11 @@ pub fn print_arg_mode(s: @ps, m: ast::mode) { if ms != ~"" { word(s.s, ms); } } -pub fn print_bounds(s: @ps, bounds: @~[ast::ty_param_bound]) { +pub fn print_bounds(s: @ps, bounds: @OptVec<ast::TyParamBound>) { if !bounds.is_empty() { word(s.s, ~":"); let mut first = true; - for vec::each(*bounds) |&bound| { + for bounds.each |bound| { nbsp(s); if first { first = false; @@ -1803,7 +1807,7 @@ pub fn print_bounds(s: @ps, bounds: @~[ast::ty_param_bound]) { word_space(s, ~"+"); } - match bound { + match *bound { TraitTyParamBound(ty) => print_type(s, ty), RegionTyParamBound => word(s.s, ~"&static"), } @@ -1811,14 +1815,33 @@ pub fn print_bounds(s: @ps, bounds: @~[ast::ty_param_bound]) { } } -pub fn print_type_params(s: @ps, &¶ms: ~[ast::ty_param]) { - if vec::len(params) > 0u { +pub fn print_lifetime(s: @ps, lifetime: &ast::Lifetime) { + word(s.s, ~"'"); + print_ident(s, lifetime.ident); +} + +pub fn print_generics(s: @ps, &&generics: &ast::Generics) { + let total = generics.lifetimes.len() + generics.ty_params.len(); + if total > 0 { word(s.s, ~"<"); - fn printParam(s: @ps, param: ast::ty_param) { - print_ident(s, param.ident); - print_bounds(s, param.bounds); + fn print_item(s: @ps, generics: &ast::Generics, idx: uint) { + if idx < generics.lifetimes.len() { + let lifetime = generics.lifetimes.get(idx); + print_lifetime(s, lifetime); + } else { + let param = generics.ty_params.get(idx); + print_ident(s, param.ident); + print_bounds(s, param.bounds); + } } - commasep(s, inconsistent, params, printParam); + + let mut ints = ~[]; + for uint::range(0, total) |i| { + ints.push(i); + } + + commasep(s, inconsistent, ints, + |s, i| print_item(s, generics, i)); word(s.s, ~">"); } } @@ -1954,7 +1977,7 @@ pub fn print_ty_fn(s: @ps, purity: ast::purity, onceness: ast::Onceness, decl: ast::fn_decl, id: Option<ast::ident>, - tps: Option<~[ast::ty_param]>, + generics: Option<&ast::Generics>, opt_self_ty: Option<ast::self_ty_>) { ibox(s, indent_unit); @@ -1968,7 +1991,7 @@ pub fn print_ty_fn(s: @ps, print_onceness(s, onceness); word(s.s, ~"fn"); match id { Some(id) => { word(s.s, ~" "); print_ident(s, id); } _ => () } - match tps { Some(tps) => print_type_params(s, tps), _ => () } + match generics { Some(g) => print_generics(s, g), _ => () } zerobreak(s.s); popen(s); @@ -2301,7 +2324,8 @@ pub mod test { span: codemap::dummy_sp()}, cf: ast::return_val }; - check_equal (&fun_to_str(decl, abba_ident, ~[],mock_interner), + let generics = ast_util::empty_generics(); + check_equal (&fun_to_str(decl, abba_ident, &generics, mock_interner), &~"fn abba()"); } |
