use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{self, AssocCtxt, Visitor};
-use rustc_ast::{AstLike, AttrItem, AttrStyle, Block, Inline, ItemKind, LitKind, MacArgs};
+use rustc_ast::{AstLike, AttrItem, Block, Inline, ItemKind, LitKind, MacArgs};
use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, ModKind, NestedMetaItem};
use rustc_ast::{NodeId, PatKind, Path, StmtKind, Unsafe};
use rustc_ast_pretty::pprust;
use rustc_data_structures::map_in_place::MapInPlace;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lrc;
-use rustc_errors::{Applicability, PResult};
+use rustc_errors::{Applicability, FatalError, PResult};
use rustc_feature::Features;
use rustc_parse::parser::{AttemptLocalParseRecovery, ForceCollect, Parser, RecoverComma};
use rustc_parse::validate_attr;
kind.article(), kind.descr()
),
);
+ // FIXME: this workaround issue #84569
+ FatalError.raise();
}
};
self.cx.trace_macros_diag();
let invocations = {
let mut collector = InvocationCollector {
+ // Non-derive macro invocations cannot see the results of cfg expansion - they
+ // will either be removed along with the item, or invoked before the cfg/cfg_attr
+ // attribute is expanded. Therefore, we don't need to configure the tokens
+ // Derive macros *can* see the results of cfg-expansion - they are handled
+ // specially in `fully_expand_fragment`
cfg: StripUnconfigured {
sess: &self.cx.sess,
features: self.cx.ecfg.features,
- modified: false,
+ config_tokens: false,
},
cx: self.cx,
invocations: Vec::new(),
SyntaxExtensionKind::Attr(expander) => {
self.gate_proc_macro_input(&item);
self.gate_proc_macro_attr_item(span, &item);
- let tokens = match attr.style {
- AttrStyle::Outer => item.into_tokens(&self.cx.sess.parse_sess),
- // FIXME: Properly collect tokens for inner attributes
- AttrStyle::Inner => rustc_parse::fake_token_stream(
+ let mut fake_tokens = false;
+ if let Annotatable::Item(item_inner) = &item {
+ if let ItemKind::Mod(_, mod_kind) = &item_inner.kind {
+ // FIXME: Collect tokens and use them instead of generating
+ // fake ones. These are unstable, so it needs to be
+ // fixed prior to stabilization
+ // Fake tokens when we are invoking an inner attribute, and:
+ fake_tokens = matches!(attr.style, ast::AttrStyle::Inner) &&
+ // We are invoking an attribute on the crate root, or an outline
+ // module
+ (item_inner.ident.name.is_empty() || !matches!(mod_kind, ast::ModKind::Loaded(_, Inline::Yes, _)));
+ }
+ }
+ let tokens = if fake_tokens {
+ rustc_parse::fake_token_stream(
&self.cx.sess.parse_sess,
&item.into_nonterminal(),
- ),
+ )
+ } else {
+ item.into_tokens(&self.cx.sess.parse_sess)
};
let attr_item = attr.unwrap_normal_item();
if let MacArgs::Eq(..) = attr_item.args {
}
AstFragmentKind::TraitItems => {
let mut items = SmallVec::new();
- while let Some(item) = this.parse_trait_item()? {
+ while let Some(item) = this.parse_trait_item(ForceCollect::No)? {
items.extend(item);
}
AstFragment::TraitItems(items)
}
AstFragmentKind::ImplItems => {
let mut items = SmallVec::new();
- while let Some(item) = this.parse_impl_item()? {
+ while let Some(item) = this.parse_impl_item(ForceCollect::No)? {
items.extend(item);
}
AstFragment::ImplItems(items)
}
AstFragmentKind::ForeignItems => {
let mut items = SmallVec::new();
- while let Some(item) = this.parse_foreign_item()? {
+ while let Some(item) = this.parse_foreign_item(ForceCollect::No)? {
items.extend(item);
}
AstFragment::ForeignItems(items)