Auto merge of #28137 - nrc:remove-non-multi, r=huonw
This is a [breaking-change] for syntax extension authors. The fix is to use MultiModifier or MultiDecorator, which have the same functionality but are more flexible. Users of syntax extensions are unaffected.
This commit is contained in:
@@ -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, MultiDecorator};
|
||||
use syntax::ext::base::{IdentTT, MultiModifier, MultiDecorator};
|
||||
use syntax::ext::base::{MacroExpanderFn, MacroRulesTT};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
@@ -98,9 +98,7 @@ impl<'a> Registry<'a> {
|
||||
IdentTT(ext, _, allow_internal_unstable) => {
|
||||
IdentTT(ext, Some(self.krate_span), allow_internal_unstable)
|
||||
}
|
||||
Decorator(ext) => Decorator(ext),
|
||||
MultiDecorator(ext) => MultiDecorator(ext),
|
||||
Modifier(ext) => Modifier(ext),
|
||||
MultiModifier(ext) => MultiModifier(ext),
|
||||
MacroRulesTT => {
|
||||
self.sess.err("plugin tried to register a new MacroRulesTT");
|
||||
|
||||
@@ -31,60 +31,6 @@ use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::default::Default;
|
||||
|
||||
#[unstable(feature = "rustc_private")]
|
||||
#[deprecated(since = "1.0.0", reason = "replaced by MultiItemDecorator")]
|
||||
pub trait ItemDecorator {
|
||||
fn expand(&self,
|
||||
ecx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: &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
|
||||
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, &mut FnMut(P<ast::Item>))
|
||||
{
|
||||
fn expand(&self,
|
||||
ecx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: &ast::Item,
|
||||
push: &mut FnMut(P<ast::Item>)) {
|
||||
(*self)(ecx, sp, meta_item, item, push)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rustc_private")]
|
||||
#[deprecated(since = "1.0.0", reason = "replaced by MultiItemModifier")]
|
||||
pub trait ItemModifier {
|
||||
fn expand(&self,
|
||||
ecx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: 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
|
||||
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, P<ast::Item>) -> P<ast::Item>
|
||||
{
|
||||
|
||||
fn expand(&self,
|
||||
ecx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: P<ast::Item>)
|
||||
-> P<ast::Item> {
|
||||
(*self)(ecx, span, meta_item, item)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone)]
|
||||
pub enum Annotatable {
|
||||
@@ -460,26 +406,12 @@ 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.
|
||||
#[unstable(feature = "rustc_private")]
|
||||
#[deprecated(since = "1.0.0", reason = "replaced by MultiDecorator")]
|
||||
#[allow(deprecated)]
|
||||
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
|
||||
/// in-place.
|
||||
#[unstable(feature = "rustc_private")]
|
||||
#[deprecated(since = "1.0.0", reason = "replaced by MultiModifier")]
|
||||
#[allow(deprecated)]
|
||||
Modifier(Box<ItemModifier + 'static>),
|
||||
|
||||
/// A syntax extension that is attached to an item and modifies it
|
||||
/// in-place. More flexible version than Modifier.
|
||||
MultiModifier(Box<MultiItemModifier + 'static>),
|
||||
|
||||
@@ -636,9 +636,9 @@ macro_rules! with_exts_frame {
|
||||
// When we enter a module, record it, for the sake of `module!`
|
||||
pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
|
||||
-> SmallVector<P<ast::Item>> {
|
||||
let it = expand_item_modifiers(it, fld);
|
||||
let it = expand_item_multi_modifier(Annotatable::Item(it), fld);
|
||||
|
||||
expand_annotatable(Annotatable::Item(it), fld)
|
||||
expand_annotatable(it, fld)
|
||||
.into_iter().map(|i| i.expect_item()).collect()
|
||||
}
|
||||
|
||||
@@ -1275,11 +1275,9 @@ macro_rules! partition {
|
||||
}
|
||||
}
|
||||
|
||||
partition!(modifiers, Modifier);
|
||||
partition!(multi_modifiers, MultiModifier);
|
||||
|
||||
|
||||
#[allow(deprecated)] // The `allow` is needed because the `Decorator` variant is used.
|
||||
fn expand_decorators(a: Annotatable,
|
||||
fld: &mut MacroExpander,
|
||||
decorator_items: &mut SmallVector<Annotatable>,
|
||||
@@ -1289,33 +1287,6 @@ fn expand_decorators(a: Annotatable,
|
||||
let mname = intern(&attr.name());
|
||||
match fld.cx.syntax_env.find(&mname) {
|
||||
Some(rc) => match *rc {
|
||||
Decorator(ref dec) => {
|
||||
attr::mark_used(&attr);
|
||||
|
||||
fld.cx.bt_push(ExpnInfo {
|
||||
call_site: attr.span,
|
||||
callee: NameAndSpan {
|
||||
format: MacroAttribute(mname),
|
||||
span: Some(attr.span),
|
||||
// attributes can do whatever they like,
|
||||
// for now.
|
||||
allow_internal_unstable: true,
|
||||
}
|
||||
});
|
||||
|
||||
// we'd ideally decorator_items.push_all(expand_item(item, fld)),
|
||||
// but that double-mut-borrows fld
|
||||
let mut items: SmallVector<Annotatable> = SmallVector::zero();
|
||||
dec.expand(fld.cx,
|
||||
attr.span,
|
||||
&attr.node.value,
|
||||
&a.clone().expect_item(),
|
||||
&mut |item| items.push(Annotatable::Item(item)));
|
||||
decorator_items.extend(items.into_iter()
|
||||
.flat_map(|ann| expand_annotatable(ann, fld).into_iter()));
|
||||
|
||||
fld.cx.bt_pop();
|
||||
}
|
||||
MultiDecorator(ref dec) => {
|
||||
attr::mark_used(&attr);
|
||||
|
||||
@@ -1392,58 +1363,6 @@ fn expand_item_multi_modifier(mut it: Annotatable,
|
||||
expand_item_multi_modifier(it, fld)
|
||||
}
|
||||
|
||||
#[allow(deprecated)] // This is needed because the `ItemModifier` trait is used
|
||||
fn expand_item_modifiers(mut it: P<ast::Item>,
|
||||
fld: &mut MacroExpander)
|
||||
-> P<ast::Item> {
|
||||
// partition the attributes into ItemModifiers and others
|
||||
let (modifiers, other_attrs) = modifiers(&it.attrs, fld);
|
||||
|
||||
// update the attrs, leave everything else alone. Is this mutation really a good idea?
|
||||
it = P(ast::Item {
|
||||
attrs: other_attrs,
|
||||
..(*it).clone()
|
||||
});
|
||||
|
||||
if modifiers.is_empty() {
|
||||
let it = expand_item_multi_modifier(Annotatable::Item(it), fld);
|
||||
return it.expect_item();
|
||||
}
|
||||
|
||||
for attr in &modifiers {
|
||||
let mname = intern(&attr.name());
|
||||
|
||||
match fld.cx.syntax_env.find(&mname) {
|
||||
Some(rc) => match *rc {
|
||||
Modifier(ref mac) => {
|
||||
attr::mark_used(attr);
|
||||
fld.cx.bt_push(ExpnInfo {
|
||||
call_site: attr.span,
|
||||
callee: NameAndSpan {
|
||||
format: MacroAttribute(mname),
|
||||
span: Some(attr.span),
|
||||
// attributes can do whatever they like,
|
||||
// for now
|
||||
allow_internal_unstable: true,
|
||||
}
|
||||
});
|
||||
it = mac.expand(fld.cx, attr.span, &*attr.node.value, it);
|
||||
fld.cx.bt_pop();
|
||||
}
|
||||
_ => unreachable!()
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
// Expansion may have added new ItemModifiers.
|
||||
// It is possible, that an item modifier could expand to a multi-modifier or
|
||||
// vice versa. In this case we will expand all modifiers before multi-modifiers,
|
||||
// which might give an odd ordering. However, I think it is unlikely that the
|
||||
// two kinds will be mixed, and old-style multi-modifiers are deprecated.
|
||||
expand_item_modifiers(it, fld)
|
||||
}
|
||||
|
||||
fn expand_impl_item(ii: P<ast::ImplItem>, fld: &mut MacroExpander)
|
||||
-> SmallVector<P<ast::ImplItem>> {
|
||||
match ii.node {
|
||||
|
||||
@@ -30,10 +30,6 @@ macro_rules! unexported_macro { () => (3) }
|
||||
pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_macro("make_a_1", expand_make_a_1);
|
||||
reg.register_macro("identity", expand_identity);
|
||||
reg.register_syntax_extension(
|
||||
token::intern("into_foo"),
|
||||
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
|
||||
Modifier(Box::new(expand_into_foo)));
|
||||
reg.register_syntax_extension(
|
||||
token::intern("into_multi_foo"),
|
||||
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
|
||||
@@ -62,14 +58,6 @@ fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree])
|
||||
MacEager::expr(quote_expr!(&mut *cx, $expr))
|
||||
}
|
||||
|
||||
fn expand_into_foo(cx: &mut ExtCtxt, sp: Span, attr: &MetaItem, it: P<Item>)
|
||||
-> P<Item> {
|
||||
P(Item {
|
||||
attrs: it.attrs.clone(),
|
||||
..(*quote_item!(cx, enum Foo { Bar, Baz }).unwrap()).clone()
|
||||
})
|
||||
}
|
||||
|
||||
fn expand_into_foo_multi(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
attr: &MetaItem,
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
#[macro_use] #[no_link]
|
||||
extern crate macro_crate_test;
|
||||
|
||||
#[into_foo]
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
fn foo() -> AFakeTypeThatHadBetterGoAway {}
|
||||
|
||||
#[into_multi_foo]
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
fn foo() -> AnotherFakeTypeThatHadBetterGoAway {}
|
||||
@@ -41,9 +37,6 @@ pub fn main() {
|
||||
assert_eq!(1, make_a_1!());
|
||||
assert_eq!(2, exported_macro!());
|
||||
|
||||
assert_eq!(Foo::Bar, Foo::Bar);
|
||||
test(None::<Foo>);
|
||||
|
||||
assert_eq!(Foo2::Bar2, Foo2::Bar2);
|
||||
test(None::<Foo2>);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user