about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-11-10 17:04:12 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-11-16 21:21:37 +0300
commita699f17483baeff87dc027331bce9a552a6b0624 (patch)
tree5142f5ba40dd086d783cdcffed2db7d114c7801d
parentb85a3da421abad7d1936ec6e57e43c7b0ff10bd3 (diff)
downloadrust-a699f17483baeff87dc027331bce9a552a6b0624.tar.gz
rust-a699f17483baeff87dc027331bce9a552a6b0624.zip
parse: Use string literal parsing in the `asm` macro
-rw-r--r--src/librustc_parse/parser/expr.rs16
-rw-r--r--src/librustc_parse/parser/item.rs6
-rw-r--r--src/librustc_parse/parser/mod.rs54
-rw-r--r--src/libsyntax_ext/asm.rs39
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