From 9f94f823b0e6a89b4a210cb077f94919bfc7a118 Mon Sep 17 00:00:00 2001 From: John Clements Date: Sun, 6 Jul 2014 14:29:29 -0700 Subject: change if/else to match --- src/libsyntax/parse/parser.rs | 376 ++++++++++++++++++++++-------------------- 1 file changed, 197 insertions(+), 179 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a3917e93197..2f6555dcb69 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1877,211 +1877,229 @@ impl<'a> Parser<'a> { let ex: Expr_; - if self.token == token::LPAREN { - self.bump(); - // (e) is parenthesized e - // (e,) is a tuple with only one field, e - let mut trailing_comma = false; - if self.token == token::RPAREN { - hi = self.span.hi; - self.bump(); - let lit = box(GC) spanned(lo, hi, LitNil); - return self.mk_expr(lo, hi, ExprLit(lit)); - } - let mut es = vec!(self.parse_expr()); - self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]); - while self.token == token::COMMA { + match self.token { + token::LPAREN => { self.bump(); - if self.token != token::RPAREN { - es.push(self.parse_expr()); - self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]); + // (e) is parenthesized e + // (e,) is a tuple with only one field, e + let mut trailing_comma = false; + if self.token == token::RPAREN { + hi = self.span.hi; + self.bump(); + let lit = box(GC) spanned(lo, hi, LitNil); + return self.mk_expr(lo, hi, ExprLit(lit)); } - else { - trailing_comma = true; + let mut es = vec!(self.parse_expr()); + self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]); + while self.token == token::COMMA { + self.bump(); + if self.token != token::RPAREN { + es.push(self.parse_expr()); + self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]); + } + else { + trailing_comma = true; + } } - } - hi = self.span.hi; - self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN); - - return if es.len() == 1 && !trailing_comma { - self.mk_expr(lo, hi, ExprParen(*es.get(0))) - } - else { - self.mk_expr(lo, hi, ExprTup(es)) - } - } else if self.token == token::LBRACE { - self.bump(); - let blk = self.parse_block_tail(lo, DefaultBlock); - return self.mk_expr(blk.span.lo, blk.span.hi, - ExprBlock(blk)); - } else if token::is_bar(&self.token) { - return self.parse_lambda_expr(); - } else if self.eat_keyword(keywords::Proc) { - let decl = self.parse_proc_decl(); - let body = self.parse_expr(); - let fakeblock = P(ast::Block { - view_items: Vec::new(), - stmts: Vec::new(), - expr: Some(body), - id: ast::DUMMY_NODE_ID, - rules: DefaultBlock, - span: body.span, - }); + hi = self.span.hi; + self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN); - return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock)); - } else if self.eat_keyword(keywords::Self) { - let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_); - ex = ExprPath(path); - hi = self.last_span.hi; - } else if self.eat_keyword(keywords::If) { - return self.parse_if_expr(); - } else if self.eat_keyword(keywords::For) { - return self.parse_for_expr(None); - } else if self.eat_keyword(keywords::While) { - return self.parse_while_expr(); - } else if Parser::token_is_lifetime(&self.token) { - let lifetime = self.get_lifetime(); - self.bump(); - self.expect(&token::COLON); - if self.eat_keyword(keywords::For) { - return self.parse_for_expr(Some(lifetime)) - } else if self.eat_keyword(keywords::Loop) { - return self.parse_loop_expr(Some(lifetime)) - } else { - self.fatal("expected `for` or `loop` after a label") + return if es.len() == 1 && !trailing_comma { + self.mk_expr(lo, hi, ExprParen(*es.get(0))) + } + else { + self.mk_expr(lo, hi, ExprTup(es)) + } + }, + token::LBRACE => { + self.bump(); + let blk = self.parse_block_tail(lo, DefaultBlock); + return self.mk_expr(blk.span.lo, blk.span.hi, + ExprBlock(blk)); + }, + _ if token::is_bar(&self.token) => { + return self.parse_lambda_expr(); + }, + _ if self.eat_keyword(keywords::Proc) => { + let decl = self.parse_proc_decl(); + let body = self.parse_expr(); + let fakeblock = P(ast::Block { + view_items: Vec::new(), + stmts: Vec::new(), + expr: Some(body), + id: ast::DUMMY_NODE_ID, + rules: DefaultBlock, + span: body.span, + }); + return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock)); + }, + _ if self.eat_keyword(keywords::Self) => { + let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_); + ex = ExprPath(path); + hi = self.last_span.hi; } - } else if self.eat_keyword(keywords::Loop) { - return self.parse_loop_expr(None); - } else if self.eat_keyword(keywords::Continue) { - let lo = self.span.lo; - let ex = if Parser::token_is_lifetime(&self.token) { + _ if self.eat_keyword(keywords::If) => { + return self.parse_if_expr(); + }, + _ if self.eat_keyword(keywords::For) => { + return self.parse_for_expr(None); + }, + _ if self.eat_keyword(keywords::While) => { + return self.parse_while_expr(); + }, + _ if Parser::token_is_lifetime(&self.token) => { let lifetime = self.get_lifetime(); self.bump(); - ExprAgain(Some(lifetime)) - } else { - ExprAgain(None) - }; - let hi = self.span.hi; - return self.mk_expr(lo, hi, ex); - } else if self.eat_keyword(keywords::Match) { - return self.parse_match_expr(); - } else if self.eat_keyword(keywords::Unsafe) { - return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided)); - } else if self.token == token::LBRACKET { - self.bump(); - - if self.token == token::RBRACKET { - // Empty vector. - self.bump(); - ex = ExprVec(Vec::new()); - } else { - // Nonempty vector. - let first_expr = self.parse_expr(); - if self.token == token::COMMA && - self.look_ahead(1, |t| *t == token::DOTDOT) { - // Repeating vector syntax: [ 0, ..512 ] + self.expect(&token::COLON); + if self.eat_keyword(keywords::For) { + return self.parse_for_expr(Some(lifetime)) + } else if self.eat_keyword(keywords::Loop) { + return self.parse_loop_expr(Some(lifetime)) + } else { + self.fatal("expected `for` or `loop` after a label") + } + }, + _ if self.eat_keyword(keywords::Loop) => { + return self.parse_loop_expr(None); + }, + _ if self.eat_keyword(keywords::Continue) => { + let lo = self.span.lo; + let ex = if Parser::token_is_lifetime(&self.token) { + let lifetime = self.get_lifetime(); self.bump(); + ExprAgain(Some(lifetime)) + } else { + ExprAgain(None) + }; + let hi = self.span.hi; + return self.mk_expr(lo, hi, ex); + }, + _ if self.eat_keyword(keywords::Match) => { + return self.parse_match_expr(); + }, + _ if self.eat_keyword(keywords::Unsafe) => { + return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided)); + }, + token::LBRACKET => { + self.bump(); + + if self.token == token::RBRACKET { + // Empty vector. self.bump(); - let count = self.parse_expr(); - self.expect(&token::RBRACKET); - ex = ExprRepeat(first_expr, count); - } else if self.token == token::COMMA { - // Vector with two or more elements. + ex = ExprVec(Vec::new()); + } else { + // Nonempty vector. + let first_expr = self.parse_expr(); + if self.token == token::COMMA && + self.look_ahead(1, |t| *t == token::DOTDOT) { + // Repeating vector syntax: [ 0, ..512 ] + self.bump(); + self.bump(); + let count = self.parse_expr(); + self.expect(&token::RBRACKET); + ex = ExprRepeat(first_expr, count); + } else if self.token == token::COMMA { + // Vector with two or more elements. + self.bump(); + let remaining_exprs = self.parse_seq_to_end( + &token::RBRACKET, + seq_sep_trailing_allowed(token::COMMA), + |p| p.parse_expr() + ); + let mut exprs = vec!(first_expr); + exprs.push_all_move(remaining_exprs); + ex = ExprVec(exprs); + } else { + // Vector with one element. + self.expect(&token::RBRACKET); + ex = ExprVec(vec!(first_expr)); + } + } + hi = self.last_span.hi; + }, + _ if self.eat_keyword(keywords::Return) => { + // RETURN expression + if can_begin_expr(&self.token) { + let e = self.parse_expr(); + hi = e.span.hi; + ex = ExprRet(Some(e)); + } else { ex = ExprRet(None); } + }, + _ if self.eat_keyword(keywords::Break) => { + // BREAK expression + if Parser::token_is_lifetime(&self.token) { + let lifetime = self.get_lifetime(); self.bump(); - let remaining_exprs = self.parse_seq_to_end( - &token::RBRACKET, - seq_sep_trailing_allowed(token::COMMA), - |p| p.parse_expr() - ); - let mut exprs = vec!(first_expr); - exprs.push_all_move(remaining_exprs); - ex = ExprVec(exprs); + ex = ExprBreak(Some(lifetime)); } else { - // Vector with one element. - self.expect(&token::RBRACKET); - ex = ExprVec(vec!(first_expr)); + ex = ExprBreak(None); } - } - hi = self.last_span.hi; - } else if self.eat_keyword(keywords::Return) { - // RETURN expression - if can_begin_expr(&self.token) { - let e = self.parse_expr(); - hi = e.span.hi; - ex = ExprRet(Some(e)); - } else { ex = ExprRet(None); } - } else if self.eat_keyword(keywords::Break) { - // BREAK expression - if Parser::token_is_lifetime(&self.token) { - let lifetime = self.get_lifetime(); - self.bump(); - ex = ExprBreak(Some(lifetime)); - } else { - ex = ExprBreak(None); - } - hi = self.span.hi; - } else if self.token == token::MOD_SEP || + hi = self.span.hi; + }, + _ if self.token == token::MOD_SEP || is_ident(&self.token) && !self.is_keyword(keywords::True) && - !self.is_keyword(keywords::False) { - let pth = self.parse_path(LifetimeAndTypesWithColons).path; + !self.is_keyword(keywords::False) => { + let pth = self.parse_path(LifetimeAndTypesWithColons).path; - // `!`, as an operator, is prefix, so we know this isn't that - if self.token == token::NOT { - // MACRO INVOCATION expression - self.bump(); + // `!`, as an operator, is prefix, so we know this isn't that + if self.token == token::NOT { + // MACRO INVOCATION expression + self.bump(); - let ket = token::close_delimiter_for(&self.token) - .unwrap_or_else(|| self.fatal("expected open delimiter")); - self.bump(); + let ket = token::close_delimiter_for(&self.token) + .unwrap_or_else(|| self.fatal("expected open delimiter")); + self.bump(); - let tts = self.parse_seq_to_end(&ket, - seq_sep_none(), - |p| p.parse_token_tree()); - let hi = self.span.hi; + let tts = self.parse_seq_to_end(&ket, + seq_sep_none(), + |p| p.parse_token_tree()); + let hi = self.span.hi; - return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)); - } else if self.token == token::LBRACE { - // This is a struct literal, unless we're prohibited from - // parsing struct literals here. - if self.restriction != RESTRICT_NO_STRUCT_LITERAL { - // It's a struct literal. - self.bump(); - let mut fields = Vec::new(); - let mut base = None; + return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT)); + } else if self.token == token::LBRACE { + // This is a struct literal, unless we're prohibited from + // parsing struct literals here. + if self.restriction != RESTRICT_NO_STRUCT_LITERAL { + // It's a struct literal. + self.bump(); + let mut fields = Vec::new(); + let mut base = None; - while self.token != token::RBRACE { - if self.eat(&token::DOTDOT) { - base = Some(self.parse_expr()); - break; + while self.token != token::RBRACE { + if self.eat(&token::DOTDOT) { + base = Some(self.parse_expr()); + break; + } + + fields.push(self.parse_field()); + self.commit_expr(fields.last().unwrap().expr, + &[token::COMMA], &[token::RBRACE]); } - fields.push(self.parse_field()); - self.commit_expr(fields.last().unwrap().expr, - &[token::COMMA], &[token::RBRACE]); - } + if fields.len() == 0 && base.is_none() { + let last_span = self.last_span; + self.span_err(last_span, + "structure literal must either have at \ + least one field or use functional \ + structure update syntax"); + } - if fields.len() == 0 && base.is_none() { - let last_span = self.last_span; - self.span_err(last_span, - "structure literal must either have at \ - least one field or use functional \ - structure update syntax"); + hi = self.span.hi; + self.expect(&token::RBRACE); + ex = ExprStruct(pth, fields, base); + return self.mk_expr(lo, hi, ex); } - - hi = self.span.hi; - self.expect(&token::RBRACE); - ex = ExprStruct(pth, fields, base); - return self.mk_expr(lo, hi, ex); } - } hi = pth.span.hi; ex = ExprPath(pth); - } else { - // other literal expression - let lit = self.parse_lit(); - hi = lit.span.hi; - ex = ExprLit(box(GC) lit); + }, + _ => { + // other literal expression + let lit = self.parse_lit(); + hi = lit.span.hi; + ex = ExprLit(box(GC) lit); + } } return self.mk_expr(lo, hi, ex); -- cgit 1.4.1-3-g733a5 From 728b269199484f50779c44bad495cc5ddecd4a15 Mon Sep 17 00:00:00 2001 From: John Clements Date: Sun, 6 Jul 2014 15:07:31 -0700 Subject: remove unused fn, make SELF_KEYWORD_NAME public --- src/libsyntax/parse/token.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 84834f54a04..84562413ac1 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -365,10 +365,6 @@ pub fn is_plain_ident(t: &Token) -> bool { match *t { IDENT(_, false) => true, _ => false } } -pub fn is_bar(t: &Token) -> bool { - match *t { BINOP(OR) | OROR => true, _ => false } -} - // Get the first "argument" macro_rules! first { ( $first:expr, $( $remainder:expr, )* ) => ( $first ) @@ -447,7 +443,7 @@ macro_rules! declare_special_idents_and_keywords {( }} // If the special idents get renumbered, remember to modify these two as appropriate -static SELF_KEYWORD_NAME: Name = 1; +pub static SELF_KEYWORD_NAME: Name = 1; static STATIC_KEYWORD_NAME: Name = 2; // NB: leaving holes in the ident table is bad! a different ident will get -- cgit 1.4.1-3-g733a5 From 06b64345d681681adc97e64c0dd74a1c9b0762ea Mon Sep 17 00:00:00 2001 From: John Clements Date: Sun, 6 Jul 2014 15:11:44 -0700 Subject: preserve context in parsing of `self` varref --- src/libsyntax/parse/parser.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2f6555dcb69..d0e44b20139 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -541,12 +541,13 @@ impl<'a> Parser<'a> { // if the next token is the given keyword, eat it and return // true. Otherwise, return false. pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool { - let is_kw = match self.token { - token::IDENT(sid, false) => kw.to_ident().name == sid.name, + match self.token { + token::IDENT(sid, false) if kw.to_ident().name == sid.name => { + self.bump(); + true + } _ => false - }; - if is_kw { self.bump() } - is_kw + } } // if the given word is not a keyword, signal an error. @@ -1917,7 +1918,7 @@ impl<'a> Parser<'a> { return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk)); }, - _ if token::is_bar(&self.token) => { + token::BINOP(token::OR) | token::OROR => { return self.parse_lambda_expr(); }, _ if self.eat_keyword(keywords::Proc) => { @@ -1933,8 +1934,9 @@ impl<'a> Parser<'a> { }); return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock)); }, - _ if self.eat_keyword(keywords::Self) => { - let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_); + token::IDENT(id @ ast::Ident{name:token::SELF_KEYWORD_NAME,ctxt:_},false) => { + self.bump(); + let path = ast_util::ident_to_path(mk_sp(lo, hi), id); ex = ExprPath(path); hi = self.last_span.hi; } @@ -1982,7 +1984,7 @@ impl<'a> Parser<'a> { }, token::LBRACKET => { self.bump(); - + if self.token == token::RBRACKET { // Empty vector. self.bump(); -- cgit 1.4.1-3-g733a5 From c1b8b3c35c1e59c475412864c230491843b52ab1 Mon Sep 17 00:00:00 2001 From: John Clements Date: Sun, 6 Jul 2014 15:19:29 -0700 Subject: get rid of keyword idents, replace with names should prevent future bugs --- src/libsyntax/parse/parser.rs | 4 ++-- src/libsyntax/parse/token.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d0e44b20139..584670cc654 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -542,7 +542,7 @@ impl<'a> Parser<'a> { // true. Otherwise, return false. pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool { match self.token { - token::IDENT(sid, false) if kw.to_ident().name == sid.name => { + token::IDENT(sid, false) if kw.to_name() == sid.name => { self.bump(); true } @@ -555,7 +555,7 @@ impl<'a> Parser<'a> { // otherwise, eat it. pub fn expect_keyword(&mut self, kw: keywords::Keyword) { if !self.eat_keyword(kw) { - let id_interned_str = token::get_ident(kw.to_ident()); + let id_interned_str = token::get_name(kw.to_name()); let token_str = self.this_token_to_string(); self.fatal(format!("expected `{}`, found `{}`", id_interned_str, token_str).as_slice()) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 84562413ac1..dc0be39c42c 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -413,7 +413,7 @@ macro_rules! declare_special_idents_and_keywords {( * the language and may not appear as identifiers. */ pub mod keywords { - use ast::Ident; + use ast::Name; pub enum Keyword { $( $sk_variant, )* @@ -421,10 +421,10 @@ macro_rules! declare_special_idents_and_keywords {( } impl Keyword { - pub fn to_ident(&self) -> Ident { + pub fn to_name(&self) -> Name { match *self { - $( $sk_variant => Ident { name: $sk_name, ctxt: 0 }, )* - $( $rk_variant => Ident { name: $rk_name, ctxt: 0 }, )* + $( $sk_variant => $sk_name, )* + $( $rk_variant => $rk_name, )* } } } @@ -432,7 +432,7 @@ macro_rules! declare_special_idents_and_keywords {( fn mk_fresh_ident_interner() -> IdentInterner { // The indices here must correspond to the numbers in - // special_idents, in Keyword to_ident(), and in static + // special_idents, in Keyword to_name(), and in static // constants below. let mut init_vec = Vec::new(); $(init_vec.push($si_str);)* @@ -710,7 +710,7 @@ pub fn fresh_mark() -> Mrk { pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool { match *tok { - token::IDENT(sid, false) => { kw.to_ident().name == sid.name } + token::IDENT(sid, false) => { kw.to_name() == sid.name } _ => { false } } } -- cgit 1.4.1-3-g733a5 From 6007797ed6f712576bccac799d0fc79a2eb61ae7 Mon Sep 17 00:00:00 2001 From: John Clements Date: Sun, 6 Jul 2014 16:02:48 -0700 Subject: replace idents with names --- src/librustc/middle/resolve.rs | 18 ++++++++++-------- src/libsyntax/parse/token.rs | 5 +++++ 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 612b29afd3e..129a5b7c6be 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -25,6 +25,7 @@ use syntax::ast; use syntax::ast_util::{local_def}; use syntax::ast_util::{walk_pat, trait_method_to_ty_method}; use syntax::ext::mtwt; +use syntax::parse::token::special_names; use syntax::parse::token::special_idents; use syntax::parse::token; use syntax::codemap::{Span, DUMMY_SP, Pos}; @@ -830,9 +831,9 @@ struct Resolver<'a> { current_self_type: Option, // The ident for the keyword "self". - self_ident: Ident, + self_name: Name, // The ident for the non-keyword "Self". - type_self_ident: Ident, + type_self_name: Name, // The idents for the primitive types. primitive_type_table: PrimitiveTypeTable, @@ -926,8 +927,8 @@ impl<'a> Resolver<'a> { current_trait_ref: None, current_self_type: None, - self_ident: special_idents::self_, - type_self_ident: special_idents::type_self, + self_name: special_names::self_, + type_self_name: special_names::type_self, primitive_type_table: PrimitiveTypeTable::new(), @@ -3628,8 +3629,8 @@ impl<'a> Resolver<'a> { // Create a new rib for the self type. let self_type_rib = Rib::new(ItemRibKind); - // plain insert (no renaming) - let name = self.type_self_ident.name; + // plain insert (no renaming, types are not currently hygienic....) + let name = self.type_self_name; self_type_rib.bindings.borrow_mut() .insert(name, DlDef(DefSelfTy(item.id))); self.type_ribs.borrow_mut().push(self_type_rib); @@ -5159,8 +5160,8 @@ impl<'a> Resolver<'a> { false // Stop advancing }); - if method_scope && token::get_name(self.self_ident.name).get() - == wrong_name.as_slice() { + if method_scope && token::get_name(self.self_name).get() + == wrong_name.as_slice() { self.resolve_error( expr.span, "`self` is not available \ @@ -5532,6 +5533,7 @@ impl<'a> Resolver<'a> { collect_mod(idents, &*module.upgrade().unwrap()); } BlockParentLink(ref module, _) => { + // danger, shouldn't be ident? idents.push(special_idents::opaque); collect_mod(idents, &*module.upgrade().unwrap()); } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index dc0be39c42c..55db3482a61 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -405,6 +405,11 @@ macro_rules! declare_special_idents_and_keywords {( $( pub static $si_static: Ident = Ident { name: $si_name, ctxt: 0 }; )* } + pub mod special_names { + use ast::Name; + $( pub static $si_static: Name = $si_name; )* + } + /** * All the valid words that have meaning in the Rust language. * -- cgit 1.4.1-3-g733a5 From 7f575186f988ecc489af95b874afd4f82ccaccd0 Mon Sep 17 00:00:00 2001 From: John Clements Date: Mon, 7 Jul 2014 14:27:07 -0700 Subject: remove outdated comment I believe this comment is now irrelevant, as a result of commit 6757053cffb585249105fbd76f --- src/libsyntax/parse/parser.rs | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 584670cc654..b77b366021c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3233,18 +3233,6 @@ impl<'a> Parser<'a> { } else if is_ident(&self.token) && !token::is_any_keyword(&self.token) && self.look_ahead(1, |t| *t == token::NOT) { - // parse a macro invocation. Looks like there's serious - // overlap here; if this clause doesn't catch it (and it - // won't, for brace-delimited macros) it will fall through - // to the macro clause of parse_item_or_view_item. This - // could use some cleanup, it appears to me. - - // whoops! I now have a guess: I'm guessing the "parens-only" - // rule here is deliberate, to allow macro users to use parens - // for things that should be parsed as stmt_mac, and braces - // for things that should expand into items. Tricky, and - // somewhat awkward... and probably undocumented. Of course, - // I could just be wrong. check_expected_item(self, !item_attrs.is_empty()); -- cgit 1.4.1-3-g733a5 From 19e718b34def6c3f98372a40352ab9c889ff9f7a Mon Sep 17 00:00:00 2001 From: John Clements Date: Sun, 6 Jul 2014 15:10:57 -0700 Subject: carry self ident forward through re-parsing formerly, the self identifier was being discarded during parsing, which stymies hygiene. The best fix here seems to be to attach a self identifier to ExplicitSelf_, a change that rippled through the rest of the compiler, but without any obvious damage. --- src/librustc/metadata/decoder.rs | 7 ++- src/librustc/metadata/encoder.rs | 8 +-- src/librustc/middle/trans/meth.rs | 15 +++-- src/librustc/middle/typeck/astconv.rs | 6 +- src/librustc/middle/typeck/check/method.rs | 12 ++-- .../middle/typeck/infer/error_reporting.rs | 6 +- src/librustdoc/clean/mod.rs | 6 +- src/libsyntax/ast.rs | 15 ++--- src/libsyntax/ext/deriving/generic/mod.rs | 4 +- src/libsyntax/ext/deriving/generic/ty.rs | 10 +-- src/libsyntax/ext/expand.rs | 17 ++++- src/libsyntax/fold.rs | 6 +- src/libsyntax/parse/parser.rs | 72 +++++++++++++--------- src/libsyntax/print/pprust.rs | 6 +- src/libsyntax/visit.rs | 4 +- 15 files changed, 114 insertions(+), 80 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 0b9ed37c838..8a2b95ae463 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -739,10 +739,11 @@ fn get_explicit_self(item: ebml::Doc) -> ast::ExplicitSelf_ { let explicit_self_kind = string.as_bytes()[0]; match explicit_self_kind as char { 's' => ast::SelfStatic, - 'v' => ast::SelfValue, - '~' => ast::SelfUniq, + 'v' => ast::SelfValue(special_idents::self_), + '~' => ast::SelfUniq(special_idents::self_), // FIXME(#4846) expl. region - '&' => ast::SelfRegion(None, get_mutability(string.as_bytes()[1])), + '&' => ast::SelfRegion(None, get_mutability(string.as_bytes()[1]), + special_idents::self_), _ => fail!("unknown self type code: `{}`", explicit_self_kind as char) } } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 6c544e3809a..fbf0288418a 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -628,10 +628,10 @@ fn encode_explicit_self(ebml_w: &mut Encoder, explicit_self: ast::ExplicitSelf_) // Encode the base self type. match explicit_self { - SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); } - SelfValue => { ebml_w.writer.write(&[ 'v' as u8 ]); } - SelfUniq => { ebml_w.writer.write(&[ '~' as u8 ]); } - SelfRegion(_, m) => { + SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); } + SelfValue(_) => { ebml_w.writer.write(&[ 'v' as u8 ]); } + SelfUniq(_) => { ebml_w.writer.write(&[ '~' as u8 ]); } + SelfRegion(_, m, _) => { // FIXME(#4846) encode custom lifetime ebml_w.writer.write(&['&' as u8]); encode_mutability(ebml_w, m); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index e1d43c52400..c79e435707a 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -502,12 +502,15 @@ fn emit_vtable_methods(bcx: &Block, ExprId(0), substs.clone(), vtables.clone()); - if m.explicit_self == ast::SelfValue { - fn_ref = trans_unboxing_shim(bcx, - fn_ref, - &*m, - m_id, - substs.clone()); + match m.explicit_self { + ast::SelfValue(_) => { + fn_ref = trans_unboxing_shim(bcx, + fn_ref, + &*m, + m_id, + substs.clone()); + }, + _ => {} } fn_ref } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index d565f144f36..90331d8f434 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -938,10 +938,10 @@ fn ty_of_method_or_bare_fn(this: &AC, id: ast::NodeId, let self_ty = opt_self_info.and_then(|self_info| { match self_info.explicit_self.node { ast::SelfStatic => None, - ast::SelfValue => { + ast::SelfValue(_) => { Some(self_info.untransformed_self_ty) } - ast::SelfRegion(ref lifetime, mutability) => { + ast::SelfRegion(ref lifetime, mutability, _) => { let region = opt_ast_region_to_region(this, &rb, self_info.explicit_self.span, @@ -950,7 +950,7 @@ fn ty_of_method_or_bare_fn(this: &AC, id: ast::NodeId, ty::mt {ty: self_info.untransformed_self_ty, mutbl: mutability})) } - ast::SelfUniq => { + ast::SelfUniq(_) => { Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty)) } } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index c1a000841a4..a184ecac9de 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -270,12 +270,12 @@ fn construct_transformed_self_ty_for_object( ast::SelfStatic => { tcx.sess.span_bug(span, "static method for object type receiver"); } - ast::SelfValue => { + ast::SelfValue(_) => { let tr = ty::mk_trait(tcx, trait_def_id, obj_substs, ty::empty_builtin_bounds()); ty::mk_uniq(tcx, tr) } - ast::SelfRegion(..) | ast::SelfUniq => { + ast::SelfRegion(..) | ast::SelfUniq(..) => { let transformed_self_ty = *method_ty.fty.sig.inputs.get(0); match ty::get(transformed_self_ty).sty { ty::ty_rptr(r, mt) => { // must be SelfRegion @@ -1227,7 +1227,7 @@ impl<'a> LookupContext<'a> { through an object"); } - ast::SelfValue | ast::SelfRegion(..) | ast::SelfUniq => {} + ast::SelfValue(_) | ast::SelfRegion(..) | ast::SelfUniq(_) => {} } // reason (a) above @@ -1296,7 +1296,7 @@ impl<'a> LookupContext<'a> { self.report_statics == ReportStaticMethods } - SelfValue => { + SelfValue(_) => { debug!("(is relevant?) explicit self is by-value"); match ty::get(rcvr_ty).sty { ty::ty_uniq(typ) => { @@ -1319,7 +1319,7 @@ impl<'a> LookupContext<'a> { } } - SelfRegion(_, m) => { + SelfRegion(_, m, _) => { debug!("(is relevant?) explicit self is a region"); match ty::get(rcvr_ty).sty { ty::ty_rptr(_, mt) => { @@ -1339,7 +1339,7 @@ impl<'a> LookupContext<'a> { } } - SelfUniq => { + SelfUniq(_) => { debug!("(is relevant?) explicit self is a unique pointer"); match ty::get(rcvr_ty).sty { ty::ty_uniq(typ) => { diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index cdd51c4fa71..b0c9900be90 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -947,16 +947,16 @@ impl<'a> Rebuilder<'a> { -> Option { match expl_self_opt { Some(expl_self) => match expl_self { - ast::SelfRegion(lt_opt, muta) => match lt_opt { + ast::SelfRegion(lt_opt, muta, id) => match lt_opt { Some(lt) => if region_names.contains(<.name) { - return Some(ast::SelfRegion(Some(lifetime), muta)); + return Some(ast::SelfRegion(Some(lifetime), muta, id)); }, None => { let anon = self.cur_anon.get(); self.inc_and_offset_cur_anon(1); if anon_nums.contains(&anon) { self.track_anon(anon); - return Some(ast::SelfRegion(Some(lifetime), muta)); + return Some(ast::SelfRegion(Some(lifetime), muta, id)); } } }, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6c40ee21040..af0b6a1cb21 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -775,9 +775,9 @@ impl Clean for ast::ExplicitSelf_ { fn clean(&self) -> SelfTy { match *self { ast::SelfStatic => SelfStatic, - ast::SelfValue => SelfValue, - ast::SelfUniq => SelfOwned, - ast::SelfRegion(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()), + ast::SelfValue(_) => SelfValue, + ast::SelfUniq(_) => SelfOwned, + ast::SelfRegion(lt, mt, _) => SelfBorrowed(lt.clean(), mt.clean()), } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 141938417df..5f3adbdb54d 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -14,7 +14,7 @@ use codemap::{Span, Spanned, DUMMY_SP}; use abi::Abi; use ast_util; use owned_slice::OwnedSlice; -use parse::token::{InternedString, special_idents, str_to_ident}; +use parse::token::{InternedString, str_to_ident}; use parse::token; use std::fmt; @@ -824,8 +824,8 @@ pub struct Arg { } impl Arg { - pub fn new_self(span: Span, mutability: Mutability) -> Arg { - let path = Spanned{span:span,node:special_idents::self_}; + pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg { + let path = Spanned{span:span,node:self_ident}; Arg { // HACK(eddyb) fake type for the self argument. ty: P(Ty { @@ -874,12 +874,13 @@ pub enum RetStyle { Return, // everything else } +/// Represents the kind of 'self' associated with a method #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] pub enum ExplicitSelf_ { - SelfStatic, // no self - SelfValue, // `self` - SelfRegion(Option, Mutability), // `&'lt self`, `&'lt mut self` - SelfUniq // `~self` + SelfStatic, // no self + SelfValue(Ident), // `self` + SelfRegion(Option, Mutability, Ident), // `&'lt self`, `&'lt mut self` + SelfUniq(Ident), // `~self` } pub type ExplicitSelf = Spanned; diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 7ad11b186f5..764c88cc954 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -191,6 +191,7 @@ use codemap; use codemap::Span; use owned_slice::OwnedSlice; use parse::token::InternedString; +use parse::token::special_idents; use self::ty::*; @@ -617,7 +618,8 @@ impl<'a> MethodDef<'a> { let self_arg = match explicit_self.node { ast::SelfStatic => None, - _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable)) + // creating fresh self id + _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable, special_idents::self_)) }; let args = { let args = arg_types.move_iter().map(|(name, ty)| { diff --git a/src/libsyntax/ext/deriving/generic/ty.rs b/src/libsyntax/ext/deriving/generic/ty.rs index 28f39a4cb8c..b53281f9963 100644 --- a/src/libsyntax/ext/deriving/generic/ty.rs +++ b/src/libsyntax/ext/deriving/generic/ty.rs @@ -19,6 +19,7 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use codemap::{Span,respan}; use owned_slice::OwnedSlice; +use parse::token::special_idents; use std::gc::Gc; @@ -244,22 +245,23 @@ impl<'a> LifetimeBounds<'a> { } } - pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option) -> (Gc, ast::ExplicitSelf) { + // this constructs a fresh `self` path, which will match the fresh `self` binding + // created below. let self_path = cx.expr_self(span); match *self_ptr { None => { - (self_path, respan(span, ast::SelfValue)) + (self_path, respan(span, ast::SelfValue(special_idents::self_))) } Some(ref ptr) => { let self_ty = respan( span, match *ptr { - Send => ast::SelfUniq, + Send => ast::SelfUniq(special_idents::self_), Borrowed(ref lt, mutbl) => { let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name)); - ast::SelfRegion(lt, mutbl) + ast::SelfRegion(lt, mutbl, special_idents::self_) } }); let self_expr = cx.expr_deref(span, self_path); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d5a9f34dcb9..9fe431cfb6c 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1501,8 +1501,8 @@ mod test { 0) } - // macro_rules in method position - #[test] fn macro_in_method_posn(){ + // macro_rules in method position. Sadly, unimplemented. + #[ignore] #[test] fn macro_in_method_posn(){ expand_crate_str( "macro_rules! my_method (() => fn thirteen(&self) -> int {13}) struct A; @@ -1510,6 +1510,19 @@ mod test { fn f(){A.thirteen;}".to_string()); } + // another nested macro + // expands to impl Entries {fn size_hint(&self_1) {self_1;} + #[test] fn item_macro_workaround(){ + run_renaming_test( + &("macro_rules! item { ($i:item) => {$i}} + struct Entries; + macro_rules! iterator_impl { + () => { item!( impl Entries { fn size_hint(&self) { self;}})}} + iterator_impl! { }", + vec!(vec!(0)), true), + 0) + } + // run one of the renaming tests fn run_renaming_test(t: &RenamingTest, test_idx: uint) { let invalid_name = token::special_idents::invalid.name; diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index ee4810b4b54..bcdf920e5dd 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -334,9 +334,9 @@ pub trait Folder { fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ { match *es { - SelfStatic | SelfValue | SelfUniq => *es, - SelfRegion(ref lifetime, m) => { - SelfRegion(fold_opt_lifetime(lifetime, self), m) + SelfStatic | SelfValue(_) | SelfUniq(_) => *es, + SelfRegion(ref lifetime, m, id) => { + SelfRegion(fold_opt_lifetime(lifetime, self), m, id) } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b77b366021c..ac4cbf3aa8e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3748,13 +3748,18 @@ impl<'a> Parser<'a> { } } - fn expect_self_ident(&mut self) { - if !self.is_self_ident() { - let token_str = self.this_token_to_string(); - self.fatal(format!("expected `self` but found `{}`", - token_str).as_slice()) + fn expect_self_ident(&mut self) -> ast::Ident { + match self.token { + token::IDENT(id, false) if id.name == special_idents::self_.name => { + self.bump(); + id + }, + _ => { + let token_str = self.this_token_to_string(); + self.fatal(format!("expected `self` but found `{}`", + token_str).as_slice()) + } } - self.bump(); } // parse the argument list and result type of a function @@ -3774,24 +3779,21 @@ impl<'a> Parser<'a> { if this.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) { this.bump(); - this.expect_self_ident(); - SelfRegion(None, MutImmutable) + SelfRegion(None, MutImmutable, this.expect_self_ident()) } else if this.look_ahead(1, |t| Parser::token_is_mutability(t)) && this.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) { this.bump(); let mutability = this.parse_mutability(); - this.expect_self_ident(); - SelfRegion(None, mutability) + SelfRegion(None, mutability, this.expect_self_ident()) } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) && this.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) { this.bump(); let lifetime = this.parse_lifetime(); - this.expect_self_ident(); - SelfRegion(Some(lifetime), MutImmutable) + SelfRegion(Some(lifetime), MutImmutable, this.expect_self_ident()) } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) && this.look_ahead(2, |t| { Parser::token_is_mutability(t) @@ -3801,8 +3803,7 @@ impl<'a> Parser<'a> { this.bump(); let lifetime = this.parse_lifetime(); let mutability = this.parse_mutability(); - this.expect_self_ident(); - SelfRegion(Some(lifetime), mutability) + SelfRegion(Some(lifetime), mutability, this.expect_self_ident()) } else { SelfStatic } @@ -3822,15 +3823,13 @@ impl<'a> Parser<'a> { // We need to make sure it isn't a type if self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) { self.bump(); - self.expect_self_ident(); - SelfUniq + SelfUniq(self.expect_self_ident()) } else { SelfStatic } } token::IDENT(..) if self.is_self_ident() => { - self.bump(); - SelfValue + SelfValue(self.expect_self_ident()) } token::BINOP(token::STAR) => { // Possibly "*self" or "*mut self" -- not supported. Try to avoid @@ -3844,29 +3843,32 @@ impl<'a> Parser<'a> { self.span_err(span, "cannot pass self by unsafe pointer"); self.bump(); } - SelfValue + // error case, making bogus self ident: + SelfValue(special_idents::self_) } _ if Parser::token_is_mutability(&self.token) && self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => { mutbl_self = self.parse_mutability(); - self.expect_self_ident(); - SelfValue + SelfValue(self.expect_self_ident()) } _ if Parser::token_is_mutability(&self.token) && self.look_ahead(1, |t| *t == token::TILDE) && self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => { mutbl_self = self.parse_mutability(); self.bump(); - self.expect_self_ident(); - SelfUniq + SelfUniq(self.expect_self_ident()) } _ => SelfStatic }; let explicit_self_sp = mk_sp(lo, self.span.hi); - // If we parsed a self type, expect a comma before the argument list. - let fn_inputs = if explicit_self != SelfStatic { + // shared fall-through for the three cases below. borrowing prevents simply + // writing this as a closure + macro_rules! parse_remaining_arguments { + ($self_id:ident) => + { + // If we parsed a self type, expect a comma before the argument list. match self.token { token::COMMA => { self.bump(); @@ -3876,11 +3878,11 @@ impl<'a> Parser<'a> { sep, parse_arg_fn ); - fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self)); + fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self, $self_id)); fn_inputs } token::RPAREN => { - vec!(Arg::new_self(explicit_self_sp, mutbl_self)) + vec!(Arg::new_self(explicit_self_sp, mutbl_self, $self_id)) } _ => { let token_str = self.this_token_to_string(); @@ -3888,11 +3890,21 @@ impl<'a> Parser<'a> { token_str).as_slice()) } } - } else { - let sep = seq_sep_trailing_disallowed(token::COMMA); - self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn) + } + } + + let fn_inputs = match explicit_self { + SelfStatic => { + let sep = seq_sep_trailing_disallowed(token::COMMA); + self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn) + } + SelfValue(id) => parse_remaining_arguments!(id), + SelfRegion(_,_,id) => parse_remaining_arguments!(id), + SelfUniq(id) => parse_remaining_arguments!(id) + }; + self.expect(&token::RPAREN); let hi = self.span.hi; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e695241472b..a5d70a9333d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1967,13 +1967,13 @@ impl<'a> State<'a> { try!(self.print_mutability(mutbl)); match explicit_self { ast::SelfStatic => { return Ok(false); } - ast::SelfValue => { + ast::SelfValue(_) => { try!(word(&mut self.s, "self")); } - ast::SelfUniq => { + ast::SelfUniq(_) => { try!(word(&mut self.s, "~self")); } - ast::SelfRegion(ref lt, m) => { + ast::SelfRegion(ref lt, m, _) => { try!(word(&mut self.s, "&")); try!(self.print_opt_lifetime(lt)); try!(self.print_mutability(m)); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 4ab064a88b7..df34ff30db6 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -202,8 +202,8 @@ pub fn walk_explicit_self>(visitor: &mut V, explicit_self: &ExplicitSelf, env: E) { match explicit_self.node { - SelfStatic | SelfValue | SelfUniq => {} - SelfRegion(ref lifetime, _) => { + SelfStatic | SelfValue(_) | SelfUniq(_) => {}, + SelfRegion(ref lifetime, _, _) => { visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env) } } -- cgit 1.4.1-3-g733a5