Auto merge of #61741 - Centril:rollup-fgro5kz, r=Centril
Rollup of 11 pull requests Successful merges: - #61518 (Add loops to doc list of things not stable in const fn) - #61526 (move some tests into subfolders) - #61550 (Windows 10 SDK is also required now.) - #61606 (Remove some legacy proc macro flavors) - #61652 (Mention slice patterns in array) - #61686 (librustc_errors: Add some more documentation) - #61698 (typeck: Fix const generic in repeat param ICE.) - #61707 (Azure: retry failed awscli installs) - #61715 (make sure make_ascii_lowercase actually leaves upper-case non-ASCII characters alone) - #61724 (core: use memcmp optimization for 128 bit integer slices) - #61726 (Use `for_each` in `Iterator::partition`) Failed merges: r? @ghost
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
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;
|
||||
@@ -137,29 +135,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<F> 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 {
|
||||
@@ -288,34 +263,6 @@ impl<F> TTMacroExpander for F
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IdentMacroExpander {
|
||||
fn expand<'cx>(&self,
|
||||
cx: &'cx mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
ident: ast::Ident,
|
||||
token_tree: Vec<tokenstream::TokenTree>)
|
||||
-> Box<dyn MacResult+'cx>;
|
||||
}
|
||||
|
||||
pub type IdentMacroExpanderFn =
|
||||
for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident, Vec<tokenstream::TokenTree>)
|
||||
-> Box<dyn MacResult+'cx>;
|
||||
|
||||
impl<F> IdentMacroExpander for F
|
||||
where F : for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident,
|
||||
Vec<tokenstream::TokenTree>) -> Box<dyn MacResult+'cx>
|
||||
{
|
||||
fn expand<'cx>(&self,
|
||||
cx: &'cx mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
ident: ast::Ident,
|
||||
token_tree: Vec<tokenstream::TokenTree>)
|
||||
-> Box<dyn MacResult+'cx>
|
||||
{
|
||||
(*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) => {
|
||||
@@ -570,9 +517,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 {
|
||||
@@ -606,129 +550,116 @@ 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 creates new items
|
||||
/// based upon it.
|
||||
///
|
||||
/// `#[derive(...)]` is a `MultiItemDecorator`.
|
||||
///
|
||||
/// Prefer ProcMacro or MultiModifier since they are more flexible.
|
||||
MultiDecorator(Box<dyn MultiItemDecorator + sync::Sync + sync::Send>),
|
||||
|
||||
/// A syntax extension that is attached to an item and modifies it
|
||||
/// in-place. Also allows decoration, i.e., creating new items.
|
||||
MultiModifier(Box<dyn MultiItemModifier + sync::Sync + sync::Send>),
|
||||
|
||||
/// A function-like procedural macro. TokenStream -> TokenStream.
|
||||
ProcMacro {
|
||||
/// A token-based function-like macro.
|
||||
Bang {
|
||||
/// An expander with signature TokenStream -> TokenStream.
|
||||
expander: Box<dyn ProcMacro + sync::Sync + sync::Send>,
|
||||
/// 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<Lrc<[Symbol]>>,
|
||||
/// 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<dyn AttrProcMacro + sync::Sync + sync::Send>, Edition),
|
||||
|
||||
/// A normal, function-like syntax extension.
|
||||
///
|
||||
/// `bytes!` is a `NormalTT`.
|
||||
NormalTT {
|
||||
/// An AST-based function-like macro.
|
||||
LegacyBang {
|
||||
/// An expander with signature TokenStream -> AST.
|
||||
expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
|
||||
/// Some info about the macro's definition point.
|
||||
def_info: Option<(ast::NodeId, Span)>,
|
||||
/// Whether the contents of the macro can
|
||||
/// directly use `#[unstable]` things.
|
||||
///
|
||||
/// Only allows things that require a feature gate in the given whitelist
|
||||
/// Hygienic properties of identifiers produced by this macro.
|
||||
transparency: Transparency,
|
||||
/// Whitelist of unstable features that are treated as stable inside this macro.
|
||||
allow_internal_unstable: Option<Lrc<[Symbol]>>,
|
||||
/// 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,
|
||||
},
|
||||
|
||||
/// A function-like syntax extension that has an extra ident before
|
||||
/// the block.
|
||||
IdentTT {
|
||||
expander: Box<dyn IdentMacroExpander + sync::Sync + sync::Send>,
|
||||
span: Option<Span>,
|
||||
allow_internal_unstable: Option<Lrc<[Symbol]>>,
|
||||
/// A token-based attribute macro.
|
||||
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.
|
||||
Box<dyn AttrProcMacro + sync::Sync + sync::Send>,
|
||||
/// Edition of the crate in which this macro is defined.
|
||||
Edition,
|
||||
),
|
||||
|
||||
/// An AST-based attribute macro.
|
||||
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.
|
||||
Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
|
||||
),
|
||||
|
||||
/// 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. TokenStream -> TokenStream.
|
||||
/// The input is the annotated item.
|
||||
/// Allows generating code to implement a Trait for a given struct
|
||||
/// or enum item.
|
||||
ProcMacroDerive(Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
|
||||
Vec<Symbol> /* inert attribute names */, Edition),
|
||||
/// A token-based derive macro.
|
||||
Derive(
|
||||
/// An expander with signature TokenStream -> TokenStream (not yet).
|
||||
/// The produced TokenSteam is appended to the input TokenSteam.
|
||||
Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
|
||||
/// Names of helper attributes registered by this macro.
|
||||
Vec<Symbol>,
|
||||
/// Edition of the crate in which this macro is defined.
|
||||
Edition,
|
||||
),
|
||||
|
||||
/// An attribute-like procedural macro that derives a builtin trait.
|
||||
BuiltinDerive(BuiltinDeriveFn),
|
||||
|
||||
/// 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,
|
||||
}
|
||||
/// An AST-based derive macro.
|
||||
LegacyDerive(
|
||||
/// An expander with signature AST -> AST.
|
||||
/// The produced AST fragment is appended to the input AST fragment.
|
||||
Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
|
||||
),
|
||||
}
|
||||
|
||||
impl SyntaxExtension {
|
||||
/// Returns which kind of macro calls this syntax extension.
|
||||
pub fn kind(&self) -> MacroKind {
|
||||
match *self {
|
||||
SyntaxExtension::DeclMacro { .. } |
|
||||
SyntaxExtension::NormalTT { .. } |
|
||||
SyntaxExtension::IdentTT { .. } |
|
||||
SyntaxExtension::ProcMacro { .. } =>
|
||||
MacroKind::Bang,
|
||||
SyntaxExtension::NonMacroAttr { .. } |
|
||||
SyntaxExtension::MultiDecorator(..) |
|
||||
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::ProcMacro { .. } |
|
||||
SyntaxExtension::AttrProcMacro(..) |
|
||||
SyntaxExtension::ProcMacroDerive(..) |
|
||||
SyntaxExtension::DeclMacro { is_transparent: false, .. } => Transparency::Opaque,
|
||||
SyntaxExtension::DeclMacro { is_transparent: true, .. } => Transparency::Transparent,
|
||||
_ => Transparency::SemiTransparent,
|
||||
SyntaxExtension::LegacyBang { transparency, .. } => transparency,
|
||||
SyntaxExtension::Bang { .. } |
|
||||
SyntaxExtension::Attr(..) |
|
||||
SyntaxExtension::Derive(..) |
|
||||
SyntaxExtension::NonMacroAttr { .. } => Transparency::Opaque,
|
||||
SyntaxExtension::LegacyAttr(..) |
|
||||
SyntaxExtension::LegacyDerive(..) => 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,
|
||||
SyntaxExtension::Bang { edition, .. } |
|
||||
SyntaxExtension::LegacyBang { edition, .. } |
|
||||
SyntaxExtension::Attr(.., edition) |
|
||||
SyntaxExtension::Derive(.., edition) => edition,
|
||||
// Unstable legacy stuff
|
||||
SyntaxExtension::NonMacroAttr { .. } |
|
||||
SyntaxExtension::IdentTT { .. } |
|
||||
SyntaxExtension::MultiDecorator(..) |
|
||||
SyntaxExtension::MultiModifier(..) |
|
||||
SyntaxExtension::BuiltinDerive(..) => default_edition,
|
||||
SyntaxExtension::LegacyAttr(..) |
|
||||
SyntaxExtension::LegacyDerive(..) => default_edition,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,26 +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))
|
||||
}
|
||||
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, ..) => {
|
||||
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),
|
||||
@@ -600,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)
|
||||
@@ -755,17 +747,7 @@ 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 {
|
||||
SyntaxExtension::LegacyBang {
|
||||
ref expander,
|
||||
def_info,
|
||||
ref allow_internal_unstable,
|
||||
@@ -773,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(),
|
||||
@@ -791,43 +774,22 @@ 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 { .. } => {
|
||||
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);
|
||||
@@ -924,29 +886,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 {
|
||||
SyntaxExtension::Derive(expander, ..) | SyntaxExtension::LegacyDerive(expander) => {
|
||||
let meta = match ext {
|
||||
SyntaxExtension::Derive(..) => 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))
|
||||
}
|
||||
_ => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
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};
|
||||
use crate::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
|
||||
use crate::ext::tt::macro_parser::{parse, parse_failure_msg};
|
||||
@@ -374,66 +374,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
|
||||
}
|
||||
});
|
||||
|
||||
SyntaxExtension::LegacyBang {
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user