diff options
| author | Erick Tryzelaar <erick.tryzelaar@gmail.com> | 2013-02-28 07:25:31 -0800 |
|---|---|---|
| committer | Erick Tryzelaar <erick.tryzelaar@gmail.com> | 2013-02-28 07:25:31 -0800 |
| commit | 3953bdd812d73a51f9a7be4a1c57c60d56c6aa1a (patch) | |
| tree | 8dbdab63811771af7a14543a97636fc30ccc07f2 /src/libsyntax/parse/parser.rs | |
| parent | 7f5d4cbda027482cfeb554c5bc30551377a668a2 (diff) | |
| parent | d0a12347dec3045eaf8dcded7add914d4491276f (diff) | |
| download | rust-3953bdd812d73a51f9a7be4a1c57c60d56c6aa1a.tar.gz rust-3953bdd812d73a51f9a7be4a1c57c60d56c6aa1a.zip | |
Merge remote-tracking branch 'remotes/origin/incoming' into incoming
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 262 |
1 files changed, 117 insertions, 145 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3d4e0f9020b..69afa882765 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -51,7 +51,7 @@ use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok}; use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box}; use ast::{ty_field, ty_fixed_length_vec, ty_closure, ty_bare_fn}; use ast::{ty_infer, ty_mac, ty_method}; -use ast::{ty_nil, ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr}; +use ast::{ty_nil, TyParam, TyParamBound, ty_path, ty_ptr, ty_rec, ty_rptr}; use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, type_value_ns, uniq}; use ast::{unnamed_field, unsafe_blk, unsafe_fn, variant, view_item}; use ast::{view_item_, view_item_extern_mod, view_item_use}; @@ -84,6 +84,8 @@ use parse::token; use parse::{new_sub_parser_from_file, next_node_id, ParseSess}; use print::pprust::expr_to_str; use util::interner::Interner; +use opt_vec; +use opt_vec::OptVec; use core::cmp; use core::either::{Either, Left, Right}; @@ -458,7 +460,7 @@ pub impl Parser { // could change. let ident = p.parse_method_name(); - let tps = p.parse_ty_params(); + let generics = p.parse_generics(); let (self_ty, d) = do self.parse_fn_decl_with_self() |p| { // This is somewhat dubious; We don't want to allow argument @@ -483,7 +485,7 @@ pub impl Parser { attrs: attrs, purity: pur, decl: d, - tps: tps, + generics: generics, self_ty: self_ty, id: p.get_id(), span: mk_sp(lo, hi) @@ -497,7 +499,7 @@ pub impl Parser { provided(@ast::method { ident: ident, attrs: attrs, - tps: tps, + generics: generics, self_ty: self_ty, purity: pur, decl: d, @@ -958,19 +960,7 @@ pub impl Parser { }; // Parse any lifetime or type parameters which may appear: - let tps = { - if !self.eat(&token::LT) { - ~[] - } else { - // First consume lifetimes. - let _lifetimes = self.parse_lifetimes(); - let result = self.parse_seq_to_gt( - Some(token::COMMA), - |p| p.parse_ty(false)); - result - } - }; - + let tps = self.parse_generic_values(); let hi = self.span.lo; @ast::path { span: mk_sp(lo, hi), @@ -1016,7 +1006,7 @@ pub impl Parser { } } - fn parse_lifetimes() -> ~[ast::Lifetime] { + fn parse_lifetimes() -> OptVec<ast::Lifetime> { /*! * * Parses zero or more comma separated lifetimes. @@ -1025,7 +1015,7 @@ pub impl Parser { * lists, where we expect something like `<'a, 'b, T>`. */ - let mut res = ~[]; + let mut res = opt_vec::Empty; loop { match *self.token { token::LIFETIME(_) => { @@ -1201,7 +1191,7 @@ pub impl Parser { &token::RBRACKET, seq_sep_trailing_allowed(token::COMMA), |p| p.parse_expr() - ); + ).to_vec(); ex = expr_vec(~[first_expr] + remaining_exprs, mutbl); } else { // Vector with one element. @@ -1335,10 +1325,7 @@ pub impl Parser { self.bump(); let tys = if self.eat(&token::MOD_SEP) { self.expect(&token::LT); - self.parse_seq_to_gt( - Some(token::COMMA), - |p| p.parse_ty(false) - ) + self.parse_generic_values_after_lt() } else { ~[] }; @@ -1487,7 +1474,7 @@ pub impl Parser { &ket, seq_sep_none(), |p| p.parse_token_tree() - ), + ).to_vec(), // the close delimiter: ~[parse_any_tt_tok(&self)] ) @@ -2719,82 +2706,103 @@ pub impl Parser { if self.eat_keyword(&~"once") { ast::Once } else { ast::Many } } - fn parse_optional_ty_param_bounds() -> @~[ty_param_bound] { - let mut bounds = ~[]; - if self.eat(&token::COLON) { - loop { - if self.eat(&token::BINOP(token::AND)) { - if self.eat_keyword(&~"static") { - bounds.push(RegionTyParamBound); - } else { - self.span_err(*self.span, - ~"`&static` is the only permissible \ - region bound here"); - } - } else if is_ident(&*self.token) { - let maybe_bound = match *self.token { - token::IDENT(copy sid, _) => { - match *self.id_to_str(sid) { + fn parse_optional_ty_param_bounds() -> @OptVec<TyParamBound> { + if !self.eat(&token::COLON) { + return @opt_vec::Empty; + } - ~"send" - | ~"copy" - | ~"const" - | ~"owned" => { - self.obsolete(*self.span, - ObsoleteLowerCaseKindBounds); - // Bogus value, but doesn't matter, since - // is an error - Some(TraitTyParamBound(self.mk_ty_path(sid))) - } - - _ => None + let mut result = opt_vec::Empty; + loop { + if self.eat(&token::BINOP(token::AND)) { + if self.eat_keyword(&~"static") { + result.push(RegionTyParamBound); + } else { + self.span_err(*self.span, + ~"`&static` is the only permissible \ + region bound here"); + } + } else if is_ident(&*self.token) { + let maybe_bound = match *self.token { + token::IDENT(copy sid, _) => { + match *self.id_to_str(sid) { + ~"send" | + ~"copy" | + ~"const" | + ~"owned" => { + self.obsolete( + *self.span, + ObsoleteLowerCaseKindBounds); + + // Bogus value, but doesn't matter, since + // is an error + Some(TraitTyParamBound( + self.mk_ty_path(sid))) + } + _ => None } - } - _ => self.bug( - ~"is_ident() said this would be an identifier") - }; + } + _ => fail!() + }; - match maybe_bound { - Some(bound) => { - self.bump(); - bounds.push(bound); - } - None => { - let ty = self.parse_ty(false); - bounds.push(TraitTyParamBound(ty)); - } + match maybe_bound { + Some(bound) => { + self.bump(); + result.push(bound); + } + None => { + let ty = self.parse_ty(false); + result.push(TraitTyParamBound(ty)); } - } else { - break; } + } else { + break; + } - if self.eat(&token::BINOP(token::PLUS)) { - loop; - } + if self.eat(&token::BINOP(token::PLUS)) { + loop; + } - if is_ident_or_path(&*self.token) { - self.obsolete(*self.span, - ObsoleteTraitBoundSeparator); - } + if is_ident_or_path(&*self.token) { + self.obsolete(*self.span, + ObsoleteTraitBoundSeparator); } } - return @bounds; + + return @result; } - fn parse_ty_param() -> ty_param { + fn parse_ty_param() -> TyParam { let ident = self.parse_ident(); let bounds = self.parse_optional_ty_param_bounds(); - ast::ty_param { ident: ident, id: self.get_id(), bounds: bounds } + ast::TyParam { ident: ident, id: self.get_id(), bounds: bounds } } - fn parse_ty_params() -> ~[ty_param] { + fn parse_generics() -> ast::Generics { if self.eat(&token::LT) { - let _lifetimes = self.parse_lifetimes(); - self.parse_seq_to_gt( + let lifetimes = self.parse_lifetimes(); + let ty_params = self.parse_seq_to_gt( Some(token::COMMA), - |p| p.parse_ty_param() - ) - } else { ~[] } + |p| p.parse_ty_param()); + ast::Generics { lifetimes: lifetimes, ty_params: ty_params } + } else { + ast_util::empty_generics() + } + } + + fn parse_generic_values() -> ~[@Ty] { + if !self.eat(&token::LT) { + ~[] + } else { + self.parse_generic_values_after_lt() + } + } + + fn parse_generic_values_after_lt() -> ~[@Ty] { + let _lifetimes = self.parse_lifetimes(); + let result = self.parse_seq_to_gt( + Some(token::COMMA), + |p| p.parse_ty(false)); + result.to_vec() } fn parse_fn_decl(parse_arg_fn: fn(&Parser) -> arg_or_capture_item) @@ -2896,7 +2904,7 @@ pub impl Parser { &token::RPAREN, sep, parse_arg_fn - ); + ).to_vec(); } token::RPAREN => { args_or_capture_items = ~[]; @@ -2916,7 +2924,7 @@ pub impl Parser { &token::RPAREN, sep, parse_arg_fn - ); + ).to_vec(); } self.expect(&token::RPAREN); @@ -2961,10 +2969,10 @@ pub impl Parser { } } - fn parse_fn_header() -> (ident, ~[ty_param]) { + fn parse_fn_header() -> (ident, ast::Generics) { let id = self.parse_value_ident(); - let ty_params = self.parse_ty_params(); - (id, ty_params) + let generics = self.parse_generics(); + (id, generics) } fn mk_item(+lo: BytePos, +hi: BytePos, +ident: ident, @@ -2979,10 +2987,10 @@ pub impl Parser { } fn parse_item_fn(purity: purity) -> item_info { - let (ident, tps) = self.parse_fn_header(); + let (ident, generics) = self.parse_fn_header(); let decl = self.parse_fn_decl(|p| p.parse_arg()); let (inner_attrs, body) = self.parse_inner_attrs_and_block(true); - (ident, item_fn(decl, purity, tps, body), Some(inner_attrs)) + (ident, item_fn(decl, purity, generics, body), Some(inner_attrs)) } fn parse_method_name() -> ident { @@ -2999,7 +3007,7 @@ pub impl Parser { let visa = self.parse_visibility(); let pur = self.parse_fn_purity(); let ident = self.parse_method_name(); - let tps = self.parse_ty_params(); + let generics = self.parse_generics(); let (self_ty, decl) = do self.parse_fn_decl_with_self() |p| { p.parse_arg() }; @@ -3012,7 +3020,7 @@ pub impl Parser { @ast::method { ident: ident, attrs: attrs, - tps: tps, + generics: generics, self_ty: self_ty, purity: pur, decl: decl, @@ -3027,7 +3035,7 @@ pub impl Parser { fn parse_item_trait() -> item_info { let ident = self.parse_ident(); self.parse_region_param(); - let tps = self.parse_ty_params(); + let tps = self.parse_generics(); // Parse traits, if necessary. let traits; @@ -3055,12 +3063,7 @@ pub impl Parser { } // First, parse type parameters if necessary. - let mut tps; - if *self.token == token::LT { - tps = self.parse_ty_params(); - } else { - tps = ~[]; - } + let generics = self.parse_generics(); // This is a new-style impl declaration. // XXX: clownshoes @@ -3108,37 +3111,7 @@ pub impl Parser { } } - (ident, item_impl(tps, opt_trait, ty, meths), None) - } - - // Instantiates ident <i> with references to <typarams> as arguments. - // Used to create a path that refers to a class which will be defined as - // the return type of the ctor function. - fn ident_to_path_tys(i: ident, - typarams: ~[ty_param]) -> @path { - let s = *self.last_span; - - @ast::path { - span: s, - global: false, - idents: ~[i], - rp: None, - types: do typarams.map |tp| { - @Ty { - id: self.get_id(), - node: ty_path(ident_to_path(s, tp.ident), self.get_id()), - span: s - } - } - } - } - - fn ident_to_path(i: ident) -> @path { - @ast::path { span: *self.last_span, - global: false, - idents: ~[i], - rp: None, - types: ~[] } + (ident, item_impl(generics, opt_trait, ty, meths), None) } fn parse_trait_ref() -> @trait_ref { @@ -3153,13 +3126,13 @@ pub impl Parser { ket, seq_sep_none(), |p| p.parse_trait_ref() - ) + ).to_vec() } fn parse_item_struct() -> item_info { let class_name = self.parse_value_ident(); self.parse_region_param(); - let ty_params = self.parse_ty_params(); + let generics = self.parse_generics(); if self.eat(&token::COLON) { self.obsolete(copy *self.span, ObsoleteClassTraits); let _ = self.parse_trait_ref_list(&token::LBRACE); @@ -3242,7 +3215,7 @@ pub impl Parser { fields: fields, dtor: actual_dtor, ctor_id: if is_tuple_like { Some(new_id) } else { None } - }, ty_params), + }, generics), None) } @@ -3520,13 +3493,13 @@ pub impl Parser { let lo = self.span.lo; let vis = self.parse_visibility(); let purity = self.parse_fn_purity(); - let (ident, tps) = self.parse_fn_header(); + let (ident, generics) = self.parse_fn_header(); let decl = self.parse_fn_decl(|p| p.parse_arg()); let mut hi = self.span.hi; self.expect(&token::SEMI); @ast::foreign_item { ident: ident, attrs: attrs, - node: foreign_item_fn(decl, purity, tps), + node: foreign_item_fn(decl, purity, generics), id: self.get_id(), span: mk_sp(lo, hi), vis: vis } @@ -3696,7 +3669,7 @@ pub impl Parser { fn parse_item_type() -> item_info { let (_, ident) = self.parse_type_decl(); self.parse_region_param(); - let tps = self.parse_ty_params(); + let tps = self.parse_generics(); self.expect(&token::EQ); let ty = self.parse_ty(false); self.expect(&token::SEMI); @@ -3752,9 +3725,8 @@ pub impl Parser { }; } - fn parse_enum_def(ty_params: ~[ast::ty_param]) - -> enum_def { - let mut variants: ~[variant] = ~[]; + fn parse_enum_def(generics: &ast::Generics) -> enum_def { + let mut variants = ~[]; let mut all_nullary = true, have_disr = false; let mut common_fields = None; @@ -3780,7 +3752,7 @@ pub impl Parser { if self.eat_keyword(&~"enum") { ident = self.parse_ident(); self.expect(&token::LBRACE); - let nested_enum_def = self.parse_enum_def(ty_params); + let nested_enum_def = self.parse_enum_def(generics); kind = enum_variant_kind(nested_enum_def); needs_comma = false; } else { @@ -3838,7 +3810,7 @@ pub impl Parser { fn parse_item_enum() -> item_info { let id = self.parse_ident(); self.parse_region_param(); - let ty_params = self.parse_ty_params(); + let generics = self.parse_generics(); // Newtype syntax if *self.token == token::EQ { self.bump(); @@ -3861,14 +3833,14 @@ pub impl Parser { enum_def( ast::enum_def_ { variants: ~[variant], common: None } ), - ty_params), + generics), None ); } self.expect(&token::LBRACE); - let enum_definition = self.parse_enum_def(ty_params); - (id, item_enum(enum_definition, ty_params), None) + let enum_definition = self.parse_enum_def(&generics); + (id, item_enum(enum_definition, generics), None) } fn parse_fn_ty_sigil() -> Option<Sigil> { |
