From 97f4e700c20ccc95f4e9ed3d2c9d368cbc4be445 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 6 Jun 2019 21:10:16 +0300 Subject: [PATCH 1/6] syntax: Remove `SyntaxExtension::IdentTT` and `IdentMacroExpander` --- src/librustc_plugin/registry.rs | 5 +---- src/libsyntax/ext/base.rs | 38 --------------------------------- src/libsyntax/ext/expand.rs | 22 ------------------- 3 files changed, 1 insertion(+), 64 deletions(-) diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 2ed6f868fa1ee..967fdcd2e7d41 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -4,7 +4,7 @@ use rustc::lint::{EarlyLintPassObject, LateLintPassObject, LintId, Lint}; use rustc::session::Session; use rustc::util::nodemap::FxHashMap; -use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT}; +use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT}; use syntax::ext::base::MacroExpanderFn; use syntax::symbol::{Symbol, sym}; use syntax::ast; @@ -109,9 +109,6 @@ impl<'a> Registry<'a> { edition, } } - IdentTT { expander, span: _, allow_internal_unstable } => { - IdentTT { expander, span: Some(self.krate_span), allow_internal_unstable } - } _ => extension, })); } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 61c736662c71e..ffc3212792442 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -288,34 +288,6 @@ impl TTMacroExpander for F } } -pub trait IdentMacroExpander { - fn expand<'cx>(&self, - cx: &'cx mut ExtCtxt<'_>, - sp: Span, - ident: ast::Ident, - token_tree: Vec) - -> Box; -} - -pub type IdentMacroExpanderFn = - for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident, Vec) - -> Box; - -impl IdentMacroExpander for F - where F : for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident, - Vec) -> Box -{ - fn expand<'cx>(&self, - cx: &'cx mut ExtCtxt<'_>, - sp: Span, - ident: ast::Ident, - token_tree: Vec) - -> Box - { - (*self)(cx, sp, ident, token_tree) - } -} - // Use a macro because forwarding to a simple function has type system issues macro_rules! make_stmts_default { ($me:expr) => { @@ -658,14 +630,6 @@ pub enum SyntaxExtension { edition: Edition, }, - /// A function-like syntax extension that has an extra ident before - /// the block. - IdentTT { - expander: Box, - span: Option, - allow_internal_unstable: Option>, - }, - /// An attribute-like procedural macro. TokenStream -> TokenStream. /// The input is the annotated item. /// Allows generating code to implement a Trait for a given struct @@ -691,7 +655,6 @@ impl SyntaxExtension { match *self { SyntaxExtension::DeclMacro { .. } | SyntaxExtension::NormalTT { .. } | - SyntaxExtension::IdentTT { .. } | SyntaxExtension::ProcMacro { .. } => MacroKind::Bang, SyntaxExtension::NonMacroAttr { .. } | @@ -725,7 +688,6 @@ impl SyntaxExtension { SyntaxExtension::ProcMacroDerive(.., edition) => edition, // Unstable legacy stuff SyntaxExtension::NonMacroAttr { .. } | - SyntaxExtension::IdentTT { .. } | SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | SyntaxExtension::BuiltinDerive(..) => default_edition, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9960539555332..008bcaab88914 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -791,28 +791,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - IdentTT { ref expander, span: tt_span, ref allow_internal_unstable } => { - if ident.name == kw::Invalid { - self.cx.span_err(path.span, - &format!("macro {}! expects an ident argument", path)); - self.cx.trace_macros_diag(); - kind.dummy(span) - } else { - invoc.expansion_data.mark.set_expn_info(ExpnInfo { - call_site: span, - def_site: tt_span, - format: macro_bang_format(path), - allow_internal_unstable: allow_internal_unstable.clone(), - allow_internal_unsafe: false, - local_inner_macros: false, - edition: self.cx.parse_sess.edition, - }); - - let input: Vec<_> = mac.node.stream().into_trees().collect(); - kind.make_from(expander.expand(self.cx, span, ident, input)) - } - } - MultiDecorator(..) | MultiModifier(..) | AttrProcMacro(..) | SyntaxExtension::NonMacroAttr { .. } => { self.cx.span_err(path.span, From 5a6ebec0185c9fb0d1cb319b8f640c14a3c71d7d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 6 Jun 2019 21:38:27 +0300 Subject: [PATCH 2/6] syntax: Remove `SyntaxExtension::MultiDecorator` and `MultiItemDecorator` --- src/libsyntax/ext/base.rs | 33 -------- src/libsyntax/ext/expand.rs | 11 +-- .../auxiliary/custom-derive-partial-eq.rs | 71 ---------------- .../auxiliary/custom-derive-plugin-attr.rs | 84 ------------------- .../auxiliary/custom-derive-plugin.rs | 76 ----------------- .../custom-derive-partial-eq.rs | 10 --- .../run-pass-fulldeps/derive-totalsum-attr.rs | 64 -------------- src/test/run-pass-fulldeps/derive-totalsum.rs | 49 ----------- src/test/run-pass-fulldeps/issue-40663.rs | 13 --- 9 files changed, 1 insertion(+), 410 deletions(-) delete mode 100644 src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs delete mode 100644 src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs delete mode 100644 src/test/run-pass-fulldeps/custom-derive-partial-eq.rs delete mode 100644 src/test/run-pass-fulldeps/derive-totalsum-attr.rs delete mode 100644 src/test/run-pass-fulldeps/derive-totalsum.rs delete mode 100644 src/test/run-pass-fulldeps/issue-40663.rs diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index ffc3212792442..9979f5d0a0edf 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -137,29 +137,6 @@ impl Annotatable { } } -// A more flexible ItemDecorator. -pub trait MultiItemDecorator { - fn expand(&self, - ecx: &mut ExtCtxt<'_>, - sp: Span, - meta_item: &ast::MetaItem, - item: &Annotatable, - push: &mut dyn FnMut(Annotatable)); -} - -impl MultiItemDecorator for F - where F : Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)) -{ - fn expand(&self, - ecx: &mut ExtCtxt<'_>, - sp: Span, - meta_item: &ast::MetaItem, - item: &Annotatable, - push: &mut dyn FnMut(Annotatable)) { - (*self)(ecx, sp, meta_item, item, push) - } -} - // `meta_item` is the annotation, and `item` is the item being modified. // FIXME Decorators should follow the same pattern too. pub trait MultiItemModifier { @@ -581,14 +558,6 @@ pub enum SyntaxExtension { /// A trivial "extension" that does nothing, only keeps the attribute and marks it as known. NonMacroAttr { mark_used: bool }, - /// A syntax extension that is attached to an item and creates new items - /// based upon it. - /// - /// `#[derive(...)]` is a `MultiItemDecorator`. - /// - /// Prefer ProcMacro or MultiModifier since they are more flexible. - MultiDecorator(Box), - /// A syntax extension that is attached to an item and modifies it /// in-place. Also allows decoration, i.e., creating new items. MultiModifier(Box), @@ -658,7 +627,6 @@ impl SyntaxExtension { SyntaxExtension::ProcMacro { .. } => MacroKind::Bang, SyntaxExtension::NonMacroAttr { .. } | - SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | SyntaxExtension::AttrProcMacro(..) => MacroKind::Attr, @@ -688,7 +656,6 @@ impl SyntaxExtension { SyntaxExtension::ProcMacroDerive(.., edition) => edition, // Unstable legacy stuff SyntaxExtension::NonMacroAttr { .. } | - SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | SyntaxExtension::BuiltinDerive(..) => default_edition, } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 008bcaab88914..715303db17378 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -575,14 +575,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let item = mac.expand(self.cx, attr.span, &meta, item); Some(invoc.fragment_kind.expect_from_annotatables(item)) } - MultiDecorator(ref mac) => { - let mut items = Vec::new(); - let meta = attr.parse_meta(self.cx.parse_sess) - .expect("derive meta should already have been parsed"); - mac.expand(self.cx, attr.span, &meta, &item, &mut |item| items.push(item)); - items.push(item); - Some(invoc.fragment_kind.expect_from_annotatables(items)) - } AttrProcMacro(ref mac, ..) => { self.gate_proc_macro_attr_item(attr.span, &item); let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item { @@ -791,8 +783,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - MultiDecorator(..) | MultiModifier(..) | - AttrProcMacro(..) | SyntaxExtension::NonMacroAttr { .. } => { + MultiModifier(..) | AttrProcMacro(..) | SyntaxExtension::NonMacroAttr { .. } => { self.cx.span_err(path.span, &format!("`{}` can only be used in attributes", path)); self.cx.trace_macros_diag(); diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs deleted file mode 100644 index 4d6ff47a3ee91..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs +++ /dev/null @@ -1,71 +0,0 @@ -// force-host - -#![feature(plugin_registrar, rustc_private)] - -extern crate syntax; -extern crate syntax_ext; -extern crate rustc_plugin; - -use syntax_ext::deriving; -use deriving::generic::*; -use deriving::generic::ty::*; - -use rustc_plugin::Registry; -use syntax::ast::*; -use syntax::source_map::Span; -use syntax::ext::base::*; -use syntax::ext::build::AstBuilder; -use syntax::symbol::Symbol; -use syntax::ptr::P; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension(Symbol::intern("derive_CustomPartialEq"), - MultiDecorator(Box::new(expand_deriving_partial_eq))); -} - -fn expand_deriving_partial_eq(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: &Annotatable, - push: &mut FnMut(Annotatable)) { - // structures are equal if all fields are equal, and non equal, if - // any fields are not equal or if the enum variants are different - fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { - cs_fold(true, - |cx, span, subexpr, self_f, other_fs| { - let other_f = (other_fs.len(), other_fs.get(0)).1.unwrap(); - let eq = cx.expr_binary(span, BinOpKind::Eq, self_f, other_f.clone()); - cx.expr_binary(span, BinOpKind::And, subexpr, eq) - }, - cx.expr_bool(span, true), - Box::new(|cx, span, _, _| cx.expr_bool(span, false)), - cx, - span, - substr) - } - - let inline = cx.meta_word(span, Symbol::intern("inline")); - let attrs = vec![cx.attribute(span, inline)]; - let methods = vec![MethodDef { - name: "eq", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), "other")], - ret_ty: Literal(deriving::generic::ty::Path::new_local("bool")), - attributes: attrs, - is_unsafe: false, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(Box::new(cs_eq)), - }]; - - let trait_def = TraitDef { - span: span, - attributes: Vec::new(), - path: deriving::generic::ty::Path::new(vec!["cmp", "PartialEq"]), - additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), - is_unsafe: false, - supports_unions: false, - methods: methods, - associated_types: Vec::new(), - }; - trait_def.expand(cx, mitem, item, push) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs deleted file mode 100644 index c6b33fbc75ee2..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs +++ /dev/null @@ -1,84 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(box_syntax)] -#![feature(rustc_private)] - -extern crate syntax; -extern crate syntax_ext; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; - -use syntax::ast; -use syntax::attr; -use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable}; -use syntax::ext::build::AstBuilder; -use syntax::symbol::{Symbol, sym}; -use syntax::ptr::P; -use syntax_ext::deriving::generic::{TraitDef, MethodDef, combine_substructure}; -use syntax_ext::deriving::generic::{Substructure, Struct, EnumMatching}; -use syntax_ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self}; -use syntax_pos::Span; -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension( - Symbol::intern("rustc_derive_TotalSum"), - MultiDecorator(box expand)); -} - -fn expand(cx: &mut ExtCtxt, - span: Span, - mitem: &ast::MetaItem, - item: &Annotatable, - push: &mut FnMut(Annotatable)) { - let trait_def = TraitDef { - span: span, - attributes: vec![], - path: Path::new_local("TotalSum"), - additional_bounds: vec![], - generics: LifetimeBounds::empty(), - associated_types: vec![], - is_unsafe: false, - supports_unions: false, - methods: vec![ - MethodDef { - name: "total_sum", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![], - ret_ty: Literal(Path::new_local("isize")), - attributes: vec![], - is_unsafe: false, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(Box::new(totalsum_substructure)), - }, - ], - }; - - trait_def.expand(cx, mitem, item, push) -} - -// Mostly copied from syntax::ext::deriving::hash -/// Defines how the implementation for `trace()` is to be generated -fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span, - substr: &Substructure) -> P { - let fields = match *substr.fields { - Struct(_, ref fs) | EnumMatching(.., ref fs) => fs, - _ => cx.span_bug(trait_span, "impossible substructure") - }; - - fields.iter().fold(cx.expr_isize(trait_span, 0), |acc, ref item| { - if attr::contains_name(&item.attrs, sym::ignore) { - acc - } else { - cx.expr_binary(item.span, ast::BinOpKind::Add, acc, - cx.expr_method_call(item.span, - item.self_.clone(), - substr.method_ident, - Vec::new())) - } - }) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs deleted file mode 100644 index 874a0ec7c13fb..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs +++ /dev/null @@ -1,76 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(box_syntax)] -#![feature(rustc_private)] - -extern crate syntax; -extern crate syntax_ext; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; - -use syntax::ast; -use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable}; -use syntax::ext::build::AstBuilder; -use syntax::symbol::Symbol; -use syntax_ext::deriving::generic::{cs_fold, TraitDef, MethodDef, combine_substructure}; -use syntax_ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self}; -use syntax_pos::Span; -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension( - Symbol::intern("derive_TotalSum"), - MultiDecorator(box expand)); - - reg.register_syntax_extension( - Symbol::intern("derive_Nothing"), - MultiDecorator(box noop)); -} - -fn noop(_: &mut ExtCtxt, _: Span, _: &ast::MetaItem, _: &Annotatable, _: &mut FnMut(Annotatable)) {} - -fn expand(cx: &mut ExtCtxt, - span: Span, - mitem: &ast::MetaItem, - item: &Annotatable, - push: &mut FnMut(Annotatable)) { - let trait_def = TraitDef { - span: span, - attributes: vec![], - path: Path::new_local("TotalSum"), - additional_bounds: vec![], - generics: LifetimeBounds::empty(), - associated_types: vec![], - is_unsafe: false, - supports_unions: false, - methods: vec![ - MethodDef { - name: "total_sum", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![], - ret_ty: Literal(Path::new_local("isize")), - attributes: vec![], - is_unsafe: false, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(box |cx, span, substr| { - let zero = cx.expr_isize(span, 0); - cs_fold(false, - |cx, span, subexpr, field, _| { - cx.expr_binary(span, ast::BinOpKind::Add, subexpr, - cx.expr_method_call(span, field, - ast::Ident::from_str("total_sum"), vec![])) - }, - zero, - box |cx, span, _, _| { cx.span_bug(span, "wtf??"); }, - cx, span, substr) - }), - }, - ], - }; - - trait_def.expand(cx, mitem, item, push) -} diff --git a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs deleted file mode 100644 index ac8fff4f6bfad..0000000000000 --- a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs +++ /dev/null @@ -1,10 +0,0 @@ -// aux-build:custom-derive-partial-eq.rs -// ignore-stage1 -#![feature(plugin)] -#![plugin(custom_derive_partial_eq)] -#![allow(unused)] - -#[derive_CustomPartialEq] // Check that this is not a stability error. -enum E { V1, V2 } - -fn main() {} diff --git a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs deleted file mode 100644 index 38eaa71dd6aba..0000000000000 --- a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs +++ /dev/null @@ -1,64 +0,0 @@ -// aux-build:custom-derive-plugin-attr.rs -// ignore-stage1 - -#![feature(plugin, rustc_attrs)] -#![plugin(custom_derive_plugin_attr)] - -trait TotalSum { - fn total_sum(&self) -> isize; -} - -impl TotalSum for isize { - fn total_sum(&self) -> isize { - *self - } -} - -struct Seven; - -impl TotalSum for Seven { - fn total_sum(&self) -> isize { - 7 - } -} - -#[rustc_derive_TotalSum] -struct Foo { - seven: Seven, - bar: Bar, - baz: isize, - #[ignore] - nan: NaN, -} - -#[rustc_derive_TotalSum] -struct Bar { - quux: isize, - bleh: isize, - #[ignore] - nan: NaN2 -} - -struct NaN; - -impl TotalSum for NaN { - fn total_sum(&self) -> isize { - panic!(); - } -} - -struct NaN2; - -pub fn main() { - let v = Foo { - seven: Seven, - bar: Bar { - quux: 9, - bleh: 3, - nan: NaN2 - }, - baz: 80, - nan: NaN - }; - assert_eq!(v.total_sum(), 99); -} diff --git a/src/test/run-pass-fulldeps/derive-totalsum.rs b/src/test/run-pass-fulldeps/derive-totalsum.rs deleted file mode 100644 index 2b0bb51d90aec..0000000000000 --- a/src/test/run-pass-fulldeps/derive-totalsum.rs +++ /dev/null @@ -1,49 +0,0 @@ -// aux-build:custom-derive-plugin.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(custom_derive_plugin)] - -trait TotalSum { - fn total_sum(&self) -> isize; -} - -impl TotalSum for isize { - fn total_sum(&self) -> isize { - *self - } -} - -struct Seven; - -impl TotalSum for Seven { - fn total_sum(&self) -> isize { - 7 - } -} - -#[derive_TotalSum] -struct Foo { - seven: Seven, - bar: Bar, - baz: isize, -} - -#[derive_TotalSum] -struct Bar { - quux: isize, - bleh: isize, -} - - -pub fn main() { - let v = Foo { - seven: Seven, - bar: Bar { - quux: 9, - bleh: 3, - }, - baz: 80, - }; - assert_eq!(v.total_sum(), 99); -} diff --git a/src/test/run-pass-fulldeps/issue-40663.rs b/src/test/run-pass-fulldeps/issue-40663.rs deleted file mode 100644 index 133f6302bde57..0000000000000 --- a/src/test/run-pass-fulldeps/issue-40663.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow(dead_code)] -// aux-build:custom-derive-plugin.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(custom_derive_plugin)] - -#[derive_Nothing] -#[derive_Nothing] -#[derive_Nothing] -struct S; - -fn main() {} From edb925a91f4fafb9056d181dd620937992ad6c1b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 6 Jun 2019 23:21:44 +0300 Subject: [PATCH 3/6] syntax: Use `MultiItemModifier` for built-in derives --- src/libsyntax/ext/base.rs | 7 ++---- src/libsyntax/ext/expand.rs | 40 +++++++++++++++---------------- src/libsyntax_ext/deriving/mod.rs | 24 +++++++++++++++---- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 9979f5d0a0edf..4a357b0f3121a 100644 --- a/src/libsyntax/ext/base.rs +++ b/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; @@ -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 { @@ -607,7 +604,7 @@ pub enum SyntaxExtension { Vec /* inert attribute names */, Edition), /// An attribute-like procedural macro that derives a builtin trait. - BuiltinDerive(BuiltinDeriveFn), + BuiltinDerive(Box), /// A declarative macro, e.g., `macro m() {}`. DeclMacro { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 715303db17378..892c59bbc0446 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -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)) } _ => { diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index ac41f30e6b39f..2f09ab2087e41 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/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; @@ -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 { + 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 { @@ -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)))) ); )* } From 8edbbacbcac3fe88995f02e08789ca458667b6b4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 7 Jun 2019 00:37:47 +0300 Subject: [PATCH 4/6] syntax: Remove `SyntaxExtension::DeclMacro` It's a less powerful duplicate of `SyntaxExtension::NormalTT` --- src/librustc_plugin/registry.rs | 31 ++--- src/librustc_resolve/macros.rs | 3 +- .../passes/collect_intra_doc_links.rs | 2 +- src/libsyntax/ext/base.rs | 18 +-- src/libsyntax/ext/expand.rs | 11 +- src/libsyntax/ext/tt/macro_rules.rs | 109 +++++++++--------- src/libsyntax_ext/lib.rs | 4 + .../auxiliary/plugin-args.rs | 2 + .../ui/macros/nonterminal-matching.stderr | 3 + 9 files changed, 79 insertions(+), 104 deletions(-) diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 967fdcd2e7d41..f4b4bcb043c42 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -6,6 +6,7 @@ use rustc::util::nodemap::FxHashMap; use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT}; use syntax::ext::base::MacroExpanderFn; +use syntax::ext::hygiene::Transparency; use syntax::symbol::{Symbol, sym}; use syntax::ast; use syntax::feature_gate::AttributeType; @@ -84,33 +85,14 @@ impl<'a> Registry<'a> { /// Register a syntax extension of any kind. /// /// This is the most general hook into `libsyntax`'s expansion behavior. - pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { + pub fn register_syntax_extension(&mut self, name: ast::Name, mut extension: SyntaxExtension) { if name == sym::macro_rules { panic!("user-defined macros may not be named `macro_rules`"); } - self.syntax_exts.push((name, match extension { - NormalTT { - expander, - def_info: _, - allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, - unstable_feature, - edition, - } => { - let nid = ast::CRATE_NODE_ID; - NormalTT { - expander, - def_info: Some((nid, self.krate_span)), - allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, - unstable_feature, - edition, - } - } - _ => extension, - })); + if let NormalTT { def_info: ref mut def_info @ None, .. } = extension { + *def_info = Some((ast::CRATE_NODE_ID, self.krate_span)); + } + self.syntax_exts.push((name, extension)); } /// Register a macro of the usual kind. @@ -122,6 +104,7 @@ impl<'a> Registry<'a> { self.register_syntax_extension(Symbol::intern(name), NormalTT { expander: Box::new(expander), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 08ab5b8532522..b5af7bb74a644 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -242,8 +242,7 @@ impl<'a> base::Resolver for Resolver<'a> { fn check_unused_macros(&self) { for did in self.unused_macros.iter() { let id_span = match *self.macro_map[did] { - SyntaxExtension::NormalTT { def_info, .. } | - SyntaxExtension::DeclMacro { def_info, .. } => def_info, + SyntaxExtension::NormalTT { def_info, .. } => def_info, _ => None, }; if let Some((id, span)) = id_span { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 860ea18a58ad0..1e824e6fdfba0 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -433,7 +433,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { if let Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) = res { // skip proc-macro stubs, they'll cause `get_macro` to crash } else { - if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(res) { + if let SyntaxExtension::NormalTT { .. } = *resolver.get_macro(res) { return Some(res.map_id(|_| panic!("unexpected id"))); } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 4a357b0f3121a..7ac92224f76fb 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -579,6 +579,7 @@ pub enum SyntaxExtension { NormalTT { expander: Box, def_info: Option<(ast::NodeId, Span)>, + transparency: Transparency, /// Whether the contents of the macro can /// directly use `#[unstable]` things. /// @@ -605,21 +606,12 @@ pub enum SyntaxExtension { /// An attribute-like procedural macro that derives a builtin trait. BuiltinDerive(Box), - - /// A declarative macro, e.g., `macro m() {}`. - DeclMacro { - expander: Box, - def_info: Option<(ast::NodeId, Span)>, - is_transparent: bool, - edition: Edition, - } } impl SyntaxExtension { /// Returns which kind of macro calls this syntax extension. pub fn kind(&self) -> MacroKind { match *self { - SyntaxExtension::DeclMacro { .. } | SyntaxExtension::NormalTT { .. } | SyntaxExtension::ProcMacro { .. } => MacroKind::Bang, @@ -635,19 +627,19 @@ impl SyntaxExtension { pub fn default_transparency(&self) -> Transparency { match *self { + SyntaxExtension::NormalTT { transparency, .. } => transparency, SyntaxExtension::ProcMacro { .. } | SyntaxExtension::AttrProcMacro(..) | SyntaxExtension::ProcMacroDerive(..) | - SyntaxExtension::DeclMacro { is_transparent: false, .. } => Transparency::Opaque, - SyntaxExtension::DeclMacro { is_transparent: true, .. } => Transparency::Transparent, - _ => Transparency::SemiTransparent, + SyntaxExtension::NonMacroAttr { .. } => Transparency::Opaque, + SyntaxExtension::MultiModifier(..) | + SyntaxExtension::BuiltinDerive(..) => Transparency::SemiTransparent, } } pub fn edition(&self, default_edition: Edition) -> Edition { match *self { SyntaxExtension::NormalTT { edition, .. } | - SyntaxExtension::DeclMacro { edition, .. } | SyntaxExtension::ProcMacro { edition, .. } | SyntaxExtension::AttrProcMacro(.., edition) | SyntaxExtension::ProcMacroDerive(.., edition) => edition, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 892c59bbc0446..a68103de90f1a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -747,16 +747,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let opt_expanded = match *ext { - DeclMacro { ref expander, def_info, edition, .. } => { - if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s), - None, false, false, None, - edition) { - dummy_span - } else { - kind.make_from(expander.expand(self.cx, span, mac.node.stream(), None)) - } - } - NormalTT { ref expander, def_info, @@ -765,6 +755,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { local_inner_macros, unstable_feature, edition, + .. } => { if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s), allow_internal_unstable.clone(), diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 6f82f5094651e..bbf733cfbfe95 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -3,6 +3,7 @@ use crate::edition::Edition; use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension}; use crate::ext::base::{NormalTT, TTMacroExpander}; use crate::ext::expand::{AstFragment, AstFragmentKind}; +use crate::ext::hygiene::Transparency; use crate::ext::tt::macro_parser::{Success, Error, Failure}; use crate::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; use crate::ext::tt::macro_parser::{parse, parse_failure_msg}; @@ -374,65 +375,65 @@ pub fn compile( valid, }); - if body.legacy { - let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable) - .map(|attr| attr - .meta_item_list() - .map(|list| list.iter() - .filter_map(|it| { - let name = it.ident().map(|ident| ident.name); - if name.is_none() { - sess.span_diagnostic.span_err(it.span(), - "allow internal unstable expects feature names") - } - name - }) - .collect::>().into() - ) - .unwrap_or_else(|| { - sess.span_diagnostic.span_warn( - attr.span, "allow_internal_unstable expects list of feature names. In the \ - future this will become a hard error. Please use `allow_internal_unstable(\ - foo, bar)` to only allow the `foo` and `bar` features", - ); - vec![sym::allow_internal_unstable_backcompat_hack].into() + let transparency = if attr::contains_name(&def.attrs, sym::rustc_transparent_macro) { + Transparency::Transparent + } else if body.legacy { + Transparency::SemiTransparent + } else { + Transparency::Opaque + }; + + let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable) + .map(|attr| attr + .meta_item_list() + .map(|list| list.iter() + .filter_map(|it| { + let name = it.ident().map(|ident| ident.name); + if name.is_none() { + sess.span_diagnostic.span_err(it.span(), + "allow internal unstable expects feature names") + } + name }) - ); - let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe); - let mut local_inner_macros = false; - if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { - if let Some(l) = macro_export.meta_item_list() { - local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); - } - } + .collect::>().into() + ) + .unwrap_or_else(|| { + sess.span_diagnostic.span_warn( + attr.span, "allow_internal_unstable expects list of feature names. In the \ + future this will become a hard error. Please use `allow_internal_unstable(\ + foo, bar)` to only allow the `foo` and `bar` features", + ); + vec![sym::allow_internal_unstable_backcompat_hack].into() + }) + ); - let unstable_feature = attr::find_stability(&sess, - &def.attrs, def.span).and_then(|stability| { - if let attr::StabilityLevel::Unstable { issue, .. } = stability.level { - Some((stability.feature, issue)) - } else { - None - } - }); - - NormalTT { - expander, - def_info: Some((def.id, def.span)), - allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, - unstable_feature, - edition, + let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe); + + let mut local_inner_macros = false; + if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { + if let Some(l) = macro_export.meta_item_list() { + local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); } - } else { - let is_transparent = attr::contains_name(&def.attrs, sym::rustc_transparent_macro); + } - SyntaxExtension::DeclMacro { - expander, - def_info: Some((def.id, def.span)), - is_transparent, - edition, + let unstable_feature = attr::find_stability(&sess, + &def.attrs, def.span).and_then(|stability| { + if let attr::StabilityLevel::Unstable { issue, .. } = stability.level { + Some((stability.feature, issue)) + } else { + None } + }); + + NormalTT { + expander, + def_info: Some((def.id, def.span)), + transparency, + allow_internal_unstable, + allow_internal_unsafe, + local_inner_macros, + unstable_feature, + edition, } } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index fc00154427501..7d6abd14a4a00 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -42,6 +42,7 @@ pub mod proc_macro_impl; use rustc_data_structures::sync::Lrc; use syntax::ast; use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension, MultiModifier}; +use syntax::ext::hygiene::Transparency; use syntax::edition::Edition; use syntax::symbol::{sym, Symbol}; @@ -59,6 +60,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, NormalTT { expander: Box::new($f as MacroExpanderFn), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, @@ -102,6 +104,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, NormalTT { expander: Box::new(format::expand_format_args), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: Some(vec![sym::fmt_internals].into()), allow_internal_unsafe: false, local_inner_macros: false, @@ -112,6 +115,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, NormalTT { expander: Box::new(format::expand_format_args_nl), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: Some(vec![sym::fmt_internals].into()), allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs index 096701bd9b3ed..cf12b80848436 100644 --- a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs +++ b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs @@ -13,6 +13,7 @@ use syntax::ast; use syntax::ext::hygiene; use syntax::ext::build::AstBuilder; use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager, NormalTT}; +use syntax::ext::hygiene::Transparency; use syntax::print::pprust; use syntax::ptr::P; use syntax::symbol::Symbol; @@ -43,6 +44,7 @@ pub fn plugin_registrar(reg: &mut Registry) { NormalTT { expander: Box::new(Expander { args: args, }), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/test/ui/macros/nonterminal-matching.stderr b/src/test/ui/macros/nonterminal-matching.stderr index 5fba8002e1c48..93cc97d45830b 100644 --- a/src/test/ui/macros/nonterminal-matching.stderr +++ b/src/test/ui/macros/nonterminal-matching.stderr @@ -1,6 +1,9 @@ error: no rules expected the token `enum E { }` --> $DIR/nonterminal-matching.rs:19:10 | +LL | macro n(a $nt_item b) { + | --------------------- when calling this macro +... LL | n!(a $nt_item b); | ^^^^^^^^ no rules expected this token in macro call ... From 0468eb63ad96e1dd4b10cd099ceca87f56417b1c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 7 Jun 2019 01:59:27 +0300 Subject: [PATCH 5/6] syntax: Improve documentation of `SyntaxExtension` --- src/libsyntax/ext/base.rs | 90 +++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 7ac92224f76fb..e4f4b40fc7cc6 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -552,60 +552,78 @@ impl MacroKind { /// An enum representing the different kinds of syntax extensions. pub enum SyntaxExtension { - /// A trivial "extension" that does nothing, only keeps the attribute and marks it as known. - NonMacroAttr { mark_used: bool }, - - /// A syntax extension that is attached to an item and modifies it - /// in-place. Also allows decoration, i.e., creating new items. - MultiModifier(Box), - - /// A function-like procedural macro. TokenStream -> TokenStream. + /// A token-based function-like macro. ProcMacro { + /// An expander with signature TokenStream -> TokenStream. expander: Box, - /// Whitelist of unstable features that are treated as stable inside this macro + /// Whitelist of unstable features that are treated as stable inside this macro. allow_internal_unstable: Option>, + /// Edition of the crate in which this macro is defined. edition: Edition, }, - /// An attribute-like procedural macro. TokenStream, TokenStream -> TokenStream. - /// The first TokenSteam is the attribute, the second is the annotated item. - /// Allows modification of the input items and adding new items, similar to - /// MultiModifier, but uses TokenStreams, rather than AST nodes. - AttrProcMacro(Box, Edition), - - /// A normal, function-like syntax extension. - /// - /// `bytes!` is a `NormalTT`. + /// An AST-based function-like macro. NormalTT { + /// An expander with signature TokenStream -> AST. expander: Box, + /// Some info about the macro's definition point. def_info: Option<(ast::NodeId, Span)>, + /// Hygienic properties of identifiers produced by this macro. transparency: Transparency, - /// Whether the contents of the macro can - /// directly use `#[unstable]` things. - /// - /// Only allows things that require a feature gate in the given whitelist + /// Whitelist of unstable features that are treated as stable inside this macro. allow_internal_unstable: Option>, - /// Whether the contents of the macro can use `unsafe` - /// without triggering the `unsafe_code` lint. + /// Suppresses the `unsafe_code` lint for code produced by this macro. allow_internal_unsafe: bool, - /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) - /// for a given macro. + /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. local_inner_macros: bool, - /// The macro's feature name if it is unstable, and the stability feature + /// The macro's feature name and tracking issue number if it is unstable. unstable_feature: Option<(Symbol, u32)>, - /// Edition of the crate in which the macro is defined + /// Edition of the crate in which this macro is defined. edition: Edition, }, - /// An attribute-like procedural macro. TokenStream -> TokenStream. - /// The input is the annotated item. - /// Allows generating code to implement a Trait for a given struct - /// or enum item. - ProcMacroDerive(Box, - Vec /* inert attribute names */, Edition), + /// A token-based attribute macro. + AttrProcMacro( + /// An expander with signature (TokenStream, TokenStream) -> TokenStream. + /// The first TokenSteam is the attribute itself, the second is the annotated item. + /// The produced TokenSteam replaces the input TokenSteam. + Box, + /// Edition of the crate in which this macro is defined. + Edition, + ), + + /// An AST-based attribute macro. + MultiModifier( + /// An expander with signature (AST, AST) -> AST. + /// The first AST fragment is the attribute itself, the second is the annotated item. + /// The produced AST fragment replaces the input AST fragment. + Box, + ), + + /// A trivial attribute "macro" that does nothing, + /// only keeps the attribute and marks it as known. + NonMacroAttr { + /// Suppresses the `unused_attributes` lint for this attribute. + mark_used: bool, + }, - /// An attribute-like procedural macro that derives a builtin trait. - BuiltinDerive(Box), + /// A token-based derive macro. + ProcMacroDerive( + /// An expander with signature TokenStream -> TokenStream (not yet). + /// The produced TokenSteam is appended to the input TokenSteam. + Box, + /// Names of helper attributes registered by this macro. + Vec, + /// Edition of the crate in which this macro is defined. + Edition, + ), + + /// An AST-based derive macro. + BuiltinDerive( + /// An expander with signature AST -> AST. + /// The produced AST fragment is appended to the input AST fragment. + Box, + ), } impl SyntaxExtension { From 93eb63c9a540e8721adf8b97085301b7b692785d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 7 Jun 2019 02:30:01 +0300 Subject: [PATCH 6/6] syntax: Rename variants of `SyntaxExtension` for consistency --- src/librustc_metadata/creader.rs | 6 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_plugin/registry.rs | 8 +-- src/librustc_resolve/macros.rs | 4 +- src/librustdoc/clean/inline.rs | 2 +- .../passes/collect_intra_doc_links.rs | 2 +- src/libsyntax/ext/base.rs | 55 +++++++++---------- src/libsyntax/ext/expand.rs | 26 +++++---- src/libsyntax/ext/tt/macro_rules.rs | 5 +- src/libsyntax_ext/deriving/mod.rs | 2 +- src/libsyntax_ext/lib.rs | 15 ++--- .../auxiliary/plugin-args.rs | 8 +-- 12 files changed, 65 insertions(+), 70 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 991bebc647d0f..7ffba41e2569a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -614,7 +614,7 @@ impl<'a> CrateLoader<'a> { match decl { ProcMacro::CustomDerive { trait_name, attributes, client } => { let attrs = attributes.iter().cloned().map(Symbol::intern).collect::>(); - (trait_name, SyntaxExtension::ProcMacroDerive( + (trait_name, SyntaxExtension::Derive( Box::new(ProcMacroDerive { client, attrs: attrs.clone(), @@ -624,13 +624,13 @@ impl<'a> CrateLoader<'a> { )) } ProcMacro::Attr { name, client } => { - (name, SyntaxExtension::AttrProcMacro( + (name, SyntaxExtension::Attr( Box::new(AttrProcMacro { client }), root.edition, )) } ProcMacro::Bang { name, client } => { - (name, SyntaxExtension::ProcMacro { + (name, SyntaxExtension::Bang { expander: Box::new(BangProcMacro { client }), allow_internal_unstable: None, edition: root.edition, diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index db452bb4ac7bc..35faa1df82b84 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -430,7 +430,7 @@ impl cstore::CStore { use syntax_ext::proc_macro_impl::BangProcMacro; let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); - let ext = SyntaxExtension::ProcMacro { + let ext = SyntaxExtension::Bang { expander: Box::new(BangProcMacro { client }), allow_internal_unstable: Some(vec![sym::proc_macro_def_site].into()), edition: data.root.edition, diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index f4b4bcb043c42..dd5e42684c427 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -4,7 +4,7 @@ use rustc::lint::{EarlyLintPassObject, LateLintPassObject, LintId, Lint}; use rustc::session::Session; use rustc::util::nodemap::FxHashMap; -use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT}; +use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension}; use syntax::ext::base::MacroExpanderFn; use syntax::ext::hygiene::Transparency; use syntax::symbol::{Symbol, sym}; @@ -89,7 +89,7 @@ impl<'a> Registry<'a> { if name == sym::macro_rules { panic!("user-defined macros may not be named `macro_rules`"); } - if let NormalTT { def_info: ref mut def_info @ None, .. } = extension { + if let SyntaxExtension::LegacyBang { def_info: ref mut def_info @ None, .. } = extension { *def_info = Some((ast::CRATE_NODE_ID, self.krate_span)); } self.syntax_exts.push((name, extension)); @@ -98,10 +98,10 @@ impl<'a> Registry<'a> { /// Register a macro of the usual kind. /// /// This is a convenience wrapper for `register_syntax_extension`. - /// It builds for you a `NormalTT` that calls `expander`, + /// It builds for you a `SyntaxExtension::LegacyBang` that calls `expander`, /// and also takes care of interning the macro's name. pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) { - self.register_syntax_extension(Symbol::intern(name), NormalTT { + self.register_syntax_extension(Symbol::intern(name), SyntaxExtension::LegacyBang { expander: Box::new(expander), def_info: None, transparency: Transparency::SemiTransparent, diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index b5af7bb74a644..2369bddf4f75f 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -242,7 +242,7 @@ impl<'a> base::Resolver for Resolver<'a> { fn check_unused_macros(&self) { for did in self.unused_macros.iter() { let id_span = match *self.macro_map[did] { - SyntaxExtension::NormalTT { def_info, .. } => def_info, + SyntaxExtension::LegacyBang { def_info, .. } => def_info, _ => None, }; if let Some((id, span)) = id_span { @@ -586,7 +586,7 @@ impl<'a> Resolver<'a> { match self.resolve_macro_to_res(derive, MacroKind::Derive, &parent_scope, true, force) { Ok((_, ext)) => { - if let SyntaxExtension::ProcMacroDerive(_, helpers, _) = &*ext { + if let SyntaxExtension::Derive(_, helpers, _) = &*ext { if helpers.contains(&ident.name) { let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper), diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 15108a7dbb91c..5a5540e7e3855 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -471,7 +471,7 @@ fn build_macro(cx: &DocContext<'_>, did: DefId, name: ast::Name) -> clean::ItemE } LoadedMacro::ProcMacro(ext) => { let helpers = match &*ext { - &SyntaxExtension::ProcMacroDerive(_, ref syms, ..) => { syms.clean(cx) } + &SyntaxExtension::Derive(_, ref syms, ..) => { syms.clean(cx) } _ => Vec::new(), }; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 1e824e6fdfba0..7fbfc3e1fc0f4 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -433,7 +433,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { if let Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) = res { // skip proc-macro stubs, they'll cause `get_macro` to crash } else { - if let SyntaxExtension::NormalTT { .. } = *resolver.get_macro(res) { + if let SyntaxExtension::LegacyBang { .. } = *resolver.get_macro(res) { return Some(res.map_id(|_| panic!("unexpected id"))); } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index e4f4b40fc7cc6..38b7dee40c447 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,5 +1,3 @@ -pub use SyntaxExtension::*; - use crate::ast::{self, Attribute, Name, PatKind}; use crate::attr::HasAttrs; use crate::source_map::{SourceMap, Spanned, respan}; @@ -553,7 +551,7 @@ impl MacroKind { /// An enum representing the different kinds of syntax extensions. pub enum SyntaxExtension { /// A token-based function-like macro. - ProcMacro { + Bang { /// An expander with signature TokenStream -> TokenStream. expander: Box, /// Whitelist of unstable features that are treated as stable inside this macro. @@ -563,7 +561,7 @@ pub enum SyntaxExtension { }, /// An AST-based function-like macro. - NormalTT { + LegacyBang { /// An expander with signature TokenStream -> AST. expander: Box, /// Some info about the macro's definition point. @@ -583,7 +581,7 @@ pub enum SyntaxExtension { }, /// A token-based attribute macro. - AttrProcMacro( + Attr( /// An expander with signature (TokenStream, TokenStream) -> TokenStream. /// The first TokenSteam is the attribute itself, the second is the annotated item. /// The produced TokenSteam replaces the input TokenSteam. @@ -593,7 +591,7 @@ pub enum SyntaxExtension { ), /// An AST-based attribute macro. - MultiModifier( + LegacyAttr( /// An expander with signature (AST, AST) -> AST. /// The first AST fragment is the attribute itself, the second is the annotated item. /// The produced AST fragment replaces the input AST fragment. @@ -608,7 +606,7 @@ pub enum SyntaxExtension { }, /// A token-based derive macro. - ProcMacroDerive( + Derive( /// An expander with signature TokenStream -> TokenStream (not yet). /// The produced TokenSteam is appended to the input TokenSteam. Box, @@ -619,7 +617,7 @@ pub enum SyntaxExtension { ), /// An AST-based derive macro. - BuiltinDerive( + LegacyDerive( /// An expander with signature AST -> AST. /// The produced AST fragment is appended to the input AST fragment. Box, @@ -630,41 +628,38 @@ impl SyntaxExtension { /// Returns which kind of macro calls this syntax extension. pub fn kind(&self) -> MacroKind { match *self { - SyntaxExtension::NormalTT { .. } | - SyntaxExtension::ProcMacro { .. } => - MacroKind::Bang, - SyntaxExtension::NonMacroAttr { .. } | - SyntaxExtension::MultiModifier(..) | - SyntaxExtension::AttrProcMacro(..) => - MacroKind::Attr, - SyntaxExtension::ProcMacroDerive(..) | - SyntaxExtension::BuiltinDerive(..) => - MacroKind::Derive, + SyntaxExtension::Bang { .. } | + SyntaxExtension::LegacyBang { .. } => MacroKind::Bang, + SyntaxExtension::Attr(..) | + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::NonMacroAttr { .. } => MacroKind::Attr, + SyntaxExtension::Derive(..) | + SyntaxExtension::LegacyDerive(..) => MacroKind::Derive, } } pub fn default_transparency(&self) -> Transparency { match *self { - SyntaxExtension::NormalTT { transparency, .. } => transparency, - SyntaxExtension::ProcMacro { .. } | - SyntaxExtension::AttrProcMacro(..) | - SyntaxExtension::ProcMacroDerive(..) | + SyntaxExtension::LegacyBang { transparency, .. } => transparency, + SyntaxExtension::Bang { .. } | + SyntaxExtension::Attr(..) | + SyntaxExtension::Derive(..) | SyntaxExtension::NonMacroAttr { .. } => Transparency::Opaque, - SyntaxExtension::MultiModifier(..) | - SyntaxExtension::BuiltinDerive(..) => Transparency::SemiTransparent, + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::LegacyDerive(..) => Transparency::SemiTransparent, } } pub fn edition(&self, default_edition: Edition) -> Edition { match *self { - SyntaxExtension::NormalTT { edition, .. } | - SyntaxExtension::ProcMacro { edition, .. } | - SyntaxExtension::AttrProcMacro(.., edition) | - SyntaxExtension::ProcMacroDerive(.., edition) => edition, + SyntaxExtension::Bang { edition, .. } | + SyntaxExtension::LegacyBang { edition, .. } | + SyntaxExtension::Attr(.., edition) | + SyntaxExtension::Derive(.., edition) => edition, // Unstable legacy stuff SyntaxExtension::NonMacroAttr { .. } | - SyntaxExtension::MultiModifier(..) | - SyntaxExtension::BuiltinDerive(..) => default_edition, + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::LegacyDerive(..) => default_edition, } } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a68103de90f1a..084d4fd382017 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -389,7 +389,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let item = match self.cx.resolver.resolve_macro_path( path, MacroKind::Derive, Mark::root(), Vec::new(), false) { Ok(ext) => match *ext { - BuiltinDerive(..) => item_with_markers.clone(), + SyntaxExtension::LegacyDerive(..) => item_with_markers.clone(), _ => item.clone(), }, _ => item.clone(), @@ -548,7 +548,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => unreachable!(), }; - if let NonMacroAttr { mark_used: false } = *ext {} else { + if let SyntaxExtension::NonMacroAttr { mark_used: false } = *ext {} else { // Macro attrs are always used when expanded, // non-macro attrs are considered used when the field says so. attr::mark_used(&attr); @@ -564,18 +564,18 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }); match *ext { - NonMacroAttr { .. } => { + SyntaxExtension::NonMacroAttr { .. } => { attr::mark_known(&attr); item.visit_attrs(|attrs| attrs.push(attr)); Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item))) } - MultiModifier(ref mac) => { + SyntaxExtension::LegacyAttr(ref mac) => { let meta = attr.parse_meta(self.cx.parse_sess) .map_err(|mut e| { e.emit(); }).ok()?; let item = mac.expand(self.cx, attr.span, &meta, item); Some(invoc.fragment_kind.expect_from_annotatables(item)) } - AttrProcMacro(ref mac, ..) => { + SyntaxExtension::Attr(ref mac, ..) => { self.gate_proc_macro_attr_item(attr.span, &item); let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item { Annotatable::Item(item) => token::NtItem(item), @@ -592,7 +592,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.gate_proc_macro_expansion(attr.span, &res); res } - ProcMacroDerive(..) | BuiltinDerive(..) => { + SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => { self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path)); self.cx.trace_macros_diag(); invoc.fragment_kind.dummy(attr.span) @@ -747,7 +747,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let opt_expanded = match *ext { - NormalTT { + SyntaxExtension::LegacyBang { ref expander, def_info, ref allow_internal_unstable, @@ -774,20 +774,22 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - MultiModifier(..) | AttrProcMacro(..) | SyntaxExtension::NonMacroAttr { .. } => { + SyntaxExtension::Attr(..) | + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::NonMacroAttr { .. } => { self.cx.span_err(path.span, &format!("`{}` can only be used in attributes", path)); self.cx.trace_macros_diag(); kind.dummy(span) } - ProcMacroDerive(..) | BuiltinDerive(..) => { + SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => { self.cx.span_err(path.span, &format!("`{}` is a derive macro", path)); self.cx.trace_macros_diag(); kind.dummy(span) } - SyntaxExtension::ProcMacro { ref expander, ref allow_internal_unstable, edition } => { + SyntaxExtension::Bang { ref expander, ref allow_internal_unstable, edition } => { if ident.name != kw::Invalid { let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); @@ -885,9 +887,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; match ext { - ProcMacroDerive(expander, ..) | BuiltinDerive(expander) => { + SyntaxExtension::Derive(expander, ..) | SyntaxExtension::LegacyDerive(expander) => { let meta = match ext { - ProcMacroDerive(..) => ast::MetaItem { // FIXME(jseyfried) avoid this + SyntaxExtension::Derive(..) => ast::MetaItem { // FIXME(jseyfried) avoid this path: Path::from_ident(Ident::invalid()), span: DUMMY_SP, node: ast::MetaItemKind::Word, diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index bbf733cfbfe95..5dbf21867afa6 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -1,7 +1,6 @@ use crate::{ast, attr}; use crate::edition::Edition; -use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension}; -use crate::ext::base::{NormalTT, TTMacroExpander}; +use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension, TTMacroExpander}; use crate::ext::expand::{AstFragment, AstFragmentKind}; use crate::ext::hygiene::Transparency; use crate::ext::tt::macro_parser::{Success, Error, Failure}; @@ -425,7 +424,7 @@ pub fn compile( } }); - NormalTT { + SyntaxExtension::LegacyBang { expander, def_info: Some((def.id, def.span)), transparency, diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index 2f09ab2087e41..cf54eacc3d46c 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -71,7 +71,7 @@ macro_rules! derive_traits { $( resolver.add_builtin( ast::Ident::with_empty_ctxt(Symbol::intern($name)), - Lrc::new(SyntaxExtension::BuiltinDerive(Box::new(BuiltinDerive($func)))) + Lrc::new(SyntaxExtension::LegacyDerive(Box::new(BuiltinDerive($func)))) ); )* } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 7d6abd14a4a00..7c4085aa09653 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -41,7 +41,8 @@ pub mod proc_macro_impl; use rustc_data_structures::sync::Lrc; use syntax::ast; -use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension, MultiModifier}; + +use syntax::ext::base::{MacroExpanderFn, NamedSyntaxExtension, SyntaxExtension}; use syntax::ext::hygiene::Transparency; use syntax::edition::Edition; use syntax::symbol::{sym, Symbol}; @@ -57,7 +58,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, macro_rules! register { ($( $name:ident: $f:expr, )*) => { $( register(Symbol::intern(stringify!($name)), - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new($f as MacroExpanderFn), def_info: None, transparency: Transparency::SemiTransparent, @@ -95,13 +96,13 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, assert: assert::expand_assert, } - register(sym::test_case, MultiModifier(Box::new(test_case::expand))); - register(sym::test, MultiModifier(Box::new(test::expand_test))); - register(sym::bench, MultiModifier(Box::new(test::expand_bench))); + register(sym::test_case, SyntaxExtension::LegacyAttr(Box::new(test_case::expand))); + register(sym::test, SyntaxExtension::LegacyAttr(Box::new(test::expand_test))); + register(sym::bench, SyntaxExtension::LegacyAttr(Box::new(test::expand_bench))); // format_args uses `unstable` things internally. register(Symbol::intern("format_args"), - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new(format::expand_format_args), def_info: None, transparency: Transparency::SemiTransparent, @@ -112,7 +113,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, edition, }); register(sym::format_args_nl, - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new(format::expand_format_args_nl), def_info: None, transparency: Transparency::SemiTransparent, diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs index cf12b80848436..330459fc08f55 100644 --- a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs +++ b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs @@ -10,12 +10,10 @@ extern crate rustc_plugin; use std::borrow::ToOwned; use syntax::ast; -use syntax::ext::hygiene; use syntax::ext::build::AstBuilder; -use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager, NormalTT}; +use syntax::ext::base::{SyntaxExtension, TTMacroExpander, ExtCtxt, MacResult, MacEager}; use syntax::ext::hygiene::Transparency; use syntax::print::pprust; -use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; use syntax::tokenstream::TokenStream; @@ -30,7 +28,7 @@ impl TTMacroExpander for Expander { ecx: &'cx mut ExtCtxt, sp: Span, _: TokenStream, - _: Option) -> Box { + _: Option) -> Box { let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i)) .collect::>().join(", "); MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args))) @@ -41,7 +39,7 @@ impl TTMacroExpander for Expander { pub fn plugin_registrar(reg: &mut Registry) { let args = reg.args().to_owned(); reg.register_syntax_extension(Symbol::intern("plugin_args"), - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new(Expander { args: args, }), def_info: None, transparency: Transparency::SemiTransparent,