Skip to content

Commit

Permalink
Rollup merge of #92573 - petrochenkov:ltrattr3, r=Aaron1011
Browse files Browse the repository at this point in the history
expand: Refactor InvocationCollector visitor for better code reuse

The refactoring part of #92473.

Invocation collector visitor logic now lives in two main functions:
- `fn flat_map_node`, corresponding to "one to many" expansions
- `fn visit_node`, corresponding to "one to one" expansions

All specific mut visitor methods now use one of these functions.

The new `InvocationCollectorNode` trait implemented for all `AstFragment` nodes provides the necessary small pieces of functionality required to implement the `(flat_map,visit)_node` functions.
r? `@Aaron1011`
  • Loading branch information
matthiaskrgr authored Jan 9, 2022
2 parents 464a081 + 4523466 commit b681dc2
Show file tree
Hide file tree
Showing 6 changed files with 761 additions and 540 deletions.
39 changes: 37 additions & 2 deletions compiler/rustc_ast/src/ast_like.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ use super::{AssocItem, Expr, ForeignItem, Item, Local, MacCallStmt};
use super::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility};
use super::{AttrVec, Attribute, Stmt, StmtKind};

use std::fmt::Debug;
use std::fmt;
use std::marker::PhantomData;

/// An `AstLike` represents an AST node (or some wrapper around
/// and AST node) which stores some combination of attributes
/// and tokens.
pub trait AstLike: Sized + Debug {
pub trait AstLike: Sized + fmt::Debug {
/// This is `true` if this `AstLike` might support 'custom' (proc-macro) inner
/// attributes. Attributes like `#![cfg]` and `#![cfg_attr]` are not
/// considered 'custom' attributes
Expand Down Expand Up @@ -285,3 +286,37 @@ derive_has_attrs_no_tokens! {
derive_has_tokens_no_attrs! {
Ty, Block, AttrItem, Pat, Path, Visibility
}

/// A newtype around an `AstLike` node that implements `AstLike` itself.
pub struct AstLikeWrapper<Wrapped, Tag> {
pub wrapped: Wrapped,
pub tag: PhantomData<Tag>,
}

impl<Wrapped, Tag> AstLikeWrapper<Wrapped, Tag> {
pub fn new(wrapped: Wrapped, _tag: Tag) -> AstLikeWrapper<Wrapped, Tag> {
AstLikeWrapper { wrapped, tag: Default::default() }
}
}

impl<Wrapped: fmt::Debug, Tag> fmt::Debug for AstLikeWrapper<Wrapped, Tag> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AstLikeWrapper")
.field("wrapped", &self.wrapped)
.field("tag", &self.tag)
.finish()
}
}

impl<Wrapped: AstLike, Tag> AstLike for AstLikeWrapper<Wrapped, Tag> {
const SUPPORTS_CUSTOM_INNER_ATTRS: bool = Wrapped::SUPPORTS_CUSTOM_INNER_ATTRS;
fn attrs(&self) -> &[Attribute] {
self.wrapped.attrs()
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
self.wrapped.visit_attrs(f)
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
self.wrapped.tokens_mut()
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub mod tokenstream;
pub mod visit;

pub use self::ast::*;
pub use self::ast_like::AstLike;
pub use self::ast_like::{AstLike, AstLikeWrapper};

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};

Expand Down
17 changes: 7 additions & 10 deletions compiler/rustc_expand/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ macro_rules! configure {
}

impl<'a> StripUnconfigured<'a> {
pub fn configure<T: AstLike>(&mut self, mut node: T) -> Option<T> {
pub fn configure<T: AstLike>(&self, mut node: T) -> Option<T> {
self.process_cfg_attrs(&mut node);
if self.in_cfg(node.attrs()) {
self.try_configure_tokens(&mut node);
Expand All @@ -248,7 +248,7 @@ impl<'a> StripUnconfigured<'a> {
}
}

fn try_configure_tokens<T: AstLike>(&mut self, node: &mut T) {
fn try_configure_tokens<T: AstLike>(&self, node: &mut T) {
if self.config_tokens {
if let Some(Some(tokens)) = node.tokens_mut() {
let attr_annotated_tokens = tokens.create_token_stream();
Expand All @@ -257,10 +257,7 @@ impl<'a> StripUnconfigured<'a> {
}
}

fn configure_krate_attrs(
&mut self,
mut attrs: Vec<ast::Attribute>,
) -> Option<Vec<ast::Attribute>> {
fn configure_krate_attrs(&self, mut attrs: Vec<ast::Attribute>) -> Option<Vec<ast::Attribute>> {
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
if self.in_cfg(&attrs) { Some(attrs) } else { None }
}
Expand All @@ -269,7 +266,7 @@ impl<'a> StripUnconfigured<'a> {
/// This is only used during the invocation of `derive` proc-macros,
/// which require that we cfg-expand their entire input.
/// Normal cfg-expansion operates on parsed AST nodes via the `configure` method
fn configure_tokens(&mut self, stream: &AttrAnnotatedTokenStream) -> AttrAnnotatedTokenStream {
fn configure_tokens(&self, stream: &AttrAnnotatedTokenStream) -> AttrAnnotatedTokenStream {
fn can_skip(stream: &AttrAnnotatedTokenStream) -> bool {
stream.0.iter().all(|(tree, _spacing)| match tree {
AttrAnnotatedTokenTree::Attributes(_) => false,
Expand Down Expand Up @@ -325,7 +322,7 @@ impl<'a> StripUnconfigured<'a> {
/// Gives compiler warnings if any `cfg_attr` does not contain any
/// attributes and is in the original source code. Gives compiler errors if
/// the syntax of any `cfg_attr` is incorrect.
fn process_cfg_attrs<T: AstLike>(&mut self, node: &mut T) {
fn process_cfg_attrs<T: AstLike>(&self, node: &mut T) {
node.visit_attrs(|attrs| {
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
});
Expand All @@ -338,7 +335,7 @@ impl<'a> StripUnconfigured<'a> {
/// Gives a compiler warning when the `cfg_attr` contains no attributes and
/// is in the original source file. Gives a compiler error if the syntax of
/// the attribute is incorrect.
fn process_cfg_attr(&mut self, attr: Attribute) -> Vec<Attribute> {
fn process_cfg_attr(&self, attr: Attribute) -> Vec<Attribute> {
if !attr.has_name(sym::cfg_attr) {
return vec![attr];
}
Expand Down Expand Up @@ -461,7 +458,7 @@ impl<'a> StripUnconfigured<'a> {
}
}

pub fn configure_expr(&mut self, expr: &mut P<ast::Expr>) {
pub fn configure_expr(&self, expr: &mut P<ast::Expr>) {
for attr in expr.attrs.iter() {
self.maybe_emit_expr_attr_err(attr);
}
Expand Down
Loading

0 comments on commit b681dc2

Please sign in to comment.