summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-05 19:01:17 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-05 19:01:17 -0800
commit7975fd9cee750f26f9f6ef85b92a20b24ee24120 (patch)
tree0c36840cd8bf89ad1f662ed81d8e71c93e22c41e /src/libsyntax/parse
parent563f6d8218cf15bf2590507c38ce4cbb734d6bba (diff)
parent78e841d8b10e05b5bbad4b02a9d5f0e9611100c7 (diff)
downloadrust-7975fd9cee750f26f9f6ef85b92a20b24ee24120.tar.gz
rust-7975fd9cee750f26f9f6ef85b92a20b24ee24120.zip
rollup merge of #20482: kmcallister/macro-reform
Conflicts:
	src/libflate/lib.rs
	src/libstd/lib.rs
	src/libstd/macros.rs
	src/libsyntax/feature_gate.rs
	src/libsyntax/parse/parser.rs
	src/libsyntax/show_span.rs
	src/test/auxiliary/macro_crate_test.rs
	src/test/compile-fail/lint-stability.rs
	src/test/run-pass/intrinsics-math.rs
	src/test/run-pass/tcp-connect-timeouts.rs
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/mod.rs11
-rw-r--r--src/libsyntax/parse/parser.rs23
-rw-r--r--src/libsyntax/parse/token.rs25
3 files changed, 51 insertions, 8 deletions
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 8598571e5c3..b0969a573e6 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -24,8 +24,11 @@ use std::num::Int;
 use std::str;
 use std::iter;
 
-pub mod lexer;
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 pub mod parser;
+
+pub mod lexer;
 pub mod token;
 pub mod attr;
 
@@ -166,6 +169,8 @@ pub fn parse_stmt_from_source_str(name: String,
 
 // Note: keep in sync with `with_hygiene::parse_tts_from_source_str`
 // until #16472 is resolved.
+//
+// Warning: This parses with quote_depth > 0, which is not the default.
 pub fn parse_tts_from_source_str(name: String,
                                  source: String,
                                  cfg: ast::CrateConfig,
@@ -291,7 +296,7 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
 pub fn tts_to_parser<'a>(sess: &'a ParseSess,
                          tts: Vec<ast::TokenTree>,
                          cfg: ast::CrateConfig) -> Parser<'a> {
-    let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts);
+    let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, None, tts);
     Parser::new(sess, cfg, box trdr)
 }
 
@@ -307,6 +312,8 @@ pub mod with_hygiene {
 
     // Note: keep this in sync with `super::parse_tts_from_source_str` until
     // #16472 is resolved.
+    //
+    // Warning: This parses with quote_depth > 0, which is not the default.
     pub fn parse_tts_from_source_str(name: String,
                                      source: String,
                                      cfg: ast::CrateConfig,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 58b08757cdf..cdfbd2c74b6 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
-
 pub use self::PathParsingMode::*;
 use self::ItemOrViewItem::*;
 
@@ -74,8 +72,8 @@ use parse::classify;
 use parse::common::{SeqSep, seq_sep_none, seq_sep_trailing_allowed};
 use parse::lexer::{Reader, TokenAndSpan};
 use parse::obsolete::*;
-use parse::token::{self, MatchNt, SubstNt, InternedString};
-use parse::token::{keywords, special_idents};
+use parse::token::{self, MatchNt, SubstNt, SpecialVarNt, InternedString};
+use parse::token::{keywords, special_idents, SpecialMacroVar};
 use parse::{new_sub_parser_from_file, ParseSess};
 use print::pprust;
 use ptr::P;
@@ -2739,6 +2737,9 @@ impl<'a> Parser<'a> {
                                    op: repeat,
                                    num_captures: name_num
                                }))
+                } else if p.token.is_keyword_allow_following_colon(keywords::Crate) {
+                    p.bump();
+                    TtToken(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar))
                 } else {
                     // A nonterminal that matches or not
                     let namep = match p.token { token::Ident(_, p) => p, _ => token::Plain };
@@ -3881,13 +3882,13 @@ impl<'a> Parser<'a> {
                                                                   &mut stmts,
                                                                   &mut expr);
                         }
-                        StmtMac(macro, MacStmtWithoutBraces) => {
+                        StmtMac(mac, MacStmtWithoutBraces) => {
                             // statement macro without braces; might be an
                             // expr depending on whether a semicolon follows
                             match self.token {
                                 token::Semi => {
                                     stmts.push(P(Spanned {
-                                        node: StmtMac(macro,
+                                        node: StmtMac(mac,
                                                       MacStmtWithSemicolon),
                                         span: span,
                                     }));
@@ -3896,10 +3897,16 @@ impl<'a> Parser<'a> {
                                 _ => {
                                     let e = self.mk_mac_expr(span.lo,
                                                              span.hi,
+<<<<<<< HEAD
                                                              macro.and_then(|m| m.node));
                                     let e = self.parse_dot_or_call_expr_with(e);
                                     let e = self.parse_more_binops(e, 0);
                                     let e = self.parse_assign_expr_with(e);
+=======
+                                                             mac.and_then(|m| m.node));
+                                    let e =
+                                        self.parse_dot_or_call_expr_with(e);
+>>>>>>> kmc/macro-reform
                                     self.handle_expression_like_statement(
                                         e,
                                         ast::DUMMY_NODE_ID,
@@ -6026,6 +6033,10 @@ impl<'a> Parser<'a> {
     fn parse_view_path(&mut self) -> P<ViewPath> {
         let lo = self.span.lo;
 
+        // Allow a leading :: because the paths are absolute either way.
+        // This occurs with "use $crate::..." in macros.
+        self.eat(&token::ModSep);
+
         if self.check(&token::OpenDelim(token::Brace)) {
             // use {foo,bar}
             let idents = self.parse_unspanned_seq(
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index b7e89b32b70..094aacf3207 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -62,6 +62,21 @@ pub enum IdentStyle {
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Show, 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, Show, Copy)]
 pub enum Lit {
     Byte(ast::Name),
     Char(ast::Name),
@@ -143,6 +158,8 @@ pub enum Token {
     // In right-hand-sides of MBE macros:
     /// A syntactic variable that will be filled in by macro expansion.
     SubstNt(ast::Ident, IdentStyle),
+    /// 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
@@ -265,6 +282,13 @@ impl Token {
         }
     }
 
+    pub fn is_keyword_allow_following_colon(&self, kw: keywords::Keyword) -> bool {
+        match *self {
+            Ident(sid, _) => { kw.to_name() == sid.name }
+            _ => { false }
+        }
+    }
+
     /// Returns `true` if the token is either a special identifier, or a strict
     /// or reserved keyword.
     #[allow(non_upper_case_globals)]
@@ -550,6 +574,7 @@ declare_special_idents_and_keywords! {
         (56,                         Abstract,   "abstract");
         (57,                         Final,      "final");
         (58,                         Override,   "override");
+        (59,                         Macro,      "macro");
     }
 }