diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/diagnostics/plugin.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 45 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 27 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 36 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/transcribe.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 28 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/owned_slice.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 49 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 36 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 349 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 358 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 32 | ||||
| -rw-r--r-- | src/libsyntax/ptr.rs | 42 | ||||
| -rw-r--r-- | src/libsyntax/std_inject.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 2 |
21 files changed, 453 insertions, 687 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index df9f935446d..bf1c305e206 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -93,7 +93,7 @@ impl Ident { pub fn new(name: Name, ctxt: SyntaxContext) -> Ident { Ident {name: name, ctxt: ctxt} } - pub fn with_empty_ctxt(name: Name) -> Ident { + pub const fn with_empty_ctxt(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT} } } @@ -248,8 +248,8 @@ impl PathParameters { pub fn none() -> PathParameters { PathParameters::AngleBracketed(AngleBracketedParameterData { lifetimes: Vec::new(), - types: P::empty(), - bindings: P::empty(), + types: P::new(), + bindings: P::new(), }) } @@ -421,7 +421,7 @@ impl Default for Generics { fn default() -> Generics { Generics { lifetimes: Vec::new(), - ty_params: P::empty(), + ty_params: P::new(), where_clause: WhereClause { id: DUMMY_NODE_ID, predicates: Vec::new(), @@ -986,7 +986,9 @@ pub enum ExprKind { /// A `match` block. Match(P<Expr>, Vec<Arm>), /// A closure (for example, `move |a, b, c| {a + b + c}`) - Closure(CaptureBy, P<FnDecl>, P<Block>), + /// + /// The final span is the span of the argument block `|...|` + Closure(CaptureBy, P<FnDecl>, P<Block>, Span), /// A block (`{ ... }`) Block(P<Block>), @@ -1206,8 +1208,7 @@ impl TokenTree { TokenTree::Delimited(sp, Rc::new(Delimited { delim: token::Bracket, open_span: sp, - tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc"), - token::Plain)), + tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc"))), TokenTree::Token(sp, token::Eq), TokenTree::Token(sp, token::Literal( token::StrRaw(token::intern(&stripped), num_of_hashes), None))], @@ -1225,14 +1226,13 @@ impl TokenTree { } (&TokenTree::Token(sp, token::SpecialVarNt(var)), _) => { let v = [TokenTree::Token(sp, token::Dollar), - TokenTree::Token(sp, token::Ident(token::str_to_ident(var.as_str()), - token::Plain))]; + TokenTree::Token(sp, token::Ident(token::str_to_ident(var.as_str())))]; v[index].clone() } - (&TokenTree::Token(sp, token::MatchNt(name, kind, name_st, kind_st)), _) => { - let v = [TokenTree::Token(sp, token::SubstNt(name, name_st)), + (&TokenTree::Token(sp, token::MatchNt(name, kind)), _) => { + let v = [TokenTree::Token(sp, token::SubstNt(name)), TokenTree::Token(sp, token::Colon), - TokenTree::Token(sp, token::Ident(kind, kind_st))]; + TokenTree::Token(sp, token::Ident(kind))]; v[index].clone() } (&TokenTree::Sequence(_, ref seq), _) => { diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 43b4a201afc..26088b1242e 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -54,7 +54,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, token_tree: &[TokenTree]) -> Box<MacResult+'cx> { let code = match (token_tree.len(), token_tree.get(0)) { - (1, Some(&TokenTree::Token(_, token::Ident(code, _)))) => code, + (1, Some(&TokenTree::Token(_, token::Ident(code)))) => code, _ => unreachable!() }; @@ -92,10 +92,10 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, token_tree.get(1), token_tree.get(2) ) { - (1, Some(&TokenTree::Token(_, token::Ident(ref code, _))), None, None) => { + (1, Some(&TokenTree::Token(_, token::Ident(ref code))), None, None) => { (code, None) }, - (3, Some(&TokenTree::Token(_, token::Ident(ref code, _))), + (3, Some(&TokenTree::Token(_, token::Ident(ref code))), Some(&TokenTree::Token(_, token::Comma)), Some(&TokenTree::Token(_, token::Literal(token::StrRaw(description, _), None)))) => { (code, Some(description)) @@ -160,9 +160,9 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, let (crate_name, name) = match (&token_tree[0], &token_tree[2]) { ( // Crate name. - &TokenTree::Token(_, token::Ident(ref crate_name, _)), + &TokenTree::Token(_, token::Ident(ref crate_name)), // DIAGNOSTICS ident. - &TokenTree::Token(_, token::Ident(ref name, _)) + &TokenTree::Token(_, token::Ident(ref name)) ) => (*&crate_name, name), _ => unreachable!() }; diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index a4e5b68277d..67bce440d4d 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -13,9 +13,7 @@ use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind}; use attr; use codemap::{Span, respan, Spanned, DUMMY_SP, Pos}; use ext::base::ExtCtxt; -use parse::token::special_idents; -use parse::token::InternedString; -use parse::token; +use parse::token::{self, keywords, InternedString}; use ptr::P; // Transitional reexports so qquote can find the paths it is looking for @@ -194,10 +192,14 @@ pub trait AstBuilder { cond: P<ast::Expr>, then: P<ast::Expr>, els: Option<P<ast::Expr>>) -> P<ast::Expr>; fn expr_loop(&self, span: Span, block: P<ast::Block>) -> P<ast::Expr>; - fn lambda_fn_decl(&self, span: Span, - fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> P<ast::Expr>; + fn lambda_fn_decl(&self, + span: Span, + fn_decl: P<ast::FnDecl>, + blk: P<ast::Block>, + fn_decl_span: Span) + -> P<ast::Expr>; - fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> P<ast::Expr>; + fn lambda(&self, span: Span, ids: Vec<ast::Ident>, blk: P<ast::Block>) -> P<ast::Expr>; fn lambda0(&self, span: Span, blk: P<ast::Block>) -> P<ast::Expr>; fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> P<ast::Expr>; @@ -602,7 +604,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr_path(self.path_ident(span, id)) } fn expr_self(&self, span: Span) -> P<ast::Expr> { - self.expr_ident(span, special_idents::self_) + self.expr_ident(span, keywords::SelfValue.ident()) } fn expr_binary(&self, sp: Span, op: ast::BinOpKind, @@ -894,17 +896,34 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr(span, ast::ExprKind::Loop(block, None)) } - fn lambda_fn_decl(&self, span: Span, - fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> P<ast::Expr> { - self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, fn_decl, blk)) + fn lambda_fn_decl(&self, + span: Span, + fn_decl: P<ast::FnDecl>, + blk: P<ast::Block>, + fn_decl_span: Span) // span of the `|...|` part + -> P<ast::Expr> { + self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, + fn_decl, + blk, + fn_decl_span)) } - fn lambda(&self, span: Span, ids: Vec<ast::Ident>, blk: P<ast::Block>) -> P<ast::Expr> { + + fn lambda(&self, + span: Span, + ids: Vec<ast::Ident>, + blk: P<ast::Block>) + -> P<ast::Expr> { let fn_decl = self.fn_decl( ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(), self.ty_infer(span)); - self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, fn_decl, blk)) + // FIXME -- We are using `span` as the span of the `|...|` + // part of the lambda, but it probably (maybe?) corresponds to + // the entire lambda body. Probably we should extend the API + // here, but that's not entirely clear. + self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, fn_decl, blk, span)) } + fn lambda0(&self, span: Span, blk: P<ast::Block>) -> P<ast::Expr> { self.lambda(span, Vec::new(), blk) } @@ -1132,7 +1151,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item> { P(ast::Item { id: ast::DUMMY_NODE_ID, - ident: special_idents::invalid, + ident: keywords::Invalid.ident(), attrs: vec![], node: ast::ItemKind::Use(vp), vis: vis, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index cd7b0fcfb00..a2c8ae898e1 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -25,7 +25,7 @@ use fold; use fold::*; use util::move_map::MoveMap; use parse; -use parse::token::{fresh_mark, fresh_name, intern}; +use parse::token::{fresh_mark, fresh_name, intern, keywords}; use ptr::P; use util::small_vector::SmallVector; use visit; @@ -149,14 +149,17 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { fld.cx.expr(span, il).with_attrs(fold_thin_attrs(attrs, fld)) } - ast::ExprKind::Closure(capture_clause, fn_decl, block) => { + ast::ExprKind::Closure(capture_clause, fn_decl, block, fn_decl_span) => { let (rewritten_fn_decl, rewritten_block) = expand_and_rename_fn_decl_and_block(fn_decl, block, fld); let new_node = ast::ExprKind::Closure(capture_clause, - rewritten_fn_decl, - rewritten_block); - P(ast::Expr{id:id, node: new_node, span: fld.new_span(span), - attrs: fold_thin_attrs(attrs, fld)}) + rewritten_fn_decl, + rewritten_block, + fld.new_span(fn_decl_span)); + P(ast::Expr{ id:id, + node: new_node, + span: fld.new_span(span), + attrs: fold_thin_attrs(attrs, fld) }) } _ => { @@ -380,7 +383,7 @@ pub fn expand_item_mac(it: P<ast::Item>, Some(rc) => match *rc { NormalTT(ref expander, tt_span, allow_internal_unstable) => { - if ident.name != parse::token::special_idents::invalid.name { + if ident.name != keywords::Invalid.name() { fld.cx .span_err(path_span, &format!("macro {}! expects no ident argument, given '{}'", @@ -401,7 +404,7 @@ pub fn expand_item_mac(it: P<ast::Item>, expander.expand(fld.cx, span, &marked_before[..]) } IdentTT(ref expander, tt_span, allow_internal_unstable) => { - if ident.name == parse::token::special_idents::invalid.name { + if ident.name == keywords::Invalid.name() { fld.cx.span_err(path_span, &format!("macro {}! expects an ident argument", extname)); @@ -420,7 +423,7 @@ pub fn expand_item_mac(it: P<ast::Item>, expander.expand(fld.cx, span, ident, marked_tts) } MacroRulesTT => { - if ident.name == parse::token::special_idents::invalid.name { + if ident.name == keywords::Invalid.name() { fld.cx.span_err(path_span, "macro_rules! expects an ident argument"); return SmallVector::zero(); } @@ -893,7 +896,7 @@ fn expand_annotatable(a: Annotatable, } ast::ItemKind::Mod(_) | ast::ItemKind::ForeignMod(_) => { let valid_ident = - it.ident.name != parse::token::special_idents::invalid.name; + it.ident.name != keywords::Invalid.name(); if valid_ident { fld.cx.mod_push(it.ident); @@ -1486,7 +1489,7 @@ mod tests { use ext::mtwt; use fold::Folder; use parse; - use parse::token; + use parse::token::{self, keywords}; use util::parser_testing::{string_to_parser}; use util::parser_testing::{string_to_pat, string_to_crate, strs_to_idents}; use visit; @@ -1807,7 +1810,7 @@ mod tests { // run one of the renaming tests fn run_renaming_test(t: &RenamingTest, test_idx: usize) { - let invalid_name = token::special_idents::invalid.name; + let invalid_name = keywords::Invalid.name(); let (teststr, bound_connections, bound_ident_check) = match *t { (ref str,ref conns, bic) => (str.to_string(), conns.clone(), bic) }; diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 77aeaf8459a..ee9a197ce56 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -13,7 +13,7 @@ use codemap::Span; use ext::base::ExtCtxt; use ext::base; use ext::build::AstBuilder; -use parse::parser::{Parser, PathParsingMode}; +use parse::parser::{Parser, PathStyle}; use parse::token::*; use parse::token; use ptr::P; @@ -72,7 +72,7 @@ pub mod rt { impl ToTokens for ast::Ident { fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> { - vec![TokenTree::Token(DUMMY_SP, token::Ident(*self, token::Plain))] + vec![TokenTree::Token(DUMMY_SP, token::Ident(*self))] } } @@ -401,7 +401,7 @@ pub fn parse_meta_item_panic(parser: &mut Parser) -> P<ast::MetaItem> { panictry!(parser.parse_meta_item()) } -pub fn parse_path_panic(parser: &mut Parser, mode: PathParsingMode) -> ast::Path { +pub fn parse_path_panic(parser: &mut Parser, mode: PathStyle) -> ast::Path { panictry!(parser.parse_path(mode)) } @@ -500,7 +500,7 @@ pub fn expand_quote_path(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<base::MacResult+'static> { - let mode = mk_parser_path(cx, sp, "LifetimeAndTypesWithoutColons"); + let mode = mk_parser_path(cx, sp, &["PathStyle", "Type"]); let expanded = expand_parse_call(cx, sp, "parse_path_panic", vec!(mode), tts); base::MacEager::expr(expanded) } @@ -557,8 +557,9 @@ fn mk_token_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> { cx.expr_path(cx.path_global(sp, idents)) } -fn mk_parser_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> { - let idents = vec!(id_ext("syntax"), id_ext("parse"), id_ext("parser"), id_ext(name)); +fn mk_parser_path(cx: &ExtCtxt, sp: Span, names: &[&str]) -> P<ast::Expr> { + let mut idents = vec![id_ext("syntax"), id_ext("parse"), id_ext("parser")]; + idents.extend(names.iter().cloned().map(id_ext)); cx.expr_path(cx.path_global(sp, idents)) } @@ -646,14 +647,10 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { cx.expr_usize(sp, n)) } - token::Ident(ident, style) => { + token::Ident(ident) => { return cx.expr_call(sp, mk_token_path(cx, sp, "Ident"), - vec![mk_ident(cx, sp, ident), - match style { - ModName => mk_token_path(cx, sp, "ModName"), - Plain => mk_token_path(cx, sp, "Plain"), - }]); + vec![mk_ident(cx, sp, ident)]); } token::Lifetime(ident) => { @@ -668,19 +665,10 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { vec!(mk_name(cx, sp, ast::Ident::with_empty_ctxt(ident)))); } - token::MatchNt(name, kind, namep, kindp) => { + token::MatchNt(name, kind) => { return cx.expr_call(sp, mk_token_path(cx, sp, "MatchNt"), - vec!(mk_ident(cx, sp, name), - mk_ident(cx, sp, kind), - match namep { - ModName => mk_token_path(cx, sp, "ModName"), - Plain => mk_token_path(cx, sp, "Plain"), - }, - match kindp { - ModName => mk_token_path(cx, sp, "ModName"), - Plain => mk_token_path(cx, sp, "Plain"), - })); + vec![mk_ident(cx, sp, name), mk_ident(cx, sp, kind)]); } token::Interpolated(_) => panic!("quote! with interpolated token"), @@ -722,7 +710,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { fn statements_mk_tt(cx: &ExtCtxt, tt: &TokenTree, matcher: bool) -> Vec<ast::Stmt> { match *tt { - TokenTree::Token(sp, SubstNt(ident, _)) => { + TokenTree::Token(sp, SubstNt(ident)) => { // tt.extend($ident.to_tokens(ext_cx)) let e_to_toks = diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 4e4c644776a..89ecf02ee4c 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -85,7 +85,7 @@ use codemap; use errors::FatalError; use parse::lexer::*; //resolve bug? use parse::ParseSess; -use parse::parser::{LifetimeAndTypesWithoutColons, Parser}; +use parse::parser::{PathStyle, Parser}; use parse::token::{DocComment, MatchNt, SubstNt}; use parse::token::{Token, Nonterminal}; use parse::token; @@ -216,7 +216,7 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>]) n_rec(p_s, next_m, res, ret_val, idx)?; } } - TokenTree::Token(sp, MatchNt(bind_name, _, _, _)) => { + TokenTree::Token(sp, MatchNt(bind_name, _)) => { match ret_val.entry(bind_name.name) { Vacant(spot) => { spot.insert(res[*idx].clone()); @@ -263,7 +263,7 @@ pub type PositionalParseResult = ParseResult<Vec<Rc<NamedMatch>>>; /// unhygienic comparison) pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool { match (t1,t2) { - (&token::Ident(id1,_),&token::Ident(id2,_)) + (&token::Ident(id1),&token::Ident(id2)) | (&token::Lifetime(id1),&token::Lifetime(id2)) => id1.name == id2.name, _ => *t1 == *t2 @@ -451,7 +451,7 @@ pub fn parse(sess: &ParseSess, if (!bb_eis.is_empty() && !next_eis.is_empty()) || bb_eis.len() > 1 { let nts = bb_eis.iter().map(|ei| match ei.top_elts.get_tt(ei.idx) { - TokenTree::Token(_, MatchNt(bind, name, _, _)) => { + TokenTree::Token(_, MatchNt(bind, name)) => { format!("{} ('{}')", name, bind) } _ => panic!() @@ -479,7 +479,7 @@ pub fn parse(sess: &ParseSess, let mut ei = bb_eis.pop().unwrap(); match ei.top_elts.get_tt(ei.idx) { - TokenTree::Token(span, MatchNt(_, ident, _, _)) => { + TokenTree::Token(span, MatchNt(_, ident)) => { let match_cur = ei.match_cur; (&mut ei.matches[match_cur]).push(Rc::new(MatchedNonterminal( parse_nt(&mut rust_parser, span, &ident.name.as_str())))); @@ -534,9 +534,9 @@ pub fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { "ty" => token::NtTy(panictry!(p.parse_ty())), // this could be handled like a token, since it is one "ident" => match p.token { - token::Ident(sn,b) => { + token::Ident(sn) => { p.bump(); - token::NtIdent(Box::new(Spanned::<Ident>{node: sn, span: p.span}),b) + token::NtIdent(Box::new(Spanned::<Ident>{node: sn, span: p.span})) } _ => { let token_str = pprust::token_to_string(&p.token); @@ -546,7 +546,7 @@ pub fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { } }, "path" => { - token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons)))) + token::NtPath(Box::new(panictry!(p.parse_path(PathStyle::Type)))) }, "meta" => token::NtMeta(panictry!(p.parse_meta_item())), _ => { diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 87ab3dad50c..41d3991aee8 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -17,7 +17,7 @@ use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; use ext::tt::macro_parser::parse; use parse::lexer::new_tt_reader; use parse::parser::{Parser, Restrictions}; -use parse::token::{self, special_idents, gensym_ident, NtTT, Token}; +use parse::token::{self, gensym_ident, NtTT, Token}; use parse::token::Token::*; use print; use ptr::P; @@ -244,8 +244,8 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt, // $( $lhs:tt => $rhs:tt );+ // ...quasiquoting this would be nice. // These spans won't matter, anyways - let match_lhs_tok = MatchNt(lhs_nm, special_idents::tt, token::Plain, token::Plain); - let match_rhs_tok = MatchNt(rhs_nm, special_idents::tt, token::Plain, token::Plain); + let match_lhs_tok = MatchNt(lhs_nm, token::str_to_ident("tt")); + let match_rhs_tok = MatchNt(rhs_nm, token::str_to_ident("tt")); let argument_gram = vec!( TokenTree::Sequence(DUMMY_SP, Rc::new(ast::SequenceRepetition { @@ -415,7 +415,7 @@ fn check_matcher_old<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token, on_fai let mut tokens = matcher.peekable(); while let Some(token) = tokens.next() { last = match *token { - TokenTree::Token(sp, MatchNt(ref name, ref frag_spec, _, _)) => { + TokenTree::Token(sp, MatchNt(ref name, ref frag_spec)) => { // ii. If T is a simple NT, look ahead to the next token T' in // M. If T' is in the set FOLLOW(NT), continue. Else; reject. if can_be_followed_by_any(&frag_spec.name.as_str()) { @@ -881,7 +881,7 @@ fn check_matcher_core(cx: &mut ExtCtxt, // Now `last` holds the complete set of NT tokens that could // end the sequence before SUFFIX. Check that every one works with `suffix`. 'each_last: for &(_sp, ref t) in &last.tokens { - if let MatchNt(ref name, ref frag_spec, _, _) = *t { + if let MatchNt(ref name, ref frag_spec) = *t { for &(sp, ref next_token) in &suffix_first.tokens { match is_in_follow(cx, next_token, &frag_spec.name.as_str()) { Err(msg) => { @@ -917,9 +917,8 @@ fn check_matcher_core(cx: &mut ExtCtxt, last } - fn token_can_be_followed_by_any(tok: &Token) -> bool { - if let &MatchNt(_, ref frag_spec, _, _) = tok { + if let &MatchNt(_, ref frag_spec) = tok { frag_can_be_followed_by_any(&frag_spec.name.as_str()) } else { // (Non NT's can always be followed by anthing in matchers.) @@ -1005,8 +1004,8 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> { "pat" => { match *tok { FatArrow | Comma | Eq | BinOp(token::Or) => Ok(true), - Ident(i, _) if (i.name.as_str() == "if" || - i.name.as_str() == "in") => Ok(true), + Ident(i) if (i.name.as_str() == "if" || + i.name.as_str() == "in") => Ok(true), _ => Ok(false) } }, @@ -1014,9 +1013,8 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> { match *tok { OpenDelim(token::DelimToken::Brace) | OpenDelim(token::DelimToken::Bracket) | Comma | FatArrow | Colon | Eq | Gt | Semi | BinOp(token::Or) => Ok(true), - MatchNt(_, ref frag, _, _) if frag.name.as_str() == "block" => Ok(true), - Ident(i, _) if (i.name.as_str() == "as" || - i.name.as_str() == "where") => Ok(true), + MatchNt(_, ref frag) if frag.name.as_str() == "block" => Ok(true), + Ident(i) if i.name.as_str() == "as" || i.name.as_str() == "where" => Ok(true), _ => Ok(false) } }, @@ -1036,7 +1034,7 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> { fn has_legal_fragment_specifier(tok: &Token) -> Result<(), String> { debug!("has_legal_fragment_specifier({:?})", tok); - if let &MatchNt(_, ref frag_spec, _, _) = tok { + if let &MatchNt(_, ref frag_spec) = tok { let s = &frag_spec.name.as_str(); if !is_legal_fragment_specifier(s) { return Err(s.to_string()); diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index ae99fe81739..7f53d0f412c 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -161,7 +161,7 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize { size + lockstep_iter_size(tt, r) }) }, - TokenTree::Token(_, SubstNt(name, _)) | TokenTree::Token(_, MatchNt(name, _, _, _)) => + TokenTree::Token(_, SubstNt(name)) | TokenTree::Token(_, MatchNt(name, _)) => match lookup_cur_matched(r, name) { Some(matched) => match *matched { MatchedNonterminal(_) => LisUnconstrained, @@ -186,7 +186,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { None => (), Some(sp) => { r.cur_span = sp; - r.cur_tok = token::Ident(r.imported_from.unwrap(), token::Plain); + r.cur_tok = token::Ident(r.imported_from.unwrap()); return ret_val; }, } @@ -278,12 +278,12 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { } } // FIXME #2887: think about span stuff here - TokenTree::Token(sp, SubstNt(ident, namep)) => { + TokenTree::Token(sp, SubstNt(ident)) => { r.stack.last_mut().unwrap().idx += 1; match lookup_cur_matched(r, ident) { None => { r.cur_span = sp; - r.cur_tok = SubstNt(ident, namep); + r.cur_tok = SubstNt(ident); return ret_val; // this can't be 0 length, just like TokenTree::Delimited } @@ -292,9 +292,9 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { // sidestep the interpolation tricks for ident because // (a) idents can be in lots of places, so it'd be a pain // (b) we actually can, since it's a token. - MatchedNonterminal(NtIdent(ref sn, b)) => { + MatchedNonterminal(NtIdent(ref sn)) => { r.cur_span = sn.span; - r.cur_tok = token::Ident(sn.node, b); + r.cur_tok = token::Ident(sn.node); return ret_val; } MatchedNonterminal(ref other_whole_nt) => { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index d8352430eb9..c77671d89f8 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1168,7 +1168,19 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { fn visit_vis(&mut self, vis: &'v ast::Visibility) { let span = match *vis { ast::Visibility::Crate(span) => span, - ast::Visibility::Restricted { ref path, .. } => path.span, + ast::Visibility::Restricted { ref path, .. } => { + // Check for type parameters + let found_param = path.segments.iter().any(|segment| { + !segment.parameters.types().is_empty() || + !segment.parameters.lifetimes().is_empty() || + !segment.parameters.bindings().is_empty() + }); + if found_param { + self.context.span_handler.span_err(path.span, "type or lifetime parameters \ + in visibility path"); + } + path.span + } _ => return, }; self.gate_feature("pub_restricted", span, "`pub(restricted)` syntax is experimental"); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 89451e79550..2c325080c0c 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -22,7 +22,7 @@ use ast::*; use ast; use attr::{ThinAttributes, ThinAttributesExt}; use codemap::{respan, Span, Spanned}; -use parse::token; +use parse::token::{self, keywords}; use ptr::P; use util::small_vector::SmallVector; use util::move_map::MoveMap; @@ -610,17 +610,11 @@ pub fn noop_fold_tts<T: Folder>(tts: &[TokenTree], fld: &mut T) -> Vec<TokenTree // apply ident folder if it's an ident, apply other folds to interpolated nodes pub fn noop_fold_token<T: Folder>(t: token::Token, fld: &mut T) -> token::Token { match t { - token::Ident(id, followed_by_colons) => { - token::Ident(fld.fold_ident(id), followed_by_colons) - } + token::Ident(id) => token::Ident(fld.fold_ident(id)), token::Lifetime(id) => token::Lifetime(fld.fold_ident(id)), token::Interpolated(nt) => token::Interpolated(fld.fold_interpolated(nt)), - token::SubstNt(ident, namep) => { - token::SubstNt(fld.fold_ident(ident), namep) - } - token::MatchNt(name, kind, namep, kindp) => { - token::MatchNt(fld.fold_ident(name), fld.fold_ident(kind), namep, kindp) - } + token::SubstNt(ident) => token::SubstNt(fld.fold_ident(ident)), + token::MatchNt(name, kind) => token::MatchNt(fld.fold_ident(name), fld.fold_ident(kind)), _ => t } } @@ -664,9 +658,8 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T) token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)), token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)), token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)), - token::NtIdent(id, is_mod_name) => - token::NtIdent(Box::new(Spanned::<Ident>{node: fld.fold_ident(id.node), .. *id}), - is_mod_name), + token::NtIdent(id) => + token::NtIdent(Box::new(Spanned::<Ident>{node: fld.fold_ident(id.node), ..*id})), token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)), token::NtPath(path) => token::NtPath(Box::new(fld.fold_path(*path))), token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&tt))), @@ -1022,7 +1015,7 @@ pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_mac let config = folder.fold_meta_items(config); let mut items = folder.fold_item(P(ast::Item { - ident: token::special_idents::invalid, + ident: keywords::Invalid.ident(), attrs: attrs, id: ast::DUMMY_NODE_ID, vis: ast::Visibility::Public, @@ -1241,10 +1234,11 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu ExprKind::Match(folder.fold_expr(expr), arms.move_map(|x| folder.fold_arm(x))) } - ExprKind::Closure(capture_clause, decl, body) => { + ExprKind::Closure(capture_clause, decl, body, span) => { ExprKind::Closure(capture_clause, - folder.fold_fn_decl(decl), - folder.fold_block(body)) + folder.fold_fn_decl(decl), + folder.fold_block(body), + folder.new_span(span)) } ExprKind::Block(blk) => ExprKind::Block(folder.fold_block(blk)), ExprKind::Assign(el, er) => { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index ca7e5729c0b..6cfa1e9847b 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -25,6 +25,7 @@ #![cfg_attr(not(stage0), deny(warnings))] #![feature(associated_consts)] +#![feature(const_fn)] #![feature(filling_drop)] #![feature(libc)] #![feature(rustc_private)] @@ -96,7 +97,6 @@ pub mod config; pub mod entry; pub mod feature_gate; pub mod fold; -pub mod owned_slice; pub mod parse; pub mod ptr; pub mod show_span; diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs deleted file mode 100644 index 33a3d578598..00000000000 --- a/src/libsyntax/owned_slice.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/// A non-growable owned slice. -#[unstable(feature = "rustc_private", issue = "0")] -#[rustc_deprecated(since = "1.7.0", reason = "use `ptr::P<[T]>` instead")] -pub type OwnedSlice<T> = ::ptr::P<[T]>; diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index a5cb5c7117e..2eda13adcb5 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -13,8 +13,7 @@ use codemap::{BytePos, CharPos, CodeMap, Pos, Span}; use codemap; use errors::{FatalError, Handler, DiagnosticBuilder}; use ext::tt::transcribe::tt_next_token; -use parse::token::str_to_ident; -use parse::token; +use parse::token::{self, keywords, str_to_ident}; use str::char_at; use rustc_unicode::property::Pattern_White_Space; @@ -1039,11 +1038,7 @@ impl<'a> StringReader<'a> { token::Underscore } else { // FIXME: perform NFKC normalization here. (Issue #2253) - if self.curr_is(':') && self.nextch_is(':') { - token::Ident(str_to_ident(string), token::ModName) - } else { - token::Ident(str_to_ident(string), token::Plain) - } + token::Ident(str_to_ident(string)) } }); } @@ -1231,17 +1226,11 @@ impl<'a> StringReader<'a> { let keyword_checking_ident = self.with_str_from(start, |lifetime_name| { str_to_ident(lifetime_name) }); - let keyword_checking_token = &token::Ident(keyword_checking_ident, - token::Plain); + let keyword_checking_token = &token::Ident(keyword_checking_ident); let last_bpos = self.last_pos; - if keyword_checking_token.is_keyword(token::keywords::SelfValue) { - self.err_span_(start, - last_bpos, - "invalid lifetime name: 'self is no longer a special \ - lifetime"); - } else if keyword_checking_token.is_any_keyword() && - !keyword_checking_token.is_keyword(token::keywords::Static) { - self.err_span_(start, last_bpos, "invalid lifetime name"); + if keyword_checking_token.is_any_keyword() && + !keyword_checking_token.is_keyword(keywords::Static) { + self.err_span_(start, last_bpos, "lifetimes cannot use keyword names"); } return token::Lifetime(ident); @@ -1687,7 +1676,7 @@ mod tests { assert_eq!(string_reader.next_token().tok, token::Whitespace); let tok1 = string_reader.next_token(); let tok2 = TokenAndSpan { - tok: token::Ident(id, token::Plain), + tok: token::Ident(id), sp: Span { lo: BytePos(21), hi: BytePos(23), @@ -1701,7 +1690,7 @@ mod tests { // read another token: let tok3 = string_reader.next_token(); let tok4 = TokenAndSpan { - tok: token::Ident(str_to_ident("main"), token::Plain), + tok: token::Ident(str_to_ident("main")), sp: Span { lo: BytePos(24), hi: BytePos(28), @@ -1722,8 +1711,8 @@ mod tests { } // make the identifier by looking up the string in the interner - fn mk_ident(id: &str, style: token::IdentStyle) -> token::Token { - token::Ident(str_to_ident(id), style) + fn mk_ident(id: &str) -> token::Token { + token::Ident(str_to_ident(id)) } #[test] @@ -1731,9 +1720,7 @@ mod tests { let cm = Rc::new(CodeMap::new()); let sh = mk_sh(cm.clone()); check_tokenization(setup(&cm, &sh, "a b".to_string()), - vec![mk_ident("a", token::Plain), - token::Whitespace, - mk_ident("b", token::Plain)]); + vec![mk_ident("a"), token::Whitespace, mk_ident("b")]); } #[test] @@ -1741,9 +1728,7 @@ mod tests { let cm = Rc::new(CodeMap::new()); let sh = mk_sh(cm.clone()); check_tokenization(setup(&cm, &sh, "a::b".to_string()), - vec![mk_ident("a", token::ModName), - token::ModSep, - mk_ident("b", token::Plain)]); + vec![mk_ident("a"), token::ModSep, mk_ident("b")]); } #[test] @@ -1751,10 +1736,7 @@ mod tests { let cm = Rc::new(CodeMap::new()); let sh = mk_sh(cm.clone()); check_tokenization(setup(&cm, &sh, "a ::b".to_string()), - vec![mk_ident("a", token::Plain), - token::Whitespace, - token::ModSep, - mk_ident("b", token::Plain)]); + vec![mk_ident("a"), token::Whitespace, token::ModSep, mk_ident("b")]); } #[test] @@ -1762,10 +1744,7 @@ mod tests { let cm = Rc::new(CodeMap::new()); let sh = mk_sh(cm.clone()); check_tokenization(setup(&cm, &sh, "a:: b".to_string()), - vec![mk_ident("a", token::ModName), - token::ModSep, - token::Whitespace, - mk_ident("b", token::Plain)]); + vec![mk_ident("a"), token::ModSep, token::Whitespace, mk_ident("b")]); } #[test] diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 29b1d5b9aff..c2050d2a8f4 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -734,9 +734,9 @@ mod tests { match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) { ( 4, - Some(&TokenTree::Token(_, token::Ident(name_macro_rules, token::Plain))), + Some(&TokenTree::Token(_, token::Ident(name_macro_rules))), Some(&TokenTree::Token(_, token::Not)), - Some(&TokenTree::Token(_, token::Ident(name_zip, token::Plain))), + Some(&TokenTree::Token(_, token::Ident(name_zip))), Some(&TokenTree::Delimited(_, ref macro_delimed)), ) if name_macro_rules.name.as_str() == "macro_rules" @@ -755,7 +755,7 @@ mod tests { ( 2, Some(&TokenTree::Token(_, token::Dollar)), - Some(&TokenTree::Token(_, token::Ident(ident, token::Plain))), + Some(&TokenTree::Token(_, token::Ident(ident))), ) if first_delimed.delim == token::Paren && ident.name.as_str() == "a" => {}, @@ -766,7 +766,7 @@ mod tests { ( 2, Some(&TokenTree::Token(_, token::Dollar)), - Some(&TokenTree::Token(_, token::Ident(ident, token::Plain))), + Some(&TokenTree::Token(_, token::Ident(ident))), ) if second_delimed.delim == token::Paren && ident.name.as_str() == "a" => {}, @@ -785,26 +785,17 @@ mod tests { let tts = string_to_tts("fn a (b : i32) { b; }".to_string()); let expected = vec![ - TokenTree::Token(sp(0, 2), - token::Ident(str_to_ident("fn"), - token::IdentStyle::Plain)), - TokenTree::Token(sp(3, 4), - token::Ident(str_to_ident("a"), - token::IdentStyle::Plain)), + TokenTree::Token(sp(0, 2), token::Ident(str_to_ident("fn"))), + TokenTree::Token(sp(3, 4), token::Ident(str_to_ident("a"))), TokenTree::Delimited( sp(5, 14), Rc::new(ast::Delimited { delim: token::DelimToken::Paren, open_span: sp(5, 6), tts: vec![ - TokenTree::Token(sp(6, 7), - token::Ident(str_to_ident("b"), - token::IdentStyle::Plain)), - TokenTree::Token(sp(8, 9), - token::Colon), - TokenTree::Token(sp(10, 13), - token::Ident(str_to_ident("i32"), - token::IdentStyle::Plain)), + TokenTree::Token(sp(6, 7), token::Ident(str_to_ident("b"))), + TokenTree::Token(sp(8, 9), token::Colon), + TokenTree::Token(sp(10, 13), token::Ident(str_to_ident("i32"))), ], close_span: sp(13, 14), })), @@ -814,11 +805,8 @@ mod tests { delim: token::DelimToken::Brace, open_span: sp(15, 16), tts: vec![ - TokenTree::Token(sp(17, 18), - token::Ident(str_to_ident("b"), - token::IdentStyle::Plain)), - TokenTree::Token(sp(18, 19), - token::Semi) + TokenTree::Token(sp(17, 18), token::Ident(str_to_ident("b"))), + TokenTree::Token(sp(18, 19), token::Semi), ], close_span: sp(20, 21), })) @@ -937,7 +925,7 @@ mod tests { Abi::Rust, ast::Generics{ // no idea on either of these: lifetimes: Vec::new(), - ty_params: P::empty(), + ty_params: P::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 f3d3bbd9f99..8722fe9d79d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::PathParsingMode::*; - use abi::{self, Abi}; use ast::BareFnTy; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; @@ -51,7 +49,7 @@ use parse::common::SeqSep; use parse::lexer::{Reader, TokenAndSpan}; use parse::obsolete::{ParserObsoleteMethods, ObsoleteSyntax}; use parse::token::{self, intern, MatchNt, SubstNt, SpecialVarNt, InternedString}; -use parse::token::{keywords, special_idents, SpecialMacroVar}; +use parse::token::{keywords, SpecialMacroVar}; use parse::{new_sub_parser_from_file, ParseSess}; use util::parser::{AssocOp, Fixity}; use print::pprust; @@ -69,26 +67,24 @@ bitflags! { const RESTRICTION_STMT_EXPR = 1 << 0, const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1, const NO_NONINLINE_MOD = 1 << 2, - const ALLOW_MODULE_PATHS = 1 << 3, } } type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute> >); -/// How to parse a path. There are four different kinds of paths, all of which +/// How to parse a path. There are three different kinds of paths, all of which /// are parsed somewhat differently. #[derive(Copy, Clone, PartialEq)] -pub enum PathParsingMode { - /// A path with no type parameters; e.g. `foo::bar::Baz` - NoTypesAllowed, - /// Same as `NoTypesAllowed`, but may end with `::{` or `::*`, which are left unparsed - ImportPrefix, +pub enum PathStyle { + /// A path with no type parameters, e.g. `foo::bar::Baz`, used in imports or visibilities. + Mod, /// A path with a lifetime and type parameters, with no double colons - /// before the type parameters; e.g. `foo::bar<'a>::Baz<T>` - LifetimeAndTypesWithoutColons, + /// before the type parameters; e.g. `foo::bar<'a>::Baz<T>`, used in types. + /// Paths using this style can be passed into macros expecting `path` nonterminals. + Type, /// A path with a lifetime and type parameters with double colons before - /// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>` - LifetimeAndTypesWithColons, + /// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>`, used in expressions or patterns. + Expr, } /// How to parse a bound, whether to allow bound modifiers such as `?`. @@ -292,13 +288,13 @@ impl TokenType { match *self { TokenType::Token(ref t) => format!("`{}`", Parser::token_to_string(t)), TokenType::Operator => "an operator".to_string(), - TokenType::Keyword(kw) => format!("`{}`", kw.to_name()), + TokenType::Keyword(kw) => format!("`{}`", kw.name()), } } } -fn is_plain_ident_or_underscore(t: &token::Token) -> bool { - t.is_plain_ident() || *t == token::Underscore +fn is_ident_or_underscore(t: &token::Token) -> bool { + t.is_ident() || *t == token::Underscore } /// Information about the path to a module. @@ -398,6 +394,17 @@ impl<'a> Parser<'a> { Parser::token_to_string(&self.token) } + pub fn this_token_descr(&self) -> String { + let s = self.this_token_to_string(); + if self.token.is_strict_keyword() { + format!("keyword `{}`", s) + } else if self.token.is_reserved_keyword() { + format!("reserved keyword `{}`", s) + } else { + format!("`{}`", s) + } + } + pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> { let token_str = Parser::token_to_string(t); let last_span = self.last_span; @@ -562,12 +569,10 @@ impl<'a> Parser<'a> { } pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { - if !self.restrictions.contains(Restrictions::ALLOW_MODULE_PATHS) { - self.check_strict_keywords(); - } + self.check_strict_keywords(); self.check_reserved_keywords(); match self.token { - token::Ident(i, _) => { + token::Ident(i) => { self.bump(); Ok(i) } @@ -585,12 +590,9 @@ impl<'a> Parser<'a> { } } - pub fn parse_ident_or_self_type(&mut self) -> PResult<'a, ast::Ident> { - if self.is_self_type_ident() { - self.expect_self_type_ident() - } else { - self.parse_ident() - } + fn parse_ident_into_path(&mut self) -> PResult<'a, ast::Path> { + let ident = self.parse_ident()?; + Ok(ast::Path::from_ident(self.last_span, ident)) } /// Check if the next token is `tok`, and return `true` if so. @@ -637,9 +639,8 @@ impl<'a> Parser<'a> { } pub fn check_contextual_keyword(&mut self, ident: Ident) -> bool { - let tok = token::Ident(ident, token::Plain); - self.expected_tokens.push(TokenType::Token(tok)); - if let token::Ident(ref cur_ident, _) = self.token { + self.expected_tokens.push(TokenType::Token(token::Ident(ident))); + if let token::Ident(ref cur_ident) = self.token { cur_ident.name == ident.name } else { false @@ -1159,7 +1160,7 @@ impl<'a> Parser<'a> { let other_bounds = if self.eat(&token::BinOp(token::Plus)) { self.parse_ty_param_bounds(BoundParsingMode::Bare)? } else { - P::empty() + P::new() }; let all_bounds = Some(TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)).into_iter() @@ -1170,7 +1171,7 @@ impl<'a> Parser<'a> { } pub fn parse_ty_path(&mut self) -> PResult<'a, TyKind> { - Ok(TyKind::Path(None, self.parse_path(LifetimeAndTypesWithoutColons)?)) + Ok(TyKind::Path(None, self.parse_path(PathStyle::Type)?)) } /// parse a TyKind::BareFn type: @@ -1473,13 +1474,11 @@ impl<'a> Parser<'a> { } else if self.eat_lt() { let (qself, path) = - self.parse_qualified_path(NoTypesAllowed)?; + self.parse_qualified_path(PathStyle::Type)?; TyKind::Path(Some(qself), path) - } else if self.check(&token::ModSep) || - self.token.is_ident() || - self.token.is_path() { - let path = self.parse_path(LifetimeAndTypesWithoutColons)?; + } else if self.token.is_path_start() { + let path = self.parse_path(PathStyle::Type)?; if self.check(&token::Not) { // MACRO INVOCATION self.bump(); @@ -1497,9 +1496,8 @@ impl<'a> Parser<'a> { // TYPE TO BE INFERRED TyKind::Infer } else { - let this_token_str = self.this_token_to_string(); - let msg = format!("expected type, found `{}`", this_token_str); - return Err(self.fatal(&msg[..])); + let msg = format!("expected type, found {}", self.this_token_descr()); + return Err(self.fatal(&msg)); }; let sp = mk_sp(lo, self.last_span.hi); @@ -1541,10 +1539,10 @@ impl<'a> Parser<'a> { debug!("parser is_named_argument offset:{}", offset); if offset == 0 { - is_plain_ident_or_underscore(&self.token) + is_ident_or_underscore(&self.token) && self.look_ahead(1, |t| *t == token::Colon) } else { - self.look_ahead(offset, |t| is_plain_ident_or_underscore(t)) + self.look_ahead(offset, |t| is_ident_or_underscore(t)) && self.look_ahead(offset + 1, |t| *t == token::Colon) } } @@ -1564,7 +1562,7 @@ impl<'a> Parser<'a> { } else { debug!("parse_arg_general ident_to_pat"); let sp = self.last_span; - let spanned = Spanned { span: sp, node: special_idents::invalid }; + let spanned = Spanned { span: sp, node: keywords::Invalid.ident() }; P(Pat { id: ast::DUMMY_NODE_ID, node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), @@ -1616,12 +1614,12 @@ impl<'a> Parser<'a> { } /// Matches token_lit = LIT_INTEGER | ... - pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, LitKind> { - match *tok { + pub fn parse_lit_token(&mut self) -> PResult<'a, LitKind> { + let out = match self.token { token::Interpolated(token::NtExpr(ref v)) => { match v.node { - ExprKind::Lit(ref lit) => { Ok(lit.node.clone()) } - _ => { return self.unexpected_last(tok); } + ExprKind::Lit(ref lit) => { lit.node.clone() } + _ => { return self.unexpected_last(&self.token); } } } token::Literal(lit, suf) => { @@ -1636,13 +1634,13 @@ impl<'a> Parser<'a> { (false, parse::integer_lit(&s.as_str(), suf.as_ref().map(|s| s.as_str()), &self.sess.span_diagnostic, - self.last_span)) + self.span)) } token::Float(s) => { (false, parse::float_lit(&s.as_str(), suf.as_ref().map(|s| s.as_str()), &self.sess.span_diagnostic, - self.last_span)) + self.span)) } token::Str_(s) => { @@ -1664,14 +1662,17 @@ impl<'a> Parser<'a> { }; if suffix_illegal { - let sp = self.last_span; + let sp = self.span; self.expect_no_suffix(sp, &format!("{} literal", lit.short_name()), suf) } - Ok(out) + out } - _ => { return self.unexpected_last(tok); } - } + _ => { return self.unexpected_last(&self.token); } + }; + + self.bump(); + Ok(out) } /// Matches lit = true | false | token_lit @@ -1682,8 +1683,7 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(keywords::False) { LitKind::Bool(false) } else { - let token = self.bump_and_get(); - let lit = self.lit_from_token(&token)?; + let lit = self.parse_lit_token()?; lit }; Ok(codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }) @@ -1707,6 +1707,16 @@ impl<'a> Parser<'a> { } } + pub fn parse_path_segment_ident(&mut self) -> PResult<'a, ast::Ident> { + match self.token { + token::Ident(sid) if self.token.is_path_segment_keyword() => { + self.bump(); + Ok(sid) + } + _ => self.parse_ident(), + } + } + /// Parses qualified path. /// /// Assumes that the leading `<` has been parsed already. @@ -1722,12 +1732,12 @@ impl<'a> Parser<'a> { /// /// `<T as U>::a` /// `<T as U>::F::a::<S>` - pub fn parse_qualified_path(&mut self, mode: PathParsingMode) + pub fn parse_qualified_path(&mut self, mode: PathStyle) -> PResult<'a, (QSelf, ast::Path)> { let span = self.last_span; let self_type = self.parse_ty_sum()?; let mut path = if self.eat_keyword(keywords::As) { - self.parse_path(LifetimeAndTypesWithoutColons)? + self.parse_path(PathStyle::Type)? } else { ast::Path { span: span, @@ -1745,14 +1755,14 @@ impl<'a> Parser<'a> { self.expect(&token::ModSep)?; let segments = match mode { - LifetimeAndTypesWithoutColons => { + PathStyle::Type => { self.parse_path_segments_without_colons()? } - LifetimeAndTypesWithColons => { + PathStyle::Expr => { self.parse_path_segments_with_colons()? } - NoTypesAllowed | ImportPrefix => { - self.parse_path_segments_without_types(mode == ImportPrefix)? + PathStyle::Mod => { + self.parse_path_segments_without_types()? } }; path.segments.extend(segments); @@ -1766,7 +1776,7 @@ impl<'a> Parser<'a> { /// mode. The `mode` parameter determines whether lifetimes, types, and/or /// bounds are permitted and whether `::` must precede type parameter /// groups. - pub fn parse_path(&mut self, mode: PathParsingMode) -> PResult<'a, ast::Path> { + pub fn parse_path(&mut self, mode: PathStyle) -> PResult<'a, ast::Path> { // Check for a whole path... let found = match self.token { token::Interpolated(token::NtPath(_)) => Some(self.bump_and_get()), @@ -1783,14 +1793,14 @@ impl<'a> Parser<'a> { // identifier followed by an optional lifetime and a set of types. // A bound set is a set of type parameter bounds. let segments = match mode { - LifetimeAndTypesWithoutColons => { + PathStyle::Type => { self.parse_path_segments_without_colons()? } - LifetimeAndTypesWithColons => { + PathStyle::Expr => { self.parse_path_segments_with_colons()? } - NoTypesAllowed | ImportPrefix => { - self.parse_path_segments_without_types(mode == ImportPrefix)? + PathStyle::Mod => { + self.parse_path_segments_without_types()? } }; @@ -1813,7 +1823,7 @@ impl<'a> Parser<'a> { let mut segments = Vec::new(); loop { // First, parse an identifier. - let identifier = self.parse_ident_or_self_type()?; + let identifier = self.parse_path_segment_ident()?; // Parse types, optionally. let parameters = if self.eat_lt() { @@ -1866,7 +1876,7 @@ impl<'a> Parser<'a> { let mut segments = Vec::new(); loop { // First, parse an identifier. - let identifier = self.parse_ident_or_self_type()?; + let identifier = self.parse_path_segment_ident()?; // If we do not see a `::`, stop. if !self.eat(&token::ModSep) { @@ -1905,15 +1915,14 @@ impl<'a> Parser<'a> { } } - /// Examples: /// - `a::b::c` - pub fn parse_path_segments_without_types(&mut self, import_prefix: bool) + pub fn parse_path_segments_without_types(&mut self) -> PResult<'a, Vec<ast::PathSegment>> { let mut segments = Vec::new(); loop { // First, parse an identifier. - let identifier = self.parse_ident_or_self_type()?; + let identifier = self.parse_path_segment_ident()?; // Assemble and push the result. segments.push(ast::PathSegment { @@ -1922,7 +1931,7 @@ impl<'a> Parser<'a> { }); // If we do not see a `::` or see `::{`/`::*`, stop. - if !self.check(&token::ModSep) || import_prefix && self.is_import_coupler() { + if !self.check(&token::ModSep) || self.is_import_coupler() { return Ok(segments); } else { self.bump(); @@ -2212,15 +2221,6 @@ impl<'a> Parser<'a> { let lo = self.span.lo; return self.parse_lambda_expr(lo, CaptureBy::Ref, attrs); }, - token::Ident(id @ ast::Ident { - name: token::SELF_KEYWORD_NAME, - ctxt: _ - }, token::Plain) => { - self.bump(); - let path = ast::Path::from_ident(mk_sp(lo, hi), id); - ex = ExprKind::Path(None, path); - hi = self.last_span.hi; - } token::OpenDelim(token::Bracket) => { self.bump(); @@ -2263,7 +2263,7 @@ impl<'a> Parser<'a> { _ => { if self.eat_lt() { let (qself, path) = - self.parse_qualified_path(LifetimeAndTypesWithColons)?; + self.parse_qualified_path(PathStyle::Expr)?; hi = path.span.hi; return Ok(self.mk_expr(lo, hi, ExprKind::Path(Some(qself), path), attrs)); } @@ -2350,12 +2350,8 @@ impl<'a> Parser<'a> { let mut db = self.fatal("expected expression, found statement (`let`)"); db.note("variable declaration using `let` is a statement"); return Err(db); - } else if self.check(&token::ModSep) || - self.token.is_ident() && - !self.check_keyword(keywords::True) && - !self.check_keyword(keywords::False) { - let pth = - self.parse_path(LifetimeAndTypesWithColons)?; + } else if self.token.is_path_start() { + let pth = self.parse_path(PathStyle::Expr)?; // `!`, as an operator, is prefix, so we know this isn't that if self.check(&token::Not) { @@ -2435,10 +2431,18 @@ impl<'a> Parser<'a> { hi = pth.span.hi; ex = ExprKind::Path(None, pth); } else { - // other literal expression - let lit = self.parse_lit()?; - hi = lit.span.hi; - ex = ExprKind::Lit(P(lit)); + match self.parse_lit() { + Ok(lit) => { + hi = lit.span.hi; + ex = ExprKind::Lit(P(lit)); + } + Err(mut err) => { + err.cancel(); + let msg = format!("expected expression, found {}", + self.this_token_descr()); + return Err(self.fatal(&msg)); + } + } } } } @@ -2577,7 +2581,7 @@ impl<'a> Parser<'a> { // expr.f if self.eat(&token::Dot) { match self.token { - token::Ident(i, _) => { + token::Ident(i) => { let dot_pos = self.last_span.hi; hi = self.span.hi; self.bump(); @@ -2632,7 +2636,7 @@ impl<'a> Parser<'a> { self.span_err(self.span, &format!("unexpected token: `{}`", actual)); let dot_pos = self.last_span.hi; - e = self.parse_dot_suffix(special_idents::invalid, + e = self.parse_dot_suffix(keywords::Invalid.ident(), mk_sp(dot_pos, dot_pos), e, lo)?; } @@ -2674,7 +2678,7 @@ impl<'a> Parser<'a> { // Parse unquoted tokens after a `$` in a token tree fn parse_unquoted(&mut self) -> PResult<'a, TokenTree> { let mut sp = self.span; - let (name, namep) = match self.token { + let name = match self.token { token::Dollar => { self.bump(); @@ -2694,40 +2698,36 @@ impl<'a> Parser<'a> { op: repeat, num_captures: name_num }))); - } else if self.token.is_keyword_allow_following_colon(keywords::Crate) { + } else if self.token.is_keyword(keywords::Crate) { self.bump(); return Ok(TokenTree::Token(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar))); } else { sp = mk_sp(sp.lo, self.span.hi); - let namep = match self.token { token::Ident(_, p) => p, _ => token::Plain }; - let name = self.parse_ident()?; - (name, namep) + self.parse_ident()? } } - token::SubstNt(name, namep) => { + token::SubstNt(name) => { self.bump(); - (name, namep) + name } _ => unreachable!() }; // continue by trying to parse the `:ident` after `$name` - if self.token == token::Colon && self.look_ahead(1, |t| t.is_ident() && - !t.is_strict_keyword() && - !t.is_reserved_keyword()) { + if self.token == token::Colon && + self.look_ahead(1, |t| t.is_ident() && !t.is_any_keyword()) { self.bump(); sp = mk_sp(sp.lo, self.span.hi); - let kindp = match self.token { token::Ident(_, p) => p, _ => token::Plain }; let nt_kind = self.parse_ident()?; - Ok(TokenTree::Token(sp, MatchNt(name, nt_kind, namep, kindp))) + Ok(TokenTree::Token(sp, MatchNt(name, nt_kind))) } else { - Ok(TokenTree::Token(sp, SubstNt(name, namep))) + Ok(TokenTree::Token(sp, SubstNt(name))) } } pub fn check_unknown_macro_variable(&mut self) { if self.quote_depth == 0 { match self.token { - token::SubstNt(name, _) => + token::SubstNt(name) => self.fatal(&format!("unknown macro variable `{}`", name)).emit(), _ => {} } @@ -3225,13 +3225,15 @@ impl<'a> Parser<'a> { Ok(self.mk_expr(lo, hi, ExprKind::IfLet(pat, expr, thn, els), attrs)) } - // `|args| expr` - pub fn parse_lambda_expr(&mut self, lo: BytePos, + // `move |args| expr` + pub fn parse_lambda_expr(&mut self, + lo: BytePos, capture_clause: CaptureBy, attrs: ThinAttributes) -> PResult<'a, P<Expr>> { let decl = self.parse_fn_block_decl()?; + let decl_hi = self.last_span.hi; let body = match decl.output { FunctionRetTy::Default(_) => { // If no explicit return type is given, parse any @@ -3255,7 +3257,8 @@ impl<'a> Parser<'a> { Ok(self.mk_expr( lo, body.span.hi, - ExprKind::Closure(capture_clause, decl, body), attrs)) + ExprKind::Closure(capture_clause, decl, body, mk_sp(lo, decl_hi)), + attrs)) } // `else` token already eaten @@ -3587,16 +3590,16 @@ impl<'a> Parser<'a> { } fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> { - if self.is_path_start() { + if self.token.is_path_start() { let lo = self.span.lo; let (qself, path) = if self.eat_lt() { // Parse a qualified path let (qself, path) = - self.parse_qualified_path(NoTypesAllowed)?; + self.parse_qualified_path(PathStyle::Expr)?; (Some(qself), path) } else { // Parse an unqualified path - (None, self.parse_path(LifetimeAndTypesWithColons)?) + (None, self.parse_path(PathStyle::Expr)?) }; let hi = self.last_span.hi; Ok(self.mk_expr(lo, hi, ExprKind::Path(qself, path), None)) @@ -3605,12 +3608,6 @@ impl<'a> Parser<'a> { } } - fn is_path_start(&self) -> bool { - (self.token == token::Lt || self.token == token::ModSep - || self.token.is_ident() || self.token.is_path()) - && !self.token.is_keyword(keywords::True) && !self.token.is_keyword(keywords::False) - } - /// Parse a pattern. pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> { maybe_whole!(self, NtPat); @@ -3661,19 +3658,16 @@ impl<'a> Parser<'a> { // Parse box pat let subpat = self.parse_pat()?; pat = PatKind::Box(subpat); - } else if self.is_path_start() { + } else if self.token.is_path_start() { // Parse pattern starting with a path - if self.token.is_plain_ident() && self.look_ahead(1, |t| *t != token::DotDotDot && + if self.token.is_ident() && self.look_ahead(1, |t| *t != token::DotDotDot && *t != token::OpenDelim(token::Brace) && *t != token::OpenDelim(token::Paren) && - // Contrary to its definition, a plain ident can be followed by :: in macros *t != token::ModSep) { // Plain idents have some extra abilities here compared to general paths if self.look_ahead(1, |t| *t == token::Not) { // Parse macro invocation - let ident = self.parse_ident()?; - let ident_span = self.last_span; - let path = ast::Path::from_ident(ident_span, ident); + let path = self.parse_ident_into_path()?; self.bump(); let delim = self.expect_open_delim()?; let tts = self.parse_seq_to_end( @@ -3693,11 +3687,11 @@ impl<'a> Parser<'a> { let (qself, path) = if self.eat_lt() { // Parse a qualified path let (qself, path) = - self.parse_qualified_path(NoTypesAllowed)?; + self.parse_qualified_path(PathStyle::Expr)?; (Some(qself), path) } else { // Parse an unqualified path - (None, self.parse_path(LifetimeAndTypesWithColons)?) + (None, self.parse_path(PathStyle::Expr)?) }; match self.token { token::DotDotDot => { @@ -3754,12 +3748,20 @@ impl<'a> Parser<'a> { } } else { // Try to parse everything else as literal with optional minus - let begin = self.parse_pat_literal_maybe_minus()?; - if self.eat(&token::DotDotDot) { - let end = self.parse_pat_range_end()?; - pat = PatKind::Range(begin, end); - } else { - pat = PatKind::Lit(begin); + match self.parse_pat_literal_maybe_minus() { + Ok(begin) => { + if self.eat(&token::DotDotDot) { + let end = self.parse_pat_range_end()?; + pat = PatKind::Range(begin, end); + } else { + pat = PatKind::Lit(begin); + } + } + Err(mut err) => { + err.cancel(); + let msg = format!("expected pattern, found {}", self.this_token_descr()); + return Err(self.fatal(&msg)); + } } } } @@ -3956,11 +3958,11 @@ impl<'a> Parser<'a> { // Potential trouble: if we allow macros with paths instead of // idents, we'd need to look ahead past the whole path here... - let pth = self.parse_path(NoTypesAllowed)?; + let pth = self.parse_ident_into_path()?; self.bump(); let id = match self.token { - token::OpenDelim(_) => token::special_idents::invalid, // no special identifier + token::OpenDelim(_) => keywords::Invalid.ident(), // no special identifier _ => self.parse_ident()?, }; @@ -3972,7 +3974,7 @@ impl<'a> Parser<'a> { _ => { // we only expect an ident if we didn't parse one // above. - let ident_str = if id.name == token::special_idents::invalid.name { + let ident_str = if id.name == keywords::Invalid.name() { "identifier, " } else { "" @@ -3998,7 +4000,7 @@ impl<'a> Parser<'a> { MacStmtStyle::NoBraces }; - if id.name == token::special_idents::invalid.name { + if id.name == keywords::Invalid.name() { let mac = P(spanned(lo, hi, Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })); let stmt = StmtKind::Mac(mac, style, attrs.into_thin_attrs()); spanned(lo, hi, stmt) @@ -4240,7 +4242,7 @@ impl<'a> Parser<'a> { -> PResult<'a, TyParamBounds> { if !self.eat(&token::Colon) { - Ok(P::empty()) + Ok(P::new()) } else { self.parse_ty_param_bounds(mode) } @@ -4626,17 +4628,12 @@ impl<'a> Parser<'a> { })) } - fn is_self_ident(&mut self) -> bool { - match self.token { - token::Ident(id, token::Plain) => id.name == special_idents::self_.name, - _ => false - } - } - fn expect_self_ident(&mut self) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(id, token::Plain) if id.name == special_idents::self_.name => { + token::Ident(id) if id.name == keywords::SelfValue.name() => { self.bump(); + // The hygiene context of `id` needs to be preserved here, + // so we can't just return `SelfValue.ident()`. Ok(id) }, _ => { @@ -4647,27 +4644,6 @@ impl<'a> Parser<'a> { } } - fn is_self_type_ident(&mut self) -> bool { - match self.token { - token::Ident(id, token::Plain) => id.name == special_idents::type_self.name, - _ => false - } - } - - fn expect_self_type_ident(&mut self) -> PResult<'a, ast::Ident> { - match self.token { - token::Ident(id, token::Plain) if id.name == special_idents::type_self.name => { - self.bump(); - Ok(id) - }, - _ => { - let token_str = self.this_token_to_string(); - Err(self.fatal(&format!("expected `Self`, found `{}`", - token_str))) - } - } - } - /// Parse the argument list and result type of a function /// that may have a self type. fn parse_fn_decl_with_self<F>(&mut self, @@ -4736,16 +4712,16 @@ impl<'a> Parser<'a> { } else { Mutability::Immutable }; - if self.is_self_ident() { + if self.token.is_keyword(keywords::SelfValue) { let span = self.span; self.span_err(span, "cannot pass self by raw pointer"); self.bump(); } // error case, making bogus self ident: - SelfKind::Value(special_idents::self_) + SelfKind::Value(keywords::SelfValue.ident()) } token::Ident(..) => { - if self.is_self_ident() { + if self.token.is_keyword(keywords::SelfValue) { let self_ident = self.expect_self_ident()?; // Determine whether this is the fully explicit form, `self: @@ -4969,7 +4945,7 @@ impl<'a> Parser<'a> { Visibility::Inherited => (), _ => { let is_macro_rules: bool = match self.token { - token::Ident(sid, _) => sid.name == intern("macro_rules"), + token::Ident(sid) => sid.name == intern("macro_rules"), _ => false, }; if is_macro_rules { @@ -5002,7 +4978,7 @@ impl<'a> Parser<'a> { self.complain_if_pub_macro(&vis, last_span); let lo = self.span.lo; - let pth = self.parse_path(NoTypesAllowed)?; + let pth = self.parse_ident_into_path()?; self.expect(&token::Not)?; // eat a matched-delimiter token tree: @@ -5017,7 +4993,7 @@ impl<'a> Parser<'a> { if delim != token::Brace { self.expect(&token::Semi)? } - Ok((token::special_idents::invalid, vec![], ast::ImplItemKind::Macro(m))) + Ok((keywords::Invalid.ident(), vec![], ast::ImplItemKind::Macro(m))) } else { let (constness, unsafety, abi) = self.parse_fn_front_matter()?; let ident = self.parse_ident()?; @@ -5112,7 +5088,7 @@ impl<'a> Parser<'a> { self.expect(&token::OpenDelim(token::Brace))?; self.expect(&token::CloseDelim(token::Brace))?; - Ok((special_idents::invalid, + Ok((keywords::Invalid.ident(), ItemKind::DefaultImpl(unsafety, opt_trait.unwrap()), None)) } else { if opt_trait.is_some() { @@ -5128,7 +5104,7 @@ impl<'a> Parser<'a> { impl_items.push(self.parse_impl_item()?); } - Ok((special_idents::invalid, + Ok((keywords::Invalid.ident(), ItemKind::Impl(unsafety, polarity, generics, opt_trait, ty, impl_items), Some(attrs))) } @@ -5137,7 +5113,7 @@ impl<'a> Parser<'a> { /// Parse a::B<String,i32> fn parse_trait_ref(&mut self) -> PResult<'a, TraitRef> { Ok(ast::TraitRef { - path: self.parse_path(LifetimeAndTypesWithoutColons)?, + path: self.parse_path(PathStyle::Type)?, ref_id: ast::DUMMY_NODE_ID, }) } @@ -5297,8 +5273,7 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Paren))?; Ok(Visibility::Crate(span)) } else { - let path = self.with_res(Restrictions::ALLOW_MODULE_PATHS, - |this| this.parse_path(NoTypesAllowed))?; + let path = self.parse_path(PathStyle::Mod)?; self.expect(&token::CloseDelim(token::Paren))?; Ok(Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID }) } @@ -5306,7 +5281,7 @@ impl<'a> Parser<'a> { /// Parse defaultness: DEFAULT or nothing fn parse_defaultness(&mut self) -> PResult<'a, Defaultness> { - if self.eat_contextual_keyword(special_idents::DEFAULT) { + if self.eat_contextual_keyword(keywords::Default.ident()) { Ok(Defaultness::Default) } else { Ok(Defaultness::Final) @@ -5634,7 +5609,7 @@ impl<'a> Parser<'a> { }; Ok(self.mk_item(lo, last_span.hi, - special_idents::invalid, + keywords::Invalid.ident(), ItemKind::ForeignMod(m), visibility, attrs)) @@ -5773,7 +5748,7 @@ impl<'a> Parser<'a> { let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, - token::special_idents::invalid, + keywords::Invalid.ident(), item_, visibility, attrs); @@ -6044,7 +6019,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, Option<P<Item>>> { if macros_allowed && !self.token.is_any_keyword() && self.look_ahead(1, |t| *t == token::Not) - && (self.look_ahead(2, |t| t.is_plain_ident()) + && (self.look_ahead(2, |t| t.is_ident()) || self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren)) || self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))) { // MACRO INVOCATION ITEM @@ -6055,16 +6030,16 @@ impl<'a> Parser<'a> { let mac_lo = self.span.lo; // item macro. - let pth = self.parse_path(NoTypesAllowed)?; + let pth = self.parse_ident_into_path()?; self.expect(&token::Not)?; // a 'special' identifier (like what `macro_rules!` uses) // is optional. We should eventually unify invoc syntax // and remove this. - let id = if self.token.is_plain_ident() { + let id = if self.token.is_ident() { self.parse_ident()? } else { - token::special_idents::invalid // no special identifier + keywords::Invalid.ident() // no special identifier }; // eat a matched-delimiter token tree: let delim = self.expect_open_delim()?; @@ -6161,7 +6136,7 @@ impl<'a> Parser<'a> { let items = self.parse_path_list_items()?; Ok(P(spanned(lo, self.span.hi, ViewPathList(prefix, items)))) } else { - let prefix = self.parse_path(ImportPrefix)?; + let prefix = self.parse_path(PathStyle::Mod)?; if self.is_import_coupler() { // `foo::bar::{a, b}` or `foo::bar::*` self.bump(); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 16417ac0044..fcb6c3539db 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -11,7 +11,6 @@ pub use self::BinOpToken::*; pub use self::Nonterminal::*; pub use self::DelimToken::*; -pub use self::IdentStyle::*; pub use self::Lit::*; pub use self::Token::*; @@ -26,7 +25,6 @@ use std::fmt; use std::ops::Deref; use std::rc::Rc; -#[allow(non_camel_case_types)] #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] pub enum BinOpToken { Plus, @@ -53,13 +51,6 @@ pub enum DelimToken { } #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] -pub enum IdentStyle { - /// `::` follows the identifier with no whitespace in-between. - ModName, - Plain, -} - -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] pub enum SpecialMacroVar { /// `$crate` will be filled in with the name of the crate a macro was /// imported from, if any. @@ -99,7 +90,6 @@ impl Lit { } } -#[allow(non_camel_case_types)] #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug)] pub enum Token { /* Expression-operator symbols. */ @@ -141,7 +131,7 @@ pub enum Token { Literal(Lit, Option<ast::Name>), /* Name components */ - Ident(ast::Ident, IdentStyle), + Ident(ast::Ident), Underscore, Lifetime(ast::Ident), @@ -151,11 +141,11 @@ pub enum Token { /// Doc comment DocComment(ast::Name), // In left-hand-sides of MBE macros: - /// Parse a nonterminal (name to bind, name of NT, styles of their idents) - MatchNt(ast::Ident, ast::Ident, IdentStyle, IdentStyle), + /// Parse a nonterminal (name to bind, name of NT) + MatchNt(ast::Ident, ast::Ident), // In right-hand-sides of MBE macros: /// A syntactic variable that will be filled in by macro expansion. - SubstNt(ast::Ident, IdentStyle), + SubstNt(ast::Ident), /// A macro variable with special meaning. SpecialVarNt(SpecialMacroVar), @@ -185,7 +175,7 @@ impl Token { pub fn can_begin_expr(&self) -> bool { match *self { OpenDelim(_) => true, - Ident(_, _) => true, + Ident(..) => true, Underscore => true, Tilde => true, Literal(_, _) => true, @@ -218,7 +208,7 @@ impl Token { /// Returns `true` if the token is an identifier. pub fn is_ident(&self) -> bool { match *self { - Ident(_, _) => true, + Ident(..) => true, _ => false, } } @@ -239,16 +229,6 @@ impl Token { } } - /// Returns `true` if the token is a path that is not followed by a `::` - /// token. - #[allow(non_upper_case_globals)] - pub fn is_plain_ident(&self) -> bool { - match *self { - Ident(_, Plain) => true, - _ => false, - } - } - /// Returns `true` if the token is a lifetime. pub fn is_lifetime(&self) -> bool { match *self { @@ -263,6 +243,11 @@ impl Token { self.is_keyword(keywords::Const) } + pub fn is_path_start(&self) -> bool { + self == &ModSep || self == &Lt || self.is_path() || + self.is_path_segment_keyword() || self.is_ident() && !self.is_any_keyword() + } + /// Maps a token to its corresponding binary operator. pub fn to_binop(&self) -> Option<BinOpKind> { match *self { @@ -289,77 +274,41 @@ impl Token { } /// Returns `true` if the token is a given keyword, `kw`. - #[allow(non_upper_case_globals)] pub fn is_keyword(&self, kw: keywords::Keyword) -> bool { match *self { - Ident(sid, Plain) => kw.to_name() == sid.name, - _ => false, + Ident(id) => id.name == kw.name(), + _ => false, } } - pub fn is_keyword_allow_following_colon(&self, kw: keywords::Keyword) -> bool { + pub fn is_path_segment_keyword(&self) -> bool { match *self { - Ident(sid, _) => { kw.to_name() == sid.name } - _ => { false } + Ident(id) => id.name == keywords::Super.name() || + id.name == keywords::SelfValue.name() || + id.name == keywords::SelfType.name(), + _ => false, } } - /// Returns `true` if the token is either a special identifier, or a strict - /// or reserved keyword. - #[allow(non_upper_case_globals)] + /// Returns `true` if the token is either a strict or reserved keyword. pub fn is_any_keyword(&self) -> bool { - match *self { - Ident(sid, Plain) => { - let n = sid.name; - - n == SELF_KEYWORD_NAME - || n == STATIC_KEYWORD_NAME - || n == SUPER_KEYWORD_NAME - || n == SELF_TYPE_KEYWORD_NAME - || STRICT_KEYWORD_START <= n - && n <= RESERVED_KEYWORD_FINAL - }, - _ => false - } + self.is_strict_keyword() || self.is_reserved_keyword() } - /// Returns `true` if the token may not appear as an identifier. - #[allow(non_upper_case_globals)] + /// Returns `true` if the token is a strict keyword. pub fn is_strict_keyword(&self) -> bool { match *self { - Ident(sid, Plain) => { - let n = sid.name; - - n == SELF_KEYWORD_NAME - || n == STATIC_KEYWORD_NAME - || n == SUPER_KEYWORD_NAME - || n == SELF_TYPE_KEYWORD_NAME - || STRICT_KEYWORD_START <= n - && n <= STRICT_KEYWORD_FINAL - }, - Ident(sid, ModName) => { - let n = sid.name; - - n != SELF_KEYWORD_NAME - && n != SUPER_KEYWORD_NAME - && STRICT_KEYWORD_START <= n - && n <= STRICT_KEYWORD_FINAL - } + Ident(id) => id.name >= keywords::As.name() && + id.name <= keywords::While.name(), _ => false, } } - /// Returns `true` if the token is a keyword that has been reserved for - /// possible future use. - #[allow(non_upper_case_globals)] + /// Returns `true` if the token is a keyword reserved for possible future use. pub fn is_reserved_keyword(&self) -> bool { match *self { - Ident(sid, Plain) => { - let n = sid.name; - - RESERVED_KEYWORD_START <= n - && n <= RESERVED_KEYWORD_FINAL - }, + Ident(id) => id.name >= keywords::Abstract.name() && + id.name <= keywords::Yield.name(), _ => false, } } @@ -369,7 +318,7 @@ impl Token { /// See `styntax::ext::mtwt`. pub fn mtwt_eq(&self, other : &Token) -> bool { match (self, other) { - (&Ident(id1,_), &Ident(id2,_)) | (&Lifetime(id1), &Lifetime(id2)) => + (&Ident(id1), &Ident(id2)) | (&Lifetime(id1), &Lifetime(id2)) => mtwt::resolve(id1) == mtwt::resolve(id2), _ => *self == *other } @@ -385,7 +334,7 @@ pub enum Nonterminal { NtPat(P<ast::Pat>), NtExpr(P<ast::Expr>), NtTy(P<ast::Ty>), - NtIdent(Box<ast::SpannedIdent>, IdentStyle), + NtIdent(Box<ast::SpannedIdent>), /// Stuff inside brackets for attributes NtMeta(P<ast::MetaItem>), NtPath(Box<ast::Path>), @@ -422,191 +371,104 @@ impl fmt::Debug for Nonterminal { } } - -// Get the first "argument" -macro_rules! first { - ( $first:expr, $( $remainder:expr, )* ) => ( $first ) -} - -// Get the last "argument" (has to be done recursively to avoid phoney local ambiguity error) -macro_rules! last { - ( $first:expr, $( $remainder:expr, )+ ) => ( last!( $( $remainder, )+ ) ); - ( $first:expr, ) => ( $first ) -} - // In this macro, there is the requirement that the name (the number) must be monotonically // increasing by one in the special identifiers, starting at 0; the same holds for the keywords, -// except starting from the next number instead of zero, and with the additional exception that -// special identifiers are *also* allowed (they are deduplicated in the important place, the -// interner), an exception which is demonstrated by "static" and "self". -macro_rules! declare_special_idents_and_keywords {( - // So now, in these rules, why is each definition parenthesised? - // Answer: otherwise we get a spurious local ambiguity bug on the "}" - pub mod special_idents { - $( ($si_name:expr, $si_static:ident, $si_str:expr); )* - } - - pub mod keywords { - 'strict: - $( ($sk_name:expr, $sk_variant:ident, $sk_str:expr); )* - 'reserved: - $( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )* - } +// except starting from the next number instead of zero. +macro_rules! declare_keywords {( + $( ($index: expr, $konst: ident, $string: expr) )* ) => { - const STRICT_KEYWORD_START: ast::Name = first!($( ast::Name($sk_name), )*); - const STRICT_KEYWORD_FINAL: ast::Name = last!($( ast::Name($sk_name), )*); - const RESERVED_KEYWORD_START: ast::Name = first!($( ast::Name($rk_name), )*); - const RESERVED_KEYWORD_FINAL: ast::Name = last!($( ast::Name($rk_name), )*); - - pub mod special_idents { - use ast; - $( - #[allow(non_upper_case_globals)] - pub const $si_static: ast::Ident = ast::Ident { - name: ast::Name($si_name), - ctxt: ast::EMPTY_CTXT, - }; - )* - } - - pub mod special_names { - use ast; - $( - #[allow(non_upper_case_globals)] - pub const $si_static: ast::Name = ast::Name($si_name); - )* - } - - /// All the valid words that have meaning in the Rust language. - /// - /// Rust keywords are either 'strict' or 'reserved'. Strict keywords may not - /// appear as identifiers at all. Reserved keywords are not used anywhere in - /// the language and may not appear as identifiers. pub mod keywords { - pub use self::Keyword::*; use ast; - - #[derive(Copy, Clone, PartialEq, Eq)] - pub enum Keyword { - $( $sk_variant, )* - $( $rk_variant, )* + #[derive(Clone, Copy, PartialEq, Eq)] + pub struct Keyword { + ident: ast::Ident, } - impl Keyword { - pub fn to_name(&self) -> ast::Name { - match *self { - $( $sk_variant => ast::Name($sk_name), )* - $( $rk_variant => ast::Name($rk_name), )* - } - } + #[inline] pub fn ident(self) -> ast::Ident { self.ident } + #[inline] pub fn name(self) -> ast::Name { self.ident.name } } + $( + #[allow(non_upper_case_globals)] + pub const $konst: Keyword = Keyword { + ident: ast::Ident::with_empty_ctxt(ast::Name($index)) + }; + )* } fn mk_fresh_ident_interner() -> IdentInterner { - let mut init_vec = Vec::new(); - $(init_vec.push($si_str);)* - $(init_vec.push($sk_str);)* - $(init_vec.push($rk_str);)* - interner::StrInterner::prefill(&init_vec[..]) + interner::StrInterner::prefill(&[$($string,)*]) } }} -// If the special idents get renumbered, remember to modify these two as appropriate -pub const SELF_KEYWORD_NAME: ast::Name = ast::Name(SELF_KEYWORD_NAME_NUM); -const STATIC_KEYWORD_NAME: ast::Name = ast::Name(STATIC_KEYWORD_NAME_NUM); -pub const SUPER_KEYWORD_NAME: ast::Name = ast::Name(SUPER_KEYWORD_NAME_NUM); -const SELF_TYPE_KEYWORD_NAME: ast::Name = ast::Name(SELF_TYPE_KEYWORD_NAME_NUM); - -pub const SELF_KEYWORD_NAME_NUM: u32 = 1; -const STATIC_KEYWORD_NAME_NUM: u32 = 2; -const SUPER_KEYWORD_NAME_NUM: u32 = 3; -const SELF_TYPE_KEYWORD_NAME_NUM: u32 = 10; - // 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 // of the reserved words, and thus tagged as "reserved". - -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"); - (super::SUPER_KEYWORD_NAME_NUM, super_, "super"); - (4, static_lifetime, "'static"); - - // for matcher NTs - (5, tt, "tt"); - (6, matchers, "matchers"); - - // outside of libsyntax - (7, clownshoe_abi, "__rust_abi"); - (8, opaque, "<opaque>"); - (9, __unused1, "<__unused1>"); - (super::SELF_TYPE_KEYWORD_NAME_NUM, type_self, "Self"); - (11, prelude_import, "prelude_import"); - (12, DEFAULT, "default"); - } - - pub mod keywords { - // These ones are variants of the Keyword enum - - 'strict: - (13, As, "as"); - (14, Break, "break"); - (15, Crate, "crate"); - (16, Else, "else"); - (17, Enum, "enum"); - (18, Extern, "extern"); - (19, False, "false"); - (20, Fn, "fn"); - (21, For, "for"); - (22, If, "if"); - (23, Impl, "impl"); - (24, In, "in"); - (25, Let, "let"); - (26, Loop, "loop"); - (27, Match, "match"); - (28, Mod, "mod"); - (29, Move, "move"); - (30, Mut, "mut"); - (31, Pub, "pub"); - (32, Ref, "ref"); - (33, Return, "return"); - // Static and Self are also special idents (prefill de-dupes) - (super::STATIC_KEYWORD_NAME_NUM, Static, "static"); - (super::SELF_KEYWORD_NAME_NUM, SelfValue, "self"); - (super::SELF_TYPE_KEYWORD_NAME_NUM, SelfType, "Self"); - (34, Struct, "struct"); - (super::SUPER_KEYWORD_NAME_NUM, Super, "super"); - (35, True, "true"); - (36, Trait, "trait"); - (37, Type, "type"); - (38, Unsafe, "unsafe"); - (39, Use, "use"); - (40, While, "while"); - (41, Continue, "continue"); - (42, Box, "box"); - (43, Const, "const"); - (44, Where, "where"); - 'reserved: - (45, Virtual, "virtual"); - (46, Proc, "proc"); - (47, Alignof, "alignof"); - (48, Become, "become"); - (49, Offsetof, "offsetof"); - (50, Priv, "priv"); - (51, Pure, "pure"); - (52, Sizeof, "sizeof"); - (53, Typeof, "typeof"); - (54, Unsized, "unsized"); - (55, Yield, "yield"); - (56, Do, "do"); - (57, Abstract, "abstract"); - (58, Final, "final"); - (59, Override, "override"); - (60, Macro, "macro"); - } +// After modifying this list adjust `is_strict_keyword`/`is_reserved_keyword`, +// this should be rarely necessary though if the keywords are kept in alphabetic order. +declare_keywords! { + // Invalid identifier + (0, Invalid, "") + + // Strict keywords used in the language. + (1, As, "as") + (2, Box, "box") + (3, Break, "break") + (4, Const, "const") + (5, Continue, "continue") + (6, Crate, "crate") + (7, Else, "else") + (8, Enum, "enum") + (9, Extern, "extern") + (10, False, "false") + (11, Fn, "fn") + (12, For, "for") + (13, If, "if") + (14, Impl, "impl") + (15, In, "in") + (16, Let, "let") + (17, Loop, "loop") + (18, Match, "match") + (19, Mod, "mod") + (20, Move, "move") + (21, Mut, "mut") + (22, Pub, "pub") + (23, Ref, "ref") + (24, Return, "return") + (25, SelfValue, "self") + (26, SelfType, "Self") + (27, Static, "static") + (28, Struct, "struct") + (29, Super, "super") + (30, Trait, "trait") + (31, True, "true") + (32, Type, "type") + (33, Unsafe, "unsafe") + (34, Use, "use") + (35, Where, "where") + (36, While, "while") + + // Keywords reserved for future use. + (37, Abstract, "abstract") + (38, Alignof, "alignof") + (39, Become, "become") + (40, Do, "do") + (41, Final, "final") + (42, Macro, "macro") + (43, Offsetof, "offsetof") + (44, Override, "override") + (45, Priv, "priv") + (46, Proc, "proc") + (47, Pure, "pure") + (48, Sizeof, "sizeof") + (49, Typeof, "typeof") + (50, Unsized, "unsized") + (51, Virtual, "virtual") + (52, Yield, "yield") + + // Weak keywords, have special meaning only in specific contexts. + (53, Default, "default") + (54, StaticLifetime, "'static") + (55, Union, "union") } // looks like we can get rid of this completely... @@ -779,6 +641,6 @@ mod tests { assert!(Gt.mtwt_eq(&Gt)); let a = str_to_ident("bac"); let a1 = mark_ident(a,92); - assert!(Ident(a, ModName).mtwt_eq(&Ident(a1, Plain))); + assert!(Ident(a).mtwt_eq(&Ident(a1))); } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 95f1b63168b..7bfc58e85c2 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -20,7 +20,7 @@ use attr; use attr::{AttrMetaMethods, AttributeMethods}; use codemap::{self, CodeMap, BytePos}; use errors; -use parse::token::{self, BinOpToken, Token, InternedString}; +use parse::token::{self, keywords, BinOpToken, Token, InternedString}; use parse::lexer::comments; use parse; use print::pp::{self, break_offset, word, space, zerobreak, hardbreak}; @@ -270,14 +270,14 @@ pub fn token_to_string(tok: &Token) -> String { } /* Name components */ - token::Ident(s, _) => s.to_string(), + token::Ident(s) => s.to_string(), token::Lifetime(s) => s.to_string(), token::Underscore => "_".to_string(), /* Other */ token::DocComment(s) => s.to_string(), - token::SubstNt(s, _) => format!("${}", s), - token::MatchNt(s, t, _, _) => format!("${}:{}", s, t), + token::SubstNt(s) => format!("${}", s), + token::MatchNt(s, t) => format!("${}:{}", s, t), token::Eof => "<eof>".to_string(), token::Whitespace => " ".to_string(), token::Comment => "/* */".to_string(), @@ -294,7 +294,7 @@ pub fn token_to_string(tok: &Token) -> String { token::NtBlock(ref e) => block_to_string(&e), token::NtStmt(ref e) => stmt_to_string(&e), token::NtPat(ref e) => pat_to_string(&e), - token::NtIdent(ref e, _) => ident_to_string(e.node), + token::NtIdent(ref e) => ident_to_string(e.node), token::NtTT(ref e) => tt_to_string(&e), token::NtArm(ref e) => arm_to_string(&e), token::NtImplItem(ref e) => impl_item_to_string(&e), @@ -995,7 +995,7 @@ impl<'a> State<'a> { ast::TyKind::BareFn(ref f) => { let generics = ast::Generics { lifetimes: f.lifetimes.clone(), - ty_params: P::empty(), + ty_params: P::new(), where_clause: ast::WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), @@ -1488,20 +1488,11 @@ impl<'a> State<'a> { pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> io::Result<()> { self.ibox(0)?; - let mut suppress_space = false; for (i, tt) in tts.iter().enumerate() { - if i != 0 && !suppress_space { + if i != 0 { space(&mut self.s)?; } self.print_tt(tt)?; - // There should be no space between the module name and the following `::` in paths, - // otherwise imported macros get re-parsed from crate metadata incorrectly (#20701) - suppress_space = match *tt { - TokenTree::Token(_, token::Ident(_, token::ModName)) | - TokenTree::Token(_, token::MatchNt(_, _, _, token::ModName)) | - TokenTree::Token(_, token::SubstNt(_, token::ModName)) => true, - _ => false - } } self.end() } @@ -2086,7 +2077,7 @@ impl<'a> State<'a> { } self.bclose_(expr.span, INDENT_UNIT)?; } - ast::ExprKind::Closure(capture_clause, ref decl, ref body) => { + ast::ExprKind::Closure(capture_clause, ref decl, ref body, _) => { self.print_capture_clause(capture_clause)?; self.print_fn_block_args(&decl)?; @@ -2966,9 +2957,8 @@ impl<'a> State<'a> { ast::TyKind::Infer if is_closure => self.print_pat(&input.pat)?, _ => { match input.pat.node { - PatKind::Ident(_, ref path1, _) if - path1.node.name == - parse::token::special_idents::invalid.name => { + PatKind::Ident(_, ref path1, _) + if path1.node.name == keywords::Invalid.name() => { // Do nothing. } _ => { @@ -3021,7 +3011,7 @@ impl<'a> State<'a> { } let generics = ast::Generics { lifetimes: Vec::new(), - ty_params: P::empty(), + ty_params: P::new(), where_clause: ast::WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index fda9741d35c..9d04cb75daa 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -83,10 +83,10 @@ impl<T: 'static> P<T> { } } -impl<T> Deref for P<T> { +impl<T: ?Sized> Deref for P<T> { type Target = T; - fn deref<'a>(&'a self) -> &'a T { + fn deref(&self) -> &T { &self.ptr } } @@ -97,11 +97,12 @@ impl<T: 'static + Clone> Clone for P<T> { } } -impl<T: Debug> Debug for P<T> { +impl<T: ?Sized + Debug> Debug for P<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&**self, f) + Debug::fmt(&self.ptr, f) } } + impl<T: Display> Display for P<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(&**self, f) @@ -126,19 +127,8 @@ impl<T: Encodable> Encodable for P<T> { } } - -impl<T:fmt::Debug> fmt::Debug for P<[T]> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - self.ptr.fmt(fmt) - } -} - impl<T> P<[T]> { pub fn new() -> P<[T]> { - P::empty() - } - - pub fn empty() -> P<[T]> { P { ptr: Default::default() } } @@ -151,31 +141,11 @@ impl<T> P<[T]> { pub fn into_vec(self) -> Vec<T> { self.ptr.into_vec() } - - pub fn as_slice<'a>(&'a self) -> &'a [T] { - &self.ptr - } - - pub fn move_iter(self) -> vec::IntoIter<T> { - self.into_vec().into_iter() - } - - pub fn map<U, F: FnMut(&T) -> U>(&self, f: F) -> P<[U]> { - self.iter().map(f).collect() - } -} - -impl<T> Deref for P<[T]> { - type Target = [T]; - - fn deref(&self) -> &[T] { - self.as_slice() - } } impl<T> Default for P<[T]> { fn default() -> P<[T]> { - P::empty() + P::new() } } diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 9049b21d8b4..84a7b144848 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -14,7 +14,7 @@ use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; use codemap; use fold::Folder; use fold; -use parse::token::{intern, InternedString, special_idents}; +use parse::token::{intern, InternedString, keywords}; use parse::{token, ParseSess}; use ptr::P; use util::small_vector::SmallVector; @@ -148,7 +148,7 @@ impl fold::Folder for PreludeInjector { let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path))); mod_.items.insert(0, P(ast::Item { id: ast::DUMMY_NODE_ID, - ident: special_idents::invalid, + ident: keywords::Invalid.ident(), node: ast::ItemKind::Use(vp), attrs: vec![ast::Attribute { span: self.span, @@ -157,7 +157,9 @@ impl fold::Folder for PreludeInjector { style: ast::AttrStyle::Outer, value: P(ast::MetaItem { span: self.span, - node: ast::MetaItemKind::Word(special_idents::prelude_import.name.as_str()), + node: ast::MetaItemKind::Word( + token::intern_and_get_ident("prelude_import") + ), }), is_sugared_doc: false, }, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 703b1611540..8eeb61e0de4 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -31,7 +31,7 @@ use ext::expand::ExpansionConfig; use fold::Folder; use util::move_map::MoveMap; use fold; -use parse::token::{intern, InternedString}; +use parse::token::{intern, keywords, InternedString}; use parse::{token, ParseSess}; use print::pprust; use ast; @@ -116,7 +116,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> { let ident = i.ident; - if ident.name != token::special_idents::invalid.name { + if ident.name != keywords::Invalid.name() { self.cx.path.push(ident); } debug!("current path: {}", path_name_i(&self.cx.path)); @@ -160,7 +160,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { ast::ItemKind::Mod(..) => fold::noop_fold_item(i, self), _ => SmallVector::one(i), }; - if ident.name != token::special_idents::invalid.name { + if ident.name != keywords::Invalid.name() { self.cx.path.pop(); } res @@ -453,7 +453,7 @@ fn mk_std(cx: &TestCtxt) -> P<ast::Item> { (ast::ItemKind::Use( P(nospan(ast::ViewPathSimple(id_test, path_node(vec!(id_test)))))), - ast::Visibility::Public, token::special_idents::invalid) + ast::Visibility::Public, keywords::Invalid.ident()) } else { (ast::ItemKind::ExternCrate(None), ast::Visibility::Inherited, id_test) }; @@ -545,7 +545,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) { P(ast::Item { id: ast::DUMMY_NODE_ID, - ident: token::special_idents::invalid, + ident: keywords::Invalid.ident(), attrs: vec![], node: ast::ItemKind::Use(P(use_path)), vis: ast::Visibility::Inherited, @@ -590,7 +590,7 @@ fn mk_tests(cx: &TestCtxt) -> P<ast::Item> { let struct_type = ecx.ty_path(ecx.path(sp, vec![ecx.ident_of("self"), ecx.ident_of("test"), ecx.ident_of("TestDescAndFn")])); - let static_lt = ecx.lifetime(sp, token::special_idents::static_lifetime.name); + let static_lt = ecx.lifetime(sp, keywords::StaticLifetime.name()); // &'static [self::test::TestDescAndFn] let static_type = ecx.ty_rptr(sp, ecx.ty(sp, ast::TyKind::Vec(struct_type)), diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 413017c7271..f50a480e5e5 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -743,7 +743,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(subexpression); walk_list!(visitor, visit_arm, arms); } - ExprKind::Closure(_, ref function_declaration, ref body) => { + ExprKind::Closure(_, ref function_declaration, ref body, _decl_span) => { visitor.visit_fn(FnKind::Closure, function_declaration, body, |
