about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-10-19 06:33:10 -0700
committerGitHub <noreply@github.com>2016-10-19 06:33:10 -0700
commitcfc9b5185bbf5ab04a2736347bfa7fd9ab70c1e7 (patch)
tree52adabcf51c925346f633af820f0f8404de5f4d1 /src/libsyntax/parse
parenta41505f4f4a93bf94f4f7439d41afd826ab20b94 (diff)
parent8b0c292a728c113aaf1f27f079aae6a28110c587 (diff)
downloadrust-cfc9b5185bbf5ab04a2736347bfa7fd9ab70c1e7.tar.gz
rust-cfc9b5185bbf5ab04a2736347bfa7fd9ab70c1e7.zip
Auto merge of #37213 - jseyfried:refactor_crate_var, r=nrc
macros: improve `$crate`

This PR refactors the implementation of `$crate` so that
 - `$crate` is only allowed at the start of a path (like `super`),
 - we can make `$crate` work with inter-crate re-exports (groundwork for macro modularization), and
 - we can support importing macros from an extern crate that is not declared at the crate root (also groundwork for macro modularization).

This is a [breaking-change]. For example, the following would break:
```rust
fn foo() {}
macro_rules! m { () => {
    $crate foo $crate () $crate $crate;
    //^ Today, `$crate` is allowed just about anywhere in unexported macros.
} }
fn main() {
    m!();
}
```
r? @nrc
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/mod.rs2
-rw-r--r--src/libsyntax/parse/parser.rs9
-rw-r--r--src/libsyntax/parse/token.rs17
3 files changed, 7 insertions, 21 deletions
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 1e286c143de..1a84a750463 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -276,7 +276,7 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
 pub fn tts_to_parser<'a>(sess: &'a ParseSess,
                          tts: Vec<tokenstream::TokenTree>,
                          cfg: ast::CrateConfig) -> Parser<'a> {
-    let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, None, tts);
+    let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts);
     let mut p = Parser::new(sess, cfg, Box::new(trdr));
     p.check_unknown_macro_variable();
     p
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 61268d457ce..eac78f5e6c6 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -48,8 +48,7 @@ use parse::classify;
 use parse::common::SeqSep;
 use parse::lexer::{Reader, TokenAndSpan};
 use parse::obsolete::ObsoleteSyntax;
-use parse::token::{self, intern, MatchNt, SubstNt, SpecialVarNt, InternedString};
-use parse::token::{keywords, SpecialMacroVar};
+use parse::token::{self, intern, keywords, MatchNt, SubstNt, InternedString};
 use parse::{new_sub_parser_from_file, ParseSess};
 use util::parser::{AssocOp, Fixity};
 use print::pprust;
@@ -2653,8 +2652,12 @@ impl<'a> Parser<'a> {
                                           num_captures: name_num
                                       })));
                 } else if self.token.is_keyword(keywords::Crate) {
+                    let ident = match self.token {
+                        token::Ident(id) => ast::Ident { name: token::intern("$crate"), ..id },
+                        _ => unreachable!(),
+                    };
                     self.bump();
-                    return Ok(TokenTree::Token(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar)));
+                    return Ok(TokenTree::Token(sp, token::Ident(ident)));
                 } else {
                     sp = mk_sp(sp.lo, self.span.hi);
                     self.parse_ident().unwrap_or_else(|mut e| {
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 3d4dd9ec064..26b5b99c8cc 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -53,21 +53,6 @@ pub enum DelimToken {
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
-pub enum SpecialMacroVar {
-    /// `$crate` will be filled in with the name of the crate a macro was
-    /// imported from, if any.
-    CrateMacroVar,
-}
-
-impl SpecialMacroVar {
-    pub fn as_str(self) -> &'static str {
-        match self {
-            SpecialMacroVar::CrateMacroVar => "crate",
-        }
-    }
-}
-
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
 pub enum Lit {
     Byte(ast::Name),
     Char(ast::Name),
@@ -148,8 +133,6 @@ pub enum Token {
     // In right-hand-sides of MBE macros:
     /// A syntactic variable that will be filled in by macro expansion.
     SubstNt(ast::Ident),
-    /// A macro variable with special meaning.
-    SpecialVarNt(SpecialMacroVar),
 
     // Junk. These carry no data because we don't really care about the data
     // they *would* carry, and don't really want to allocate a new ident for