Cleanup the definition of group_type
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
This commit is contained in:
@@ -62,15 +62,23 @@ use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
|
||||
use crate::parser::{ArgParser, MetaItemParser, PathParser};
|
||||
use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem};
|
||||
|
||||
macro_rules! group_type {
|
||||
($stage: ty) => {
|
||||
LazyLock<(
|
||||
BTreeMap<&'static [Symbol], Vec<(AttributeTemplate, Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, $stage>, &ArgParser<'a>) + Send + Sync>)>>,
|
||||
Vec<Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, $stage>) -> Option<AttributeKind>>>
|
||||
)>
|
||||
};
|
||||
type GroupType<S> = LazyLock<GroupTypeInner<S>>;
|
||||
|
||||
struct GroupTypeInner<S: Stage> {
|
||||
accepters: BTreeMap<&'static [Symbol], Vec<GroupTypeInnerAccept<S>>>,
|
||||
finalizers: Vec<FinalizeFn<S>>,
|
||||
}
|
||||
|
||||
struct GroupTypeInnerAccept<S: Stage> {
|
||||
template: AttributeTemplate,
|
||||
accept_fn: AcceptFn<S>,
|
||||
}
|
||||
|
||||
type AcceptFn<S> =
|
||||
Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, S>, &ArgParser<'a>) + Send + Sync>;
|
||||
type FinalizeFn<S> =
|
||||
Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, S>) -> Option<AttributeKind>>;
|
||||
|
||||
macro_rules! attribute_parsers {
|
||||
(
|
||||
pub(crate) static $name: ident = [$($names: ty),* $(,)?];
|
||||
@@ -93,11 +101,11 @@ macro_rules! attribute_parsers {
|
||||
}
|
||||
};
|
||||
(
|
||||
@[$ty: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?];
|
||||
@[$stage: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?];
|
||||
) => {
|
||||
pub(crate) static $name: group_type!($ty) = LazyLock::new(|| {
|
||||
let mut accepts = BTreeMap::<_, Vec<(AttributeTemplate, Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, $ty>, &ArgParser<'a>) + Send + Sync>)>>::new();
|
||||
let mut finalizes = Vec::<Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, $ty>) -> Option<AttributeKind>>>::new();
|
||||
pub(crate) static $name: GroupType<$stage> = LazyLock::new(|| {
|
||||
let mut accepts = BTreeMap::<_, Vec<GroupTypeInnerAccept<$stage>>>::new();
|
||||
let mut finalizes = Vec::<FinalizeFn<$stage>>::new();
|
||||
$(
|
||||
{
|
||||
thread_local! {
|
||||
@@ -105,11 +113,14 @@ macro_rules! attribute_parsers {
|
||||
};
|
||||
|
||||
for (path, template, accept_fn) in <$names>::ATTRIBUTES {
|
||||
accepts.entry(*path).or_default().push((*template, Box::new(|cx, args| {
|
||||
STATE_OBJECT.with_borrow_mut(|s| {
|
||||
accept_fn(s, cx, args)
|
||||
accepts.entry(*path).or_default().push(GroupTypeInnerAccept {
|
||||
template: *template,
|
||||
accept_fn: Box::new(|cx, args| {
|
||||
STATE_OBJECT.with_borrow_mut(|s| {
|
||||
accept_fn(s, cx, args)
|
||||
})
|
||||
})
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
||||
finalizes.push(Box::new(|cx| {
|
||||
@@ -119,7 +130,7 @@ macro_rules! attribute_parsers {
|
||||
}
|
||||
)*
|
||||
|
||||
(accepts, finalizes)
|
||||
GroupTypeInner { accepters:accepts, finalizers:finalizes }
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -215,7 +226,7 @@ pub trait Stage: Sized + 'static + Sealed {
|
||||
type Id: Copy;
|
||||
const SHOULD_EMIT_LINTS: bool;
|
||||
|
||||
fn parsers() -> &'static group_type!(Self);
|
||||
fn parsers() -> &'static GroupType<Self>;
|
||||
|
||||
fn emit_err<'sess>(
|
||||
&self,
|
||||
@@ -230,7 +241,7 @@ impl Stage for Early {
|
||||
type Id = NodeId;
|
||||
const SHOULD_EMIT_LINTS: bool = false;
|
||||
|
||||
fn parsers() -> &'static group_type!(Self) {
|
||||
fn parsers() -> &'static GroupType<Self> {
|
||||
&early::ATTRIBUTE_PARSERS
|
||||
}
|
||||
fn emit_err<'sess>(
|
||||
@@ -252,7 +263,7 @@ impl Stage for Late {
|
||||
type Id = HirId;
|
||||
const SHOULD_EMIT_LINTS: bool = true;
|
||||
|
||||
fn parsers() -> &'static group_type!(Self) {
|
||||
fn parsers() -> &'static GroupType<Self> {
|
||||
&late::ATTRIBUTE_PARSERS
|
||||
}
|
||||
fn emit_err<'sess>(
|
||||
@@ -811,8 +822,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
||||
let args = parser.args();
|
||||
let parts = path.segments().map(|i| i.name).collect::<Vec<_>>();
|
||||
|
||||
if let Some(accepts) = S::parsers().0.get(parts.as_slice()) {
|
||||
for (template, accept) in accepts {
|
||||
if let Some(accepts) = S::parsers().accepters.get(parts.as_slice()) {
|
||||
for accept in accepts {
|
||||
let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext {
|
||||
shared: SharedContext {
|
||||
cx: self,
|
||||
@@ -821,11 +832,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
||||
emit_lint: &mut emit_lint,
|
||||
},
|
||||
attr_span: lower_span(attr.span),
|
||||
template,
|
||||
template: &accept.template,
|
||||
attr_path: path.get_attribute_path(),
|
||||
};
|
||||
|
||||
accept(&mut cx, args)
|
||||
(accept.accept_fn)(&mut cx, args)
|
||||
}
|
||||
} else {
|
||||
// If we're here, we must be compiling a tool attribute... Or someone
|
||||
@@ -856,7 +867,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
||||
}
|
||||
|
||||
let mut parsed_attributes = Vec::new();
|
||||
for f in &S::parsers().1 {
|
||||
for f in &S::parsers().finalizers {
|
||||
if let Some(attr) = f(&mut FinalizeContext {
|
||||
shared: SharedContext {
|
||||
cx: self,
|
||||
@@ -877,7 +888,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
||||
|
||||
/// Returns whether there is a parser for an attribute with this name
|
||||
pub fn is_parsed_attribute(path: &[Symbol]) -> bool {
|
||||
Late::parsers().0.contains_key(path)
|
||||
Late::parsers().accepters.contains_key(path)
|
||||
}
|
||||
|
||||
fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs {
|
||||
|
||||
Reference in New Issue
Block a user