use rustc_ast::attr::MarkedAttrs;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Nonterminal};
-use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream};
+use rustc_ast::tokenstream::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, MACRO_ARGUMENTS};
use rustc_session::{parse::ParseSess, Limit, Session};
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
use rustc_span::edition::Edition;
use std::path::PathBuf;
use std::rc::Rc;
-crate use rustc_span::hygiene::MacroKind;
+pub(crate) use rustc_span::hygiene::MacroKind;
// When adding new variants, make sure to
// adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector`
}
}
- pub fn into_nonterminal(self) -> Nonterminal {
+ pub fn to_tokens(&self) -> 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) => TokenStream::from_ast(node),
+ Annotatable::TraitItem(node) | Annotatable::ImplItem(node) => {
+ TokenStream::from_ast(node)
}
- Annotatable::ForeignItem(item) => {
- token::NtItem(P(item.and_then(ast::ForeignItem::into_item)))
+ Annotatable::ForeignItem(node) => TokenStream::from_ast(node),
+ Annotatable::Stmt(node) => {
+ assert!(!matches!(node.kind, ast::StmtKind::Empty));
+ TokenStream::from_ast(node)
}
- Annotatable::Stmt(stmt) => token::NtStmt(stmt),
- Annotatable::Expr(expr) => token::NtExpr(expr),
+ Annotatable::Expr(node) => TokenStream::from_ast(node),
Annotatable::Arm(..)
| Annotatable::ExprField(..)
| Annotatable::PatField(..)
}
}
- 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,
}
}
-pub trait ProcMacro {
+pub trait BangProcMacro {
fn expand<'cx>(
&self,
ecx: &'cx mut ExtCtxt<'_>,
) -> Result<TokenStream, ErrorGuaranteed>;
}
-impl<F> ProcMacro for F
+impl<F> BangProcMacro for F
where
F: Fn(TokenStream) -> TokenStream,
{
/// A token-based function-like macro.
Bang(
/// An expander with signature TokenStream -> TokenStream.
- Box<dyn ProcMacro + sync::Sync + sync::Send>,
+ Box<dyn BangProcMacro + sync::Sync + sync::Send>,
),
/// An AST-based function-like macro.
force: bool,
) -> Result<Lrc<SyntaxExtension>, Indeterminate>;
+ fn record_macro_rule_usage(&mut self, mac_id: NodeId, rule_index: usize);
+
fn check_unused_macros(&mut self);
// Resolver interfaces for specific built-in macros.
/// 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 {
}
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)
+}