Skip to content

Commit

Permalink
renamings
Browse files Browse the repository at this point in the history
  • Loading branch information
jdonszelmann committed Jan 20, 2025
1 parent e920917 commit 5d70659
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 242 deletions.
1 change: 0 additions & 1 deletion ,

This file was deleted.

9 changes: 5 additions & 4 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

use rustc_ast::node_id::NodeMap;
use rustc_ast::{self as ast, *};
use rustc_attr_parsing::{AttributeParseContext, OmitDoc};
use rustc_attr_parsing::{AttributeParser, OmitDoc};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::sorted_map::SortedMap;
Expand All @@ -60,7 +60,8 @@ use rustc_macros::extension;
use rustc_middle::span_bug;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_session::parse::{add_feature_diagnostics, feature_err};
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
use rustc_span::symbol::{Ident, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
use smallvec::{SmallVec, smallvec};
use thin_vec::ThinVec;
use tracing::{debug, instrument, trace};
Expand Down Expand Up @@ -135,7 +136,7 @@ struct LoweringContext<'a, 'hir> {
allow_for_await: Lrc<[Symbol]>,
allow_async_fn_traits: Lrc<[Symbol]>,

attribute_parse_context: AttributeParseContext<'hir>,
attribute_parse_context: AttributeParser<'hir>,
}

impl<'a, 'hir> LoweringContext<'a, 'hir> {
Expand Down Expand Up @@ -181,7 +182,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// interact with `gen`/`async gen` blocks
allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),

attribute_parse_context: AttributeParseContext::new(
attribute_parse_context: AttributeParser::new(
tcx.sess,
tcx.features(),
registered_tools,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_attr_data_structures/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ impl Deprecation {
}
}

// TODO: improve these docs
/// Attributes represent parsed, *built in* attributes. That means,
/// attributes that are not actually ever expanded. They're instead used as markers,
/// to guide the compilation process in various way in most every stage of the compiler.
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,41 @@ use std::iter;
use rustc_attr_data_structures::AttributeKind;
use rustc_span::{Span, Symbol, sym};

use super::{CombineAttributeGroup, ConvertFn};
use crate::context::AttributeAcceptContext;
use super::{CombineAttributeParser, ConvertFn};
use crate::context::AcceptContext;
use crate::parser::ArgParser;
use crate::session_diagnostics;

pub(crate) struct AllowInternalUnstableGroup;
impl CombineAttributeGroup for AllowInternalUnstableGroup {
pub(crate) struct AllowInternalUnstableParser;
impl CombineAttributeParser for AllowInternalUnstableParser {
const PATH: &'static [rustc_span::Symbol] = &[sym::allow_internal_unstable];
type Item = (Symbol, Span);
const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowInternalUnstable;

fn extend<'a>(
cx: &'a AttributeAcceptContext<'a>,
cx: &'a AcceptContext<'a>,
args: &'a ArgParser<'a>,
) -> impl IntoIterator<Item = Self::Item> + 'a {
parse_unstable(cx, args, Self::PATH[0]).into_iter().zip(iter::repeat(cx.attr_span))
}
}

pub(crate) struct AllowConstFnUnstableGroup;
impl CombineAttributeGroup for AllowConstFnUnstableGroup {
pub(crate) struct AllowConstFnUnstableParser;
impl CombineAttributeParser for AllowConstFnUnstableParser {
const PATH: &'static [rustc_span::Symbol] = &[sym::rustc_allow_const_fn_unstable];
type Item = Symbol;
const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowConstFnUnstable;

fn extend<'a>(
cx: &'a AttributeAcceptContext<'a>,
cx: &'a AcceptContext<'a>,
args: &'a ArgParser<'a>,
) -> impl IntoIterator<Item = Self::Item> + 'a {
parse_unstable(cx, args, Self::PATH[0])
}
}

