ast: Introduce some traits to get AST node properties generically

And use them to avoid constructing some artificial `Nonterminal` tokens during expansion
This commit is contained in:
Vadim Petrochenkov
2022-05-01 20:58:24 +03:00
parent ee6eaabdd4
commit f2b7fa4847
24 changed files with 593 additions and 500 deletions

View File

@@ -6,14 +6,14 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Nonterminal};
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream};
use rustc_ast::visit::{AssocCtxt, Visitor};
use rustc_ast::{self as ast, AstLike, Attribute, Item, NodeId, PatKind};
use rustc_ast::{self as ast, Attribute, HasAttrs, Item, NodeId, PatKind};
use rustc_attr::{self as attr, Deprecation, Stability};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{self, Lrc};
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, PResult};
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
use rustc_lint_defs::BuiltinLintDiagnostics;
use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS};
use rustc_parse::{self, parser, to_token_stream, MACRO_ARGUMENTS};
use rustc_session::{parse::ParseSess, Limit, Session};
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
use rustc_span::edition::Edition;
@@ -109,17 +109,20 @@ impl Annotatable {
}
}
pub fn into_nonterminal(self) -> Nonterminal {
pub fn to_tokens(&self, sess: &ParseSess) -> TokenStream {
match self {
Annotatable::Item(item) => token::NtItem(item),
Annotatable::TraitItem(item) | Annotatable::ImplItem(item) => {
token::NtItem(P(item.and_then(ast::AssocItem::into_item)))
Annotatable::Item(node) => to_token_stream(node, sess, CanSynthesizeMissingTokens::No),
Annotatable::TraitItem(node) | Annotatable::ImplItem(node) => {
to_token_stream(node, sess, CanSynthesizeMissingTokens::No)
}
Annotatable::ForeignItem(item) => {
token::NtItem(P(item.and_then(ast::ForeignItem::into_item)))
Annotatable::ForeignItem(node) => {
to_token_stream(node, sess, CanSynthesizeMissingTokens::No)
}
Annotatable::Stmt(stmt) => token::NtStmt(stmt),
Annotatable::Expr(expr) => token::NtExpr(expr),
Annotatable::Stmt(node) => {
assert!(!matches!(node.kind, ast::StmtKind::Empty));
to_token_stream(node, sess, CanSynthesizeMissingTokens::No)
}
Annotatable::Expr(node) => to_token_stream(node, sess, CanSynthesizeMissingTokens::No),
Annotatable::Arm(..)
| Annotatable::ExprField(..)
| Annotatable::PatField(..)
@@ -131,10 +134,6 @@ impl Annotatable {
}
}
crate fn into_tokens(self, sess: &ParseSess) -> TokenStream {
nt_to_tokenstream(&self.into_nonterminal(), sess, CanSynthesizeMissingTokens::No)
}
pub fn expect_item(self) -> P<ast::Item> {
match self {
Annotatable::Item(i) => i,
@@ -1380,16 +1379,7 @@ pub fn parse_macro_name_and_helper_attrs(
/// asserts in old versions of those crates and their wide use in the ecosystem.
/// See issue #73345 for more details.
/// FIXME(#73933): Remove this eventually.
pub(crate) fn pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &ParseSess) -> bool {
let item = match nt {
Nonterminal::NtItem(item) => item,
Nonterminal::NtStmt(stmt) => match &stmt.kind {
ast::StmtKind::Item(item) => item,
_ => return false,
},
_ => return false,
};
fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
let name = item.ident.name;
if name == sym::ProceduralMasqueradeDummyType {
if let ast::ItemKind::Enum(enum_def, _) = &item.kind {
@@ -1411,3 +1401,27 @@ pub(crate) fn pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &ParseS
}
false
}
pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &ParseSess) -> bool {
let item = match ann {
Annotatable::Item(item) => item,
Annotatable::Stmt(stmt) => match &stmt.kind {
ast::StmtKind::Item(item) => item,
_ => return false,
},
_ => return false,
};
pretty_printing_compatibility_hack(item, sess)
}
pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &ParseSess) -> bool {
let item = match nt {
Nonterminal::NtItem(item) => item,
Nonterminal::NtStmt(stmt) => match &stmt.kind {
ast::StmtKind::Item(item) => item,
_ => return false,
},
_ => return false,
};
pretty_printing_compatibility_hack(item, sess)
}