diff options
| author | bors <bors@rust-lang.org> | 2014-09-20 03:11:12 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-09-20 03:11:12 +0000 |
| commit | aef6c4b1382dcf2f943bd5872656625f935c0b7c (patch) | |
| tree | 95920a7c62cbc07301ec8fe4b189b33e208327cd /src/libsyntax/parse | |
| parent | 3b6e880fffb8e09b15bc6fc41d5b23f21bf5056d (diff) | |
| parent | f082416bece7cbb16ec46f870fb7f91ca15f2231 (diff) | |
| download | rust-aef6c4b1382dcf2f943bd5872656625f935c0b7c.tar.gz rust-aef6c4b1382dcf2f943bd5872656625f935c0b7c.zip | |
auto merge of #17399 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 183 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 83 |
4 files changed, 177 insertions, 99 deletions
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index da43f08a4e5..68ddd17dd01 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1406,7 +1406,7 @@ fn ident_continue(c: Option<char>) -> bool { mod test { use super::*; - use codemap::{BytePos, CodeMap, Span}; + use codemap::{BytePos, CodeMap, Span, NO_EXPANSION}; use diagnostic; use parse::token; use parse::token::{str_to_ident}; @@ -1436,7 +1436,7 @@ mod test { let tok1 = string_reader.next_token(); let tok2 = TokenAndSpan{ tok:token::IDENT(id, false), - sp:Span {lo:BytePos(21),hi:BytePos(23),expn_info: None}}; + sp:Span {lo:BytePos(21),hi:BytePos(23),expn_id: NO_EXPANSION}}; assert_eq!(tok1,tok2); assert_eq!(string_reader.next_token().tok, token::WS); // the 'main' id is already read: @@ -1445,7 +1445,7 @@ mod test { let tok3 = string_reader.next_token(); let tok4 = TokenAndSpan{ tok:token::IDENT(str_to_ident("main"), false), - sp:Span {lo:BytePos(24),hi:BytePos(28),expn_info: None}}; + sp:Span {lo:BytePos(24),hi:BytePos(28),expn_id: NO_EXPANSION}}; assert_eq!(tok3,tok4); // the lparen is already read: assert_eq!(string_reader.last_pos.clone(), BytePos(29)) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index d73cb211694..66ecdbfca02 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -721,7 +721,7 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ { mod test { use super::*; use serialize::json; - use codemap::{Span, BytePos, Spanned}; + use codemap::{Span, BytePos, Spanned, NO_EXPANSION}; use owned_slice::OwnedSlice; use ast; use abi; @@ -736,7 +736,7 @@ mod test { // produce a codemap::span fn sp(a: u32, b: u32) -> Span { - Span{lo:BytePos(a),hi:BytePos(b),expn_info:None} + Span {lo: BytePos(a), hi: BytePos(b), expn_id: NO_EXPANSION} } #[test] fn path_exprs_1() { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ff4fd41fbd7..069d30cbd83 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -23,7 +23,7 @@ use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, Explicit use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain}; use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; use ast::{ExprBreak, ExprCall, ExprCast}; -use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex}; +use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex, ExprSlice}; use ast::{ExprLit, ExprLoop, ExprMac}; use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn}; @@ -55,7 +55,8 @@ use ast::{TyTypeof, TyInfer, TypeMethod}; use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyQPath}; use ast::{TyRptr, TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq}; use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind}; -use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock}; +use ast::{UnboxedFnBound, UnboxedFnTy, UnboxedFnTyParamBound}; +use ast::{UnnamedField, UnsafeBlock}; use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause, WherePredicate}; @@ -1986,6 +1987,14 @@ impl<'a> Parser<'a> { ExprIndex(expr, idx) } + pub fn mk_slice(&mut self, expr: P<Expr>, + start: Option<P<Expr>>, + end: Option<P<Expr>>, + mutbl: Mutability) + -> ast::Expr_ { + ExprSlice(expr, start, end, mutbl) + } + pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent, tys: Vec<P<Ty>>) -> ast::Expr_ { ExprField(expr, ident, tys) @@ -2400,13 +2409,87 @@ impl<'a> Parser<'a> { } // expr[...] + // Could be either an index expression or a slicing expression. + // Any slicing non-terminal can have a mutable version with `mut` + // after the opening square bracket. token::LBRACKET => { self.bump(); - let ix = self.parse_expr(); - hi = self.span.hi; - self.commit_expr_expecting(&*ix, token::RBRACKET); - let index = self.mk_index(e, ix); - e = self.mk_expr(lo, hi, index) + let mutbl = if self.eat_keyword(keywords::Mut) { + MutMutable + } else { + MutImmutable + }; + match self.token { + // e[] + token::RBRACKET => { + self.bump(); + hi = self.span.hi; + let slice = self.mk_slice(e, None, None, mutbl); + e = self.mk_expr(lo, hi, slice) + } + // e[..e] + token::DOTDOT => { + self.bump(); + match self.token { + // e[..] + token::RBRACKET => { + self.bump(); + hi = self.span.hi; + let slice = self.mk_slice(e, None, None, mutbl); + e = self.mk_expr(lo, hi, slice); + + self.span_err(e.span, "incorrect slicing expression: `[..]`"); + self.span_note(e.span, + "use `expr[]` to construct a slice of the whole of expr"); + } + // e[..e] + _ => { + hi = self.span.hi; + let e2 = self.parse_expr(); + self.commit_expr_expecting(&*e2, token::RBRACKET); + let slice = self.mk_slice(e, None, Some(e2), mutbl); + e = self.mk_expr(lo, hi, slice) + } + } + } + // e[e] | e[e..] | e[e..e] + _ => { + let ix = self.parse_expr(); + match self.token { + // e[e..] | e[e..e] + token::DOTDOT => { + self.bump(); + let e2 = match self.token { + // e[e..] + token::RBRACKET => { + self.bump(); + None + } + // e[e..e] + _ => { + let e2 = self.parse_expr(); + self.commit_expr_expecting(&*e2, token::RBRACKET); + Some(e2) + } + }; + hi = self.span.hi; + let slice = self.mk_slice(e, Some(ix), e2, mutbl); + e = self.mk_expr(lo, hi, slice) + } + // e[e] + _ => { + if mutbl == ast::MutMutable { + self.span_err(e.span, + "`mut` keyword is invalid in index expressions"); + } + hi = self.span.hi; + self.commit_expr_expecting(&*ix, token::RBRACKET); + let index = self.mk_index(e, ix); + e = self.mk_expr(lo, hi, index) + } + } + } + } } _ => return e @@ -3153,7 +3236,8 @@ impl<'a> Parser<'a> { // These expressions are limited to literals (possibly // preceded by unary-minus) or identifiers. let val = self.parse_literal_maybe_minus(); - if self.token == token::DOTDOT && + // FIXME(#17295) remove the DOTDOT option. + if (self.token == token::DOTDOTDOT || self.token == token::DOTDOT) && self.look_ahead(1, |t| { *t != token::COMMA && *t != token::RBRACKET }) { @@ -3198,12 +3282,16 @@ impl<'a> Parser<'a> { } }); - if self.look_ahead(1, |t| *t == token::DOTDOT) && + // FIXME(#17295) remove the DOTDOT option. + if self.look_ahead(1, |t| *t == token::DOTDOTDOT || *t == token::DOTDOT) && self.look_ahead(2, |t| { *t != token::COMMA && *t != token::RBRACKET }) { let start = self.parse_expr_res(RestrictionNoBarOp); - self.eat(&token::DOTDOT); + // FIXME(#17295) remove the DOTDOT option (self.eat(&token::DOTDOTDOT)). + if self.token == token::DOTDOTDOT || self.token == token::DOTDOT { + self.bump(); + } let end = self.parse_expr_res(RestrictionNoBarOp); pat = PatRange(start, end); } else if is_plain_ident(&self.token) && !can_be_enum_or_struct { @@ -3590,7 +3678,7 @@ impl<'a> Parser<'a> { let span_with_semi = Span { lo: span.lo, hi: self.last_span.hi, - expn_info: span.expn_info, + expn_id: span.expn_id, }; stmts.push(P(Spanned { node: StmtSemi(e, stmt_id), @@ -3666,39 +3754,6 @@ impl<'a> Parser<'a> { }) } - fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy { - let (optional_unboxed_closure_kind, inputs) = - if self.eat(&token::OROR) { - (None, Vec::new()) - } else { - self.expect_or(); - - let optional_unboxed_closure_kind = - self.parse_optional_unboxed_closure_kind(); - - let inputs = self.parse_seq_to_before_or(&token::COMMA, - |p| { - p.parse_arg_general(false) - }); - self.expect_or(); - (optional_unboxed_closure_kind, inputs) - }; - - let (return_style, output) = self.parse_ret_ty(); - UnboxedFnTy { - decl: P(FnDecl { - inputs: inputs, - output: output, - cf: return_style, - variadic: false, - }), - kind: match optional_unboxed_closure_kind { - Some(kind) => kind, - None => FnMutUnboxedClosureKind, - }, - } - } - // Parses a sequence of bounds if a `:` is found, // otherwise returns empty list. fn parse_colon_then_ty_param_bounds(&mut self) @@ -3730,13 +3785,31 @@ impl<'a> Parser<'a> { self.bump(); } token::MOD_SEP | token::IDENT(..) => { - let tref = self.parse_trait_ref(); - result.push(TraitTyParamBound(tref)); - } - token::BINOP(token::OR) | token::OROR => { - let unboxed_function_type = - self.parse_unboxed_function_type(); - result.push(UnboxedFnTyParamBound(unboxed_function_type)); + let path = + self.parse_path(LifetimeAndTypesWithoutColons).path; + if self.token == token::LPAREN { + self.bump(); + let inputs = self.parse_seq_to_end( + &token::RPAREN, + seq_sep_trailing_allowed(token::COMMA), + |p| p.parse_arg_general(false)); + let (return_style, output) = self.parse_ret_ty(); + result.push(UnboxedFnTyParamBound(P(UnboxedFnBound { + path: path, + decl: P(FnDecl { + inputs: inputs, + output: output, + cf: return_style, + variadic: false, + }), + ref_id: ast::DUMMY_NODE_ID, + }))); + } else { + result.push(TraitTyParamBound(ast::TraitRef { + path: path, + ref_id: ast::DUMMY_NODE_ID, + })) + } } _ => break, } @@ -4423,14 +4496,6 @@ impl<'a> Parser<'a> { Some(attrs)) } - /// Parse a::B<String,int> - fn parse_trait_ref(&mut self) -> TraitRef { - ast::TraitRef { - path: self.parse_path(LifetimeAndTypesWithoutColons).path, - ref_id: ast::DUMMY_NODE_ID, - } - } - /// Parse struct Foo { ... } fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo { let class_name = self.parse_ident(); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 5a0aeece272..f71190da430 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -431,9 +431,11 @@ macro_rules! declare_special_idents_and_keywords {( // If the special idents get renumbered, remember to modify these two as appropriate pub static SELF_KEYWORD_NAME: Name = Name(SELF_KEYWORD_NAME_NUM); static STATIC_KEYWORD_NAME: Name = Name(STATIC_KEYWORD_NAME_NUM); +static SUPER_KEYWORD_NAME: Name = Name(SUPER_KEYWORD_NAME_NUM); pub static SELF_KEYWORD_NAME_NUM: u32 = 1; static STATIC_KEYWORD_NAME_NUM: u32 = 2; +static SUPER_KEYWORD_NAME_NUM: u32 = 3; // NB: leaving holes in the ident table is bad! a different ident will get // interned with the id from the hole, but it will be between the min and max @@ -443,52 +445,53 @@ declare_special_idents_and_keywords! { pub mod special_idents { // These ones are statics (0, invalid, ""); - (super::SELF_KEYWORD_NAME_NUM, self_, "self"); - (super::STATIC_KEYWORD_NAME_NUM, statik, "static"); - (3, static_lifetime, "'static"); + (super::SELF_KEYWORD_NAME_NUM, self_, "self"); + (super::STATIC_KEYWORD_NAME_NUM, statik, "static"); + (super::SUPER_KEYWORD_NAME_NUM, super_, "super"); + (4, static_lifetime, "'static"); // for matcher NTs - (4, tt, "tt"); - (5, matchers, "matchers"); + (5, tt, "tt"); + (6, matchers, "matchers"); // outside of libsyntax - (6, clownshoe_abi, "__rust_abi"); - (7, opaque, "<opaque>"); - (8, unnamed_field, "<unnamed_field>"); - (9, type_self, "Self"); - (10, prelude_import, "prelude_import"); + (7, clownshoe_abi, "__rust_abi"); + (8, opaque, "<opaque>"); + (9, unnamed_field, "<unnamed_field>"); + (10, type_self, "Self"); + (11, prelude_import, "prelude_import"); } pub mod keywords { // These ones are variants of the Keyword enum 'strict: - (11, As, "as"); - (12, Break, "break"); - (13, Crate, "crate"); - (14, Else, "else"); - (15, Enum, "enum"); - (16, Extern, "extern"); - (17, False, "false"); - (18, Fn, "fn"); - (19, For, "for"); - (20, If, "if"); - (21, Impl, "impl"); - (22, In, "in"); - (23, Let, "let"); - (24, Loop, "loop"); - (25, Match, "match"); - (26, Mod, "mod"); - (27, Mut, "mut"); - (28, Once, "once"); - (29, Pub, "pub"); - (30, Ref, "ref"); - (31, Return, "return"); + (12, As, "as"); + (13, Break, "break"); + (14, Crate, "crate"); + (15, Else, "else"); + (16, Enum, "enum"); + (17, Extern, "extern"); + (18, False, "false"); + (19, Fn, "fn"); + (20, For, "for"); + (21, If, "if"); + (22, Impl, "impl"); + (23, In, "in"); + (24, Let, "let"); + (25, Loop, "loop"); + (26, Match, "match"); + (27, Mod, "mod"); + (28, Mut, "mut"); + (29, Once, "once"); + (30, Pub, "pub"); + (31, Ref, "ref"); + (32, Return, "return"); // Static and Self are also special idents (prefill de-dupes) - (super::STATIC_KEYWORD_NAME_NUM, Static, "static"); - (super::SELF_KEYWORD_NAME_NUM, Self, "self"); - (32, Struct, "struct"); - (33, Super, "super"); + (super::STATIC_KEYWORD_NAME_NUM, Static, "static"); + (super::SELF_KEYWORD_NAME_NUM, Self, "self"); + (33, Struct, "struct"); + (super::SUPER_KEYWORD_NAME_NUM, Super, "super"); (34, True, "true"); (35, Trait, "trait"); (36, Type, "type"); @@ -713,6 +716,7 @@ pub fn is_any_keyword(tok: &Token) -> bool { n == SELF_KEYWORD_NAME || n == STATIC_KEYWORD_NAME + || n == SUPER_KEYWORD_NAME || STRICT_KEYWORD_START <= n && n <= RESERVED_KEYWORD_FINAL }, @@ -727,9 +731,18 @@ pub fn is_strict_keyword(tok: &Token) -> bool { n == SELF_KEYWORD_NAME || n == STATIC_KEYWORD_NAME + || n == SUPER_KEYWORD_NAME || STRICT_KEYWORD_START <= n && n <= STRICT_KEYWORD_FINAL }, + token::IDENT(sid, true) => { + let n = sid.name; + + n != SELF_KEYWORD_NAME + && n != SUPER_KEYWORD_NAME + && STRICT_KEYWORD_START <= n + && n <= STRICT_KEYWORD_FINAL + } _ => false, } } |