fn parse_unstable<'a>(
cx: &AttributeAcceptContext<'_>,
cx: &AcceptContext<'_>,
args: &'a ArgParser<'a>,
symbol: Symbol,
) -> impl IntoIterator<Item = Symbol> {
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_attr_parsing/src/attributes/confusables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@ use rustc_attr_data_structures::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use thin_vec::ThinVec;

use super::{AttributeGroup, AttributeMapping};
use crate::context::AttributeGroupContext;
use super::{AcceptMapping, AttributeParser};
use crate::context::FinalizeContext;
use crate::session_diagnostics;

// TODO: turn into CombineGroup?
#[derive(Default)]
pub(crate) struct ConfusablesGroup {
pub(crate) struct ConfusablesParser {
confusables: ThinVec<Symbol>,
first_span: Option<Span>,
}

impl AttributeGroup for ConfusablesGroup {
const ATTRIBUTES: AttributeMapping<Self> = &[(&[sym::rustc_confusables], |this, cx, args| {
impl AttributeParser for ConfusablesParser {
const ATTRIBUTES: AcceptMapping<Self> = &[(&[sym::rustc_confusables], |this, cx, args| {
let Some(list) = args.list() else {
// FIXME(jdonszelmann): error when not a list? Bring validation code here.
// NOTE: currently subsequent attributes are silently ignored using
Expand Down Expand Up @@ -46,7 +45,7 @@ impl AttributeGroup for ConfusablesGroup {
this.first_span.get_or_insert(cx.attr_span);
})];

fn finalize(self, _cx: &AttributeGroupContext<'_>) -> Option<AttributeKind> {
fn finalize(self, _cx: &FinalizeContext<'_>) -> Option<AttributeKind> {
if self.confusables.is_empty() {
return None;
}
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_attr_parsing/src/attributes/deprecation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ use rustc_attr_data_structures::{AttributeKind, DeprecatedSince, Deprecation};
use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol, sym};

use super::SingleAttributeGroup;
use super::SingleAttributeParser;
use super::util::parse_version;
use crate::context::AttributeAcceptContext;
use crate::context::AcceptContext;
use crate::parser::ArgParser;
use crate::session_diagnostics;
use crate::session_diagnostics::UnsupportedLiteralReason;

pub(crate) struct DeprecationGroup;
pub(crate) struct DeprecationParser;

fn get(
cx: &AttributeAcceptContext<'_>,
cx: &AcceptContext<'_>,
ident: Ident,
param_span: Span,
arg: &ArgParser<'_>,
Expand Down Expand Up @@ -46,10 +46,10 @@ fn get(
}
}

impl SingleAttributeGroup for DeprecationGroup {
impl SingleAttributeParser for DeprecationParser {
const PATH: &'static [rustc_span::Symbol] = &[sym::deprecated];

fn on_duplicate(cx: &AttributeAcceptContext<'_>, first_span: rustc_span::Span) {
fn on_duplicate(cx: &AcceptContext<'_>, first_span: rustc_span::Span) {
// FIXME(jdonszelmann): merge with errors from check_attrs.rs
cx.emit_err(session_diagnostics::UnusedMultiple {
this: cx.attr_span,
Expand All @@ -58,7 +58,7 @@ impl SingleAttributeGroup for DeprecationGroup {
});
}

fn convert(cx: &AttributeAcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind> {
fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind> {
let features = cx.features();

let mut since = None;
Expand Down
108 changes: 56 additions & 52 deletions compiler/rustc_attr_parsing/src/attributes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
//! [`AttributeGroup`]s are groups of attributes (groups can be size 1) that are parsed together.
//! An [`AttributeGroup`] implementation defines its parser.
//!
//! You can find more docs on what groups are on [`AttributeGroup`] itself.
//! However, for many types of attributes, implementing [`AttributeGroup`] is not necessary.
//! You can find more docs on what groups are on [`AttributeParser`] itself.
//! However, for many types of attributes, implementing [`AttributeParser`] is not necessary.
//! It allows for a lot of flexibility you might not want.
//!
//! Specifically, you care about managing the state of your [AttributeGroup] state machine
//! yourself. In this case you can choose to implement:
//! Specifically, you might not care about managing the state of your [`AttributeParser`]
//! state machine yourself. In this case you can choose to implement:
//!
//! - [`SingleAttributeGroup`]: makes it easy to implement an attribute which should error if it
//! - [`SingleAttributeParser`]: makes it easy to implement an attribute which should error if it
//! appears more than once in a list of attributes
//! - [`CombineAttributeGroup`]: makes it easy to implement an attribute which should combine the
//! - [`CombineAttributeParser`]: makes it easy to implement an attribute which should combine the
//! contents of attributes, if an attribute appear multiple times in a list
//!
//! Attributes should be added to [`ATTRIBUTE_GROUP_MAPPING`](crate::context::ATTRIBUTE_GROUP_MAPPING) to be parsed.
Expand All @@ -21,7 +18,7 @@ use rustc_attr_data_structures::AttributeKind;
use rustc_span::Span;
use thin_vec::ThinVec;

use crate::context::{AttributeAcceptContext, AttributeGroupContext};
use crate::context::{AcceptContext, FinalizeContext};
use crate::parser::ArgParser;

pub(crate) mod allow_unstable;
Expand All @@ -33,60 +30,68 @@ pub(crate) mod stability;
pub(crate) mod transparency;
pub(crate) mod util;

type AttributeHandler<T> = fn(&mut T, &AttributeAcceptContext<'_>, &ArgParser<'_>);
type AttributeMapping<T> = &'static [(&'static [rustc_span::Symbol], AttributeHandler<T>)];
type AcceptFn<T> = fn(&mut T, &AcceptContext<'_>, &ArgParser<'_>);
type AcceptMapping<T> = &'static [(&'static [rustc_span::Symbol], AcceptFn<T>)];

/// An [`AttributeGroup`] is a type which searches for syntactic attributes.
/// An [`AttributeParser`] is a type which searches for syntactic attributes.
///
/// Groups are often tiny state machines. [`Default::default`]
/// creates a new instance that sits in some kind of initial state, usually that the
/// Parsers are often tiny state machines that gets to see all syntactical attributes on an item.
/// [`Default::default`] creates a fresh instance that sits in some kind of initial state, usually that the
/// attribute it is looking for was not yet seen.
///
/// Then, it defines what paths this group will accept in [`AttributeGroup::ATTRIBUTES`].
/// Then, it defines what paths this group will accept in [`AttributeParser::ATTRIBUTES`].
/// These are listed as pairs, of symbols and function pointers. The function pointer will
/// be called when that attribute is found on an item, which can influence the state.
/// be called when that attribute is found on an item, which can influence the state of the little
/// state machine.
///
/// Finally, after all attributes on an item have been seen, and possibly been accepted,
/// the [`finalize`](AttributeParser::finalize) functions for all attribute parsers are called. Each can then report
/// whether it has seen the attribute it has been looking for.
///
/// Finally, all `finalize` functions are called, for each piece of state,
pub(crate) trait AttributeGroup: Default + 'static {
/// The symbols for the attributes that this extractor can extract.
/// The state machine is automatically reset to parse attributes on the next item.
pub(crate) trait AttributeParser: Default + 'static {
/// The symbols for the attributes that this parser is interested in.
///
/// If an attribute has this symbol, the `accept` function will be called on it.
const ATTRIBUTES: AttributeMapping<Self>;
const ATTRIBUTES: AcceptMapping<Self>;

/// The extractor has gotten a chance to accept the attributes on an item,
/// now produce an attribute.
fn finalize(self, cx: &AttributeGroupContext<'_>) -> Option<AttributeKind>;
/// The parser has gotten a chance to accept the attributes on an item,
/// here it can produce an attribute.
fn finalize(self, cx: &FinalizeContext<'_>) -> Option<AttributeKind>;
}

/// A slightly simpler and more restricted way to convert attributes which you can implement for
/// unit types. Assumes that a single attribute can only appear a single time on an item
/// [`SingleGroup<T> where T: SingleAttributeGroup`](Single) creates an [`AttributeGroup`] from any [`SingleAttributeGroup`].
/// Alternative to [`AttributeParser`] that automatically handles state management.
/// A slightly simpler and more restricted way to convert attributes.
/// Assumes that an attribute can only appear a single time on an item,
/// and errors when it sees more.
///
/// [`Single<T> where T: SingleAttributeParser`](Single) implements [`AttributeParser`].
///
/// [`SingleGroup`] can only convert attributes one-to-one, and cannot combine multiple
/// [`SingleAttributeParser`] can only convert attributes one-to-one, and cannot combine multiple
/// attributes together like is necessary for `#[stable()]` and `#[unstable()]` for example.
pub(crate) trait SingleAttributeGroup: 'static {
pub(crate) trait SingleAttributeParser: 'static {
const PATH: &'static [rustc_span::Symbol];

/// Caled when a duplicate attribute is found.
///
/// `first_span` is the span of the first occurrence of this attribute.
fn on_duplicate(cx: &AttributeAcceptContext<'_>, first_span: Span);
// FIXME(jdonszelmann): default error
fn on_duplicate(cx: &AcceptContext<'_>, first_span: Span);

/// The extractor has gotten a chance to accept the attributes on an item,
/// now produce an attribute.
fn convert(cx: &AttributeAcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind>;
/// Converts a single syntactical attribute to a single semantic attribute, or [`AttributeKind`]
fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind>;
}

pub(crate) struct Single<T: SingleAttributeGroup>(PhantomData<T>, Option<(AttributeKind, Span)>);
pub(crate) struct Single<T: SingleAttributeParser>(PhantomData<T>, Option<(AttributeKind, Span)>);

impl<T: SingleAttributeGroup> Default for Single<T> {
impl<T: SingleAttributeParser> Default for Single<T> {
fn default() -> Self {
Self(Default::default(), Default::default())
}
}

impl<T: SingleAttributeGroup> AttributeGroup for Single<T> {
const ATTRIBUTES: AttributeMapping<Self> = &[(T::PATH, |group: &mut Single<T>, cx, args| {
impl<T: SingleAttributeParser> AttributeParser for Single<T> {
const ATTRIBUTES: AcceptMapping<Self> = &[(T::PATH, |group: &mut Single<T>, cx, args| {
if let Some((_, s)) = group.1 {
T::on_duplicate(cx, s);
return;
Expand All @@ -97,50 +102,49 @@ impl<T: SingleAttributeGroup> AttributeGroup for Single<T> {
}
})];

fn finalize(self, _cx: &AttributeGroupContext<'_>) -> Option<AttributeKind> {
fn finalize(self, _cx: &FinalizeContext<'_>) -> Option<AttributeKind> {
Some(self.1?.0)
}
}

type ConvertFn<E> = fn(ThinVec<E>) -> AttributeKind;

/// A slightly simpler and more restricted way to convert attributes which you can implement for
/// unit types. If multiple attributes appear on an element, combines the values of each into a
/// Alternative to [`AttributeParser`] that automatically handles state management.
/// If multiple attributes appear on an element, combines the values of each into a
/// [`ThinVec`].
/// [`CombineGroup<T> where T: CombineAttributeGroup`](Combine) creates an [`AttributeGroup`] from any [`CombineAttributeGroup`].
/// [`Combine<T> where T: CombineAttributeParser`](Combine) implements [`AttributeParser`].
///
/// [`CombineAttributeGroup`] can only convert a single kind of attribute, and cannot combine multiple
/// [`CombineAttributeParser`] can only convert a single kind of attribute, and cannot combine multiple
/// attributes together like is necessary for `#[stable()]` and `#[unstable()]` for example.
pub(crate) trait CombineAttributeGroup: 'static {
pub(crate) trait CombineAttributeParser: 'static {
const PATH: &'static [rustc_span::Symbol];

type Item;
const CONVERT: ConvertFn<Self::Item>;

/// The extractor has gotten a chance to accept the attributes on an item,
/// now produce an attribute.
/// Converts a single syntactical attribute to a number of elements of the semantic attribute, or [`AttributeKind`]
fn extend<'a>(
cx: &'a AttributeAcceptContext<'a>,
cx: &'a AcceptContext<'a>,
args: &'a ArgParser<'a>,
) -> impl IntoIterator<Item = Self::Item> + 'a;
}

pub(crate) struct Combine<T: CombineAttributeGroup>(
pub(crate) struct Combine<T: CombineAttributeParser>(
PhantomData<T>,
ThinVec<<T as CombineAttributeGroup>::Item>,
ThinVec<<T as CombineAttributeParser>::Item>,
);

impl<T: CombineAttributeGroup> Default for Combine<T> {
impl<T: CombineAttributeParser> Default for Combine<T> {
fn default() -> Self {
Self(Default::default(), Default::default())
}
}

impl<T: CombineAttributeGroup> AttributeGroup for Combine<T> {
const ATTRIBUTES: AttributeMapping<Self> =
impl<T: CombineAttributeParser> AttributeParser for Combine<T> {
const ATTRIBUTES: AcceptMapping<Self> =
&[(T::PATH, |group: &mut Combine<T>, cx, args| group.1.extend(T::extend(cx, args)))];

fn finalize(self, _cx: &AttributeGroupContext<'_>) -> Option<AttributeKind> {
fn finalize(self, _cx: &FinalizeContext<'_>) -> Option<AttributeKind> {
if self.1.is_empty() { None } else { Some(T::CONVERT(self.1)) }
}
}
Loading

0 comments on commit 5d70659

Please sign in to comment.