Merge branch 'syntax' of https://github.com/aochagavia/rust into mulit-decor
Conflicts: src/librustc/plugin/registry.rs src/libsyntax/ext/base.rs src/libsyntax/ext/cfg_attr.rs src/libsyntax/ext/deriving/mod.rs src/libsyntax/ext/expand.rs src/libsyntax/print/pprust.rs src/test/auxiliary/macro_crate_test.rs
This commit is contained in:
@@ -14,8 +14,13 @@ use lint::{LintPassObject, LintId, Lint};
|
|||||||
use session::Session;
|
use session::Session;
|
||||||
|
|
||||||
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
|
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
|
||||||
|
<<<<<<< HEAD
|
||||||
use syntax::ext::base::{IdentTT, Decorator, Modifier, MultiModifier, MacroRulesTT};
|
use syntax::ext::base::{IdentTT, Decorator, Modifier, MultiModifier, MacroRulesTT};
|
||||||
use syntax::ext::base::MacroExpanderFn;
|
use syntax::ext::base::MacroExpanderFn;
|
||||||
|
=======
|
||||||
|
use syntax::ext::base::{IdentTT, Decorator, MultiDecorator, Modifier, MultiModifier, MacroRulesTT};
|
||||||
|
use syntax::ext::base::{MacroExpanderFn};
|
||||||
|
>>>>>>> 143f2db3174103e459218958f567985b1f47944b
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
@@ -84,6 +89,7 @@ impl<'a> Registry<'a> {
|
|||||||
/// Register a syntax extension of any kind.
|
/// Register a syntax extension of any kind.
|
||||||
///
|
///
|
||||||
/// This is the most general hook into `libsyntax`'s expansion behavior.
|
/// This is the most general hook into `libsyntax`'s expansion behavior.
|
||||||
|
#[allow(deprecated)]
|
||||||
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
|
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
|
||||||
self.syntax_exts.push((name, match extension {
|
self.syntax_exts.push((name, match extension {
|
||||||
NormalTT(ext, _, allow_internal_unstable) => {
|
NormalTT(ext, _, allow_internal_unstable) => {
|
||||||
@@ -93,6 +99,7 @@ impl<'a> Registry<'a> {
|
|||||||
IdentTT(ext, Some(self.krate_span), allow_internal_unstable)
|
IdentTT(ext, Some(self.krate_span), allow_internal_unstable)
|
||||||
}
|
}
|
||||||
Decorator(ext) => Decorator(ext),
|
Decorator(ext) => Decorator(ext),
|
||||||
|
MultiDecorator(ext) => MultiDecorator(ext),
|
||||||
Modifier(ext) => Modifier(ext),
|
Modifier(ext) => Modifier(ext),
|
||||||
MultiModifier(ext) => MultiModifier(ext),
|
MultiModifier(ext) => MultiModifier(ext),
|
||||||
MacroRulesTT => {
|
MacroRulesTT => {
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ use std::collections::HashMap;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
|
||||||
|
#[unstable(feature = "rustc_private")]
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced by MultiItemDecorator")]
|
||||||
pub trait ItemDecorator {
|
pub trait ItemDecorator {
|
||||||
fn expand(&self,
|
fn expand(&self,
|
||||||
ecx: &mut ExtCtxt,
|
ecx: &mut ExtCtxt,
|
||||||
@@ -39,6 +41,9 @@ pub trait ItemDecorator {
|
|||||||
push: &mut FnMut(P<ast::Item>));
|
push: &mut FnMut(P<ast::Item>));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
|
#[unstable(feature = "rustc_private")]
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced by MultiItemDecorator")]
|
||||||
impl<F> ItemDecorator for F
|
impl<F> ItemDecorator for F
|
||||||
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, &mut FnMut(P<ast::Item>))
|
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, &mut FnMut(P<ast::Item>))
|
||||||
{
|
{
|
||||||
@@ -52,6 +57,8 @@ impl<F> ItemDecorator for F
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "rustc_private")]
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced by MultiItemModifier")]
|
||||||
pub trait ItemModifier {
|
pub trait ItemModifier {
|
||||||
fn expand(&self,
|
fn expand(&self,
|
||||||
ecx: &mut ExtCtxt,
|
ecx: &mut ExtCtxt,
|
||||||
@@ -61,9 +68,13 @@ pub trait ItemModifier {
|
|||||||
-> P<ast::Item>;
|
-> P<ast::Item>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
|
#[unstable(feature = "rustc_private")]
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced by MultiItemModifier")]
|
||||||
impl<F> ItemModifier for F
|
impl<F> ItemModifier for F
|
||||||
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, P<ast::Item>) -> P<ast::Item>
|
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, P<ast::Item>) -> P<ast::Item>
|
||||||
{
|
{
|
||||||
|
|
||||||
fn expand(&self,
|
fn expand(&self,
|
||||||
ecx: &mut ExtCtxt,
|
ecx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
@@ -127,6 +138,29 @@ impl Annotatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A more flexible ItemDecorator.
|
||||||
|
pub trait MultiItemDecorator {
|
||||||
|
fn expand(&self,
|
||||||
|
ecx: &mut ExtCtxt,
|
||||||
|
sp: Span,
|
||||||
|
meta_item: &ast::MetaItem,
|
||||||
|
item: &Annotatable,
|
||||||
|
push: Box<FnMut(Annotatable)>);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> MultiItemDecorator for F
|
||||||
|
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, Box<FnMut(Annotatable)>)
|
||||||
|
{
|
||||||
|
fn expand(&self,
|
||||||
|
ecx: &mut ExtCtxt,
|
||||||
|
sp: Span,
|
||||||
|
meta_item: &ast::MetaItem,
|
||||||
|
item: &Annotatable,
|
||||||
|
push: Box<FnMut(Annotatable)>) {
|
||||||
|
(*self)(ecx, sp, meta_item, item, push)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// A more flexible ItemModifier (ItemModifier should go away, eventually, FIXME).
|
// A more flexible ItemModifier (ItemModifier should go away, eventually, FIXME).
|
||||||
// meta_item is the annotation, item is the item being modified, parent_item
|
// meta_item is the annotation, item is the item being modified, parent_item
|
||||||
// is the impl or trait item is declared in if item is part of such a thing.
|
// is the impl or trait item is declared in if item is part of such a thing.
|
||||||
@@ -397,12 +431,20 @@ impl MacResult for DummyResult {
|
|||||||
pub enum SyntaxExtension {
|
pub enum SyntaxExtension {
|
||||||
/// A syntax extension that is attached to an item and creates new items
|
/// A syntax extension that is attached to an item and creates new items
|
||||||
/// based upon it.
|
/// based upon it.
|
||||||
///
|
#[unstable(feature = "rustc_private")]
|
||||||
/// `#[derive(...)]` is an `ItemDecorator`.
|
#[deprecated(since = "1.0.0", reason = "replaced by MultiDecorator")]
|
||||||
Decorator(Box<ItemDecorator + 'static>),
|
Decorator(Box<ItemDecorator + 'static>),
|
||||||
|
|
||||||
|
/// A syntax extension that is attached to an item and creates new items
|
||||||
|
/// based upon it.
|
||||||
|
///
|
||||||
|
/// `#[derive(...)]` is a `MultiItemDecorator`.
|
||||||
|
MultiDecorator(Box<MultiItemDecorator + 'static>),
|
||||||
|
|
||||||
/// A syntax extension that is attached to an item and modifies it
|
/// A syntax extension that is attached to an item and modifies it
|
||||||
/// in-place.
|
/// in-place.
|
||||||
|
#[unstable(feature = "rustc_private")]
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced by MultiModifier")]
|
||||||
Modifier(Box<ItemModifier + 'static>),
|
Modifier(Box<ItemModifier + 'static>),
|
||||||
|
|
||||||
/// A syntax extension that is attached to an item and modifies it
|
/// A syntax extension that is attached to an item and modifies it
|
||||||
@@ -473,6 +515,13 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
|
|||||||
syntax_expanders.insert(intern("log_syntax"),
|
syntax_expanders.insert(intern("log_syntax"),
|
||||||
builtin_normal_expander(
|
builtin_normal_expander(
|
||||||
ext::log_syntax::expand_syntax_ext));
|
ext::log_syntax::expand_syntax_ext));
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
syntax_expanders.insert(intern("derive"),
|
||||||
|
MultiDecorator(box ext::deriving::expand_meta_derive));
|
||||||
|
syntax_expanders.insert(intern("deriving"),
|
||||||
|
MultiDecorator(box ext::deriving::expand_deprecated_deriving));
|
||||||
|
>>>>>>> 143f2db3174103e459218958f567985b1f47944b
|
||||||
|
|
||||||
ext::deriving::register_all(&mut syntax_expanders);
|
ext::deriving::register_all(&mut syntax_expanders);
|
||||||
|
|
||||||
@@ -537,6 +586,11 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
|
|||||||
syntax_expanders.insert(intern("cfg"),
|
syntax_expanders.insert(intern("cfg"),
|
||||||
builtin_normal_expander(
|
builtin_normal_expander(
|
||||||
ext::cfg::expand_cfg));
|
ext::cfg::expand_cfg));
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
syntax_expanders.insert(intern("cfg_attr"),
|
||||||
|
MultiModifier(box ext::cfg_attr::expand));
|
||||||
|
>>>>>>> 143f2db3174103e459218958f567985b1f47944b
|
||||||
syntax_expanders.insert(intern("trace_macros"),
|
syntax_expanders.insert(intern("trace_macros"),
|
||||||
builtin_normal_expander(
|
builtin_normal_expander(
|
||||||
ext::trace_macros::expand_trace_macros));
|
ext::trace_macros::expand_trace_macros));
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
//! FIXME (#2810): hygiene. Search for "__" strings (in other files too). We also assume "extra" is
|
//! FIXME (#2810): hygiene. Search for "__" strings (in other files too). We also assume "extra" is
|
||||||
//! the standard library, and "std" is the core library.
|
//! the standard library, and "std" is the core library.
|
||||||
|
|
||||||
use ast::{Item, MetaItem, MetaWord};
|
use ast::{Item, MetaItem, MetaWord, MetaList, MetaNameValue};
|
||||||
use attr::AttrMetaMethods;
|
use attr::AttrMetaMethods;
|
||||||
use ext::base::{ExtCtxt, SyntaxEnv, Decorator, ItemDecorator, Modifier};
|
use ext::base::{ExtCtxt, SyntaxEnv, Decorator, ItemDecorator, Modifier, Annotatable};
|
||||||
use ext::build::AstBuilder;
|
use ext::build::AstBuilder;
|
||||||
use feature_gate;
|
use feature_gate;
|
||||||
use codemap::Span;
|
use codemap::Span;
|
||||||
@@ -78,9 +78,19 @@ pub mod ord;
|
|||||||
pub mod generic;
|
pub mod generic;
|
||||||
|
|
||||||
fn expand_derive(cx: &mut ExtCtxt,
|
fn expand_derive(cx: &mut ExtCtxt,
|
||||||
_: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: P<Item>) -> P<Item> {
|
annotatable: &Annotatable)
|
||||||
|
-> P<Annotatable> {
|
||||||
|
// Derive can only be applied to items
|
||||||
|
let item = match annotatable {
|
||||||
|
&Annotatable::Item(ref it) => it.clone(),
|
||||||
|
_ => {
|
||||||
|
cx.span_err(span, "`derive` can only be applied to items");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
item.map(|mut item| {
|
item.map(|mut item| {
|
||||||
if mitem.value_str().is_some() {
|
if mitem.value_str().is_some() {
|
||||||
cx.span_err(mitem.span, "unexpected value in `derive`");
|
cx.span_err(mitem.span, "unexpected value in `derive`");
|
||||||
@@ -113,7 +123,7 @@ fn expand_derive(cx: &mut ExtCtxt,
|
|||||||
intern_and_get_ident(&format!("derive_{}", tname)))));
|
intern_and_get_ident(&format!("derive_{}", tname)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
item
|
Annotatable::Item(item)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -477,6 +477,7 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
|
|||||||
.into_iter().map(|i| i.expect_item()).collect()
|
.into_iter().map(|i| i.expect_item()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)] // This is needed because the `ItemModifier` trait is used
|
||||||
fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander)
|
fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander)
|
||||||
-> P<ast::Item> {
|
-> P<ast::Item> {
|
||||||
// partition the attributes into ItemModifiers and others
|
// partition the attributes into ItemModifiers and others
|
||||||
@@ -1082,6 +1083,7 @@ impl<'a> Folder for PatIdentRenamer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)] // This is needed because the `Decorator` variant is used
|
||||||
fn expand_annotatable(a: Annotatable,
|
fn expand_annotatable(a: Annotatable,
|
||||||
fld: &mut MacroExpander)
|
fld: &mut MacroExpander)
|
||||||
-> SmallVector<Annotatable> {
|
-> SmallVector<Annotatable> {
|
||||||
@@ -1120,9 +1122,31 @@ fn expand_annotatable(a: Annotatable,
|
|||||||
let mut items: SmallVector<P<ast::Item>> = SmallVector::zero();
|
let mut items: SmallVector<P<ast::Item>> = SmallVector::zero();
|
||||||
dec.expand(fld.cx, attr.span, &*attr.node.value, &**it,
|
dec.expand(fld.cx, attr.span, &*attr.node.value, &**it,
|
||||||
&mut |item| items.push(item));
|
&mut |item| items.push(item));
|
||||||
decorator_items.extend(
|
decorator_items.extend(items.into_iter()
|
||||||
items.into_iter()
|
.flat_map(|item| expand_item(item, fld).into_iter()
|
||||||
.flat_map(|item| expand_item(item, fld).into_iter()));
|
.map(|i| Annotatable::Item(i))));
|
||||||
|
|
||||||
|
fld.cx.bt_pop();
|
||||||
|
}
|
||||||
|
MultiDecorator(ref dec) => {
|
||||||
|
attr::mark_used(attr);
|
||||||
|
|
||||||
|
fld.cx.bt_push(ExpnInfo {
|
||||||
|
call_site: attr.span,
|
||||||
|
callee: NameAndSpan {
|
||||||
|
name: mname.get().to_string(),
|
||||||
|
format: MacroAttribute,
|
||||||
|
span: None
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// we'd ideally decorator_items.push_all(expand_annotatable(ann, fld)),
|
||||||
|
// but that double-mut-borrows fld
|
||||||
|
let mut anns: SmallVector<Annotatable> = SmallVector::zero();
|
||||||
|
dec.expand(fld.cx, attr.span, &*attr.node.value, &a,
|
||||||
|
&mut |ann| anns.push(ann));
|
||||||
|
decorator_items.extend(anns.into_iter()
|
||||||
|
.flat_map(|ann| expand_annotatable(ann, fld).into_iter()));
|
||||||
|
|
||||||
fld.cx.bt_pop();
|
fld.cx.bt_pop();
|
||||||
}
|
}
|
||||||
@@ -1184,7 +1208,7 @@ fn expand_annotatable(a: Annotatable,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
new_items.push_all(decorator_items.into_iter().map(|i| Annotatable::Item(i)).collect());
|
new_items.push_all(decorator_items);
|
||||||
new_items
|
new_items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -814,7 +814,6 @@ impl<'a> State<'a> {
|
|||||||
word(&mut self.s, ";")
|
word(&mut self.s, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Pretty-print an item
|
/// Pretty-print an item
|
||||||
pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
|
pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
|
||||||
try!(self.hardbreak_if_not_bol());
|
try!(self.hardbreak_if_not_bol());
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ extern crate rustc;
|
|||||||
use syntax::ast::{self, TokenTree, Item, MetaItem};
|
use syntax::ast::{self, TokenTree, Item, MetaItem};
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ext::base::*;
|
use syntax::ext::base::*;
|
||||||
use syntax::parse::token;
|
use syntax::parse::{self, token};
|
||||||
use syntax::parse;
|
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use rustc::plugin::Registry;
|
use rustc::plugin::Registry;
|
||||||
|
|
||||||
@@ -42,6 +41,9 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||||||
token::intern("into_multi_foo"),
|
token::intern("into_multi_foo"),
|
||||||
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
|
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
|
||||||
MultiModifier(Box::new(expand_into_foo_multi)));
|
MultiModifier(Box::new(expand_into_foo_multi)));
|
||||||
|
reg.register_syntax_extension(
|
||||||
|
token::intern("duplicate"),
|
||||||
|
MultiDecorator(box expand_duplicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
|
fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
|
||||||
@@ -104,6 +106,83 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a duplicate of the annotatable, based on the MetaItem
|
||||||
|
fn expand_duplicate(cx: &mut ExtCtxt,
|
||||||
|
sp: Span,
|
||||||
|
mi: &MetaItem,
|
||||||
|
it: &Annotatable,
|
||||||
|
mut push: Box<FnMut(Annotatable)>)
|
||||||
|
{
|
||||||
|
let copy_name = match mi.node {
|
||||||
|
ast::MetaItem_::MetaList(_, ref xs) => {
|
||||||
|
if let ast::MetaItem_::MetaWord(ref w) = xs[0].node {
|
||||||
|
token::str_to_ident(w.get())
|
||||||
|
} else {
|
||||||
|
cx.span_err(mi.span, "Expected word");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
cx.span_err(mi.span, "Expected list");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Duplicate the item but replace its ident by the MetaItem
|
||||||
|
match it.clone() {
|
||||||
|
Annotatable::Item(it) => {
|
||||||
|
let mut new_it = (*it).clone();
|
||||||
|
new_it.attrs.clear();
|
||||||
|
new_it.ident = copy_name;
|
||||||
|
push(Annotatable::Item(P(new_it)));
|
||||||
|
}
|
||||||
|
Annotatable::ImplItem(it) => {
|
||||||
|
match it {
|
||||||
|
ImplItem::MethodImplItem(m) => {
|
||||||
|
let mut new_m = (*m).clone();
|
||||||
|
new_m.attrs.clear();
|
||||||
|
replace_method_name(&mut new_m.node, copy_name);
|
||||||
|
push(Annotatable::ImplItem(ImplItem::MethodImplItem(P(new_m))));
|
||||||
|
}
|
||||||
|
ImplItem::TypeImplItem(t) => {
|
||||||
|
let mut new_t = (*t).clone();
|
||||||
|
new_t.attrs.clear();
|
||||||
|
new_t.ident = copy_name;
|
||||||
|
push(Annotatable::ImplItem(ImplItem::TypeImplItem(P(new_t))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Annotatable::TraitItem(it) => {
|
||||||
|
match it {
|
||||||
|
TraitItem::RequiredMethod(rm) => {
|
||||||
|
let mut new_rm = rm.clone();
|
||||||
|
new_rm.attrs.clear();
|
||||||
|
new_rm.ident = copy_name;
|
||||||
|
push(Annotatable::TraitItem(TraitItem::RequiredMethod(new_rm)));
|
||||||
|
}
|
||||||
|
TraitItem::ProvidedMethod(pm) => {
|
||||||
|
let mut new_pm = (*pm).clone();
|
||||||
|
new_pm.attrs.clear();
|
||||||
|
replace_method_name(&mut new_pm.node, copy_name);
|
||||||
|
push(Annotatable::TraitItem(TraitItem::ProvidedMethod(P(new_pm))));
|
||||||
|
}
|
||||||
|
TraitItem::TypeTraitItem(t) => {
|
||||||
|
let mut new_t = (*t).clone();
|
||||||
|
new_t.attrs.clear();
|
||||||
|
new_t.ty_param.ident = copy_name;
|
||||||
|
push(Annotatable::TraitItem(TraitItem::TypeTraitItem(P(new_t))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn replace_method_name(m: &mut ast::Method_, i: ast::Ident) {
|
||||||
|
if let &mut ast::Method_::MethDecl(ref mut ident, _, _, _, _, _, _, _) = m {
|
||||||
|
*ident = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn expand_forged_ident(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult+'static> {
|
fn expand_forged_ident(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult+'static> {
|
||||||
use syntax::ext::quote::rt::*;
|
use syntax::ext::quote::rt::*;
|
||||||
|
|
||||||
|
|||||||
52
src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs
Normal file
52
src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// aux-build:macro_crate_test.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
#![feature(plugin)]
|
||||||
|
|
||||||
|
#[plugin] #[no_link]
|
||||||
|
extern crate macro_crate_test;
|
||||||
|
|
||||||
|
// The duplicate macro will create a copy of the item with the given identifier
|
||||||
|
#[duplicate(MyCopy)]
|
||||||
|
struct MyStruct {
|
||||||
|
number: i32
|
||||||
|
}
|
||||||
|
|
||||||
|
trait TestTrait {
|
||||||
|
#[duplicate(TestType2)]
|
||||||
|
type TestType;
|
||||||
|
|
||||||
|
#[duplicate(required_fn2)]
|
||||||
|
fn required_fn(&self);
|
||||||
|
|
||||||
|
#[duplicate(provided_fn2)]
|
||||||
|
fn provided_fn(&self) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestTrait for MyStruct {
|
||||||
|
#[duplicate(TestType2)]
|
||||||
|
type TestType = f64;
|
||||||
|
|
||||||
|
#[duplicate(required_fn2)]
|
||||||
|
fn required_fn(&self) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = MyStruct { number: 42 };
|
||||||
|
s.required_fn();
|
||||||
|
s.required_fn2();
|
||||||
|
s.provided_fn();
|
||||||
|
s.provided_fn2();
|
||||||
|
|
||||||
|
let s = MyCopy { number: 42 };
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user