diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-11-10 00:44:59 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-11-16 21:21:37 +0300 |
| commit | 00bc4496026a3168eed95e88c29f17dac2739d48 (patch) | |
| tree | 8848a81d29817d48c21111a119637703cae0656f | |
| parent | 266f5471272532989332117e8a2e0bacb5b94ccf (diff) | |
| download | rust-00bc4496026a3168eed95e88c29f17dac2739d48.tar.gz rust-00bc4496026a3168eed95e88c29f17dac2739d48.zip | |
ast: Keep string literals in ABIs precisely
| -rw-r--r-- | src/librustc/hir/lowering/item.rs | 6 | ||||
| -rw-r--r-- | src/librustc_parse/parser/item.rs | 4 | ||||
| -rw-r--r-- | src/librustc_parse/parser/mod.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/ast.rs | 42 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate/check.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 10 |
6 files changed, 49 insertions, 30 deletions
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs index 2dc7e014445..f689e7f9622 100644 --- a/src/librustc/hir/lowering/item.rs +++ b/src/librustc/hir/lowering/item.rs @@ -1287,8 +1287,8 @@ impl LoweringContext<'_> { } } - pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi { - abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| { + pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi { + abi::lookup(&abi.symbol_unescaped.as_str()).unwrap_or_else(|| { self.error_on_invalid_abi(abi); abi::Abi::Rust }) @@ -1302,7 +1302,7 @@ impl LoweringContext<'_> { } } - fn error_on_invalid_abi(&self, abi: Abi) { + fn error_on_invalid_abi(&self, abi: StrLit) { struct_span_err!( self.sess, abi.span, diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index fe86d03c6e7..3b824dc939f 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1100,7 +1100,7 @@ impl<'a> Parser<'a> { fn parse_item_foreign_mod( &mut self, lo: Span, - abi: Option<Abi>, + abi: Option<StrLit>, visibility: Visibility, mut attrs: Vec<Attribute>, extern_sp: Span, @@ -1778,7 +1778,7 @@ impl<'a> Parser<'a> { let is_c_abi = match header.ext { ast::Extern::None => false, ast::Extern::Implicit => true, - ast::Extern::Explicit(abi) => abi.symbol == sym::C, + ast::Extern::Explicit(abi) => abi.symbol_unescaped == sym::C, }; let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { is_self_allowed: false, diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 2d05a696791..2b49091192c 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -15,7 +15,7 @@ use crate::{Directory, DirectoryOwnership}; use crate::lexer::UnmatchedBrace; use syntax::ast::{ - self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, + self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety, }; @@ -1221,11 +1221,14 @@ impl<'a> Parser<'a> { } /// Parses a string literal as an ABI spec. - fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> { + fn parse_opt_abi(&mut self) -> PResult<'a, Option<StrLit>> { if self.token.can_begin_literal_or_bool() { - let ast::Lit { span, kind, .. } = self.parse_lit()?; + let ast::Lit { token: token::Lit { symbol, suffix, .. }, span, kind } + = self.parse_lit()?; match kind { - ast::LitKind::Str(symbol, _) => return Ok(Some(Abi { symbol, span })), + ast::LitKind::Str(symbol_unescaped, style) => return Ok(Some(StrLit { + style, symbol, suffix, span, symbol_unescaped, + })), ast::LitKind::Err(_) => {} _ => { self.struct_span_err(span, "non-string ABI literal") diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 575795758ae..dee493a708e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1422,6 +1422,33 @@ pub struct Lit { pub span: Span, } +/// Same as `Lit`, but restricted to string literals. +#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] +pub struct StrLit { + /// The original literal token as written in source code. + pub style: StrStyle, + pub symbol: Symbol, + pub suffix: Option<Symbol>, + pub span: Span, + /// The unescaped "semantic" representation of the literal lowered from the original token. + /// FIXME: Remove this and only create the semantic representation during lowering to HIR. + pub symbol_unescaped: Symbol, +} + +impl StrLit { + crate fn as_lit(&self) -> Lit { + let token_kind = match self.style { + StrStyle::Cooked => token::Str, + StrStyle::Raw(n) => token::StrRaw(n), + }; + Lit { + token: token::Lit::new(token_kind, self.symbol, self.suffix), + span: self.span, + kind: LitKind::Str(self.symbol_unescaped, self.style), + } + } +} + // Clippy uses Hash and PartialEq /// Type of the integer literal based on provided suffix. #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)] @@ -2128,7 +2155,7 @@ pub struct Mod { /// E.g., `extern { .. }` or `extern C { .. }`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct ForeignMod { - pub abi: Option<Abi>, + pub abi: Option<StrLit>, pub items: Vec<ForeignItem>, } @@ -2411,25 +2438,16 @@ impl Item { } } -/// A reference to an ABI. -/// -/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`. -#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)] -pub struct Abi { - pub symbol: Symbol, - pub span: Span, -} - /// `extern` qualifier on a function item or function type. #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] pub enum Extern { None, Implicit, - Explicit(Abi), + Explicit(StrLit), } impl Extern { - pub fn from_abi(abi: Option<Abi>) -> Extern { + pub fn from_abi(abi: Option<StrLit>) -> Extern { match abi { Some(abi) => Extern::Explicit(abi), None => Extern::Implicit, diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index d90fa9addf7..abf9adefd3c 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -191,10 +191,10 @@ macro_rules! gate_feature_post { } impl<'a> PostExpansionVisitor<'a> { - fn check_abi(&self, abi: ast::Abi) { - let ast::Abi { symbol, span } = abi; + fn check_abi(&self, abi: ast::StrLit) { + let ast::StrLit { symbol_unescaped, span, .. } = abi; - match &*symbol.as_str() { + match &*symbol_unescaped.as_str() { // Stable "Rust" | "C" | diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index de28bd6cf83..17a7cbddff9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1233,7 +1233,8 @@ impl<'a> State<'a> { ast::ItemKind::ForeignMod(ref nmod) => { self.head("extern"); if let Some(abi) = nmod.abi { - self.print_abi(abi); + self.print_literal(&abi.as_lit()); + self.nbsp(); } self.bopen(); self.print_foreign_mod(nmod, &item.attrs); @@ -2875,17 +2876,14 @@ impl<'a> State<'a> { } ast::Extern::Explicit(abi) => { self.word_nbsp("extern"); - self.print_abi(abi); + self.print_literal(&abi.as_lit()); + self.nbsp(); } } self.s.word("fn") } - fn print_abi(&mut self, abi: ast::Abi) { - self.word_nbsp(format!("\"{}\"", abi.symbol)); - } - crate fn print_unsafety(&mut self, s: ast::Unsafety) { match s { ast::Unsafety::Normal => {}, |
