]> git.lizzy.rs Git - rust.git/commitdiff
Extend macro machinery to expand macros in types
authorJared Roesch <roeschinc@gmail.com>
Sun, 26 Jul 2015 04:54:19 +0000 (21:54 -0700)
committerJared Roesch <roeschinc@gmail.com>
Tue, 4 Aug 2015 23:05:06 +0000 (16:05 -0700)
Reapplied the changes from https://github.com/freebroccolo/rust/commit/7aafe24139abc2d1f302bbb166bcaa006f12cf4d
to a clean branch of master

src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_rules.rs

index 409ae86db35d4ebe53404379c8a674e8b3e35c0f..28c7ead20bcaef7adac840bf867980e5a3c84d7f 100644 (file)
@@ -290,6 +290,10 @@ fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
     fn make_stmts(self: Box<Self>) -> Option<SmallVector<P<ast::Stmt>>> {
         make_stmts_default!(self)
     }
+
+    fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
+        None
+    }
 }
 
 macro_rules! make_MacEager {
@@ -322,6 +326,7 @@ pub fn $fld(v: $t) -> Box<MacResult> {
     items: SmallVector<P<ast::Item>>,
     impl_items: SmallVector<P<ast::ImplItem>>,
     stmts: SmallVector<P<ast::Stmt>>,
+    ty: P<ast::Ty>,
 }
 
 impl MacResult for MacEager {
@@ -359,6 +364,10 @@ fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
         }
         None
     }
+
+    fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
+        self.ty
+    }
 }
 
 /// Fill-in macro expansion result, to allow compilation to continue
@@ -405,6 +414,12 @@ pub fn raw_pat(sp: Span) -> ast::Pat {
         }
     }
 
+    pub fn raw_ty(sp: Span) -> P<ast::Ty> {
+        P(ast::Ty {
+            id: ast:DUMMY_NODE_ID,
+            node: ast::TyInfer,
+            span: sp
+        })
 }
 
 impl MacResult for DummyResult {
index 6e49b190f7c21076042f3888dc4f5e686b9672d9..cd340fc91891f6aa206a51378cc4f2b68730ffa0 100644 (file)
@@ -1552,6 +1552,35 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
     }, rewritten_body)
 }
 
+pub fn expand_type(t: P<ast::Ty>, fld: &mut MacroExpander) -> P<ast::Ty> {
+    let t = match t.node.clone() {
+        ast::Ty_::TyMac(mac) => {
+            let expanded_ty = match expand_mac_invoc(mac, t.span,
+                                                     |r| r.make_ty(),
+                                                     mark_ty,
+                                                     fld) {
+                Some(ty) => ty,
+                None => {
+                    return DummyResult::raw_ty(t.span);
+                }
+            };
+
+            // Keep going, outside-in.
+            //
+            let fully_expanded = fld.fold_ty(expanded_ty);
+            fld.cx.bt_pop();
+
+            fully_expanded.map(|t| ast::Ty {
+                id: ast::DUMMY_NODE_ID,
+                node: t.node,
+                span: t.span,
+            })
+        }
+        _ => t
+    };
+    fold::noop_fold_ty(t, fld)
+}
+
 /// A tree-folder that performs macro expansion
 pub struct MacroExpander<'a, 'b:'a> {
     pub cx: &'a mut ExtCtxt<'b>,
@@ -1602,6 +1631,10 @@ fn fold_impl_item(&mut self, i: P<ast::ImplItem>) -> SmallVector<P<ast::ImplItem
             .into_iter().map(|i| i.expect_impl_item()).collect()
     }
 
+    fn fold_ty(&mut self, ty: P<ast::Ty>) -> P<ast::Ty> {
+        expand_type(ty, self)
+    }
+
     fn new_span(&mut self, span: Span) -> Span {
         new_span(self.cx, span)
     }
@@ -1748,6 +1781,10 @@ fn mark_impl_item(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> {
         .expect_one("marking an impl item didn't return exactly one impl item")
 }
 
+fn mark_ty(ty: P<ast::Ty>, m: Mrk) -> P<ast::Ty> {
+    Marker { mark: m }.fold_ty(ty)
+}
+
 /// Check that there are no macro invocations left in the AST:
 pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) {
     visit::walk_crate(&mut MacroExterminator{sess:sess}, krate);
index adc88c329a31731e00093645bb1df3ec7fba8757..d16fde7bc394e44dc5ded3ca9a1dd2a2fbffb639 100644 (file)
@@ -117,6 +117,12 @@ fn make_stmts(self: Box<ParserAnyMacro<'a>>)
         self.ensure_complete_parse(false);
         Some(ret)
     }
+
+    fn make_ty(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Ty>> {
+        let ret = self.parser.borrow_mut().parse_ty();
+        self.ensure_complete_parse(true);
+        Some(ret)
+    }
 }
 
 struct MacroRulesMacroExpander {