diff options
| author | bors <bors@rust-lang.org> | 2018-06-30 09:19:21 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-06-30 09:19:21 +0000 |
| commit | bfc1ee4968ff5778cd80e12150f379ddfe6c2767 (patch) | |
| tree | 1e61b5ce7879de8613a142ffd6c029f8866bf70a /src/libsyntax | |
| parent | acf50b79beb5909c16861cc7c91e8226b7f78272 (diff) | |
| parent | 84f1bc8b662da4ceb0e448bf0d24ce627e6a462b (diff) | |
| download | rust-bfc1ee4968ff5778cd80e12150f379ddfe6c2767.tar.gz rust-bfc1ee4968ff5778cd80e12150f379ddfe6c2767.zip | |
Auto merge of #51762 - petrochenkov:oh-hi-mark, r=oli-obk
hygiene: Implement transparent marks and use them for call-site hygiene in proc-macros Fixes https://github.com/rust-lang/rust/issues/50050
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/codemap.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 38 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/quoted.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/tokenstream.rs | 8 |
8 files changed, 56 insertions, 39 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 1d5429bdf8f..ea6b39504e8 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -443,7 +443,7 @@ impl CodeMap { } pub fn span_to_string(&self, sp: Span) -> String { - if self.files.borrow().file_maps.is_empty() && sp.source_equal(&DUMMY_SP) { + if self.files.borrow().file_maps.is_empty() && sp.is_dummy() { return "no-location".to_string(); } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 9afce74f53c..e2424de4d14 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -597,11 +597,11 @@ pub enum SyntaxExtension { MultiModifier(Box<MultiItemModifier + sync::Sync + sync::Send>), /// A function-like procedural macro. TokenStream -> TokenStream. - ProcMacro( - /* expander: */ Box<ProcMacro + sync::Sync + sync::Send>, - /* allow_internal_unstable: */ bool, - /* edition: */ Edition, - ), + ProcMacro { + expander: Box<ProcMacro + sync::Sync + sync::Send>, + allow_internal_unstable: bool, + edition: Edition, + }, /// An attribute-like procedural macro. TokenStream, TokenStream -> TokenStream. /// The first TokenSteam is the attribute, the second is the annotated item. @@ -646,19 +646,22 @@ pub enum SyntaxExtension { BuiltinDerive(BuiltinDeriveFn), /// A declarative macro, e.g. `macro m() {}`. - /// - /// The second element is the definition site span. - DeclMacro(Box<TTMacroExpander + sync::Sync + sync::Send>, Option<(ast::NodeId, Span)>, Edition), + DeclMacro { + expander: Box<TTMacroExpander + sync::Sync + sync::Send>, + def_info: Option<(ast::NodeId, Span)>, + is_transparent: bool, + edition: Edition, + } } impl SyntaxExtension { /// Return which kind of macro calls this syntax extension. pub fn kind(&self) -> MacroKind { match *self { - SyntaxExtension::DeclMacro(..) | + SyntaxExtension::DeclMacro { .. } | SyntaxExtension::NormalTT { .. } | SyntaxExtension::IdentTT(..) | - SyntaxExtension::ProcMacro(..) => + SyntaxExtension::ProcMacro { .. } => MacroKind::Bang, SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | @@ -672,19 +675,26 @@ impl SyntaxExtension { pub fn is_modern(&self) -> bool { match *self { - SyntaxExtension::DeclMacro(..) | - SyntaxExtension::ProcMacro(..) | + SyntaxExtension::DeclMacro { .. } | + SyntaxExtension::ProcMacro { .. } | SyntaxExtension::AttrProcMacro(..) | SyntaxExtension::ProcMacroDerive(..) => true, _ => false, } } + pub fn is_transparent(&self) -> bool { + match *self { + SyntaxExtension::DeclMacro { is_transparent, .. } => is_transparent, + _ => false, + } + } + pub fn edition(&self) -> Edition { match *self { SyntaxExtension::NormalTT { edition, .. } | - SyntaxExtension::DeclMacro(.., edition) | - SyntaxExtension::ProcMacro(.., edition) | + SyntaxExtension::DeclMacro { edition, .. } | + SyntaxExtension::ProcMacro { edition, .. } | SyntaxExtension::AttrProcMacro(.., edition) | SyntaxExtension::ProcMacroDerive(.., edition) => edition, // Unstable legacy stuff diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9cd410d4243..f29bff20f3d 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -738,13 +738,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let opt_expanded = match *ext { - DeclMacro(ref expand, def_span, edition) => { - if let Err(dummy_span) = validate_and_set_expn_info(self, def_span.map(|(_, s)| s), + DeclMacro { ref expander, def_info, edition, .. } => { + if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s), false, false, false, None, edition) { dummy_span } else { - kind.make_from(expand.expand(self.cx, span, mac.node.stream())) + kind.make_from(expander.expand(self.cx, span, mac.node.stream())) } } @@ -804,7 +804,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { kind.dummy(span) } - ProcMacro(ref expandfun, allow_internal_unstable, edition) => { + SyntaxExtension::ProcMacro { ref expander, allow_internal_unstable, edition } => { if ident.name != keywords::Invalid.name() { let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); @@ -826,7 +826,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { edition, }); - let tok_result = expandfun.expand(self.cx, span, mac.node.stream()); + let tok_result = expander.expand(self.cx, span, mac.node.stream()); let result = self.parse_ast_fragment(tok_result, kind, path, span); self.gate_proc_macro_expansion(span, &result); result @@ -1297,7 +1297,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { // Detect if this is an inline module (`mod m { ... }` as opposed to `mod m;`). // In the non-inline case, `inner` is never the dummy span (c.f. `parse_item_mod`). // Thus, if `inner` is the dummy span, we know the module is inline. - let inline_module = item.span.contains(inner) || inner == DUMMY_SP; + let inline_module = item.span.contains(inner) || inner.is_dummy(); if inline_module { if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") { diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 3b3892729d9..70fc9dada42 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -312,7 +312,14 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition: edition, } } else { - SyntaxExtension::DeclMacro(expander, Some((def.id, def.span)), edition) + let is_transparent = attr::contains_name(&def.attrs, "rustc_transparent_macro"); + + SyntaxExtension::DeclMacro { + expander, + def_info: Some((def.id, def.span)), + is_transparent, + edition, + } } } diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index 01b971976a7..82b0fae3e9c 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -14,7 +14,7 @@ use feature_gate::{self, emit_feature_err, Features, GateIssue}; use parse::{token, ParseSess}; use print::pprust; use symbol::keywords; -use syntax_pos::{BytePos, Span, DUMMY_SP}; +use syntax_pos::{BytePos, Span}; use tokenstream; use std::iter::Peekable; @@ -41,8 +41,8 @@ impl Delimited { /// Return a `self::TokenTree` with a `Span` corresponding to the opening delimiter. pub fn open_tt(&self, span: Span) -> TokenTree { - let open_span = if span == DUMMY_SP { - DUMMY_SP + let open_span = if span.is_dummy() { + span } else { span.with_lo(span.lo() + BytePos(self.delim.len() as u32)) }; @@ -51,8 +51,8 @@ impl Delimited { /// Return a `self::TokenTree` with a `Span` corresponding to the closing delimiter. pub fn close_tt(&self, span: Span) -> TokenTree { - let close_span = if span == DUMMY_SP { - DUMMY_SP + let close_span = if span.is_dummy() { + span } else { span.with_lo(span.hi() - BytePos(self.delim.len() as u32)) }; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index cce8da1dcbd..c443f240780 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::sync::{Lrc, Lock}; use ast::{self, CrateConfig}; use codemap::{CodeMap, FilePathMapping}; -use syntax_pos::{self, Span, FileMap, NO_EXPANSION, FileName}; +use syntax_pos::{Span, FileMap, FileName}; use errors::{Handler, ColorConfig, DiagnosticBuilder}; use feature_gate::UnstableFeatures; use parse::parser::Parser; @@ -188,8 +188,8 @@ fn filemap_to_parser(sess: & ParseSess, filemap: Lrc<FileMap>) -> Parser { let end_pos = filemap.end_pos; let mut parser = stream_to_parser(sess, filemap_to_stream(sess, filemap, None)); - if parser.token == token::Eof && parser.span == syntax_pos::DUMMY_SP { - parser.span = Span::new(end_pos, end_pos, NO_EXPANSION); + if parser.token == token::Eof && parser.span.is_dummy() { + parser.span = Span::new(end_pos, end_pos, parser.span.ctxt()); } parser diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e04fec797e0..673157d0ffa 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -43,7 +43,7 @@ use ast::{BinOpKind, UnOp}; use ast::{RangeEnd, RangeSyntax}; use {ast, attr}; use codemap::{self, CodeMap, Spanned, respan}; -use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, DUMMY_SP, edition::Edition}; +use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, edition::Edition}; use errors::{self, Applicability, DiagnosticBuilder}; use parse::{self, SeqSep, classify, token}; use parse::lexer::TokenAndSpan; @@ -567,7 +567,7 @@ impl<'a> Parser<'a> { if let Some(directory) = directory { parser.directory = directory; - } else if !parser.span.source_equal(&DUMMY_SP) { + } else if !parser.span.is_dummy() { if let FileName::Real(mut path) = sess.codemap().span_to_unmapped_path(parser.span) { path.pop(); parser.directory.path = Cow::from(path); @@ -584,7 +584,7 @@ impl<'a> Parser<'a> { } else { self.token_cursor.next() }; - if next.sp == syntax_pos::DUMMY_SP { + if next.sp.is_dummy() { // Tweak the location for better diagnostics, but keep syntactic context intact. next.sp = self.prev_span.with_ctxt(next.sp.ctxt()); } @@ -6138,7 +6138,7 @@ impl<'a> Parser<'a> { return Err(err); } - let hi = if self.span == syntax_pos::DUMMY_SP { + let hi = if self.span.is_dummy() { inner_lo } else { self.prev_span @@ -6369,7 +6369,7 @@ impl<'a> Parser<'a> { } let mut err = self.diagnostic().struct_span_err(id_sp, "cannot declare a new module at this location"); - if id_sp != syntax_pos::DUMMY_SP { + if !id_sp.is_dummy() { let src_path = self.sess.codemap().span_to_filename(id_sp); if let FileName::Real(src_path) = src_path { if let Some(stem) = src_path.file_stem() { diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 455cc4391dd..8736fcf9729 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -57,8 +57,8 @@ impl Delimited { /// Returns the opening delimiter as a token tree. pub fn open_tt(&self, span: Span) -> TokenTree { - let open_span = if span == DUMMY_SP { - DUMMY_SP + let open_span = if span.is_dummy() { + span } else { span.with_hi(span.lo() + BytePos(self.delim.len() as u32)) }; @@ -67,8 +67,8 @@ impl Delimited { /// Returns the closing delimiter as a token tree. pub fn close_tt(&self, span: Span) -> TokenTree { - let close_span = if span == DUMMY_SP { - DUMMY_SP + let close_span = if span.is_dummy() { + span } else { span.with_lo(span.hi() - BytePos(self.delim.len() as u32)) }; |
