Skip to content

Commit edb925a

Browse files
committed
syntax: Use MultiItemModifier for built-in derives
1 parent 5a6ebec commit edb925a

File tree

3 files changed

+42
-29
lines changed

3 files changed

+42
-29
lines changed

src/libsyntax/ext/base.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub use SyntaxExtension::*;
22

3-
use crate::ast::{self, Attribute, Name, PatKind, MetaItem};
3+
use crate::ast::{self, Attribute, Name, PatKind};
44
use crate::attr::HasAttrs;
55
use crate::source_map::{SourceMap, Spanned, respan};
66
use crate::edition::Edition;
@@ -519,9 +519,6 @@ impl MacResult for DummyResult {
519519
}
520520
}
521521

522-
pub type BuiltinDeriveFn =
523-
for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable));
524-
525522
/// Represents different kinds of macro invocations that can be resolved.
526523
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
527524
pub enum MacroKind {
@@ -607,7 +604,7 @@ pub enum SyntaxExtension {
607604
Vec<Symbol> /* inert attribute names */, Edition),
608605

609606
/// An attribute-like procedural macro that derives a builtin trait.
610-
BuiltinDerive(BuiltinDeriveFn),
607+
BuiltinDerive(Box<dyn MultiItemModifier + sync::Sync + sync::Send>),
611608

612609
/// A declarative macro, e.g., `macro m() {}`.
613610
DeclMacro {

src/libsyntax/ext/expand.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -893,29 +893,29 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
893893
edition: ext.edition(self.cx.parse_sess.edition),
894894
};
895895

896-
match *ext {
897-
ProcMacroDerive(ref ext, ..) => {
898-
invoc.expansion_data.mark.set_expn_info(expn_info);
899-
let span = span.with_ctxt(self.cx.backtrace());
900-
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
901-
path: Path::from_ident(Ident::invalid()),
902-
span: DUMMY_SP,
903-
node: ast::MetaItemKind::Word,
896+
match ext {
897+
ProcMacroDerive(expander, ..) | BuiltinDerive(expander) => {
898+
let meta = match ext {
899+
ProcMacroDerive(..) => ast::MetaItem { // FIXME(jseyfried) avoid this
900+
path: Path::from_ident(Ident::invalid()),
901+
span: DUMMY_SP,
902+
node: ast::MetaItemKind::Word,
903+
},
904+
_ => {
905+
expn_info.allow_internal_unstable = Some(vec![
906+
sym::rustc_attrs,
907+
Symbol::intern("derive_clone_copy"),
908+
Symbol::intern("derive_eq"),
909+
// RustcDeserialize and RustcSerialize
910+
Symbol::intern("libstd_sys_internals"),
911+
].into());
912+
attr.meta()?
913+
}
904914
};
905-
let items = ext.expand(self.cx, span, &dummy, item);
906-
Some(invoc.fragment_kind.expect_from_annotatables(items))
907-
}
908-
BuiltinDerive(func) => {
909-
expn_info.allow_internal_unstable = Some(vec![
910-
sym::rustc_attrs,
911-
Symbol::intern("derive_clone_copy"),
912-
Symbol::intern("derive_eq"),
913-
Symbol::intern("libstd_sys_internals"), // RustcDeserialize and RustcSerialize
914-
].into());
915+
915916
invoc.expansion_data.mark.set_expn_info(expn_info);
916917
let span = span.with_ctxt(self.cx.backtrace());
917-
let mut items = Vec::new();
918-
func(self.cx, span, &attr.meta()?, &item, &mut |a| items.push(a));
918+
let items = expander.expand(self.cx, span, &meta, item);
919919
Some(invoc.fragment_kind.expect_from_annotatables(items))
920920
}
921921
_ => {

src/libsyntax_ext/deriving/mod.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! The compiler code necessary to implement the `#[derive]` extensions.
22
33
use rustc_data_structures::sync::Lrc;
4-
use syntax::ast;
5-
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver};
4+
use syntax::ast::{self, MetaItem};
5+
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver, MultiItemModifier};
66
use syntax::ext::build::AstBuilder;
77
use syntax::ext::hygiene::{Mark, SyntaxContext};
88
use syntax::ptr::P;
@@ -39,9 +39,25 @@ pub mod partial_ord;
3939
#[path="cmp/ord.rs"]
4040
pub mod ord;
4141

42-
4342
pub mod generic;
4443

44+
struct BuiltinDerive(
45+
fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable))
46+
);
47+
48+
impl MultiItemModifier for BuiltinDerive {
49+
fn expand(&self,
50+
ecx: &mut ExtCtxt<'_>,
51+
span: Span,
52+
meta_item: &MetaItem,
53+
item: Annotatable)
54+
-> Vec<Annotatable> {
55+
let mut items = Vec::new();
56+
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
57+
items
58+
}
59+
}
60+
4561
macro_rules! derive_traits {
4662
($( $name:expr => $func:path, )+) => {
4763
pub fn is_builtin_trait(name: ast::Name) -> bool {
@@ -55,7 +71,7 @@ macro_rules! derive_traits {
5571
$(
5672
resolver.add_builtin(
5773
ast::Ident::with_empty_ctxt(Symbol::intern($name)),
58-
Lrc::new(SyntaxExtension::BuiltinDerive($func))
74+
Lrc::new(SyntaxExtension::BuiltinDerive(Box::new(BuiltinDerive($func))))
5975
);
6076
)*
6177
}

0 commit comments

Comments
 (0)