diff options
| author | Christian Poveda <christianpoveda@protonmail.com> | 2019-07-04 01:45:29 -0500 |
|---|---|---|
| committer | Christian Poveda <christianpoveda@protonmail.com> | 2019-07-04 01:45:29 -0500 |
| commit | e45bbaf48c9fb0439426967009d837f0fe4f74ce (patch) | |
| tree | a887380eed192d6ea9b2f124574932bcc1297c34 /src/libsyntax/parse | |
| parent | e32b8eb00a94274e680d1ae63c429d5b7db65e99 (diff) | |
| parent | b43eb4235ac43c822d903ad26ed806f34cc1a14a (diff) | |
| download | rust-e45bbaf48c9fb0439426967009d837f0fe4f74ce.tar.gz rust-e45bbaf48c9fb0439426967009d837f0fe4f74ce.zip | |
Fix merge conflicts
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/unicode_chars.rs | 117 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 244 |
3 files changed, 169 insertions, 214 deletions
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 4e4fe4256c9..49f714e4e46 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -83,28 +83,6 @@ impl<'a> StringReader<'a> { Ok(ret_val) } - /// Immutably extract string if found at current position with given delimiters - fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option<String> { - let mut pos = self.pos; - let mut idx = self.src_index(pos); - let mut ch = char_at(&self.src, idx); - if ch != from_ch { - return None; - } - pos = pos + Pos::from_usize(ch.len_utf8()); - let start_pos = pos; - idx = self.src_index(pos); - while idx < self.end_src_index { - ch = char_at(&self.src, idx); - if ch == to_ch { - return Some(self.src[self.src_index(start_pos)..self.src_index(pos)].to_string()); - } - pos = pos + Pos::from_usize(ch.len_utf8()); - idx = self.src_index(pos); - } - return None; - } - fn try_real_token(&mut self) -> Result<Token, ()> { let mut t = self.try_next_token()?; loop { diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index 94ce6297fbe..6a870685938 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -1,10 +1,11 @@ // Characters and their corresponding confusables were collected from // http://www.unicode.org/Public/security/10.0.0/confusables.txt -use syntax_pos::{Span, Pos, NO_EXPANSION}; -use errors::{Applicability, DiagnosticBuilder}; use super::StringReader; +use errors::{Applicability, DiagnosticBuilder}; +use syntax_pos::{Pos, Span, NO_EXPANSION}; +#[rustfmt::skip] // for line breaks const UNICODE_ARRAY: &[(char, &str, char)] = &[ (' ', "Line Separator", ' '), (' ', "Paragraph Separator", ' '), @@ -293,8 +294,8 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[ ('〉', "Right-Pointing Angle Bracket", '>'), ('〉', "Right Angle Bracket", '>'), ('》', "Right Double Angle Bracket", '>'), - ('>', "Fullwidth Greater-Than Sign", '>'), ]; - + ('>', "Fullwidth Greater-Than Sign", '>'), +]; const ASCII_ARRAY: &[(char, &str)] = &[ (' ', "Space"), @@ -321,46 +322,72 @@ const ASCII_ARRAY: &[(char, &str)] = &[ ('+', "Plus Sign"), ('<', "Less-Than Sign"), ('=', "Equals Sign"), - ('>', "Greater-Than Sign"), ]; - -crate fn check_for_substitution<'a>(reader: &StringReader<'a>, - ch: char, - err: &mut DiagnosticBuilder<'a>) -> bool { - UNICODE_ARRAY - .iter() - .find(|&&(c, _, _)| c == ch) - .map(|&(_, u_name, ascii_char)| { - let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION); - match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) { - Some(&(ascii_char, ascii_name)) => { - // special help suggestion for "directed" double quotes - if let Some(s) = reader.peek_delimited('“', '”') { - let msg = format!("Unicode characters '“' (Left Double Quotation Mark) and \ - '”' (Right Double Quotation Mark) look like '{}' ({}), but are not", - ascii_char, ascii_name); - err.span_suggestion( - Span::new(reader.pos, reader.next_pos + Pos::from_usize(s.len()) + - Pos::from_usize('”'.len_utf8()), NO_EXPANSION), - &msg, - format!("\"{}\"", s), - Applicability::MaybeIncorrect); - } else { - let msg = - format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not", - ch, u_name, ascii_char, ascii_name); - err.span_suggestion( - span, - &msg, - ascii_char.to_string(), - Applicability::MaybeIncorrect); - } - true - }, - None => { - let msg = format!("substitution character not found for '{}'", ch); - reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); - false - } + ('>', "Greater-Than Sign"), +]; + +crate fn check_for_substitution<'a>( + reader: &StringReader<'a>, + ch: char, + err: &mut DiagnosticBuilder<'a>, +) -> bool { + let (u_name, ascii_char) = match UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) { + Some(&(_u_char, u_name, ascii_char)) => (u_name, ascii_char), + None => return false, + }; + + let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION); + + let ascii_name = match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) { + Some((_ascii_char, ascii_name)) => ascii_name, + None => { + let msg = format!("substitution character not found for '{}'", ch); + reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); + return false + }, + }; + + // special help suggestion for "directed" double quotes + if let Some(s) = reader.peek_delimited('“', '”') { + let msg = format!( + "Unicode characters '“' (Left Double Quotation Mark) and \ + '”' (Right Double Quotation Mark) look like '{}' ({}), but are not", + ascii_char, ascii_name + ); + err.span_suggestion( + Span::new( + reader.pos, + reader.next_pos + Pos::from_usize(s.len()) + Pos::from_usize('”'.len_utf8()), + NO_EXPANSION, + ), + &msg, + format!("\"{}\"", s), + Applicability::MaybeIncorrect, + ); + } else { + let msg = format!( + "Unicode character '{}' ({}) looks like '{}' ({}), but it is not", + ch, u_name, ascii_char, ascii_name + ); + err.span_suggestion( + span, + &msg, + ascii_char.to_string(), + Applicability::MaybeIncorrect, + ); + } + true +} + +impl StringReader<'_> { + /// Immutably extract string if found at current position with given delimiters + fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option<&str> { + let tail = &self.src[self.src_index(self.pos)..]; + let mut chars = tail.chars(); + let first_char = chars.next()?; + if first_char != from_ch { + return None; } - }).unwrap_or(false) + let last_char_idx = chars.as_str().find(to_ch)?; + Some(&chars.as_str()[..last_char_idx]) + } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fc206580e38..9c179600093 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4324,51 +4324,49 @@ impl<'a> Parser<'a> { fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span) -> PResult<'a, Option<P<Item>>> { let token_lo = self.token.span; - let (ident, def) = match self.token.kind { - token::Ident(name, false) if name == kw::Macro => { - self.bump(); - let ident = self.parse_ident()?; - let tokens = if self.check(&token::OpenDelim(token::Brace)) { - match self.parse_token_tree() { - TokenTree::Delimited(_, _, tts) => tts, - _ => unreachable!(), - } - } else if self.check(&token::OpenDelim(token::Paren)) { - let args = self.parse_token_tree(); - let body = if self.check(&token::OpenDelim(token::Brace)) { - self.parse_token_tree() - } else { - self.unexpected()?; - unreachable!() - }; - TokenStream::new(vec![ - args.into(), - TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(), - body.into(), - ]) + let (ident, def) = if self.eat_keyword(kw::Macro) { + let ident = self.parse_ident()?; + let tokens = if self.check(&token::OpenDelim(token::Brace)) { + match self.parse_token_tree() { + TokenTree::Delimited(_, _, tts) => tts, + _ => unreachable!(), + } + } else if self.check(&token::OpenDelim(token::Paren)) { + let args = self.parse_token_tree(); + let body = if self.check(&token::OpenDelim(token::Brace)) { + self.parse_token_tree() } else { self.unexpected()?; unreachable!() }; + TokenStream::new(vec![ + args.into(), + TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(), + body.into(), + ]) + } else { + self.unexpected()?; + unreachable!() + }; - (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) - } - token::Ident(name, _) if name == sym::macro_rules && - self.look_ahead(1, |t| *t == token::Not) => { - let prev_span = self.prev_span; - self.complain_if_pub_macro(&vis.node, prev_span); - self.bump(); - self.bump(); - - let ident = self.parse_ident()?; - let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { - self.report_invalid_macro_expansion_item(); - } + (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) + } else if self.check_keyword(sym::macro_rules) && + self.look_ahead(1, |t| *t == token::Not) && + self.look_ahead(2, |t| t.is_ident()) { + let prev_span = self.prev_span; + self.complain_if_pub_macro(&vis.node, prev_span); + self.bump(); + self.bump(); - (ident, ast::MacroDef { tokens, legacy: true }) + let ident = self.parse_ident()?; + let (delim, tokens) = self.expect_delimited_token_tree()?; + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } - _ => return Ok(None), + + (ident, ast::MacroDef { tokens, legacy: true }) + } else { + return Ok(None); }; let span = lo.to(self.prev_span); @@ -4412,14 +4410,14 @@ impl<'a> Parser<'a> { !self.is_existential_type_decl() && !self.is_auto_trait_item() && !self.is_async_fn() { - let pth = self.parse_path(PathStyle::Expr)?; + let path = self.parse_path(PathStyle::Expr)?; if !self.eat(&token::Not) { let expr = if self.check(&token::OpenDelim(token::Brace)) { - self.parse_struct_expr(lo, pth, ThinVec::new())? + self.parse_struct_expr(lo, path, ThinVec::new())? } else { let hi = self.prev_span; - self.mk_expr(lo.to(hi), ExprKind::Path(None, pth), ThinVec::new()) + self.mk_expr(lo.to(hi), ExprKind::Path(None, path), ThinVec::new()) }; let expr = self.with_res(Restrictions::STMT_EXPR, |this| { @@ -4434,34 +4432,6 @@ impl<'a> Parser<'a> { })); } - // it's a macro invocation - let id = match self.token.kind { - token::OpenDelim(_) => Ident::invalid(), // no special identifier - _ => self.parse_ident()?, - }; - - // check that we're pointing at delimiters (need to check - // again after the `if`, because of `parse_ident` - // consuming more tokens). - match self.token.kind { - token::OpenDelim(_) => {} - _ => { - // we only expect an ident if we didn't parse one - // above. - let ident_str = if id.name == kw::Invalid { - "identifier, " - } else { - "" - }; - let tok_str = self.this_token_descr(); - let mut err = self.fatal(&format!("expected {}`(` or `{{`, found {}", - ident_str, - tok_str)); - err.span_label(self.token.span, format!("expected {}`(` or `{{`", ident_str)); - return Err(err) - }, - } - let (delim, tts) = self.expect_delimited_token_tree()?; let hi = self.prev_span; @@ -4471,59 +4441,38 @@ impl<'a> Parser<'a> { MacStmtStyle::NoBraces }; - if id.name == kw::Invalid { - let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim }); - let node = if delim == MacDelimiter::Brace || - self.token == token::Semi || self.token == token::Eof { - StmtKind::Mac(P((mac, style, attrs.into()))) - } - // We used to incorrectly stop parsing macro-expanded statements here. - // If the next token will be an error anyway but could have parsed with the - // earlier behavior, stop parsing here and emit a warning to avoid breakage. - else if macro_legacy_warnings && - self.token.can_begin_expr() && - match self.token.kind { - // These can continue an expression, so we can't stop parsing and warn. - token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) | - token::BinOp(token::Minus) | token::BinOp(token::Star) | - token::BinOp(token::And) | token::BinOp(token::Or) | - token::AndAnd | token::OrOr | - token::DotDot | token::DotDotDot | token::DotDotEq => false, - _ => true, - } { - self.warn_missing_semicolon(); - StmtKind::Mac(P((mac, style, attrs.into()))) - } else { - let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new()); - let e = self.maybe_recover_from_bad_qpath(e, true)?; - let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; - let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; - StmtKind::Expr(e) - }; - Stmt { - id: ast::DUMMY_NODE_ID, - span: lo.to(hi), - node, - } + let mac = respan(lo.to(hi), Mac_ { path, tts, delim }); + let node = if delim == MacDelimiter::Brace || + self.token == token::Semi || self.token == token::Eof { + StmtKind::Mac(P((mac, style, attrs.into()))) + } + // We used to incorrectly stop parsing macro-expanded statements here. + // If the next token will be an error anyway but could have parsed with the + // earlier behavior, stop parsing here and emit a warning to avoid breakage. + else if macro_legacy_warnings && + self.token.can_begin_expr() && + match self.token.kind { + // These can continue an expression, so we can't stop parsing and warn. + token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) | + token::BinOp(token::Minus) | token::BinOp(token::Star) | + token::BinOp(token::And) | token::BinOp(token::Or) | + token::AndAnd | token::OrOr | + token::DotDot | token::DotDotDot | token::DotDotEq => false, + _ => true, + } { + self.warn_missing_semicolon(); + StmtKind::Mac(P((mac, style, attrs.into()))) } else { - // if it has a special ident, it's definitely an item - // - // Require a semicolon or braces. - if style != MacStmtStyle::Braces && !self.eat(&token::Semi) { - self.report_invalid_macro_expansion_item(); - } - let span = lo.to(hi); - Stmt { - id: ast::DUMMY_NODE_ID, - span, - node: StmtKind::Item({ - self.mk_item( - span, id /*id is good here*/, - ItemKind::Mac(respan(span, Mac_ { path: pth, tts, delim })), - respan(lo, VisibilityKind::Inherited), - attrs) - }), - } + let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new()); + let e = self.maybe_recover_from_bad_qpath(e, true)?; + let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; + let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; + StmtKind::Expr(e) + }; + Stmt { + id: ast::DUMMY_NODE_ID, + span: lo.to(hi), + node, } } else { // FIXME: Bad copy of attrs @@ -5734,9 +5683,12 @@ impl<'a> Parser<'a> { { let is_const_fn = self.eat_keyword(kw::Const); let const_span = self.prev_span; - let unsafety = self.parse_unsafety(); let asyncness = self.parse_asyncness(); + if let IsAsync::Async { .. } = asyncness { + self.ban_async_in_2015(self.prev_span); + } let asyncness = respan(self.prev_span, asyncness); + let unsafety = self.parse_unsafety(); let (constness, unsafety, abi) = if is_const_fn { (respan(const_span, Constness::Const), unsafety, Abi::Rust) } else { @@ -7254,13 +7206,7 @@ impl<'a> Parser<'a> { item_, visibility, maybe_append(attrs, extra_attrs)); - if self.token.span.rust_2015() { - self.diagnostic().struct_span_err_with_code( - async_span, - "`async fn` is not permitted in the 2015 edition", - DiagnosticId::Error("E0670".into()) - ).emit(); - } + self.ban_async_in_2015(async_span); return Ok(Some(item)); } } @@ -7534,6 +7480,19 @@ impl<'a> Parser<'a> { self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility) } + /// We are parsing `async fn`. If we are on Rust 2015, emit an error. + fn ban_async_in_2015(&self, async_span: Span) { + if async_span.rust_2015() { + self.diagnostic() + .struct_span_err_with_code( + async_span, + "`async fn` is not permitted in the 2015 edition", + DiagnosticId::Error("E0670".into()) + ) + .emit(); + } + } + /// Parses a foreign item. crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> { maybe_whole!(self, NtForeignItem, |ni| ni); @@ -7609,26 +7568,17 @@ impl<'a> Parser<'a> { let mac_lo = self.token.span; // item macro. - let pth = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?; 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_ident() { - self.parse_ident()? - } else { - Ident::invalid() // no special identifier - }; - // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item(); } let hi = self.prev_span; - let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim }); - let item = self.mk_item(lo.to(hi), id, ItemKind::Mac(mac), visibility, attrs); + let mac = respan(mac_lo.to(hi), Mac_ { path, tts, delim }); + let item = + self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs); return Ok(Some(item)); } @@ -7654,9 +7604,9 @@ impl<'a> Parser<'a> { !(self.is_async_fn() && self.token.span.rust_2015()) { let prev_span = self.prev_span; let lo = self.token.span; - let pth = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?; - if pth.segments.len() == 1 { + if path.segments.len() == 1 { if !self.eat(&token::Not) { return Err(self.missing_assoc_item_kind_err(item_kind, prev_span)); } @@ -7676,7 +7626,7 @@ impl<'a> Parser<'a> { self.expect(&token::Semi)?; } - Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim }))) + Ok(Some(respan(lo.to(self.prev_span), Mac_ { path, tts, delim }))) } else { Ok(None) } @@ -7689,7 +7639,7 @@ impl<'a> Parser<'a> { let mut tokens = Vec::new(); let prev_collecting = match self.token_cursor.frame.last_token { LastToken::Collecting(ref mut list) => { - Some(mem::replace(list, Vec::new())) + Some(mem::take(list)) } LastToken::Was(ref mut last) => { tokens.extend(last.take()); @@ -7707,7 +7657,7 @@ impl<'a> Parser<'a> { // Pull out the tokens that we've collected from the call to `f` above. let mut collected_tokens = match *last_token { - LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()), + LastToken::Collecting(ref mut v) => mem::take(v), LastToken::Was(_) => panic!("our vector went away?"), }; |
