Skip to content

Commit

Permalink
syntax: Use MultiItemModifier for built-in derives
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Jun 10, 2019
1 parent 5a6ebec commit edb925a
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 29 deletions.
7 changes: 2 additions & 5 deletions src/libsyntax/ext/base.rs
@@ -1,6 +1,6 @@
pub use SyntaxExtension::*;

use crate::ast::{self, Attribute, Name, PatKind, MetaItem};
use crate::ast::{self, Attribute, Name, PatKind};
use crate::attr::HasAttrs;
use crate::source_map::{SourceMap, Spanned, respan};
use crate::edition::Edition;
Expand Down Expand Up @@ -519,9 +519,6 @@ impl MacResult for DummyResult {
}
}

pub type BuiltinDeriveFn =
for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable));

/// Represents different kinds of macro invocations that can be resolved.
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum MacroKind {
Expand Down Expand Up @@ -607,7 +604,7 @@ pub enum SyntaxExtension {
Vec<Symbol> /* inert attribute names */, Edition),

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

/// A declarative macro, e.g., `macro m() {}`.
DeclMacro {
Expand Down
40 changes: 20 additions & 20 deletions src/libsyntax/ext/expand.rs
Expand Up @@ -893,29 +893,29 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
edition: ext.edition(self.cx.parse_sess.edition),
};

match *ext {
ProcMacroDerive(ref ext, ..) => {
invoc.expansion_data.mark.set_expn_info(expn_info);
let span = span.with_ctxt(self.cx.backtrace());
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
path: Path::from_ident(Ident::invalid()),
span: DUMMY_SP,
node: ast::MetaItemKind::Word,
match ext {
ProcMacroDerive(expander, ..) | BuiltinDerive(expander) => {
let meta = match ext {
ProcMacroDerive(..) => ast::MetaItem { // FIXME(jseyfried) avoid this
path: Path::from_ident(Ident::invalid()),
span: DUMMY_SP,
node: ast::MetaItemKind::Word,
},
_ => {
expn_info.allow_internal_unstable = Some(vec![
sym::rustc_attrs,
Symbol::intern("derive_clone_copy"),
Symbol::intern("derive_eq"),
// RustcDeserialize and RustcSerialize
Symbol::intern("libstd_sys_internals"),
].into());
attr.meta()?
}
};
let items = ext.expand(self.cx, span, &dummy, item);
Some(invoc.fragment_kind.expect_from_annotatables(items))
}
BuiltinDerive(func) => {
expn_info.allow_internal_unstable = Some(vec![
sym::rustc_attrs,
Symbol::intern("derive_clone_copy"),
Symbol::intern("derive_eq"),
Symbol::intern("libstd_sys_internals"), // RustcDeserialize and RustcSerialize
].into());

invoc.expansion_data.mark.set_expn_info(expn_info);
let span = span.with_ctxt(self.cx.backtrace());
let mut items = Vec::new();
func(self.cx, span, &attr.meta()?, &item, &mut |a| items.push(a));
let items = expander.expand(self.cx, span, &meta, item);
Some(invoc.fragment_kind.expect_from_annotatables(items))
}
_ => {
Expand Down
24 changes: 20 additions & 4 deletions src/libsyntax_ext/deriving/mod.rs
@@ -1,8 +1,8 @@
//! The compiler code necessary to implement the `#[derive]` extensions.

use rustc_data_structures::sync::Lrc;
use syntax::ast;
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver};
use syntax::ast::{self, MetaItem};
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver, MultiItemModifier};
use syntax::ext::build::AstBuilder;
use syntax::ext::hygiene::{Mark, SyntaxContext};
use syntax::ptr::P;
Expand Down Expand Up @@ -39,9 +39,25 @@ pub mod partial_ord;
#[path="cmp/ord.rs"]
pub mod ord;


pub mod generic;

struct BuiltinDerive(
fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable))
);

impl MultiItemModifier for BuiltinDerive {
fn expand(&self,
ecx: &mut ExtCtxt<'_>,
span: Span,
meta_item: &MetaItem,
item: Annotatable)
-> Vec<Annotatable> {
let mut items = Vec::new();
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
items
}
}

macro_rules! derive_traits {
($( $name:expr => $func:path, )+) => {
pub fn is_builtin_trait(name: ast::Name) -> bool {
Expand All @@ -55,7 +71,7 @@ macro_rules! derive_traits {
$(
resolver.add_builtin(
ast::Ident::with_empty_ctxt(Symbol::intern($name)),
Lrc::new(SyntaxExtension::BuiltinDerive($func))
Lrc::new(SyntaxExtension::BuiltinDerive(Box::new(BuiltinDerive($func))))
);
)*
}
Expand Down

0 comments on commit edb925a

Please sign in to comment.