about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-12-09 17:31:12 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-12-19 23:17:53 +0300
commit2bc67da378db40b23a426ea6384b2660c29a002c (patch)
treee96b2c51937ae33a44fa349f2abe1a042621358b
parent8a8ef260bef994c1e9d3444356fa9f33c01943c1 (diff)
downloadrust-2bc67da378db40b23a426ea6384b2660c29a002c.tar.gz
rust-2bc67da378db40b23a426ea6384b2660c29a002c.zip
proc_macro: Accept `$crate` as an identifier if it comes from the compiler
-rw-r--r--src/libsyntax_ext/proc_macro_server.rs6
-rw-r--r--src/test/ui/proc-macro/auxiliary/dollar-crate.rs12
-rw-r--r--src/test/ui/proc-macro/dollar-crate.rs16
3 files changed, 34 insertions, 0 deletions
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index ea4a8afc0aa..ca960cbe41b 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -150,6 +150,8 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
             Question => op!('?'),
             SingleQuote => op!('\''),
 
+            Ident(ident, false) if ident.name == keywords::DollarCrate.name() =>
+                tt!(Ident::dollar_crate()),
             Ident(ident, is_raw) => tt!(Ident::new(ident.name, is_raw)),
             Lifetime(ident) => {
                 let ident = ident.without_first_quote();
@@ -359,6 +361,10 @@ impl Ident {
         }
         Ident { sym, is_raw, span }
     }
+    fn dollar_crate(span: Span) -> Ident {
+        // `$crate` is accepted as an ident only if it comes from the compiler.
+        Ident { sym: keywords::DollarCrate.name(), is_raw: false, span }
+    }
 }
 
 // FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
diff --git a/src/test/ui/proc-macro/auxiliary/dollar-crate.rs b/src/test/ui/proc-macro/auxiliary/dollar-crate.rs
new file mode 100644
index 00000000000..b0727a33332
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/dollar-crate.rs
@@ -0,0 +1,12 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn normalize(input: TokenStream) -> TokenStream {
+    input.into_iter().collect()
+}
diff --git a/src/test/ui/proc-macro/dollar-crate.rs b/src/test/ui/proc-macro/dollar-crate.rs
new file mode 100644
index 00000000000..b8b1ddd5d1c
--- /dev/null
+++ b/src/test/ui/proc-macro/dollar-crate.rs
@@ -0,0 +1,16 @@
+// compile-pass
+// aux-build:dollar-crate.rs
+
+extern crate dollar_crate;
+
+type S = u8;
+
+macro_rules! check { () => {
+    dollar_crate::normalize! {
+        type A = $crate::S;
+    }
+}}
+
+check!();
+
+fn main() {}