diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-11-10 17:04:12 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-11-16 21:21:37 +0300 |
| commit | a699f17483baeff87dc027331bce9a552a6b0624 (patch) | |
| tree | 5142f5ba40dd086d783cdcffed2db7d114c7801d | |
| parent | b85a3da421abad7d1936ec6e57e43c7b0ff10bd3 (diff) | |
| download | rust-a699f17483baeff87dc027331bce9a552a6b0624.tar.gz rust-a699f17483baeff87dc027331bce9a552a6b0624.zip | |
parse: Use string literal parsing in the `asm` macro
| -rw-r--r-- | src/librustc_parse/parser/expr.rs | 16 | ||||
| -rw-r--r-- | src/librustc_parse/parser/item.rs | 6 | ||||
| -rw-r--r-- | src/librustc_parse/parser/mod.rs | 54 | ||||
| -rw-r--r-- | src/libsyntax_ext/asm.rs | 39 |
4 files changed, 56 insertions, 59 deletions
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index df2f6822465..be1dc4f19a7 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1073,6 +1073,22 @@ impl<'a> Parser<'a> { self.maybe_recover_from_bad_qpath(expr, true) } + pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<Lit>> { + match self.parse_opt_lit() { + Some(lit) => match lit.kind { + ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit { + style, + symbol: lit.token.symbol, + suffix: lit.token.suffix, + span: lit.span, + symbol_unescaped, + }), + _ => Err(Some(lit)), + } + None => Err(None), + } + } + pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> { self.parse_opt_lit().ok_or_else(|| { let msg = format!("unexpected token: {}", self.this_token_descr()); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 8e6df0fa4f3..20b96d5cd62 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -3,9 +3,9 @@ use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim}; use crate::maybe_whole; -use syntax::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item}; +use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item}; use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind}; -use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness}; +use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit}; use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind}; use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField}; use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param}; @@ -105,7 +105,7 @@ impl<'a> Parser<'a> { return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?)); } - let abi = self.parse_opt_abi(); + let abi = self.parse_abi(); if self.eat_keyword(kw::Fn) { // EXTERN FUNCTION ITEM diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 7757e00020a..d5ec4611498 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -15,8 +15,8 @@ use crate::{Directory, DirectoryOwnership}; use crate::lexer::UnmatchedBrace; use syntax::ast::{ - self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, - IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety, + self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, StrLit, + IsAsync, MacDelimiter, Mutability, Visibility, VisibilityKind, Unsafety, }; use syntax::print::pprust; @@ -1214,34 +1214,32 @@ impl<'a> Parser<'a> { /// Parses `extern string_literal?`. fn parse_extern(&mut self) -> PResult<'a, Extern> { Ok(if self.eat_keyword(kw::Extern) { - Extern::from_abi(self.parse_opt_abi()) + Extern::from_abi(self.parse_abi()) } else { Extern::None }) } /// Parses a string literal as an ABI spec. - fn parse_opt_abi(&mut self) -> Option<StrLit> { - if let Some(ast::Lit { token: token::Lit { symbol, suffix, .. }, span, kind }) - = self.parse_opt_lit() { - match kind { - ast::LitKind::Str(symbol_unescaped, style) => return Some(StrLit { - style, symbol, suffix, span, symbol_unescaped, - }), - ast::LitKind::Err(_) => {} + fn parse_abi(&mut self) -> Option<StrLit> { + match self.parse_str_lit() { + Ok(str_lit) => Some(str_lit), + Err(Some(lit)) => match lit.kind { + ast::LitKind::Err(_) => None, _ => { - self.struct_span_err(span, "non-string ABI literal") + self.struct_span_err(lit.span, "non-string ABI literal") .span_suggestion( - span, + lit.span, "specify the ABI with a string literal", "\"C\"".to_string(), Applicability::MaybeIncorrect, ) .emit(); + None } } + Err(None) => None, } - None } /// We are parsing `async fn`. If we are on Rust 2015, emit an error. @@ -1333,34 +1331,6 @@ impl<'a> Parser<'a> { self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace) || *t == token::BinOp(token::Star)) } - - fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> { - let ret = match self.token.kind { - token::Literal(token::Lit { kind: token::Str, symbol, suffix }) => - (symbol, ast::StrStyle::Cooked, suffix), - token::Literal(token::Lit { kind: token::StrRaw(n), symbol, suffix }) => - (symbol, ast::StrStyle::Raw(n), suffix), - _ => return None - }; - self.bump(); - Some(ret) - } - - pub fn parse_str(&mut self) -> PResult<'a, (Symbol, StrStyle)> { - match self.parse_optional_str() { - Some((s, style, suf)) => { - let sp = self.prev_span; - self.expect_no_suffix(sp, "a string literal", suf); - Ok((s, style)) - } - _ => { - let msg = "expected string literal"; - let mut err = self.fatal(msg); - err.span_label(self.token.span, msg); - Err(err) - } - } - } } crate fn make_unclosed_delims_error( diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index 5fab101957a..9b37143557e 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -2,19 +2,17 @@ // use State::*; +use errors::{DiagnosticBuilder, PResult}; use rustc_data_structures::thin_vec::ThinVec; - -use errors::DiagnosticBuilder; - -use syntax::ast; -use syntax_expand::base::{self, *}; -use syntax::token::{self, Token}; +use rustc_parse::parser::Parser; +use syntax_expand::base::*; +use syntax_pos::Span; +use syntax::{span_err, struct_span_err}; +use syntax::ast::{self, AsmDialect}; use syntax::ptr::P; use syntax::symbol::{kw, sym, Symbol}; -use syntax::ast::AsmDialect; -use syntax_pos::Span; +use syntax::token::{self, Token}; use syntax::tokenstream::{self, TokenStream}; -use syntax::{span_err, struct_span_err}; use rustc_error_codes::*; @@ -45,7 +43,7 @@ const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel]; pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream) - -> Box<dyn base::MacResult + 'cx> { + -> Box<dyn MacResult + 'cx> { let mut inline_asm = match parse_inline_asm(cx, sp, tts) { Ok(Some(inline_asm)) => inline_asm, Ok(None) => return DummyResult::any(sp), @@ -69,6 +67,19 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, })) } +fn parse_asm_str<'a>(p: &mut Parser<'a>) -> PResult<'a, Symbol> { + match p.parse_str_lit() { + Ok(str_lit) => Ok(str_lit.symbol_unescaped), + Err(opt_lit) => { + let span = opt_lit.map_or(p.token.span, |lit| lit.span); + let msg = "expected string literal"; + let mut err = p.sess.span_diagnostic.struct_span_fatal(span, msg); + err.span_label(span, msg); + Err(err) + } + } +} + fn parse_inline_asm<'a>( cx: &mut ExtCtxt<'a>, sp: Span, @@ -144,7 +155,7 @@ fn parse_inline_asm<'a>( p.eat(&token::Comma); } - let (constraint, _) = p.parse_str()?; + let constraint = parse_asm_str(&mut p)?; let span = p.prev_span; @@ -189,7 +200,7 @@ fn parse_inline_asm<'a>( p.eat(&token::Comma); } - let (constraint, _) = p.parse_str()?; + let constraint = parse_asm_str(&mut p)?; if constraint.as_str().starts_with("=") { span_err!(cx, p.prev_span, E0662, @@ -212,7 +223,7 @@ fn parse_inline_asm<'a>( p.eat(&token::Comma); } - let (s, _) = p.parse_str()?; + let s = parse_asm_str(&mut p)?; if OPTIONS.iter().any(|&opt| s == opt) { cx.span_warn(p.prev_span, "expected a clobber, found an option"); @@ -225,7 +236,7 @@ fn parse_inline_asm<'a>( } } Options => { - let (option, _) = p.parse_str()?; + let option = parse_asm_str(&mut p)?; if option == sym::volatile { // Indicates that the inline assembly has side effects |
