summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-08-07 09:47:28 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-08-27 18:46:51 -0700
commit3b6314c39bfc13b5a41c53f13c3fafa7ad91e062 (patch)
treef43929dd9d9874c8cd95a69f7c47313b2bcf055a /src/libsyntax/ext
parent5c3504799deb78d986f8267f753a87fb9e73a452 (diff)
downloadrust-3b6314c39bfc13b5a41c53f13c3fafa7ad91e062.tar.gz
rust-3b6314c39bfc13b5a41c53f13c3fafa7ad91e062.zip
librustc: Add support for type parameters in the middle of paths.
For example, `foo::<T>::bar::<U>`.

This doesn't enforce that the type parameters are in the right
positions, however.
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/base.rs20
-rw-r--r--src/libsyntax/ext/build.rs25
-rw-r--r--src/libsyntax/ext/concat_idents.rs11
-rw-r--r--src/libsyntax/ext/expand.rs31
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs6
5 files changed, 54 insertions, 39 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 6f9585652bd..7432cf80a41 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -329,20 +329,6 @@ pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::expr, err_msg: &str) -> @str {
     }
 }
 
-pub fn expr_to_ident(cx: @ExtCtxt,
-                     expr: @ast::expr,
-                     err_msg: &str) -> ast::ident {
-    match expr.node {
-      ast::expr_path(ref p) => {
-        if p.types.len() > 0u || p.idents.len() != 1u {
-            cx.span_fatal(expr.span, err_msg);
-        }
-        return p.idents[0];
-      }
-      _ => cx.span_fatal(expr.span, err_msg)
-    }
-}
-
 pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree],
                       name: &str) {
     if tts.len() != 0 {
@@ -353,15 +339,15 @@ pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree],
 pub fn get_single_str_from_tts(cx: @ExtCtxt,
                                sp: span,
                                tts: &[ast::token_tree],
-                               name: &str) -> @str {
+                               name: &str)
+                               -> @str {
     if tts.len() != 1 {
         cx.span_fatal(sp, fmt!("%s takes 1 argument.", name));
     }
 
     match tts[0] {
         ast::tt_tok(_, token::LIT_STR(ident)) => cx.str_of(ident),
-        _ =>
-        cx.span_fatal(sp, fmt!("%s requires a string.", name))
+        _ => cx.span_fatal(sp, fmt!("%s requires a string.", name)),
     }
 }
 
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 9f179672422..a62a1d121e2 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -233,18 +233,31 @@ impl AstBuilder for @ExtCtxt {
     fn path_global(&self, span: span, strs: ~[ast::ident]) -> ast::Path {
         self.path_all(span, true, strs, None, ~[])
     }
-    fn path_all(&self, sp: span,
+    fn path_all(&self,
+                sp: span,
                 global: bool,
-                idents: ~[ast::ident],
+                mut idents: ~[ast::ident],
                 rp: Option<ast::Lifetime>,
                 types: ~[ast::Ty])
-        -> ast::Path {
+                -> ast::Path {
+        let last_identifier = idents.pop();
+        let mut segments: ~[ast::PathSegment] = idents.consume_iter()
+                                                      .transform(|ident| {
+            ast::PathSegment {
+                identifier: ident,
+                lifetime: None,
+                types: opt_vec::Empty,
+            }
+        }).collect();
+        segments.push(ast::PathSegment {
+            identifier: last_identifier,
+            lifetime: rp,
+            types: opt_vec::from(types),
+        });
         ast::Path {
             span: sp,
             global: global,
-            idents: idents,
-            rp: rp,
-            types: types
+            segments: segments,
         }
     }
 
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index edb5c634d56..477f3fde99c 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -12,6 +12,7 @@ use ast;
 use codemap::span;
 use ext::base::*;
 use ext::base;
+use opt_vec;
 use parse::token;
 use parse::token::{str_to_ident};
 
@@ -39,9 +40,13 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
             ast::Path {
                  span: sp,
                  global: false,
-                 idents: ~[res],
-                 rp: None,
-                 types: ~[],
+                 segments: ~[
+                    ast::PathSegment {
+                        identifier: res,
+                        lifetime: None,
+                        types: opt_vec::Empty,
+                    }
+                ]
             }
         ),
         span: sp,
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 7b493e11ef7..86639c6f121 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -19,6 +19,7 @@ use codemap;
 use codemap::{span, spanned, ExpnInfo, NameAndSpan};
 use ext::base::*;
 use fold::*;
+use opt_vec;
 use parse;
 use parse::{parse_item_from_source_str};
 use parse::token;
@@ -42,13 +43,13 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
             match (*mac).node {
                 // Token-tree macros:
                 mac_invoc_tt(ref pth, ref tts) => {
-                    if (pth.idents.len() > 1u) {
+                    if (pth.segments.len() > 1u) {
                         cx.span_fatal(
                             pth.span,
                             fmt!("expected macro name without module \
                                   separators"));
                     }
-                    let extname = &pth.idents[0];
+                    let extname = &pth.segments[0].identifier;
                     let extnamestr = ident_to_str(extname);
                     // leaving explicit deref here to highlight unbox op:
                     match (*extsbox).find(&extname.name) {
@@ -143,9 +144,13 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
                 ast::Path {
                     span: span,
                     global: false,
-                    idents: ~[ident],
-                    rp: None,
-                    types: ~[]
+                    segments: ~[
+                        ast::PathSegment {
+                            identifier: ident,
+                            lifetime: None,
+                            types: opt_vec::Empty,
+                        }
+                    ],
                 }
             }
 
@@ -368,7 +373,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
         _ => cx.span_bug(it.span, "invalid item macro invocation")
     };
 
-    let extname = &pth.idents[0];
+    let extname = &pth.segments[0].identifier;
     let extnamestr = ident_to_str(extname);
     let expanded = match (*extsbox).find(&extname.name) {
         None => cx.span_fatal(pth.span,
@@ -459,13 +464,13 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
         }
         _ => return orig(s, sp, fld)
     };
-    if (pth.idents.len() > 1u) {
+    if (pth.segments.len() > 1u) {
         cx.span_fatal(
             pth.span,
             fmt!("expected macro name without module \
                   separators"));
     }
-    let extname = &pth.idents[0];
+    let extname = &pth.segments[0].identifier;
     let extnamestr = ident_to_str(extname);
     let (fully_expanded, sp) = match (*extsbox).find(&extname.name) {
         None =>
@@ -534,10 +539,14 @@ impl Visitor<()> for NewNameFinderContext {
                     // a path of length one:
                     &ast::Path {
                         global: false,
-                        idents: [id],
                         span: _,
-                        rp: _,
-                        types: _
+                        segments: [
+                            ast::PathSegment {
+                                identifier: id,
+                                lifetime: _,
+                                types: _
+                            }
+                        ]
                     } => self.ident_accumulator.push(id),
                     // I believe these must be enums...
                     _ => ()
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index c208a7f7e3e..327ee331c38 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -16,8 +16,8 @@ use codemap::{BytePos, mk_sp};
 use codemap;
 use parse::lexer::*; //resolve bug?
 use parse::ParseSess;
-use parse::parser::Parser;
 use parse::attr::parser_attr;
+use parse::parser::{LifetimeAndTypesWithoutColons, Parser};
 use parse::token::{Token, EOF, to_str, nonterminal, get_ident_interner, ident_to_str};
 use parse::token;
 
@@ -430,7 +430,9 @@ pub fn parse_nt(p: &Parser, name: &str) -> nonterminal {
         _ => p.fatal(~"expected ident, found "
                      + token::to_str(get_ident_interner(), p.token))
       },
-      "path" => token::nt_path(~p.parse_path_with_tps(false)),
+      "path" => {
+        token::nt_path(~p.parse_path(LifetimeAndTypesWithoutColons).path)
+      }
       "attr" => token::nt_attr(@p.parse_attribute(false)),
       "tt" => {
         *p.quote_depth += 1u; //but in theory, non-quoted tts might be useful