From 53579e6d866eea41f2d3d8d0ddff42c73e75cea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Fri, 16 Jan 2015 22:47:05 +0100 Subject: [PATCH 01/10] Deprecate ItemModifier in favor of MultiItemModifier [breaking-change] --- src/libsyntax/ext/base.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index a184cc5c2b296..b5bfd2dce80bb 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -51,6 +51,7 @@ impl ItemDecorator for F } } +#[deprecated="Replaced by MultiItemModifier"] pub trait ItemModifier { fn expand(&self, ecx: &mut ExtCtxt, @@ -60,9 +61,11 @@ pub trait ItemModifier { -> P; } +#[deprecated="Replaced by MultiItemModifier"] impl ItemModifier for F where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, P) -> P { + fn expand(&self, ecx: &mut ExtCtxt, span: Span, From 57690399a2ab6dd579ea1f97e9866b213f8b14d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Fri, 16 Jan 2015 22:51:03 +0100 Subject: [PATCH 02/10] Deprecate ItemDecorator in favor of MultiItemDecorator [breaking-change] --- src/libsyntax/ext/base.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b5bfd2dce80bb..666e69c205955 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -29,6 +29,7 @@ use fold::Folder; use std::collections::HashMap; use std::rc::Rc; +#[deprecated="Replaced by MultiItemDecorator"] pub trait ItemDecorator { fn expand(&self, ecx: &mut ExtCtxt, From 77d59217a38e2982fdcf6bff800f1c9acc0d9aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Fri, 16 Jan 2015 22:59:41 +0100 Subject: [PATCH 03/10] Add MultiItemDecorator --- src/libsyntax/ext/base.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 666e69c205955..edd66b5028620 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -150,6 +150,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)>); +} + +impl MultiItemDecorator for F + where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, Box)>) +{ + fn expand(&self, + ecx: &mut ExtCtxt, + sp: Span, + meta_item: &ast::MetaItem, + item: &Annotatable, + push: Box)>) { + (*self)(ecx, sp, meta_item, item, push) + } +} + // A more flexible ItemModifier (ItemModifier should go away, eventually, FIXME). // 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. From f97cff9abd4ea7a7a8ac24bb9afb09eb271bcda9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Fri, 16 Jan 2015 23:04:55 +0100 Subject: [PATCH 04/10] Add MultiDecorator variant to SyntaxExtension enum --- src/libsyntax/ext/base.rs | 6 +++++- src/libsyntax/ext/expand.rs | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index edd66b5028620..7d802d953b35e 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -418,11 +418,15 @@ impl MacResult for DummyResult { /// An enum representing the different kinds of syntax extensions. pub enum SyntaxExtension { + /// A syntax extension that is attached to an item and creates new items + /// based upon it. + Decorator(Box), + /// A syntax extension that is attached to an item and creates new items /// based upon it. /// /// `#[derive(...)]` is an `ItemDecorator`. - Decorator(Box), + MultiDecorator(Box), /// A syntax extension that is attached to an item and modifies it /// in-place. diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5736400313e95..dbbcee0d9d826 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1096,6 +1096,28 @@ fn expand_annotatable(a: Annotatable, 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_item(item, fld)), + // but that double-mut-borrows fld + let mut items: SmallVector> = SmallVector::zero(); + dec.expand(fld.cx, attr.span, &*attr.node.value, a, + box |&mut: item| items.push(item)); + decorator_items.extend(items.into_iter() + .flat_map(|item| expand_item(item, fld).into_iter())); + + fld.cx.bt_pop(); + } _ => new_attrs.push((*attr).clone()), }, _ => new_attrs.push((*attr).clone()), From 6f233aaa0c743cc6ca7e42d7dcd4b7d92ef4ad9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Fri, 16 Jan 2015 23:05:24 +0100 Subject: [PATCH 05/10] Deprecate SyntaxExtension::Decorator It has been replaced by SyntaxExtension::MultiDecorator [breaking-change] --- src/libsyntax/ext/base.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 7d802d953b35e..b63678881f6cb 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -420,6 +420,7 @@ impl MacResult for DummyResult { pub enum SyntaxExtension { /// A syntax extension that is attached to an item and creates new items /// based upon it. + #[deprecated="Replaced by MultiDecorator"] Decorator(Box), /// A syntax extension that is attached to an item and creates new items From 2e07b0d6be3d2ffcfb154b5cbbe02bc166014172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Fri, 16 Jan 2015 23:07:49 +0100 Subject: [PATCH 06/10] Deprecate SyntaxExtension::Modifier Replaced by SyntaxExtension::MultiModifier [breaking-change] --- src/libsyntax/ext/base.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b63678881f6cb..d3cedee6d21b9 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -431,6 +431,7 @@ pub enum SyntaxExtension { /// A syntax extension that is attached to an item and modifies it /// in-place. + #[deprecated="Replaced by MultiModifier"] Modifier(Box), /// A syntax extension that is attached to an item and modifies it From 01172eedfab32b24e38aa86ba0cba24453e842fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Tue, 20 Jan 2015 20:10:55 +0100 Subject: [PATCH 07/10] Add tests for MultiItemDecorator --- src/test/auxiliary/macro_crate_test.rs | 85 ++++++++++++++++++- .../macro-crate-multi-decorator.rs | 52 ++++++++++++ 2 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs index d545a42ae1927..d3c9659a1f170 100644 --- a/src/test/auxiliary/macro_crate_test.rs +++ b/src/test/auxiliary/macro_crate_test.rs @@ -16,11 +16,10 @@ extern crate syntax; extern crate rustc; -use syntax::ast::{TokenTree, Item, MetaItem, ImplItem, TraitItem, Method}; +use syntax::ast::{self, TokenTree, Item, MetaItem, ImplItem, TraitItem, Method}; use syntax::codemap::Span; use syntax::ext::base::*; -use syntax::parse::token; -use syntax::parse; +use syntax::parse::{self, token}; use syntax::ptr::P; use rustc::plugin::Registry; @@ -40,6 +39,9 @@ pub fn plugin_registrar(reg: &mut Registry) { reg.register_syntax_extension( token::intern("into_multi_foo"), MultiModifier(box 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]) @@ -92,6 +94,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) +{ + 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 { use syntax::ext::quote::rt::*; diff --git a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs new file mode 100644 index 0000000000000..45341d12d0743 --- /dev/null +++ b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs @@ -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 or the MIT license +// , 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 }; +} From aa3fe205223936e37c0accd91473fa3d666451ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Tue, 20 Jan 2015 20:28:36 +0100 Subject: [PATCH 08/10] Replace uses of Decorator and Modifier --- src/librustc/plugin/registry.rs | 4 +- src/libsyntax/ext/base.rs | 15 +++++--- src/libsyntax/ext/cfg_attr.rs | 61 ++++++++++++++++++++++++++----- src/libsyntax/ext/deriving/mod.rs | 25 +++++++++---- src/libsyntax/ext/expand.rs | 19 ++++++---- 5 files changed, 92 insertions(+), 32 deletions(-) diff --git a/src/librustc/plugin/registry.rs b/src/librustc/plugin/registry.rs index f6fb1c2d41928..98f1f73b563bf 100644 --- a/src/librustc/plugin/registry.rs +++ b/src/librustc/plugin/registry.rs @@ -14,7 +14,7 @@ use lint::{LintPassObject, LintId, Lint}; use session::Session; use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT}; -use syntax::ext::base::{IdentTT, Decorator, Modifier, MultiModifier, MacroRulesTT}; +use syntax::ext::base::{IdentTT, Decorator, MultiDecorator, Modifier, MultiModifier, MacroRulesTT}; use syntax::ext::base::{MacroExpanderFn}; use syntax::codemap::Span; use syntax::parse::token; @@ -76,11 +76,13 @@ impl<'a> Registry<'a> { /// Register a syntax extension of any kind. /// /// 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) { self.syntax_exts.push((name, match extension { NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)), IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)), Decorator(ext) => Decorator(ext), + MultiDecorator(ext) => MultiDecorator(ext), Modifier(ext) => Modifier(ext), MultiModifier(ext) => MultiModifier(ext), MacroRulesTT => { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index d3cedee6d21b9..cf0df37ede841 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -39,6 +39,8 @@ pub trait ItemDecorator { push: Box)>); } +#[allow(deprecated)] +#[deprecated="Replaced by MultiItemDecorator"] impl ItemDecorator for F where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, Box)>) { @@ -62,6 +64,7 @@ pub trait ItemModifier { -> P; } +#[allow(deprecated)] #[deprecated="Replaced by MultiItemModifier"] impl ItemModifier for F where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, P) -> P @@ -157,18 +160,18 @@ pub trait MultiItemDecorator { sp: Span, meta_item: &ast::MetaItem, item: &Annotatable, - push: Box)>); + push: Box); } impl MultiItemDecorator for F - where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, Box)>) + where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, Box) { fn expand(&self, ecx: &mut ExtCtxt, sp: Span, meta_item: &ast::MetaItem, item: &Annotatable, - push: Box)>) { + push: Box) { (*self)(ecx, sp, meta_item, item, push) } } @@ -426,7 +429,7 @@ pub enum SyntaxExtension { /// A syntax extension that is attached to an item and creates new items /// based upon it. /// - /// `#[derive(...)]` is an `ItemDecorator`. + /// `#[derive(...)]` is a `MultiItemDecorator`. MultiDecorator(Box), /// A syntax extension that is attached to an item and modifies it @@ -499,7 +502,7 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv { builtin_normal_expander( ext::log_syntax::expand_syntax_ext)); syntax_expanders.insert(intern("derive"), - Decorator(box ext::deriving::expand_meta_derive)); + MultiDecorator(box ext::deriving::expand_meta_derive)); syntax_expanders.insert(intern("deriving"), Decorator(box ext::deriving::expand_deprecated_deriving)); @@ -562,7 +565,7 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv { builtin_normal_expander( ext::cfg::expand_cfg)); syntax_expanders.insert(intern("cfg_attr"), - Modifier(box ext::cfg_attr::expand)); + MultiModifier(box ext::cfg_attr::expand)); syntax_expanders.insert(intern("trace_macros"), builtin_normal_expander( ext::trace_macros::expand_trace_macros)); diff --git a/src/libsyntax/ext/cfg_attr.rs b/src/libsyntax/ext/cfg_attr.rs index a85f12edb2286..d282c3084deac 100644 --- a/src/libsyntax/ext/cfg_attr.rs +++ b/src/libsyntax/ext/cfg_attr.rs @@ -8,27 +8,70 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast; +use ast::{self, TraitItem, ImplItem}; use attr; use codemap::Span; -use ext::base::ExtCtxt; +use ext::base::{Annotatable, ExtCtxt}; use ext::build::AstBuilder; use ptr::P; -pub fn expand(cx: &mut ExtCtxt, sp: Span, mi: &ast::MetaItem, it: P) -> P { +macro_rules! fold_annotatable { + ($ann:expr, $item:ident => $oper:expr) => ( + match $ann { + Annotatable::Item(it) => { + let mut $item = (*it).clone(); + $oper; + Annotatable::Item(P($item)) + } + Annotatable::TraitItem(it) => { + match it { + TraitItem::RequiredMethod(mut $item) => { + $oper; + Annotatable::TraitItem(TraitItem::RequiredMethod($item)) + } + TraitItem::ProvidedMethod(pm) => { + let mut $item = (*pm).clone(); + $oper; + Annotatable::TraitItem(TraitItem::ProvidedMethod(P($item))) + } + TraitItem::TypeTraitItem(at) => { + let mut $item = (*at).clone(); + $oper; + Annotatable::TraitItem(TraitItem::TypeTraitItem(P($item))) + } + } + } + Annotatable::ImplItem(it) => { + match it { + ImplItem::MethodImplItem(pm) => { + let mut $item = (*pm).clone(); + $oper; + Annotatable::ImplItem(ImplItem::MethodImplItem(P($item))) + } + ImplItem::TypeImplItem(at) => { + let mut $item = (*at).clone(); + $oper; + Annotatable::ImplItem(ImplItem::TypeImplItem(P($item))) + } + } + } + } + ); +} + +pub fn expand(cx: &mut ExtCtxt, sp: Span, mi: &ast::MetaItem, ann: Annotatable) -> Annotatable { let (cfg, attr) = match mi.node { ast::MetaList(_, ref mis) if mis.len() == 2 => (&mis[0], &mis[1]), _ => { cx.span_err(sp, "expected `#[cfg_attr(, )]`"); - return it; + return ann; } }; - let mut out = (*it).clone(); if attr::cfg_matches(&cx.parse_sess.span_diagnostic, cx.cfg.as_slice(), &**cfg) { - out.attrs.push(cx.attribute(attr.span, attr.clone())); + let attr = cx.attribute(attr.span, attr.clone()); + fold_annotatable!(ann, item => item.attrs.push(attr)) + } else { + ann } - - P(out) } - diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index d3d7fee3a189a..a06ed638fe14d 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -13,10 +13,9 @@ //! FIXME (#2810): hygiene. Search for "__" strings (in other files too). We also assume "extra" is //! the standard library, and "std" is the core library. -use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord}; -use ext::base::ExtCtxt; +use ast::{MetaItem, MetaList, MetaNameValue, MetaWord}; +use ext::base::{Annotatable, ExtCtxt}; use codemap::Span; -use ptr::P; pub mod bounds; pub mod clone; @@ -49,10 +48,20 @@ pub fn expand_deprecated_deriving(cx: &mut ExtCtxt, } pub fn expand_meta_derive(cx: &mut ExtCtxt, - _span: Span, + span: Span, mitem: &MetaItem, - item: &Item, - mut push: Box)>) { + annotatable: &Annotatable, + mut push: Box) +{ + // 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; + } + }; + match mitem.node { MetaNameValue(_, ref l) => { cx.span_err(l.span, "unexpected value in `derive`"); @@ -70,8 +79,8 @@ pub fn expand_meta_derive(cx: &mut ExtCtxt, MetaList(ref tname, _) | MetaWord(ref tname) => { macro_rules! expand { - ($func:path) => ($func(cx, titem.span, &**titem, item, - |i| push(i))) + ($func:path) => ($func(cx, titem.span, &**titem, + &*item, |i| push(Annotatable::Item(i)))) } match tname.get() { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index dbbcee0d9d826..672acfbff6589 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -488,6 +488,7 @@ pub fn expand_item(it: P, fld: &mut MacroExpander) .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, fld: &mut MacroExpander) -> P { // partition the attributes into ItemModifiers and others @@ -1056,6 +1057,7 @@ impl<'a> Folder for PatIdentRenamer<'a> { } } +#[allow(deprecated)] // This is needed because the `Decorator` variant is used fn expand_annotatable(a: Annotatable, fld: &mut MacroExpander) -> SmallVector { @@ -1092,7 +1094,8 @@ fn expand_annotatable(a: Annotatable, dec.expand(fld.cx, attr.span, &*attr.node.value, &**it, box |&mut: item| items.push(item)); decorator_items.extend(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(); } @@ -1108,13 +1111,13 @@ fn expand_annotatable(a: Annotatable, } }); - // we'd ideally decorator_items.push_all(expand_item(item, fld)), + // we'd ideally decorator_items.push_all(expand_annotatable(ann, fld)), // but that double-mut-borrows fld - let mut items: SmallVector> = SmallVector::zero(); - dec.expand(fld.cx, attr.span, &*attr.node.value, a, - box |&mut: item| items.push(item)); - decorator_items.extend(items.into_iter() - .flat_map(|item| expand_item(item, fld).into_iter())); + let mut anns: SmallVector = SmallVector::zero(); + dec.expand(fld.cx, attr.span, &*attr.node.value, &a, + box |&mut: ann| anns.push(ann)); + decorator_items.extend(anns.into_iter() + .flat_map(|ann| expand_annotatable(ann, fld).into_iter())); fld.cx.bt_pop(); } @@ -1179,7 +1182,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 } From 5af4df4a264ea3409189a3b64c12fcf6b6eee2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Fri, 23 Jan 2015 10:15:56 +0100 Subject: [PATCH 09/10] Fix pretty printer --- src/libsyntax/print/pprust.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5367ccc1357c9..f5ecadffeded6 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -781,6 +781,7 @@ impl<'a> State<'a> { } fn print_typedef(&mut self, typedef: &ast::Typedef) -> IoResult<()> { + try!(self.print_outer_attributes(&typedef.attrs[])); try!(self.word_space("type")); try!(self.print_ident(typedef.ident)); try!(space(&mut self.s)); From 143f2db3174103e459218958f567985b1f47944b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Sat, 31 Jan 2015 11:38:29 +0100 Subject: [PATCH 10/10] Fix rebase issues --- src/libsyntax/ext/base.rs | 20 +++++++++++++------- src/libsyntax/ext/deriving/mod.rs | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index cf0df37ede841..22477783692f2 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -29,7 +29,8 @@ use fold::Folder; use std::collections::HashMap; use std::rc::Rc; -#[deprecated="Replaced by MultiItemDecorator"] +#[unstable(feature = "rustc_private")] +#[deprecated(since = "1.0.0", reason = "replaced by MultiItemDecorator")] pub trait ItemDecorator { fn expand(&self, ecx: &mut ExtCtxt, @@ -40,7 +41,8 @@ pub trait ItemDecorator { } #[allow(deprecated)] -#[deprecated="Replaced by MultiItemDecorator"] +#[unstable(feature = "rustc_private")] +#[deprecated(since = "1.0.0", reason = "replaced by MultiItemDecorator")] impl ItemDecorator for F where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, Box)>) { @@ -54,7 +56,8 @@ impl ItemDecorator for F } } -#[deprecated="Replaced by MultiItemModifier"] +#[unstable(feature = "rustc_private")] +#[deprecated(since = "1.0.0", reason = "replaced by MultiItemModifier")] pub trait ItemModifier { fn expand(&self, ecx: &mut ExtCtxt, @@ -65,7 +68,8 @@ pub trait ItemModifier { } #[allow(deprecated)] -#[deprecated="Replaced by MultiItemModifier"] +#[unstable(feature = "rustc_private")] +#[deprecated(since = "1.0.0", reason = "replaced by MultiItemModifier")] impl ItemModifier for F where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, P) -> P { @@ -423,7 +427,8 @@ impl MacResult for DummyResult { pub enum SyntaxExtension { /// A syntax extension that is attached to an item and creates new items /// based upon it. - #[deprecated="Replaced by MultiDecorator"] + #[unstable(feature = "rustc_private")] + #[deprecated(since = "1.0.0", reason = "replaced by MultiDecorator")] Decorator(Box), /// A syntax extension that is attached to an item and creates new items @@ -434,7 +439,8 @@ pub enum SyntaxExtension { /// A syntax extension that is attached to an item and modifies it /// in-place. - #[deprecated="Replaced by MultiModifier"] + #[unstable(feature = "rustc_private")] + #[deprecated(since = "1.0.0", reason = "replaced by MultiModifier")] Modifier(Box), /// A syntax extension that is attached to an item and modifies it @@ -504,7 +510,7 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv { syntax_expanders.insert(intern("derive"), MultiDecorator(box ext::deriving::expand_meta_derive)); syntax_expanders.insert(intern("deriving"), - Decorator(box ext::deriving::expand_deprecated_deriving)); + MultiDecorator(box ext::deriving::expand_deprecated_deriving)); if ecfg.enable_quotes { // Quasi-quoting expanders diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index a06ed638fe14d..12132adb80e3d 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -42,8 +42,8 @@ pub mod generic; pub fn expand_deprecated_deriving(cx: &mut ExtCtxt, span: Span, _: &MetaItem, - _: &Item, - _: Box)>) { + _: &Annotatable, + _: Box) { cx.span_err(span, "`deriving` has been renamed to `derive`"); }