diff options
| author | Jared Roesch <roeschinc@gmail.com> | 2015-07-25 21:54:19 -0700 |
|---|---|---|
| committer | Jared Roesch <roeschinc@gmail.com> | 2015-08-04 16:05:06 -0700 |
| commit | 9fb11fe9f21051f4f03da55f949de402e78a95d5 (patch) | |
| tree | d9ae7e953684d3d6558fb45c4f85211481dd208a /src/libsyntax/ext | |
| parent | edca562c87362c80e409f53d28e19617ca44646a (diff) | |
| download | rust-9fb11fe9f21051f4f03da55f949de402e78a95d5.tar.gz rust-9fb11fe9f21051f4f03da55f949de402e78a95d5.zip | |
Extend macro machinery to expand macros in types
Reapplied the changes from https://github.com/freebroccolo/rust/commit/7aafe24139abc2d1f302bbb166bcaa006f12cf4d to a clean branch of master
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 37 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 6 |
3 files changed, 58 insertions, 0 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 409ae86db35..28c7ead20bc 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -290,6 +290,10 @@ pub trait MacResult { 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 @@ make_MacEager! { 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 @@ impl MacResult for MacEager { } 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 @@ impl DummyResult { } } + 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 { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6e49b190f7c..cd340fc9189 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -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 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { .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); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index adc88c329a3..d16fde7bc39 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -117,6 +117,12 @@ impl<'a> MacResult for 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 { |
