about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-30 09:19:21 +0000
committerbors <bors@rust-lang.org>2018-06-30 09:19:21 +0000
commitbfc1ee4968ff5778cd80e12150f379ddfe6c2767 (patch)
tree1e61b5ce7879de8613a142ffd6c029f8866bf70a /src/libsyntax
parentacf50b79beb5909c16861cc7c91e8226b7f78272 (diff)
parent84f1bc8b662da4ceb0e448bf0d24ce627e6a462b (diff)
downloadrust-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.rs2
-rw-r--r--src/libsyntax/ext/base.rs38
-rw-r--r--src/libsyntax/ext/expand.rs12
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs9
-rw-r--r--src/libsyntax/ext/tt/quoted.rs10
-rw-r--r--src/libsyntax/parse/mod.rs6
-rw-r--r--src/libsyntax/parse/parser.rs10
-rw-r--r--src/libsyntax/tokenstream.rs8
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))
         };