mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
syntax: Remove SyntaxExtension::DeclMacro
It's a less powerful duplicate of `SyntaxExtension::NormalTT`
This commit is contained in:
parent
edb925a91f
commit
8edbbacbca
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -433,7 +433,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
|
||||
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")));
|
||||
}
|
||||
}
|
||||
|
@ -579,6 +579,7 @@ pub enum SyntaxExtension {
|
||||
NormalTT {
|
||||
expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
|
||||
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<dyn MultiItemModifier + sync::Sync + sync::Send>),
|
||||
|
||||
/// A declarative macro, e.g., `macro m() {}`.
|
||||
DeclMacro {
|
||||
expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
|
||||
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,
|
||||
|
@ -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(),
|
||||
|
@ -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,66 +375,66 @@ 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::<Vec<Symbol>>().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 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);
|
||||
}
|
||||
}
|
||||
|
||||
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 transparency = if attr::contains_name(&def.attrs, sym::rustc_transparent_macro) {
|
||||
Transparency::Transparent
|
||||
} else if body.legacy {
|
||||
Transparency::SemiTransparent
|
||||
} else {
|
||||
let is_transparent = attr::contains_name(&def.attrs, sym::rustc_transparent_macro);
|
||||
Transparency::Opaque
|
||||
};
|
||||
|
||||
SyntaxExtension::DeclMacro {
|
||||
expander,
|
||||
def_info: Some((def.id, def.span)),
|
||||
is_transparent,
|
||||
edition,
|
||||
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::<Vec<Symbol>>().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 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);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
fn check_lhs_nt_follows(sess: &ParseSess,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
...
|
||||
|
Loading…
Reference in New Issue
Block a user