From ca40d7da59b07dc8f704fb2307b596a6c4ff7fd7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 5 May 2021 22:03:55 +0300 Subject: [PATCH 1/3] Move `cfg_eval` stuff back to `rustc_expand` --- compiler/rustc_builtin_macros/src/cfg_eval.rs | 254 +----------------- compiler/rustc_builtin_macros/src/derive.rs | 3 +- compiler/rustc_expand/src/config.rs | 250 ++++++++++++++++- 3 files changed, 251 insertions(+), 256 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 79dc857074d59..623bd2e8248f5 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -1,21 +1,10 @@ use crate::util::check_builtin_macro_attribute; use rustc_ast as ast; -use rustc_ast::mut_visit::MutVisitor; -use rustc_ast::tokenstream::CanSynthesizeMissingTokens; -use rustc_ast::visit::Visitor; -use rustc_ast::{mut_visit, visit}; -use rustc_ast::{AstLike, Attribute}; use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_expand::config::StripUnconfigured; -use rustc_expand::configure; -use rustc_parse::parser::ForceCollect; -use rustc_session::utils::FlattenNonterminals; - -use rustc_ast::ptr::P; +use rustc_expand::config::cfg_eval; use rustc_span::symbol::sym; use rustc_span::Span; -use smallvec::SmallVec; crate fn expand( ecx: &mut ExtCtxt<'_>, @@ -26,244 +15,3 @@ crate fn expand( check_builtin_macro_attribute(ecx, meta_item, sym::cfg_eval); cfg_eval(ecx, annotatable) } - -crate fn cfg_eval(ecx: &ExtCtxt<'_>, annotatable: Annotatable) -> Vec { - let mut visitor = CfgEval { - cfg: &mut StripUnconfigured { - sess: ecx.sess, - features: ecx.ecfg.features, - config_tokens: true, - }, - }; - let annotatable = visitor.configure_annotatable(annotatable); - vec![annotatable] -} - -struct CfgEval<'a, 'b> { - cfg: &'a mut StripUnconfigured<'b>, -} - -fn flat_map_annotatable(vis: &mut impl MutVisitor, annotatable: Annotatable) -> Annotatable { - // Since the item itself has already been configured by the InvocationCollector, - // we know that fold result vector will contain exactly one element - match annotatable { - Annotatable::Item(item) => Annotatable::Item(vis.flat_map_item(item).pop().unwrap()), - Annotatable::TraitItem(item) => { - Annotatable::TraitItem(vis.flat_map_trait_item(item).pop().unwrap()) - } - Annotatable::ImplItem(item) => { - Annotatable::ImplItem(vis.flat_map_impl_item(item).pop().unwrap()) - } - Annotatable::ForeignItem(item) => { - Annotatable::ForeignItem(vis.flat_map_foreign_item(item).pop().unwrap()) - } - Annotatable::Stmt(stmt) => { - Annotatable::Stmt(stmt.map(|stmt| vis.flat_map_stmt(stmt).pop().unwrap())) - } - Annotatable::Expr(mut expr) => Annotatable::Expr({ - vis.visit_expr(&mut expr); - expr - }), - Annotatable::Arm(arm) => Annotatable::Arm(vis.flat_map_arm(arm).pop().unwrap()), - Annotatable::ExprField(field) => { - Annotatable::ExprField(vis.flat_map_expr_field(field).pop().unwrap()) - } - Annotatable::PatField(fp) => { - Annotatable::PatField(vis.flat_map_pat_field(fp).pop().unwrap()) - } - Annotatable::GenericParam(param) => { - Annotatable::GenericParam(vis.flat_map_generic_param(param).pop().unwrap()) - } - Annotatable::Param(param) => Annotatable::Param(vis.flat_map_param(param).pop().unwrap()), - Annotatable::FieldDef(sf) => { - Annotatable::FieldDef(vis.flat_map_field_def(sf).pop().unwrap()) - } - Annotatable::Variant(v) => Annotatable::Variant(vis.flat_map_variant(v).pop().unwrap()), - } -} - -struct CfgFinder { - has_cfg_or_cfg_attr: bool, -} - -impl CfgFinder { - fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool { - let mut finder = CfgFinder { has_cfg_or_cfg_attr: false }; - match annotatable { - Annotatable::Item(item) => finder.visit_item(&item), - Annotatable::TraitItem(item) => finder.visit_assoc_item(&item, visit::AssocCtxt::Trait), - Annotatable::ImplItem(item) => finder.visit_assoc_item(&item, visit::AssocCtxt::Impl), - Annotatable::ForeignItem(item) => finder.visit_foreign_item(&item), - Annotatable::Stmt(stmt) => finder.visit_stmt(&stmt), - Annotatable::Expr(expr) => finder.visit_expr(&expr), - Annotatable::Arm(arm) => finder.visit_arm(&arm), - Annotatable::ExprField(field) => finder.visit_expr_field(&field), - Annotatable::PatField(field) => finder.visit_pat_field(&field), - Annotatable::GenericParam(param) => finder.visit_generic_param(¶m), - Annotatable::Param(param) => finder.visit_param(¶m), - Annotatable::FieldDef(field) => finder.visit_field_def(&field), - Annotatable::Variant(variant) => finder.visit_variant(&variant), - }; - finder.has_cfg_or_cfg_attr - } -} - -impl<'ast> visit::Visitor<'ast> for CfgFinder { - fn visit_attribute(&mut self, attr: &'ast Attribute) { - // We want short-circuiting behavior, so don't use the '|=' operator. - self.has_cfg_or_cfg_attr = self.has_cfg_or_cfg_attr - || attr - .ident() - .map_or(false, |ident| ident.name == sym::cfg || ident.name == sym::cfg_attr); - } -} - -impl CfgEval<'_, '_> { - fn configure(&mut self, node: T) -> Option { - self.cfg.configure(node) - } - - pub fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Annotatable { - // Tokenizing and re-parsing the `Annotatable` can have a significant - // performance impact, so try to avoid it if possible - if !CfgFinder::has_cfg_or_cfg_attr(&annotatable) { - return annotatable; - } - - // The majority of parsed attribute targets will never need to have early cfg-expansion - // run (e.g. they are not part of a `#[derive]` or `#[cfg_eval]` macro inoput). - // Therefore, we normally do not capture the necessary information about `#[cfg]` - // and `#[cfg_attr]` attributes during parsing. - // - // Therefore, when we actually *do* run early cfg-expansion, we need to tokenize - // and re-parse the attribute target, this time capturing information about - // the location of `#[cfg]` and `#[cfg_attr]` in the token stream. The tokenization - // process is lossless, so this process is invisible to proc-macros. - - // FIXME - get rid of this clone - let nt = annotatable.clone().into_nonterminal(); - - let mut orig_tokens = rustc_parse::nt_to_tokenstream( - &nt, - &self.cfg.sess.parse_sess, - CanSynthesizeMissingTokens::No, - ); - - // 'Flatten' all nonterminals (i.e. `TokenKind::Interpolated`) - // to `None`-delimited groups containing the corresponding tokens. This - // is normally delayed until the proc-macro server actually needs to - // provide a `TokenKind::Interpolated` to a proc-macro. We do this earlier, - // so that we can handle cases like: - // - // ```rust - // #[cfg_eval] #[cfg] $item - //``` - // - // where `$item` is `#[cfg_attr] struct Foo {}`. We want to make - // sure to evaluate *all* `#[cfg]` and `#[cfg_attr]` attributes - the simplest - // way to do this is to do a single parse of a stream without any nonterminals. - let mut flatten = FlattenNonterminals { - nt_to_tokenstream: rustc_parse::nt_to_tokenstream, - parse_sess: &self.cfg.sess.parse_sess, - synthesize_tokens: CanSynthesizeMissingTokens::No, - }; - orig_tokens = flatten.process_token_stream(orig_tokens); - - // Re-parse the tokens, setting the `capture_cfg` flag to save extra information - // to the captured `AttrAnnotatedTokenStream` (specifically, we capture - // `AttrAnnotatedTokenTree::AttributesData` for all occurences of `#[cfg]` and `#[cfg_attr]`) - let mut parser = - rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None); - parser.capture_cfg = true; - annotatable = match annotatable { - Annotatable::Item(_) => { - Annotatable::Item(parser.parse_item(ForceCollect::Yes).unwrap().unwrap()) - } - Annotatable::TraitItem(_) => Annotatable::TraitItem( - parser.parse_trait_item(ForceCollect::Yes).unwrap().unwrap().unwrap(), - ), - Annotatable::ImplItem(_) => Annotatable::ImplItem( - parser.parse_impl_item(ForceCollect::Yes).unwrap().unwrap().unwrap(), - ), - Annotatable::ForeignItem(_) => Annotatable::ForeignItem( - parser.parse_foreign_item(ForceCollect::Yes).unwrap().unwrap().unwrap(), - ), - Annotatable::Stmt(_) => { - Annotatable::Stmt(P(parser.parse_stmt(ForceCollect::Yes).unwrap().unwrap())) - } - Annotatable::Expr(_) => Annotatable::Expr(parser.parse_expr_force_collect().unwrap()), - _ => unreachable!(), - }; - - // Now that we have our re-parsed `AttrAnnotatedTokenStream`, recursively configuring - // our attribute target will correctly the tokens as well. - flat_map_annotatable(self, annotatable) - } -} - -impl MutVisitor for CfgEval<'_, '_> { - fn visit_expr(&mut self, expr: &mut P) { - self.cfg.configure_expr(expr); - mut_visit::noop_visit_expr(expr, self); - } - - fn filter_map_expr(&mut self, expr: P) -> Option> { - let mut expr = configure!(self, expr); - mut_visit::noop_visit_expr(&mut expr, self); - Some(expr) - } - - fn flat_map_generic_param( - &mut self, - param: ast::GenericParam, - ) -> SmallVec<[ast::GenericParam; 1]> { - mut_visit::noop_flat_map_generic_param(configure!(self, param), self) - } - - fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { - mut_visit::noop_flat_map_stmt(configure!(self, stmt), self) - } - - fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { - mut_visit::noop_flat_map_item(configure!(self, item), self) - } - - fn flat_map_impl_item(&mut self, item: P) -> SmallVec<[P; 1]> { - mut_visit::noop_flat_map_assoc_item(configure!(self, item), self) - } - - fn flat_map_trait_item(&mut self, item: P) -> SmallVec<[P; 1]> { - mut_visit::noop_flat_map_assoc_item(configure!(self, item), self) - } - - fn flat_map_foreign_item( - &mut self, - foreign_item: P, - ) -> SmallVec<[P; 1]> { - mut_visit::noop_flat_map_foreign_item(configure!(self, foreign_item), self) - } - - fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { - mut_visit::noop_flat_map_arm(configure!(self, arm), self) - } - - fn flat_map_expr_field(&mut self, field: ast::ExprField) -> SmallVec<[ast::ExprField; 1]> { - mut_visit::noop_flat_map_expr_field(configure!(self, field), self) - } - - fn flat_map_pat_field(&mut self, fp: ast::PatField) -> SmallVec<[ast::PatField; 1]> { - mut_visit::noop_flat_map_pat_field(configure!(self, fp), self) - } - - fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> { - mut_visit::noop_flat_map_param(configure!(self, p), self) - } - - fn flat_map_field_def(&mut self, sf: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> { - mut_visit::noop_flat_map_field_def(configure!(self, sf), self) - } - - fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> { - mut_visit::noop_flat_map_variant(configure!(self, variant), self) - } -} diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index 1bb050a40cee2..1c58e63242f81 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -1,8 +1,7 @@ -use crate::cfg_eval::cfg_eval; - use rustc_ast::{self as ast, attr, token, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier}; +use rustc_expand::config::cfg_eval; use rustc_feature::AttributeTemplate; use rustc_parse::validate_attr; use rustc_session::Session; diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index f9140609c0f3c..ebca5df525311 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -1,10 +1,14 @@ //! Conditional compilation stripping. +use crate::base::{Annotatable, ExtCtxt}; + +use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::token::{DelimToken, Token, TokenKind}; use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree}; -use rustc_ast::tokenstream::{DelimSpan, Spacing}; +use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, DelimSpan, Spacing}; use rustc_ast::tokenstream::{LazyTokenStream, TokenTree}; +use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, AstLike, AttrItem, AttrStyle, Attribute, MetaItem}; use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; @@ -14,12 +18,15 @@ use rustc_feature::{Feature, Features, State as FeatureState}; use rustc_feature::{ ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES, }; +use rustc_parse::parser::ForceCollect; use rustc_parse::{parse_in, validate_attr}; use rustc_session::parse::feature_err; +use rustc_session::utils::FlattenNonterminals; use rustc_session::Session; use rustc_span::edition::{Edition, ALL_EDITIONS}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use smallvec::SmallVec; /// A folder that strips out items that do not belong in the current configuration. pub struct StripUnconfigured<'a> { @@ -539,3 +546,244 @@ pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a Meta fn is_cfg(sess: &Session, attr: &Attribute) -> bool { sess.check_name(attr, sym::cfg) } + +pub fn cfg_eval(ecx: &ExtCtxt<'_>, annotatable: Annotatable) -> Vec { + let mut visitor = CfgEval { + cfg: &mut StripUnconfigured { + sess: ecx.sess, + features: ecx.ecfg.features, + config_tokens: true, + }, + }; + let annotatable = visitor.configure_annotatable(annotatable); + vec![annotatable] +} + +struct CfgEval<'a, 'b> { + cfg: &'a mut StripUnconfigured<'b>, +} + +fn flat_map_annotatable(vis: &mut impl MutVisitor, annotatable: Annotatable) -> Annotatable { + // Since the item itself has already been configured by the InvocationCollector, + // we know that fold result vector will contain exactly one element + match annotatable { + Annotatable::Item(item) => Annotatable::Item(vis.flat_map_item(item).pop().unwrap()), + Annotatable::TraitItem(item) => { + Annotatable::TraitItem(vis.flat_map_trait_item(item).pop().unwrap()) + } + Annotatable::ImplItem(item) => { + Annotatable::ImplItem(vis.flat_map_impl_item(item).pop().unwrap()) + } + Annotatable::ForeignItem(item) => { + Annotatable::ForeignItem(vis.flat_map_foreign_item(item).pop().unwrap()) + } + Annotatable::Stmt(stmt) => { + Annotatable::Stmt(stmt.map(|stmt| vis.flat_map_stmt(stmt).pop().unwrap())) + } + Annotatable::Expr(mut expr) => Annotatable::Expr({ + vis.visit_expr(&mut expr); + expr + }), + Annotatable::Arm(arm) => Annotatable::Arm(vis.flat_map_arm(arm).pop().unwrap()), + Annotatable::ExprField(field) => { + Annotatable::ExprField(vis.flat_map_expr_field(field).pop().unwrap()) + } + Annotatable::PatField(fp) => { + Annotatable::PatField(vis.flat_map_pat_field(fp).pop().unwrap()) + } + Annotatable::GenericParam(param) => { + Annotatable::GenericParam(vis.flat_map_generic_param(param).pop().unwrap()) + } + Annotatable::Param(param) => Annotatable::Param(vis.flat_map_param(param).pop().unwrap()), + Annotatable::FieldDef(sf) => { + Annotatable::FieldDef(vis.flat_map_field_def(sf).pop().unwrap()) + } + Annotatable::Variant(v) => Annotatable::Variant(vis.flat_map_variant(v).pop().unwrap()), + } +} + +struct CfgFinder { + has_cfg_or_cfg_attr: bool, +} + +impl CfgFinder { + fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool { + let mut finder = CfgFinder { has_cfg_or_cfg_attr: false }; + match annotatable { + Annotatable::Item(item) => finder.visit_item(&item), + Annotatable::TraitItem(item) => finder.visit_assoc_item(&item, visit::AssocCtxt::Trait), + Annotatable::ImplItem(item) => finder.visit_assoc_item(&item, visit::AssocCtxt::Impl), + Annotatable::ForeignItem(item) => finder.visit_foreign_item(&item), + Annotatable::Stmt(stmt) => finder.visit_stmt(&stmt), + Annotatable::Expr(expr) => finder.visit_expr(&expr), + Annotatable::Arm(arm) => finder.visit_arm(&arm), + Annotatable::ExprField(field) => finder.visit_expr_field(&field), + Annotatable::PatField(field) => finder.visit_pat_field(&field), + Annotatable::GenericParam(param) => finder.visit_generic_param(¶m), + Annotatable::Param(param) => finder.visit_param(¶m), + Annotatable::FieldDef(field) => finder.visit_field_def(&field), + Annotatable::Variant(variant) => finder.visit_variant(&variant), + }; + finder.has_cfg_or_cfg_attr + } +} + +impl<'ast> visit::Visitor<'ast> for CfgFinder { + fn visit_attribute(&mut self, attr: &'ast Attribute) { + // We want short-circuiting behavior, so don't use the '|=' operator. + self.has_cfg_or_cfg_attr = self.has_cfg_or_cfg_attr + || attr + .ident() + .map_or(false, |ident| ident.name == sym::cfg || ident.name == sym::cfg_attr); + } +} + +impl CfgEval<'_, '_> { + fn configure(&mut self, node: T) -> Option { + self.cfg.configure(node) + } + + pub fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Annotatable { + // Tokenizing and re-parsing the `Annotatable` can have a significant + // performance impact, so try to avoid it if possible + if !CfgFinder::has_cfg_or_cfg_attr(&annotatable) { + return annotatable; + } + + // The majority of parsed attribute targets will never need to have early cfg-expansion + // run (e.g. they are not part of a `#[derive]` or `#[cfg_eval]` macro inoput). + // Therefore, we normally do not capture the necessary information about `#[cfg]` + // and `#[cfg_attr]` attributes during parsing. + // + // Therefore, when we actually *do* run early cfg-expansion, we need to tokenize + // and re-parse the attribute target, this time capturing information about + // the location of `#[cfg]` and `#[cfg_attr]` in the token stream. The tokenization + // process is lossless, so this process is invisible to proc-macros. + + // FIXME - get rid of this clone + let nt = annotatable.clone().into_nonterminal(); + + let mut orig_tokens = rustc_parse::nt_to_tokenstream( + &nt, + &self.cfg.sess.parse_sess, + CanSynthesizeMissingTokens::No, + ); + + // 'Flatten' all nonterminals (i.e. `TokenKind::Interpolated`) + // to `None`-delimited groups containing the corresponding tokens. This + // is normally delayed until the proc-macro server actually needs to + // provide a `TokenKind::Interpolated` to a proc-macro. We do this earlier, + // so that we can handle cases like: + // + // ```rust + // #[cfg_eval] #[cfg] $item + //``` + // + // where `$item` is `#[cfg_attr] struct Foo {}`. We want to make + // sure to evaluate *all* `#[cfg]` and `#[cfg_attr]` attributes - the simplest + // way to do this is to do a single parse of a stream without any nonterminals. + let mut flatten = FlattenNonterminals { + nt_to_tokenstream: rustc_parse::nt_to_tokenstream, + parse_sess: &self.cfg.sess.parse_sess, + synthesize_tokens: CanSynthesizeMissingTokens::No, + }; + orig_tokens = flatten.process_token_stream(orig_tokens); + + // Re-parse the tokens, setting the `capture_cfg` flag to save extra information + // to the captured `AttrAnnotatedTokenStream` (specifically, we capture + // `AttrAnnotatedTokenTree::AttributesData` for all occurences of `#[cfg]` and `#[cfg_attr]`) + let mut parser = + rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None); + parser.capture_cfg = true; + annotatable = match annotatable { + Annotatable::Item(_) => { + Annotatable::Item(parser.parse_item(ForceCollect::Yes).unwrap().unwrap()) + } + Annotatable::TraitItem(_) => Annotatable::TraitItem( + parser.parse_trait_item(ForceCollect::Yes).unwrap().unwrap().unwrap(), + ), + Annotatable::ImplItem(_) => Annotatable::ImplItem( + parser.parse_impl_item(ForceCollect::Yes).unwrap().unwrap().unwrap(), + ), + Annotatable::ForeignItem(_) => Annotatable::ForeignItem( + parser.parse_foreign_item(ForceCollect::Yes).unwrap().unwrap().unwrap(), + ), + Annotatable::Stmt(_) => { + Annotatable::Stmt(P(parser.parse_stmt(ForceCollect::Yes).unwrap().unwrap())) + } + Annotatable::Expr(_) => Annotatable::Expr(parser.parse_expr_force_collect().unwrap()), + _ => unreachable!(), + }; + + // Now that we have our re-parsed `AttrAnnotatedTokenStream`, recursively configuring + // our attribute target will correctly the tokens as well. + flat_map_annotatable(self, annotatable) + } +} + +impl MutVisitor for CfgEval<'_, '_> { + fn visit_expr(&mut self, expr: &mut P) { + self.cfg.configure_expr(expr); + mut_visit::noop_visit_expr(expr, self); + } + + fn filter_map_expr(&mut self, expr: P) -> Option> { + let mut expr = configure!(self, expr); + mut_visit::noop_visit_expr(&mut expr, self); + Some(expr) + } + + fn flat_map_generic_param( + &mut self, + param: ast::GenericParam, + ) -> SmallVec<[ast::GenericParam; 1]> { + mut_visit::noop_flat_map_generic_param(configure!(self, param), self) + } + + fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { + mut_visit::noop_flat_map_stmt(configure!(self, stmt), self) + } + + fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { + mut_visit::noop_flat_map_item(configure!(self, item), self) + } + + fn flat_map_impl_item(&mut self, item: P) -> SmallVec<[P; 1]> { + mut_visit::noop_flat_map_assoc_item(configure!(self, item), self) + } + + fn flat_map_trait_item(&mut self, item: P) -> SmallVec<[P; 1]> { + mut_visit::noop_flat_map_assoc_item(configure!(self, item), self) + } + + fn flat_map_foreign_item( + &mut self, + foreign_item: P, + ) -> SmallVec<[P; 1]> { + mut_visit::noop_flat_map_foreign_item(configure!(self, foreign_item), self) + } + + fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { + mut_visit::noop_flat_map_arm(configure!(self, arm), self) + } + + fn flat_map_expr_field(&mut self, field: ast::ExprField) -> SmallVec<[ast::ExprField; 1]> { + mut_visit::noop_flat_map_expr_field(configure!(self, field), self) + } + + fn flat_map_pat_field(&mut self, fp: ast::PatField) -> SmallVec<[ast::PatField; 1]> { + mut_visit::noop_flat_map_pat_field(configure!(self, fp), self) + } + + fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> { + mut_visit::noop_flat_map_param(configure!(self, p), self) + } + + fn flat_map_field_def(&mut self, sf: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> { + mut_visit::noop_flat_map_field_def(configure!(self, sf), self) + } + + fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> { + mut_visit::noop_flat_map_variant(configure!(self, variant), self) + } +} From b224261e977cd16fa164ff40e6a78096c229fc89 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 5 May 2021 22:27:28 +0300 Subject: [PATCH 2/3] [experiment] Eagerly expand `cfg` and `cfg_attr` in all attribute inputs --- compiler/rustc_builtin_macros/src/cfg_eval.rs | 3 +- compiler/rustc_builtin_macros/src/derive.rs | 3 +- compiler/rustc_expand/src/config.rs | 5 +- compiler/rustc_expand/src/expand.rs | 4 +- .../proc-macro/attribute-after-derive.stdout | 48 +- src/test/ui/proc-macro/auxiliary/attr-cfg.rs | 9 +- .../proc-macro/issue-75930-derive-cfg.stdout | 646 +----------------- 7 files changed, 27 insertions(+), 691 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 623bd2e8248f5..21ec2e697dc54 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -2,7 +2,6 @@ use crate::util::check_builtin_macro_attribute; use rustc_ast as ast; use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_expand::config::cfg_eval; use rustc_span::symbol::sym; use rustc_span::Span; @@ -13,5 +12,5 @@ crate fn expand( annotatable: Annotatable, ) -> Vec { check_builtin_macro_attribute(ecx, meta_item, sym::cfg_eval); - cfg_eval(ecx, annotatable) + vec![annotatable] } diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index 1c58e63242f81..dca920a335ca6 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -1,7 +1,6 @@ use rustc_ast::{self as ast, attr, token, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier}; -use rustc_expand::config::cfg_eval; use rustc_feature::AttributeTemplate; use rustc_parse::validate_attr; use rustc_session::Session; @@ -58,7 +57,7 @@ impl MultiItemModifier for Expander { }); match result { - Ok(()) => ExpandResult::Ready(cfg_eval(ecx, item)), + Ok(()) => ExpandResult::Ready(vec![item]), Err(Indeterminate) => ExpandResult::Retry(item), } } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index ebca5df525311..1b9b727af0db5 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -547,7 +547,7 @@ fn is_cfg(sess: &Session, attr: &Attribute) -> bool { sess.check_name(attr, sym::cfg) } -pub fn cfg_eval(ecx: &ExtCtxt<'_>, annotatable: Annotatable) -> Vec { +pub(crate) fn cfg_eval(ecx: &ExtCtxt<'_>, annotatable: Annotatable) -> Annotatable { let mut visitor = CfgEval { cfg: &mut StripUnconfigured { sess: ecx.sess, @@ -555,8 +555,7 @@ pub fn cfg_eval(ecx: &ExtCtxt<'_>, annotatable: Annotatable) -> Vec config_tokens: true, }, }; - let annotatable = visitor.configure_annotatable(annotatable); - vec![annotatable] + visitor.configure_annotatable(annotatable) } struct CfgEval<'a, 'b> { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index f5c6bb3db6542..cbabf05d9be85 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1,5 +1,5 @@ use crate::base::*; -use crate::config::StripUnconfigured; +use crate::config::{cfg_eval, StripUnconfigured}; use crate::configure; use crate::hygiene::SyntaxContext; use crate::mbe::macro_rules::annotate_err_with_kind; @@ -731,6 +731,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { (item_inner.ident.name.is_empty() || !matches!(mod_kind, ast::ModKind::Loaded(_, Inline::Yes, _))); } } + let item = cfg_eval(self.cx, item); let tokens = if fake_tokens { rustc_parse::fake_token_stream( &self.cx.sess.parse_sess, @@ -753,6 +754,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { SyntaxExtensionKind::LegacyAttr(expander) => { match validate_attr::parse_meta(&self.cx.sess.parse_sess, &attr) { Ok(meta) => { + let item = cfg_eval(self.cx, item); let items = match expander.expand(self.cx, span, &meta, item) { ExpandResult::Ready(items) => items, ExpandResult::Retry(item) => { diff --git a/src/test/ui/proc-macro/attribute-after-derive.stdout b/src/test/ui/proc-macro/attribute-after-derive.stdout index 4c48e41ff338b..baf5bf8b60b3a 100644 --- a/src/test/ui/proc-macro/attribute-after-derive.stdout +++ b/src/test/ui/proc-macro/attribute-after-derive.stdout @@ -1,4 +1,4 @@ -PRINT-ATTR INPUT (DISPLAY): #[derive(Print)] struct AttributeDerive { #[cfg(FALSE)] field : u8, } +PRINT-ATTR INPUT (DISPLAY): #[derive(Print)] struct AttributeDerive { } PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', @@ -35,51 +35,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ }, Group { delimiter: Brace, - stream: TokenStream [ - Punct { - ch: '#', - spacing: Alone, - span: $DIR/attribute-after-derive.rs:19:5: 19:6 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/attribute-after-derive.rs:19:7: 19:10 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/attribute-after-derive.rs:19:11: 19:16 (#0), - }, - ], - span: $DIR/attribute-after-derive.rs:19:10: 19:17 (#0), - }, - ], - span: $DIR/attribute-after-derive.rs:19:6: 19:18 (#0), - }, - Ident { - ident: "field", - span: $DIR/attribute-after-derive.rs:20:5: 20:10 (#0), - }, - Punct { - ch: ':', - spacing: Alone, - span: $DIR/attribute-after-derive.rs:20:10: 20:11 (#0), - }, - Ident { - ident: "u8", - span: $DIR/attribute-after-derive.rs:20:12: 20:14 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/attribute-after-derive.rs:20:14: 20:15 (#0), - }, - ], + stream: TokenStream [], span: $DIR/attribute-after-derive.rs:18:24: 21:2 (#0), }, ] diff --git a/src/test/ui/proc-macro/auxiliary/attr-cfg.rs b/src/test/ui/proc-macro/auxiliary/attr-cfg.rs index 2f0054cc14aa6..d46240f49e933 100644 --- a/src/test/ui/proc-macro/auxiliary/attr-cfg.rs +++ b/src/test/ui/proc-macro/auxiliary/attr-cfg.rs @@ -11,11 +11,10 @@ use proc_macro::TokenStream; pub fn attr_cfg(args: TokenStream, input: TokenStream) -> TokenStream { let input_str = input.to_string(); - assert_eq!(input_str, "fn outer() -> u8 -{ - #[cfg(foo)] fn inner() -> u8 { 1 } #[cfg(bar)] fn inner() -> u8 { 2 } - inner() -}"); + assert!( + input_str == "fn outer() -> u8 { #[cfg(foo)] fn inner() -> u8 { 1 } inner() }" + || input_str == "fn outer() -> u8 { #[cfg(bar)] fn inner() -> u8 { 2 } inner() }" + ); input } diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout index 81b2b219c4368..3270e891c1a4c 100644 --- a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout +++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout @@ -1,25 +1,15 @@ PRINT-ATTR INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[derive(Print)] #[print_helper(b)] -struct Foo < #[cfg(FALSE)] A, B > +struct Foo < B > { - #[cfg(FALSE)] first : String, #[cfg_attr(FALSE, deny(warnings))] second : - bool, third : + second : bool, third : [u8 ; { - #[cfg(FALSE)] struct Bar ; #[cfg(not(FALSE))] struct Inner ; - #[cfg(FALSE)] let a = 25 ; match true - { - #[cfg(FALSE)] true => { }, - #[cfg_attr(not(FALSE), allow(warnings))] false => { }, _ => { } - } ; #[print_helper(should_be_removed)] fn removed_fn() - { #! [cfg(FALSE)] } #[print_helper(c)] #[cfg(not(FALSE))] fn - kept_fn() { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum - { - Foo(#[cfg(FALSE)] u8, #[cfg(FALSE)] bool, #[cfg(not(FALSE))] i32, - #[cfg(FALSE)] String, u8) - } struct - TupleStruct(#[cfg(FALSE)] String, #[cfg(not(FALSE))] i32, - #[cfg(FALSE)] bool, u8) ; fn plain_removed_fn() - { #! [cfg_attr(not(FALSE), cfg(FALSE))] } 0 + #[cfg(not(FALSE))] struct Inner ; match true + { #[allow(warnings)] false => { }, _ => { } } ; #[print_helper(c)] + #[cfg(not(FALSE))] fn kept_fn() + { # ! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum + { Foo(#[cfg(not(FALSE))] i32, u8) } struct + TupleStruct(#[cfg(not(FALSE))] i32, u8) ; 0 }], #[print_helper(d)] fourth : B } PRINT-ATTR INPUT (DEBUG): TokenStream [ @@ -136,40 +126,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ spacing: Joint, span: $DIR/issue-75930-derive-cfg.rs:25:11: 25:12 (#0), }, - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:25:12: 25:13 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:25:14: 25:17 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:25:18: 25:23 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:25:17: 25:24 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:25:13: 25:25 (#0), - }, - Ident { - ident: "A", - span: $DIR/issue-75930-derive-cfg.rs:25:26: 25:27 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:25:27: 25:28 (#0), - }, Ident { ident: "B", span: $DIR/issue-75930-derive-cfg.rs:25:29: 25:30 (#0), @@ -182,93 +138,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Group { delimiter: Brace, stream: TokenStream [ - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:26:5: 26:6 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:26:7: 26:10 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:26:11: 26:16 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:26:10: 26:17 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:26:6: 26:18 (#0), - }, - Ident { - ident: "first", - span: $DIR/issue-75930-derive-cfg.rs:26:19: 26:24 (#0), - }, - Punct { - ch: ':', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:26:24: 26:25 (#0), - }, - Ident { - ident: "String", - span: $DIR/issue-75930-derive-cfg.rs:26:26: 26:32 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:26:32: 26:33 (#0), - }, - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:27:5: 27:6 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg_attr", - span: $DIR/issue-75930-derive-cfg.rs:27:7: 27:15 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:27:16: 27:21 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:27:21: 27:22 (#0), - }, - Ident { - ident: "deny", - span: $DIR/issue-75930-derive-cfg.rs:27:23: 27:27 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "warnings", - span: $DIR/issue-75930-derive-cfg.rs:27:28: 27:36 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:27:27: 27:37 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:27:15: 27:38 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:27:6: 27:39 (#0), - }, Ident { ident: "second", span: $DIR/issue-75930-derive-cfg.rs:27:40: 27:46 (#0), @@ -311,44 +180,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Group { delimiter: Brace, stream: TokenStream [ - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:29:9: 29:10 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:29:11: 29:14 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:29:15: 29:20 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:29:14: 29:21 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:29:10: 29:22 (#0), - }, - Ident { - ident: "struct", - span: $DIR/issue-75930-derive-cfg.rs:29:23: 29:29 (#0), - }, - Ident { - ident: "Bar", - span: $DIR/issue-75930-derive-cfg.rs:29:30: 29:33 (#0), - }, - Punct { - ch: ';', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:29:33: 29:34 (#0), - }, Punct { ch: '#', spacing: Alone, @@ -397,55 +228,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ spacing: Alone, span: $DIR/issue-75930-derive-cfg.rs:30:40: 30:41 (#0), }, - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:31:9: 31:10 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:31:11: 31:14 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:31:15: 31:20 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:31:14: 31:21 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:31:10: 31:22 (#0), - }, - Ident { - ident: "let", - span: $DIR/issue-75930-derive-cfg.rs:31:23: 31:26 (#0), - }, - Ident { - ident: "a", - span: $DIR/issue-75930-derive-cfg.rs:31:27: 31:28 (#0), - }, - Punct { - ch: '=', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:31:29: 31:30 (#0), - }, - Literal { - kind: Integer, - symbol: "25", - suffix: None, - span: $DIR/issue-75930-derive-cfg.rs:31:31: 31:33 (#0), - }, - Punct { - ch: ';', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:31:33: 31:34 (#0), - }, Ident { ident: "match", span: $DIR/issue-75930-derive-cfg.rs:32:9: 32:14 (#0), @@ -457,55 +239,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Group { delimiter: Brace, stream: TokenStream [ - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:33:13: 33:14 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:33:15: 33:18 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:33:19: 33:24 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:33:18: 33:25 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:33:14: 33:26 (#0), - }, - Ident { - ident: "true", - span: $DIR/issue-75930-derive-cfg.rs:33:27: 33:31 (#0), - }, - Punct { - ch: '=', - spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:33:32: 33:34 (#0), - }, - Punct { - ch: '>', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:33:32: 33:34 (#0), - }, - Group { - delimiter: Brace, - stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:33:35: 33:37 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:33:37: 33:38 (#0), - }, Punct { ch: '#', spacing: Alone, @@ -515,50 +248,21 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ delimiter: Bracket, stream: TokenStream [ Ident { - ident: "cfg_attr", - span: $DIR/issue-75930-derive-cfg.rs:34:15: 34:23 (#0), + ident: "allow", + span: $DIR/issue-75930-derive-cfg.rs:34:36: 34:41 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { - ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:34:24: 34:27 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:34:28: 34:33 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:34:27: 34:34 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:34: 34:35 (#0), - }, - Ident { - ident: "allow", - span: $DIR/issue-75930-derive-cfg.rs:34:36: 34:41 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "warnings", - span: $DIR/issue-75930-derive-cfg.rs:34:42: 34:50 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:34:41: 34:51 (#0), + ident: "warnings", + span: $DIR/issue-75930-derive-cfg.rs:34:42: 34:50 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:34:23: 34:52 (#0), + span: $DIR/issue-75930-derive-cfg.rs:34:41: 34:51 (#0), }, ], - span: $DIR/issue-75930-derive-cfg.rs:34:14: 34:53 (#0), + span: $DIR/issue-75930-derive-cfg.rs:34:13: 34:14 (#0), }, Ident { ident: "false", @@ -611,80 +315,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ spacing: Alone, span: $DIR/issue-75930-derive-cfg.rs:36:10: 36:11 (#0), }, - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:38:9: 38:10 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:38:11: 38:23 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "should_be_removed", - span: $DIR/issue-75930-derive-cfg.rs:38:24: 38:41 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:38:23: 38:42 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:38:10: 38:43 (#0), - }, - Ident { - ident: "fn", - span: $DIR/issue-75930-derive-cfg.rs:39:9: 39:11 (#0), - }, - Ident { - ident: "removed_fn", - span: $DIR/issue-75930-derive-cfg.rs:39:12: 39:22 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:39:22: 39:24 (#0), - }, - Group { - delimiter: Brace, - stream: TokenStream [ - Punct { - ch: '#', - spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:40:13: 40:14 (#0), - }, - Punct { - ch: '!', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:40:14: 40:15 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:40:16: 40:19 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:40:20: 40:25 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:40:19: 40:26 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:40:15: 40:27 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:39:25: 41:10 (#0), - }, Punct { ch: '#', spacing: Alone, @@ -844,74 +474,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Group { delimiter: Parenthesis, stream: TokenStream [ - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:50:17: 50:18 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:50:19: 50:22 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:50:23: 50:28 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:50:22: 50:29 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:50:18: 50:30 (#0), - }, - Ident { - ident: "u8", - span: $DIR/issue-75930-derive-cfg.rs:50:31: 50:33 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:50:33: 50:34 (#0), - }, - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:51:17: 51:18 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:51:19: 51:22 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:51:23: 51:28 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:51:22: 51:29 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:51:18: 51:30 (#0), - }, - Ident { - ident: "bool", - span: $DIR/issue-75930-derive-cfg.rs:51:31: 51:35 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:51:35: 51:36 (#0), - }, Punct { ch: '#', spacing: Alone, @@ -956,40 +518,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ spacing: Alone, span: $DIR/issue-75930-derive-cfg.rs:52:39: 52:40 (#0), }, - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:53:17: 53:18 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:53:19: 53:22 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:53:23: 53:28 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:53:22: 53:29 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:53:18: 53:30 (#0), - }, - Ident { - ident: "String", - span: $DIR/issue-75930-derive-cfg.rs:53:31: 53:37 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:53:37: 53:38 (#0), - }, Ident { ident: "u8", span: $DIR/issue-75930-derive-cfg.rs:53:39: 53:41 (#0), @@ -1011,40 +539,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Group { delimiter: Parenthesis, stream: TokenStream [ - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:58:13: 58:14 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:58:15: 58:18 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:58:19: 58:24 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:58:18: 58:25 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:58:14: 58:26 (#0), - }, - Ident { - ident: "String", - span: $DIR/issue-75930-derive-cfg.rs:58:27: 58:33 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:58:33: 58:34 (#0), - }, Punct { ch: '#', spacing: Alone, @@ -1089,40 +583,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ spacing: Alone, span: $DIR/issue-75930-derive-cfg.rs:59:35: 59:36 (#0), }, - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:60:13: 60:14 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:60:15: 60:18 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:60:19: 60:24 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:60:18: 60:25 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:60:14: 60:26 (#0), - }, - Ident { - ident: "bool", - span: $DIR/issue-75930-derive-cfg.rs:60:27: 60:31 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:60:31: 60:32 (#0), - }, Ident { ident: "u8", span: $DIR/issue-75930-derive-cfg.rs:61:13: 61:15 (#0), @@ -1135,84 +595,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ spacing: Alone, span: $DIR/issue-75930-derive-cfg.rs:62:10: 62:11 (#0), }, - Ident { - ident: "fn", - span: $DIR/issue-75930-derive-cfg.rs:64:9: 64:11 (#0), - }, - Ident { - ident: "plain_removed_fn", - span: $DIR/issue-75930-derive-cfg.rs:64:12: 64:28 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [], - span: $DIR/issue-75930-derive-cfg.rs:64:28: 64:30 (#0), - }, - Group { - delimiter: Brace, - stream: TokenStream [ - Punct { - ch: '#', - spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:65:13: 65:14 (#0), - }, - Punct { - ch: '!', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:65:14: 65:15 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "cfg_attr", - span: $DIR/issue-75930-derive-cfg.rs:65:16: 65:24 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "not", - span: $DIR/issue-75930-derive-cfg.rs:65:25: 65:28 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:65:29: 65:34 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:65:28: 65:35 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:65:35: 65:36 (#0), - }, - Ident { - ident: "cfg", - span: $DIR/issue-75930-derive-cfg.rs:65:37: 65:40 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/issue-75930-derive-cfg.rs:65:41: 65:46 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:65:40: 65:47 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:65:24: 65:48 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:65:15: 65:49 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:64:31: 66:10 (#0), - }, Literal { kind: Integer, symbol: "0", From f0dbe141eefe2c114784d2ddfb0405804ed4b7f9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 6 May 2021 16:21:40 +0300 Subject: [PATCH 3/3] parser: Ensure that all nonterminals have tokens after parsing --- compiler/rustc_ast/src/ast_like.rs | 3 +- .../rustc_parse/src/parser/attr_wrapper.rs | 10 +- compiler/rustc_parse/src/parser/expr.rs | 12 +-- compiler/rustc_parse/src/parser/mod.rs | 1 + .../rustc_parse/src/parser/nonterminal.rs | 17 ++- compiler/rustc_parse/src/parser/stmt.rs | 23 ++-- .../ui/macros/expr-stmt-nonterminal-tokens.rs | 15 +++ src/test/ui/proc-macro/cfg-eval.stdout | 17 ++- src/test/ui/proc-macro/inner-attrs.stderr | 33 +++++- src/test/ui/proc-macro/inner-attrs.stdout | 100 +++--------------- .../proc-macro/issue-75930-derive-cfg.stdout | 2 +- 11 files changed, 115 insertions(+), 118 deletions(-) create mode 100644 src/test/ui/macros/expr-stmt-nonterminal-tokens.rs diff --git a/compiler/rustc_ast/src/ast_like.rs b/compiler/rustc_ast/src/ast_like.rs index 945a44ab66371..d586426d70ef0 100644 --- a/compiler/rustc_ast/src/ast_like.rs +++ b/compiler/rustc_ast/src/ast_like.rs @@ -82,7 +82,8 @@ impl AstLike for crate::token::Nonterminal { Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(), Nonterminal::NtPath(path) => path.tokens_mut(), Nonterminal::NtVis(vis) => vis.tokens_mut(), - _ => panic!("Called tokens_mut on {:?}", self), + Nonterminal::NtBlock(block) => block.tokens_mut(), + Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) | Nonterminal::NtTT(..) => None, } } } diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 35759a396e87c..e1d0b84f4193f 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -342,16 +342,10 @@ impl<'a> Parser<'a> { // If we support tokens at all if let Some(target_tokens) = ret.tokens_mut() { - if let Some(target_tokens) = target_tokens { - assert!( - !self.capture_cfg, - "Encountered existing tokens with capture_cfg set: {:?}", - target_tokens - ); - } else { + if target_tokens.is_none() { // Store se our newly captured tokens into the AST node *target_tokens = Some(tokens.clone()); - }; + } } let final_attrs = ret.attrs(); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 56c97b5947682..a764cf6bdb04e 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -94,17 +94,7 @@ impl<'a> Parser<'a> { /// Parses an expression, forcing tokens to be collected pub fn parse_expr_force_collect(&mut self) -> PResult<'a, P> { - // If we have outer attributes, then the call to `collect_tokens_trailing_token` - // will be made for us. - if matches!(self.token.kind, TokenKind::Pound | TokenKind::DocComment(..)) { - self.parse_expr() - } else { - // If we don't have outer attributes, then we need to ensure - // that collection happens by using `collect_tokens_no_attrs`. - // Expression don't support custom inner attributes, so `parse_expr` - // will never try to collect tokens if we don't have outer attributes. - self.collect_tokens_no_attrs(|this| this.parse_expr()) - } + self.collect_tokens_no_attrs(|this| this.parse_expr()) } pub fn parse_anon_const_expr(&mut self) -> PResult<'a, AnonConst> { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 4c2bc6ebf3143..cd9f84db5e559 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -63,6 +63,7 @@ enum BlockMode { /// Whether or not we should force collection of tokens for an AST node, /// regardless of whether or not it has attributes +#[derive(Clone, Copy, PartialEq)] pub enum ForceCollect { Yes, No, diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 0c43e304f1ee2..30a6b61407f69 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -1,5 +1,6 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Nonterminal, NonterminalKind, Token}; +use rustc_ast::AstLike; use rustc_ast_pretty::pprust; use rustc_errors::PResult; use rustc_span::symbol::{kw, Ident}; @@ -102,7 +103,7 @@ impl<'a> Parser<'a> { // which requires having captured tokens available. Since we cannot determine // in advance whether or not a proc-macro will be (transitively) invoked, // we always capture tokens for any `Nonterminal` which needs them. - Ok(match kind { + let mut nt = match kind { NonterminalKind::Item => match self.parse_item(ForceCollect::Yes)? { Some(item) => token::NtItem(item), None => { @@ -169,7 +170,19 @@ impl<'a> Parser<'a> { return Err(self.struct_span_err(self.token.span, msg)); } } - }) + }; + + // If tokens are supported at all, they should be collected. + if matches!(nt.tokens_mut(), Some(None)) { + panic!( + "Missing tokens for nt {:?} at {:?}: {:?}", + nt, + nt.span(), + pprust::nonterminal_to_string(&nt) + ); + } + + Ok(nt) } } diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index b40eed8c5d118..4f0dcfeb5dae0 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -73,7 +73,11 @@ impl<'a> Parser<'a> { // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something // that starts like a path (1 token), but it fact not a path. // Also, we avoid stealing syntax from `parse_item_`. - self.parse_stmt_path_start(lo, attrs, force_collect)? + if force_collect == ForceCollect::Yes { + self.collect_tokens_no_attrs(|this| this.parse_stmt_path_start(lo, attrs)) + } else { + self.parse_stmt_path_start(lo, attrs) + }? } else if let Some(item) = self.parse_item_common(attrs.clone(), false, true, |_| true, force_collect)? { @@ -85,7 +89,13 @@ impl<'a> Parser<'a> { self.mk_stmt(lo, StmtKind::Empty) } else if self.token != token::CloseDelim(token::Brace) { // Remainder are line-expr stmts. - let e = self.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs))?; + let e = if force_collect == ForceCollect::Yes { + self.collect_tokens_no_attrs(|this| { + this.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs)) + }) + } else { + self.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs)) + }?; self.mk_stmt(lo.to(e.span), StmtKind::Expr(e)) } else { self.error_outer_attrs(&attrs.take_for_recovery()); @@ -93,13 +103,8 @@ impl<'a> Parser<'a> { })) } - fn parse_stmt_path_start( - &mut self, - lo: Span, - attrs: AttrWrapper, - force_collect: ForceCollect, - ) -> PResult<'a, Stmt> { - let stmt = self.collect_tokens_trailing_token(attrs, force_collect, |this, attrs| { + fn parse_stmt_path_start(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> { + let stmt = self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { let path = this.parse_path(PathStyle::Expr)?; if this.eat(&token::Not) { diff --git a/src/test/ui/macros/expr-stmt-nonterminal-tokens.rs b/src/test/ui/macros/expr-stmt-nonterminal-tokens.rs new file mode 100644 index 0000000000000..aa1624afef7d5 --- /dev/null +++ b/src/test/ui/macros/expr-stmt-nonterminal-tokens.rs @@ -0,0 +1,15 @@ +// check-pass + +macro_rules! mac { + (expr $expr:expr) => {}; + (stmt $stmt:stmt) => {}; +} + +fn main() { + mac!(expr #[allow(warnings)] 0); + mac!(stmt 0); + mac!(stmt {}); + mac!(stmt path); + mac!(stmt 0 + 1); + mac!(stmt path + 1); +} diff --git a/src/test/ui/proc-macro/cfg-eval.stdout b/src/test/ui/proc-macro/cfg-eval.stdout index 6732caf08dd76..f1b6df0f67cc4 100644 --- a/src/test/ui/proc-macro/cfg-eval.stdout +++ b/src/test/ui/proc-macro/cfg-eval.stdout @@ -83,8 +83,23 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ span: $DIR/cfg-eval.rs:17:11: 24:2 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] (#[cfg(all())] 1,) +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] #[rustc_dummy] (#[cfg(all())] 1,) PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/cfg-eval.rs:35:39: 35:40 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "rustc_dummy", + span: $DIR/cfg-eval.rs:35:62: 35:73 (#0), + }, + ], + span: $DIR/cfg-eval.rs:35:39: 35:40 (#0), + }, Punct { ch: '#', spacing: Alone, diff --git a/src/test/ui/proc-macro/inner-attrs.stderr b/src/test/ui/proc-macro/inner-attrs.stderr index 4da8751ef7fe9..560667a2bfd2a 100644 --- a/src/test/ui/proc-macro/inner-attrs.stderr +++ b/src/test/ui/proc-macro/inner-attrs.stderr @@ -22,5 +22,36 @@ error: expected non-macro inner attribute, found attribute macro `print_attr` LL | #![print_attr] | ^^^^^^^^^^ not a non-macro inner attribute -error: aborting due to 4 previous errors +error[E0308]: mismatched types + --> $DIR/inner-attrs.rs:48:43 + | +LL | #[print_target_and_args(tuple_attrs)] ( + | ___________________________________________^ +LL | | 3, 4, { +LL | | #![cfg_attr(not(FALSE), rustc_dummy(innermost))] +LL | | 5 +LL | | } +LL | | ); + | |_____^ expected `()`, found tuple + | + = note: expected unit type `()` + found tuple `({integer}, {integer}, {integer})` + +error[E0308]: mismatched types + --> $DIR/inner-attrs.rs:55:43 + | +LL | #[print_target_and_args(tuple_attrs)] ( + | ___________________________________________^ +LL | | 3, 4, { +LL | | #![cfg_attr(not(FALSE), rustc_dummy(innermost))] +LL | | 5 +LL | | } +LL | | ); + | |_____^ expected `()`, found tuple + | + = note: expected unit type `()` + found tuple `({integer}, {integer}, {integer})` + +error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/proc-macro/inner-attrs.stdout b/src/test/ui/proc-macro/inner-attrs.stdout index 9b7865be6220e..ce861aeeff6c7 100644 --- a/src/test/ui/proc-macro/inner-attrs.stdout +++ b/src/test/ui/proc-macro/inner-attrs.stdout @@ -705,7 +705,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ span: $DIR/inner-attrs.rs:48:29: 48:40 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ; +PRINT-ATTR INPUT (DISPLAY): (3, 4, { #! [rustc_dummy(innermost)] 5 }) PRINT-ATTR INPUT (DEBUG): TokenStream [ Group { delimiter: Parenthesis, @@ -737,7 +737,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ stream: TokenStream [ Punct { ch: '#', - spacing: Joint, + spacing: Alone, span: $DIR/inner-attrs.rs:50:13: 50:14 (#0), }, Punct { @@ -749,50 +749,21 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ delimiter: Bracket, stream: TokenStream [ Ident { - ident: "cfg_attr", - span: $DIR/inner-attrs.rs:50:16: 50:24 (#0), + ident: "rustc_dummy", + span: $DIR/inner-attrs.rs:50:37: 50:48 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { - ident: "not", - span: $DIR/inner-attrs.rs:50:25: 50:28 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/inner-attrs.rs:50:29: 50:34 (#0), - }, - ], - span: $DIR/inner-attrs.rs:50:28: 50:35 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/inner-attrs.rs:50:35: 50:36 (#0), - }, - Ident { - ident: "rustc_dummy", - span: $DIR/inner-attrs.rs:50:37: 50:48 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "innermost", - span: $DIR/inner-attrs.rs:50:49: 50:58 (#0), - }, - ], - span: $DIR/inner-attrs.rs:50:48: 50:59 (#0), + ident: "innermost", + span: $DIR/inner-attrs.rs:50:49: 50:58 (#0), }, ], - span: $DIR/inner-attrs.rs:50:24: 50:60 (#0), + span: $DIR/inner-attrs.rs:50:48: 50:59 (#0), }, ], - span: $DIR/inner-attrs.rs:50:15: 50:61 (#0), + span: $DIR/inner-attrs.rs:50:13: 50:14 (#0), }, Literal { kind: Integer, @@ -806,11 +777,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ ], span: $DIR/inner-attrs.rs:48:43: 53:6 (#0), }, - Punct { - ch: ';', - spacing: Alone, - span: $DIR/inner-attrs.rs:53:6: 53:7 (#0), - }, ] PRINT-ATTR_ARGS INPUT (DISPLAY): tuple_attrs PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ @@ -819,7 +785,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ span: $DIR/inner-attrs.rs:55:29: 55:40 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ; +PRINT-ATTR INPUT (DISPLAY): (3, 4, { #! [rustc_dummy(innermost)] 5 }) PRINT-ATTR INPUT (DEBUG): TokenStream [ Group { delimiter: Parenthesis, @@ -851,7 +817,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ stream: TokenStream [ Punct { ch: '#', - spacing: Joint, + spacing: Alone, span: $DIR/inner-attrs.rs:57:13: 57:14 (#0), }, Punct { @@ -863,50 +829,21 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ delimiter: Bracket, stream: TokenStream [ Ident { - ident: "cfg_attr", - span: $DIR/inner-attrs.rs:57:16: 57:24 (#0), + ident: "rustc_dummy", + span: $DIR/inner-attrs.rs:57:37: 57:48 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { - ident: "not", - span: $DIR/inner-attrs.rs:57:25: 57:28 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "FALSE", - span: $DIR/inner-attrs.rs:57:29: 57:34 (#0), - }, - ], - span: $DIR/inner-attrs.rs:57:28: 57:35 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/inner-attrs.rs:57:35: 57:36 (#0), - }, - Ident { - ident: "rustc_dummy", - span: $DIR/inner-attrs.rs:57:37: 57:48 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "innermost", - span: $DIR/inner-attrs.rs:57:49: 57:58 (#0), - }, - ], - span: $DIR/inner-attrs.rs:57:48: 57:59 (#0), + ident: "innermost", + span: $DIR/inner-attrs.rs:57:49: 57:58 (#0), }, ], - span: $DIR/inner-attrs.rs:57:24: 57:60 (#0), + span: $DIR/inner-attrs.rs:57:48: 57:59 (#0), }, ], - span: $DIR/inner-attrs.rs:57:15: 57:61 (#0), + span: $DIR/inner-attrs.rs:57:13: 57:14 (#0), }, Literal { kind: Integer, @@ -920,11 +857,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ ], span: $DIR/inner-attrs.rs:55:43: 60:6 (#0), }, - Punct { - ch: ';', - spacing: Alone, - span: $DIR/inner-attrs.rs:60:6: 60:7 (#0), - }, ] PRINT-ATTR_ARGS INPUT (DISPLAY): tenth PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout index 3270e891c1a4c..9b5d2ad36793d 100644 --- a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout +++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout @@ -7,7 +7,7 @@ struct Foo < B > #[cfg(not(FALSE))] struct Inner ; match true { #[allow(warnings)] false => { }, _ => { } } ; #[print_helper(c)] #[cfg(not(FALSE))] fn kept_fn() - { # ! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum + { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum { Foo(#[cfg(not(FALSE))] i32, u8) } struct TupleStruct(#[cfg(not(FALSE))] i32, u8) ; 0 }], #[print_helper(d)] fourth : B