diff options
| author | Yuki Okushi <huyuumi.dev@gmail.com> | 2019-11-17 13:36:12 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-17 13:36:12 +0900 |
| commit | b83d50d34f1d2917784bce825faa8e0c5ceaa4c9 (patch) | |
| tree | e24f56e7a2716e3236f16a52cbe9f84338c18557 /src/libsyntax | |
| parent | d8f252670322466af43ba9eb8c81c1151671e070 (diff) | |
| parent | 28aec1beaa5e16b17143f993cab408debe1dcda5 (diff) | |
| download | rust-b83d50d34f1d2917784bce825faa8e0c5ceaa4c9.tar.gz rust-b83d50d34f1d2917784bce825faa8e0c5ceaa4c9.zip | |
Rollup merge of #66271 - petrochenkov:abism, r=Centril
syntax: Keep string literals in ABIs and `asm!` more precisely As a result we don't lose spans when `extern` functions or blocks are passed to proc macros, and also escape all string literals consistently. Continuation of https://github.com/rust-lang/rust/pull/60679, which did a similar thing with all literals besides those in ABIs and `asm!`. TODO: Add tests. Fixes https://github.com/rust-lang/rust/issues/60493 Fixes https://github.com/rust-lang/rust/issues/64561 r? @Centril
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 60 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate/check.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/mut_visit.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 28 |
4 files changed, 74 insertions, 40 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d358efbe543..bbf00825acb 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)] @@ -1745,7 +1772,7 @@ pub struct Ty { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct BareFnTy { pub unsafety: Unsafety, - pub abi: Abi, + pub ext: Extern, pub generic_params: Vec<GenericParam>, pub decl: P<FnDecl>, } @@ -2128,7 +2155,7 @@ pub struct Mod { /// E.g., `extern { .. }` or `extern C { .. }`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct ForeignMod { - pub abi: Abi, + pub abi: Option<StrLit>, pub items: Vec<ForeignItem>, } @@ -2411,24 +2438,17 @@ 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, -} - -impl Abi { - pub fn new(symbol: Symbol, span: Span) -> Self { - Self { symbol, span } - } +/// `extern` qualifier on a function item or function type. +#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] +pub enum Extern { + None, + Implicit, + Explicit(StrLit), } -impl Default for Abi { - fn default() -> Self { - Self::new(sym::Rust, DUMMY_SP) +impl Extern { + pub fn from_abi(abi: Option<StrLit>) -> Extern { + abi.map_or(Extern::Implicit, Extern::Explicit) } } @@ -2441,7 +2461,7 @@ pub struct FnHeader { pub unsafety: Unsafety, pub asyncness: Spanned<IsAsync>, pub constness: Spanned<Constness>, - pub abi: Abi, + pub ext: Extern, } impl Default for FnHeader { @@ -2450,7 +2470,7 @@ impl Default for FnHeader { unsafety: Unsafety::Normal, asyncness: dummy_spanned(IsAsync::NotAsync), constness: dummy_spanned(Constness::NotConst), - abi: Abi::default(), + ext: Extern::None, } } } diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index bd836eee42a..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" | @@ -258,6 +258,12 @@ impl<'a> PostExpansionVisitor<'a> { } } + fn check_extern(&self, ext: ast::Extern) { + if let ast::Extern::Explicit(abi) = ext { + self.check_abi(abi); + } + } + fn maybe_report_invalid_custom_discriminants(&self, variants: &[ast::Variant]) { let has_fields = variants.iter().any(|variant| match variant.data { VariantData::Tuple(..) | VariantData::Struct(..) => true, @@ -388,7 +394,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_item(&mut self, i: &'a ast::Item) { match i.kind { ast::ItemKind::ForeignMod(ref foreign_module) => { - self.check_abi(foreign_module.abi); + if let Some(abi) = foreign_module.abi { + self.check_abi(abi); + } } ast::ItemKind::Fn(..) => { @@ -511,7 +519,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_ty(&mut self, ty: &'a ast::Ty) { match ty.kind { ast::TyKind::BareFn(ref bare_fn_ty) => { - self.check_abi(bare_fn_ty.abi); + self.check_extern(bare_fn_ty.ext); } ast::TyKind::Never => { gate_feature_post!(&self, never_type, ty.span, @@ -605,7 +613,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { // Stability of const fn methods are covered in // `visit_trait_item` and `visit_impl_item` below; this is // because default methods don't pass through this point. - self.check_abi(header.abi); + self.check_extern(header.ext); } if fn_decl.c_variadic() { @@ -639,7 +647,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match ti.kind { ast::TraitItemKind::Method(ref sig, ref block) => { if block.is_none() { - self.check_abi(sig.header.abi); + self.check_extern(sig.header.ext); } if sig.decl.c_variadic() { gate_feature_post!(&self, c_variadic, ti.span, diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index f4ef993edb9..da3c885b860 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -441,7 +441,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) { vis.visit_mt(mt); } TyKind::BareFn(bft) => { - let BareFnTy { unsafety: _, abi: _, generic_params, decl } = bft.deref_mut(); + let BareFnTy { unsafety: _, ext: _, generic_params, decl } = bft.deref_mut(); generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_fn_decl(decl); } @@ -974,7 +974,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut } pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) { - let FnHeader { unsafety: _, asyncness, constness: _, abi: _ } = header; + let FnHeader { unsafety: _, asyncness, constness: _, ext: _ } = header; vis.visit_asyncness(&mut asyncness.node); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index ef65a744e83..17a7cbddff9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1013,7 +1013,7 @@ impl<'a> State<'a> { self.pclose(); } ast::TyKind::BareFn(ref f) => { - self.print_ty_fn(f.abi, + self.print_ty_fn(f.ext, f.unsafety, &f.decl, None, @@ -1232,7 +1232,10 @@ impl<'a> State<'a> { } ast::ItemKind::ForeignMod(ref nmod) => { self.head("extern"); - self.print_abi(nmod.abi); + if let Some(abi) = nmod.abi { + self.print_literal(&abi.as_lit()); + self.nbsp(); + } self.bopen(); self.print_foreign_mod(nmod, &item.attrs); self.bclose(item.span); @@ -2805,7 +2808,7 @@ impl<'a> State<'a> { } crate fn print_ty_fn(&mut self, - abi: ast::Abi, + ext: ast::Extern, unsafety: ast::Unsafety, decl: &ast::FnDecl, name: Option<ast::Ident>, @@ -2825,7 +2828,7 @@ impl<'a> State<'a> { span: syntax_pos::DUMMY_SP, }; self.print_fn(decl, - ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() }, + ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() }, name, &generics, &source_map::dummy_spanned(ast::VisibilityKind::Inherited)); @@ -2866,18 +2869,21 @@ impl<'a> State<'a> { self.print_asyncness(header.asyncness.node); self.print_unsafety(header.unsafety); - if header.abi.symbol != sym::Rust { - self.word_nbsp("extern"); - self.print_abi(header.abi); + match header.ext { + ast::Extern::None => {} + ast::Extern::Implicit => { + self.word_nbsp("extern"); + } + ast::Extern::Explicit(abi) => { + self.word_nbsp("extern"); + 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 => {}, |
