Skip to content

Commit

Permalink
Add support for macro expansion inside trait items
Browse files Browse the repository at this point in the history
  • Loading branch information
Joseph Dunne committed Jun 13, 2016
1 parent 0740a93 commit dc3d878
Show file tree
Hide file tree
Showing 15 changed files with 238 additions and 87 deletions.
1 change: 1 addition & 0 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,7 @@ impl<'a> LoweringContext<'a> {
hir::TypeTraitItem(this.lower_bounds(bounds),
default.as_ref().map(|x| this.lower_ty(x)))
}
TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
},
span: i.span,
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/hir/map/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
DefPathData::ValueNs(ti.ident.name),
TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name),
TraitItemKind::Macro(..) => DefPathData::MacroDef(ti.ident.name),
};

let def = self.create_def(ti.id, def_data);
Expand Down
1 change: 1 addition & 0 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ impl<'b> Resolver<'b> {
(Def::Method(item_def_id), ValueNS)
}
TraitItemKind::Type(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS),
TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
};

self.define(module_parent, item.ident.name, ns, (def, item.span, vis));
Expand Down
1 change: 1 addition & 0 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1692,6 +1692,7 @@ impl<'a> Resolver<'a> {
visit::walk_trait_item(this, trait_item)
});
}
TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
};
}
});
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_save_analysis/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,7 +1204,8 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
trait_item.span);
}
ast::TraitItemKind::Const(_, None) |
ast::TraitItemKind::Type(..) => {}
ast::TraitItemKind::Type(..) |
ast::TraitItemKind::Macro(_) => {}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,7 @@ pub enum TraitItemKind {
Const(P<Ty>, Option<P<Expr>>),
Method(MethodSig, Option<P<Block>>),
Type(TyParamBounds, Option<P<Ty>>),
Macro(Mac),
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
Expand Down
18 changes: 18 additions & 0 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ pub trait MacResult {
None
}

/// Create zero or more trait items.
fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
None
}

/// Create a pattern.
fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
None
Expand Down Expand Up @@ -274,6 +279,7 @@ make_MacEager! {
pat: P<ast::Pat>,
items: SmallVector<P<ast::Item>>,
impl_items: SmallVector<ast::ImplItem>,
trait_items: SmallVector<ast::TraitItem>,
stmts: SmallVector<ast::Stmt>,
ty: P<ast::Ty>,
}
Expand All @@ -291,6 +297,10 @@ impl MacResult for MacEager {
self.impl_items
}

fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
self.trait_items
}

fn make_stmts(self: Box<Self>) -> Option<SmallVector<ast::Stmt>> {
match self.stmts.as_ref().map_or(0, |s| s.len()) {
0 => make_stmts_default!(self),
Expand Down Expand Up @@ -399,6 +409,14 @@ impl MacResult for DummyResult {
}
}

fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVector<ast::TraitItem>> {
if self.expr_only {
None
} else {
Some(SmallVector::zero())
}
}

fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> {
Some(SmallVector::one(
codemap::respan(self.span,
Expand Down
50 changes: 31 additions & 19 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ impl_macro_generable! {
P<ast::Ty>: "type", .make_ty, .fold_ty, |span| DummyResult::raw_ty(span);
SmallVector<ast::ImplItem>:
"impl item", .make_impl_items, lift .fold_impl_item, |_span| SmallVector::zero();
SmallVector<ast::TraitItem>:
"trait item", .make_trait_items, lift .fold_trait_item, |_span| SmallVector::zero();
SmallVector<P<ast::Item>>:
"item", .make_items, lift .fold_item, |_span| SmallVector::zero();
SmallVector<ast::Stmt>:
Expand Down Expand Up @@ -760,25 +762,10 @@ fn expand_annotatable(a: Annotatable,
_ => noop_fold_item(it, fld),
}.into_iter().map(|i| Annotatable::Item(i)).collect(),

Annotatable::TraitItem(it) => match it.node {
ast::TraitItemKind::Method(_, Some(_)) => {
let ti = it.unwrap();
SmallVector::one(ast::TraitItem {
id: ti.id,
ident: ti.ident,
attrs: ti.attrs,
node: match ti.node {
ast::TraitItemKind::Method(sig, Some(body)) => {
let (sig, body) = expand_and_rename_method(sig, body, fld);
ast::TraitItemKind::Method(sig, Some(body))
}
_ => unreachable!()
},
span: ti.span,
})
}
_ => fold::noop_fold_trait_item(it.unwrap(), fld)
}.into_iter().map(|ti| Annotatable::TraitItem(P(ti))).collect(),
Annotatable::TraitItem(it) => {
expand_trait_item(it.unwrap(), fld).into_iter().
map(|it| Annotatable::TraitItem(P(it))).collect()
}

Annotatable::ImplItem(ii) => {
expand_impl_item(ii.unwrap(), fld).into_iter().
Expand Down Expand Up @@ -934,6 +921,31 @@ fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander)
}
}

fn expand_trait_item(ti: ast::TraitItem, fld: &mut MacroExpander)
-> SmallVector<ast::TraitItem> {
match ti.node {
ast::TraitItemKind::Method(_, Some(_)) => {
SmallVector::one(ast::TraitItem {
id: ti.id,
ident: ti.ident,
attrs: ti.attrs,
node: match ti.node {
ast::TraitItemKind::Method(sig, Some(body)) => {
let (sig, body) = expand_and_rename_method(sig, body, fld);
ast::TraitItemKind::Method(sig, Some(body))
}
_ => unreachable!()
},
span: ti.span,
})
}
ast::TraitItemKind::Macro(mac) => {
expand_mac_invoc(mac, None, ti.attrs, ti.span, fld)
}
_ => fold::noop_fold_trait_item(ti, fld)
}
}

/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
/// PatIdents in its arguments to perform renaming in the FnDecl and
/// the block, returning both the new FnDecl and the new Block.
Expand Down
15 changes: 15 additions & 0 deletions src/libsyntax/ext/tt/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,21 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
Some(ret)
}

fn make_trait_items(self: Box<ParserAnyMacro<'a>>)
-> Option<SmallVector<ast::TraitItem>> {
let mut ret = SmallVector::zero();
loop {
let mut parser = self.parser.borrow_mut();
match parser.token {
token::Eof => break,
_ => ret.push(panictry!(parser.parse_trait_item()))
}
}
self.ensure_complete_parse(false, "item");
Some(ret)
}


fn make_stmts(self: Box<ParserAnyMacro<'a>>)
-> Option<SmallVector<ast::Stmt>> {
let mut ret = SmallVector::zero();
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,9 @@ pub fn noop_fold_trait_item<T: Folder>(i: TraitItem, folder: &mut T)
TraitItemKind::Type(folder.fold_bounds(bounds),
default.map(|x| folder.fold_ty(x)))
}
ast::TraitItemKind::Macro(mac) => {
TraitItemKind::Macro(folder.fold_mac(mac))
}
},
span: folder.new_span(i.span)
})
Expand Down
Loading

0 comments on commit dc3d878

Please sign in to comment.