Skip to content

Commit dc3d878

Browse files
author
Joseph Dunne
committed
Add support for macro expansion inside trait items
1 parent 0740a93 commit dc3d878

File tree

15 files changed

+238
-87
lines changed

15 files changed

+238
-87
lines changed

src/librustc/hir/lowering.rs

+1
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@ impl<'a> LoweringContext<'a> {
700700
hir::TypeTraitItem(this.lower_bounds(bounds),
701701
default.as_ref().map(|x| this.lower_ty(x)))
702702
}
703+
TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
703704
},
704705
span: i.span,
705706
}

src/librustc/hir/map/def_collector.rs

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
204204
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
205205
DefPathData::ValueNs(ti.ident.name),
206206
TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name),
207+
TraitItemKind::Macro(..) => DefPathData::MacroDef(ti.ident.name),
207208
};
208209

209210
let def = self.create_def(ti.id, def_data);

src/librustc_resolve/build_reduced_graph.rs

+1
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ impl<'b> Resolver<'b> {
313313
(Def::Method(item_def_id), ValueNS)
314314
}
315315
TraitItemKind::Type(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS),
316+
TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
316317
};
317318

318319
self.define(module_parent, item.ident.name, ns, (def, item.span, vis));

src/librustc_resolve/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,7 @@ impl<'a> Resolver<'a> {
16921692
visit::walk_trait_item(this, trait_item)
16931693
});
16941694
}
1695+
TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
16951696
};
16961697
}
16971698
});

src/librustc_save_analysis/dump_visitor.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,8 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
12041204
trait_item.span);
12051205
}
12061206
ast::TraitItemKind::Const(_, None) |
1207-
ast::TraitItemKind::Type(..) => {}
1207+
ast::TraitItemKind::Type(..) |
1208+
ast::TraitItemKind::Macro(_) => {}
12081209
}
12091210
}
12101211

src/libsyntax/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,7 @@ pub enum TraitItemKind {
13901390
Const(P<Ty>, Option<P<Expr>>),
13911391
Method(MethodSig, Option<P<Block>>),
13921392
Type(TyParamBounds, Option<P<Ty>>),
1393+
Macro(Mac),
13931394
}
13941395

13951396
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]

src/libsyntax/ext/base.rs

+18
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ pub trait MacResult {
227227
None
228228
}
229229

230+
/// Create zero or more trait items.
231+
fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
232+
None
233+
}
234+
230235
/// Create a pattern.
231236
fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
232237
None
@@ -274,6 +279,7 @@ make_MacEager! {
274279
pat: P<ast::Pat>,
275280
items: SmallVector<P<ast::Item>>,
276281
impl_items: SmallVector<ast::ImplItem>,
282+
trait_items: SmallVector<ast::TraitItem>,
277283
stmts: SmallVector<ast::Stmt>,
278284
ty: P<ast::Ty>,
279285
}
@@ -291,6 +297,10 @@ impl MacResult for MacEager {
291297
self.impl_items
292298
}
293299

300+
fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
301+
self.trait_items
302+
}
303+
294304
fn make_stmts(self: Box<Self>) -> Option<SmallVector<ast::Stmt>> {
295305
match self.stmts.as_ref().map_or(0, |s| s.len()) {
296306
0 => make_stmts_default!(self),
@@ -399,6 +409,14 @@ impl MacResult for DummyResult {
399409
}
400410
}
401411

412+
fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVector<ast::TraitItem>> {
413+
if self.expr_only {
414+
None
415+
} else {
416+
Some(SmallVector::zero())
417+
}
418+
}
419+
402420
fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> {
403421
Some(SmallVector::one(
404422
codemap::respan(self.span,

src/libsyntax/ext/expand.rs

+31-19
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ impl_macro_generable! {
7070
P<ast::Ty>: "type", .make_ty, .fold_ty, |span| DummyResult::raw_ty(span);
7171
SmallVector<ast::ImplItem>:
7272
"impl item", .make_impl_items, lift .fold_impl_item, |_span| SmallVector::zero();
73+
SmallVector<ast::TraitItem>:
74+
"trait item", .make_trait_items, lift .fold_trait_item, |_span| SmallVector::zero();
7375
SmallVector<P<ast::Item>>:
7476
"item", .make_items, lift .fold_item, |_span| SmallVector::zero();
7577
SmallVector<ast::Stmt>:
@@ -760,25 +762,10 @@ fn expand_annotatable(a: Annotatable,
760762
_ => noop_fold_item(it, fld),
761763
}.into_iter().map(|i| Annotatable::Item(i)).collect(),
762764

763-
Annotatable::TraitItem(it) => match it.node {
764-
ast::TraitItemKind::Method(_, Some(_)) => {
765-
let ti = it.unwrap();
766-
SmallVector::one(ast::TraitItem {
767-
id: ti.id,
768-
ident: ti.ident,
769-
attrs: ti.attrs,
770-
node: match ti.node {
771-
ast::TraitItemKind::Method(sig, Some(body)) => {
772-
let (sig, body) = expand_and_rename_method(sig, body, fld);
773-
ast::TraitItemKind::Method(sig, Some(body))
774-
}
775-
_ => unreachable!()
776-
},
777-
span: ti.span,
778-
})
779-
}
780-
_ => fold::noop_fold_trait_item(it.unwrap(), fld)
781-
}.into_iter().map(|ti| Annotatable::TraitItem(P(ti))).collect(),
765+
Annotatable::TraitItem(it) => {
766+
expand_trait_item(it.unwrap(), fld).into_iter().
767+
map(|it| Annotatable::TraitItem(P(it))).collect()
768+
}
782769

783770
Annotatable::ImplItem(ii) => {
784771
expand_impl_item(ii.unwrap(), fld).into_iter().
@@ -934,6 +921,31 @@ fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander)
934921
}
935922
}
936923

924+
fn expand_trait_item(ti: ast::TraitItem, fld: &mut MacroExpander)
925+
-> SmallVector<ast::TraitItem> {
926+
match ti.node {
927+
ast::TraitItemKind::Method(_, Some(_)) => {
928+
SmallVector::one(ast::TraitItem {
929+
id: ti.id,
930+
ident: ti.ident,
931+
attrs: ti.attrs,
932+
node: match ti.node {
933+
ast::TraitItemKind::Method(sig, Some(body)) => {
934+
let (sig, body) = expand_and_rename_method(sig, body, fld);
935+
ast::TraitItemKind::Method(sig, Some(body))
936+
}
937+
_ => unreachable!()
938+
},
939+
span: ti.span,
940+
})
941+
}
942+
ast::TraitItemKind::Macro(mac) => {
943+
expand_mac_invoc(mac, None, ti.attrs, ti.span, fld)
944+
}
945+
_ => fold::noop_fold_trait_item(ti, fld)
946+
}
947+
}
948+
937949
/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
938950
/// PatIdents in its arguments to perform renaming in the FnDecl and
939951
/// the block, returning both the new FnDecl and the new Block.

src/libsyntax/ext/tt/macro_rules.rs

+15
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
100100
Some(ret)
101101
}
102102

103+
fn make_trait_items(self: Box<ParserAnyMacro<'a>>)
104+
-> Option<SmallVector<ast::TraitItem>> {
105+
let mut ret = SmallVector::zero();
106+
loop {
107+
let mut parser = self.parser.borrow_mut();
108+
match parser.token {
109+
token::Eof => break,
110+
_ => ret.push(panictry!(parser.parse_trait_item()))
111+
}
112+
}
113+
self.ensure_complete_parse(false, "item");
114+
Some(ret)
115+
}
116+
117+
103118
fn make_stmts(self: Box<ParserAnyMacro<'a>>)
104119
-> Option<SmallVector<ast::Stmt>> {
105120
let mut ret = SmallVector::zero();

src/libsyntax/fold.rs

+3
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,9 @@ pub fn noop_fold_trait_item<T: Folder>(i: TraitItem, folder: &mut T)
945945
TraitItemKind::Type(folder.fold_bounds(bounds),
946946
default.map(|x| folder.fold_ty(x)))
947947
}
948+
ast::TraitItemKind::Macro(mac) => {
949+
TraitItemKind::Macro(folder.fold_mac(mac))
950+
}
948951
},
949952
span: folder.new_span(i.span)
950953
})

0 commit comments

Comments
 (0)