mirror of
https://github.com/rust-lang/rust.git
synced 2026-08-10 00:31:27 -04:00
Replace "early parsed" terminology
AST attributes use "early parsed"/"parsed" terminology to refer to the
`CfgTrace` and `CfgAttrTrace` attributes. I think this terminology is
meant to echo the terminology used for HIR attributes, i.e.
`hir::Attribute::{Parsed,Unparsed}`, probably because
`hir::Attribute::Parsed` is used for attributes that aren't stored in a
token-based form.
But this naming is misleading. "Early parsed" attributes aren't parsed
at all because they are inserted by the compiler and cannot be written
in source code. There are also two comments that claim that these
attributes are kept in parsed form "so they don't have to be reparsed
every time they're used, for performance", which is simply incorrect.
This commit renames these as "synthetic" attributes, which better
reflects their nature. The commit also fixes the incorrect comments.
Note that `is_parsed_attribute` is unchanged, because it refers to the
HIR attribute meaning. (And the removal of the synthetic attributes from
it in the previous commit is now more obviously correct.)
This commit is contained in:
@@ -3418,13 +3418,11 @@ pub struct Attribute {
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
pub enum AttrKind {
|
||||
/// A normal (non-doc comment) attribute, with attributes in unparsed form.
|
||||
/// A normal attribute.
|
||||
Normal(Box<NormalAttr>),
|
||||
|
||||
/// A normal (non-doc comment) attribute, with attributes in parsed form, so they don't have to
|
||||
/// be reparsed every time they're used, for performance. Only used for a small number of
|
||||
/// attribute kinds.
|
||||
Parsed(Box<EarlyParsedAttribute>),
|
||||
/// A synthetic attribute inserted by the compiler.
|
||||
Synthetic(Box<SyntheticAttr>),
|
||||
|
||||
/// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
|
||||
/// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
|
||||
@@ -3460,29 +3458,29 @@ pub struct AttrItem {
|
||||
pub args: AttrArgs,
|
||||
}
|
||||
|
||||
/// Some attributes are stored in parsed form in the AST.
|
||||
/// This is done for performance reasons, so the attributes don't need to be reparsed on every use.
|
||||
/// Synthetic attributes are inserted by the compiler and cannot be written in source code. They
|
||||
/// receive special treatment in various ways because they must not affect observable behaviour:
|
||||
/// they are invisible to proc macros, cannot be pretty-printed, and are unable to re-enter the
|
||||
/// parser.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, StableHash)]
|
||||
pub enum EarlyParsedAttribute {
|
||||
/// This special attribute is added by the compiler when a `cfg` attribute is expanded so that
|
||||
pub enum SyntheticAttr {
|
||||
/// This synthetic attribute is added by the compiler when a `cfg` attribute is expanded so that
|
||||
/// subsequent code can tell that conditional compilation occurred. A `#[cfg(pred)]` with a
|
||||
/// true predicate is replaced by a synthetic `CfgTrace` attribute that records the parsed
|
||||
/// predicate. A `#[cfg(pred)]` with a false predicate leaves no trace because there is no node
|
||||
/// left to annotate.
|
||||
///
|
||||
/// The attribute is used for some diagnostics, by rustdoc (for detecting feature usage), and
|
||||
/// by some clippy lints. It is treated specially in various places because it must not be
|
||||
/// observable in any way that could change behaviour. For example, it is never pretty-printed
|
||||
/// and it is hidden from proc macros.
|
||||
/// by some clippy lints.
|
||||
CfgTrace(CfgEntry),
|
||||
|
||||
/// This special attribute is added by the compiler when a `cfg_attr` attribute is expanded so
|
||||
/// This synthetic attribute is added by the compiler when a `cfg_attr` attribute is expanded so
|
||||
/// that subsequent code can tell that conditional compilation occurred. A `#[cfg_attr(pred,
|
||||
/// attrs)]` is replaced by a synthetic `CfgAttrTrace` attribute whether the predicate
|
||||
/// evaluated true or not (or even failed to parse). The `pred` and `attrs` are not recorded
|
||||
/// because they are not needed.
|
||||
///
|
||||
/// In all other respects, it is the same as `CfgTrace`.
|
||||
/// The attribute is used by some clippy lints.
|
||||
CfgAttrTrace,
|
||||
}
|
||||
|
||||
|
||||
@@ -170,13 +170,13 @@ impl HasTokens for Attribute {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.tokens.as_ref(),
|
||||
AttrKind::Parsed(..) | AttrKind::DocComment(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) | AttrKind::DocComment(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
|
||||
Some(match &mut self.kind {
|
||||
AttrKind::Normal(normal) => &mut normal.tokens,
|
||||
AttrKind::Parsed(..) | AttrKind::DocComment(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) | AttrKind::DocComment(..) => unreachable!(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ use thin_vec::{ThinVec, thin_vec};
|
||||
|
||||
use crate::ast::{
|
||||
AttrArgs, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID, DelimArgs,
|
||||
EarlyParsedAttribute, Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind,
|
||||
MetaItemLit, NormalAttr, Path, PathSegment, Safety,
|
||||
Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NormalAttr, Path,
|
||||
PathSegment, Safety, SyntheticAttr,
|
||||
};
|
||||
use crate::token::{
|
||||
self, CommentKind, Delimiter, DocFragmentKind, InvisibleOrigin, MetaVarKind, Token,
|
||||
@@ -62,16 +62,16 @@ impl Attribute {
|
||||
pub fn get_normal_item(&self) -> &AttrItem {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => &normal.item,
|
||||
AttrKind::Parsed(..) | AttrKind::DocComment(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) | AttrKind::DocComment(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn convert_normal_to_parsed(&mut self, early_parsed_attribute: EarlyParsedAttribute) {
|
||||
pub fn convert_normal_to_synthetic(&mut self, synthetic_attr: SyntheticAttr) {
|
||||
match self.kind {
|
||||
AttrKind::Normal(..) => {
|
||||
self.kind = AttrKind::Parsed(Box::new(early_parsed_attribute));
|
||||
self.kind = AttrKind::Synthetic(Box::new(synthetic_attr));
|
||||
}
|
||||
AttrKind::Parsed(..) | AttrKind::DocComment(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) | AttrKind::DocComment(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ impl AttributeExt for Attribute {
|
||||
AttrArgs::Eq { expr, .. } => Some(expr.span),
|
||||
_ => None,
|
||||
},
|
||||
AttrKind::Parsed(..) | AttrKind::DocComment(..) => None,
|
||||
AttrKind::Synthetic(..) | AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,28 +96,28 @@ impl AttributeExt for Attribute {
|
||||
/// a doc comment) will return `false`.
|
||||
fn is_doc_comment(&self) -> Option<Span> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(..) | AttrKind::Parsed(..) => None,
|
||||
AttrKind::Normal(..) | AttrKind::Synthetic(..) => None,
|
||||
AttrKind::DocComment(..) => Some(self.span),
|
||||
}
|
||||
}
|
||||
|
||||
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
|
||||
fn name(&self) -> Option<Symbol> {
|
||||
use EarlyParsedAttribute::*;
|
||||
use SyntheticAttr::*;
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.item.name(),
|
||||
AttrKind::Parsed(CfgTrace(_) | CfgAttrTrace) => None,
|
||||
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => None,
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn symbol_path(&self) -> Option<SmallVec<[Symbol; 1]>> {
|
||||
use EarlyParsedAttribute::*;
|
||||
use SyntheticAttr::*;
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => {
|
||||
Some(normal.item.path.segments.iter().map(|i| i.ident.name).collect())
|
||||
}
|
||||
AttrKind::Parsed(CfgTrace(_) | CfgAttrTrace) => None,
|
||||
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => None,
|
||||
AttrKind::DocComment(_, _) => None,
|
||||
}
|
||||
}
|
||||
@@ -125,7 +125,7 @@ impl AttributeExt for Attribute {
|
||||
fn path_span(&self) -> Option<Span> {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(attr) => Some(attr.item.path.span),
|
||||
AttrKind::Parsed(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) => unreachable!(),
|
||||
AttrKind::DocComment(_, _) => None,
|
||||
}
|
||||
}
|
||||
@@ -142,7 +142,7 @@ impl AttributeExt for Attribute {
|
||||
.zip(name)
|
||||
.all(|(s, n)| s.args.is_none() && s.ident.name == *n)
|
||||
}
|
||||
AttrKind::Parsed(..) => false,
|
||||
AttrKind::Synthetic(..) => false,
|
||||
AttrKind::DocComment(..) => false,
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ impl AttributeExt for Attribute {
|
||||
fn is_word(&self) -> bool {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => matches!(normal.item.args, AttrArgs::Empty),
|
||||
AttrKind::Parsed(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) => unreachable!(),
|
||||
AttrKind::DocComment(..) => false,
|
||||
}
|
||||
}
|
||||
@@ -169,7 +169,7 @@ impl AttributeExt for Attribute {
|
||||
fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.item.meta_item_list(),
|
||||
AttrKind::Parsed(..) => None,
|
||||
AttrKind::Synthetic(..) => None,
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
@@ -192,7 +192,7 @@ impl AttributeExt for Attribute {
|
||||
fn value_str(&self) -> Option<Symbol> {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.item.value_str(),
|
||||
AttrKind::Parsed(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) => unreachable!(),
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
@@ -212,7 +212,7 @@ impl AttributeExt for Attribute {
|
||||
{
|
||||
Some((value, DocFragmentKind::Raw(value_span)))
|
||||
}
|
||||
AttrKind::Normal(..) | AttrKind::Parsed(..) => None,
|
||||
AttrKind::Normal(..) | AttrKind::Synthetic(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ impl Attribute {
|
||||
pub fn meta(&self) -> Option<MetaItem> {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.item.meta(self.span),
|
||||
AttrKind::Parsed(..) => None,
|
||||
AttrKind::Synthetic(..) => None,
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
@@ -289,7 +289,7 @@ impl Attribute {
|
||||
pub fn meta_kind(&self) -> Option<MetaItemKind> {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.item.meta_kind(),
|
||||
AttrKind::Parsed(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) => unreachable!(),
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
@@ -302,7 +302,7 @@ impl Attribute {
|
||||
.unwrap_or_else(|| panic!("attribute is missing tokens: {self:?}"))
|
||||
.to_attr_token_stream()
|
||||
.to_token_trees(),
|
||||
AttrKind::Parsed(..) => vec![],
|
||||
AttrKind::Synthetic(..) => vec![],
|
||||
AttrKind::DocComment(comment_kind, data) => vec![TokenTree::token_alone(
|
||||
token::DocComment(comment_kind, self.style, data),
|
||||
self.span,
|
||||
|
||||
@@ -365,7 +365,6 @@ macro_rules! common_visitor_and_walkers {
|
||||
crate::token::LitKind,
|
||||
crate::tokenstream::LazyAttrTokenStream,
|
||||
crate::tokenstream::TokenStream,
|
||||
EarlyParsedAttribute,
|
||||
Movability,
|
||||
Mutability,
|
||||
Pinnedness,
|
||||
@@ -374,6 +373,7 @@ macro_rules! common_visitor_and_walkers {
|
||||
rustc_span::ErrorGuaranteed,
|
||||
std::borrow::Cow<'_, str>,
|
||||
Symbol,
|
||||
SyntheticAttr,
|
||||
u8,
|
||||
usize,
|
||||
);
|
||||
|
||||
@@ -514,7 +514,7 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
|
||||
fn check_decl_attrs(&self, fn_decl: &FnDecl) {
|
||||
use EarlyParsedAttribute::*;
|
||||
use SyntheticAttr::*;
|
||||
fn_decl
|
||||
.inputs
|
||||
.iter()
|
||||
@@ -525,7 +525,7 @@ impl<'a> AstValidator<'a> {
|
||||
[sym::allow, sym::deny, sym::expect, sym::forbid, sym::splat, sym::warn];
|
||||
!attr.has_any_name(&arr) && rustc_attr_parsing::is_builtin_attr(&normal.item)
|
||||
}
|
||||
AttrKind::Parsed(CfgTrace(_) | CfgAttrTrace) => false,
|
||||
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => false,
|
||||
AttrKind::DocComment(..) => true,
|
||||
})
|
||||
.for_each(|attr| {
|
||||
|
||||
@@ -670,9 +670,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
}
|
||||
|
||||
fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) -> bool {
|
||||
use ast::EarlyParsedAttribute::*;
|
||||
use ast::SyntheticAttr::*;
|
||||
match attr.kind {
|
||||
AttrKind::Parsed(CfgTrace(_) | CfgAttrTrace) => {
|
||||
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => {
|
||||
// These are internal synthetic attributes with no syntax, so avoid printing them
|
||||
// to keep the printed code reasonably parse-able.
|
||||
return false;
|
||||
@@ -692,7 +692,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
self.print_attr_item(&normal.item, attr.span);
|
||||
self.word("]");
|
||||
}
|
||||
ast::AttrKind::Parsed(..) => unreachable!(), // due to early return above
|
||||
ast::AttrKind::Synthetic(..) => unreachable!(), // due to early return above
|
||||
ast::AttrKind::DocComment(comment_kind, data) => {
|
||||
self.word(doc_comment_to_string(
|
||||
DocFragmentKind::Sugared(*comment_kind),
|
||||
|
||||
@@ -20,9 +20,9 @@ use crate::attributes::AttributeSafety;
|
||||
use crate::context::{
|
||||
ATTRIBUTE_PARSERS, AcceptContext, FinalizeContext, FinalizeFn, SharedContext,
|
||||
};
|
||||
use crate::early_parsed::EarlyParsedState;
|
||||
use crate::parser::{AllowExprMetavar, ArgParser, PathParser, RefPathParser};
|
||||
use crate::session_diagnostics::ParsedDescription;
|
||||
use crate::synthetic::SyntheticAttrState;
|
||||
use crate::{AttributeTemplate, OmitDoc, ShouldEmit};
|
||||
|
||||
pub struct EmitAttribute(
|
||||
@@ -290,7 +290,7 @@ impl<'sess> AttributeParser<'sess> {
|
||||
) -> Vec<Attribute> {
|
||||
let mut attributes = Vec::new();
|
||||
let mut attr_paths: Vec<RefPathParser<'_>> = Vec::new();
|
||||
let mut early_parsed_state = EarlyParsedState::default();
|
||||
let mut synthetic_attr_state = SyntheticAttrState::default();
|
||||
|
||||
let mut finalizers: Vec<FinalizeFn> = Vec::with_capacity(attrs.len());
|
||||
|
||||
@@ -326,8 +326,8 @@ impl<'sess> AttributeParser<'sess> {
|
||||
comment: *symbol,
|
||||
}));
|
||||
}
|
||||
ast::AttrKind::Parsed(parsed) => {
|
||||
early_parsed_state.accept_early_parsed_attribute(attr_span, lower_span, parsed);
|
||||
ast::AttrKind::Synthetic(synthetic) => {
|
||||
synthetic_attr_state.accept_synthetic_attr(attr_span, lower_span, synthetic);
|
||||
continue;
|
||||
}
|
||||
ast::AttrKind::Normal(n) => {
|
||||
@@ -448,7 +448,7 @@ impl<'sess> AttributeParser<'sess> {
|
||||
}
|
||||
}
|
||||
|
||||
early_parsed_state.finalize_early_parsed_attributes(&mut attributes);
|
||||
synthetic_attr_state.finalize_synthetic_attrs(&mut attributes);
|
||||
for f in &finalizers {
|
||||
if let Some(attr) = f(&mut FinalizeContext {
|
||||
shared: SharedContext {
|
||||
@@ -497,7 +497,8 @@ impl<'sess> AttributeParser<'sess> {
|
||||
/// The list of attributes that are parsed attributes,
|
||||
/// even though they don't have a parser in `Late::parsers()`
|
||||
const SPECIAL_ATTRIBUTES: &[&[Symbol]] = &[
|
||||
// Cfg attrs are removed after being early-parsed, so don't need to be in the parser list
|
||||
// Cfg attrs are removed after being converted into synthetic attrs and don't need to
|
||||
// be in the parser list.
|
||||
&[sym::cfg],
|
||||
&[sym::cfg_attr],
|
||||
];
|
||||
|
||||
@@ -99,12 +99,12 @@ mod attributes;
|
||||
mod check_cfg;
|
||||
mod context;
|
||||
mod diagnostics;
|
||||
mod early_parsed;
|
||||
mod interface;
|
||||
pub mod parser;
|
||||
mod safety;
|
||||
mod session_diagnostics;
|
||||
mod stability;
|
||||
mod synthetic;
|
||||
mod target_checking;
|
||||
mod template;
|
||||
pub mod validate_attr;
|
||||
|
||||
+15
-15
@@ -1,45 +1,45 @@
|
||||
use rustc_ast::EarlyParsedAttribute;
|
||||
use rustc_ast::SyntheticAttr;
|
||||
use rustc_ast::attr::data_structures::CfgEntry;
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_span::Span;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
/// This struct contains the state necessary to convert early parsed attributes to hir attributes
|
||||
/// The only conversion that really happens here is that multiple early parsed attributes are
|
||||
/// This struct contains the state necessary to convert synthetic attributes to hir attributes
|
||||
/// The only conversion that really happens here is that multiple synthetic attributes are
|
||||
/// merged into a single hir attribute, representing their combined state.
|
||||
/// FIXME: We should make this a nice and extendable system if this is going to be used more often
|
||||
#[derive(Default)]
|
||||
pub(crate) struct EarlyParsedState {
|
||||
/// Attribute state for `#[cfg]` trace attributes
|
||||
pub(crate) struct SyntheticAttrState {
|
||||
/// Attribute state for `SyntheticAttr::CfgTrace` attributes.
|
||||
cfg_trace: ThinVec<(CfgEntry, Span)>,
|
||||
|
||||
/// Attribute state for `#[cfg_attr]` trace attributes
|
||||
/// The arguments of these attributes is no longer relevant for any later passes, only their presence.
|
||||
/// So we discard the arguments here.
|
||||
/// Attribute state for `SyntheticAttr::CfgAttrTrace` attributes.
|
||||
/// The arguments of these attributes is no longer relevant for any later passes, only their
|
||||
/// presence. So we discard the arguments here.
|
||||
cfg_attr_trace: bool,
|
||||
}
|
||||
|
||||
impl EarlyParsedState {
|
||||
pub(crate) fn accept_early_parsed_attribute(
|
||||
impl SyntheticAttrState {
|
||||
pub(crate) fn accept_synthetic_attr(
|
||||
&mut self,
|
||||
attr_span: Span,
|
||||
lower_span: impl Copy + Fn(Span) -> Span,
|
||||
parsed: &EarlyParsedAttribute,
|
||||
synthetic: &SyntheticAttr,
|
||||
) {
|
||||
match parsed {
|
||||
EarlyParsedAttribute::CfgTrace(cfg) => {
|
||||
match synthetic {
|
||||
SyntheticAttr::CfgTrace(cfg) => {
|
||||
let mut cfg = cfg.clone();
|
||||
cfg.lower_spans(lower_span);
|
||||
self.cfg_trace.push((cfg, attr_span));
|
||||
}
|
||||
EarlyParsedAttribute::CfgAttrTrace => {
|
||||
SyntheticAttr::CfgAttrTrace => {
|
||||
self.cfg_attr_trace = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn finalize_early_parsed_attributes(self, attributes: &mut Vec<Attribute>) {
|
||||
pub(crate) fn finalize_synthetic_attrs(self, attributes: &mut Vec<Attribute>) {
|
||||
if !self.cfg_trace.is_empty() {
|
||||
attributes.push(Attribute::Parsed(AttributeKind::CfgTrace(self.cfg_trace)));
|
||||
}
|
||||
@@ -21,10 +21,10 @@ use rustc_span::{Span, Symbol, sym};
|
||||
use crate::{AttributeParser, AttributeTemplate, session_diagnostics as errors, template};
|
||||
|
||||
pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
|
||||
use ast::EarlyParsedAttribute::*;
|
||||
use ast::SyntheticAttr::*;
|
||||
match &attr.kind {
|
||||
AttrKind::Normal(_) => {}
|
||||
AttrKind::Parsed(CfgTrace(_) | CfgAttrTrace) => return,
|
||||
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => return,
|
||||
AttrKind::DocComment(..) => return,
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ use rustc_ast::tokenstream::{
|
||||
AttrTokenStream, AttrTokenTree, LazyAttrTokenStream, Spacing, TokenTree, WithTokens,
|
||||
};
|
||||
use rustc_ast::{
|
||||
self as ast, AttrStyle, Attribute, EarlyParsedAttribute, HasAttrs, HasTokens, MetaItem,
|
||||
MetaItemInner, NodeId,
|
||||
self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner, NodeId,
|
||||
SyntheticAttr,
|
||||
};
|
||||
use rustc_attr_parsing::parser::AllowExprMetavar;
|
||||
use rustc_attr_parsing::{
|
||||
@@ -248,10 +248,10 @@ impl<'a> StripUnconfigured<'a> {
|
||||
/// is in the original source file. Gives a compiler error if the syntax of
|
||||
/// the attribute is incorrect.
|
||||
pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec<Attribute> {
|
||||
// A trace attribute left in AST in place of the original `cfg_attr` attribute.
|
||||
// A synthetic trace attribute left in AST in place of the original `cfg_attr` attribute.
|
||||
// It can later be used by lints or other diagnostics.
|
||||
let mut trace_attr = cfg_attr.clone();
|
||||
trace_attr.convert_normal_to_parsed(EarlyParsedAttribute::CfgAttrTrace);
|
||||
trace_attr.convert_normal_to_synthetic(SyntheticAttr::CfgAttrTrace);
|
||||
|
||||
let Some((cfg_predicate, expanded_attrs)) = rustc_attr_parsing::parse_cfg_attr(
|
||||
cfg_attr,
|
||||
|
||||
@@ -8,9 +8,9 @@ use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::visit::{AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
|
||||
use rustc_ast::{
|
||||
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrKind, AttrStyle, AttrVec,
|
||||
DUMMY_NODE_ID, DelegationSource, DelegationSuffixes, EarlyParsedAttribute, ExprKind,
|
||||
ForeignItemKind, HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner,
|
||||
MetaItemKind, ModKind, NodeId, PatKind, StmtKind, TyKind, token,
|
||||
DUMMY_NODE_ID, DelegationSource, DelegationSuffixes, ExprKind, ForeignItemKind, HasAttrs,
|
||||
HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId,
|
||||
PatKind, StmtKind, SyntheticAttr, TyKind, token,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_attr_parsing::parser::AllowExprMetavar;
|
||||
@@ -2209,7 +2209,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||
// Detect use of feature-gated or invalid attributes on macro invocations
|
||||
// since they will not be detected after macro expansion.
|
||||
fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
|
||||
use EarlyParsedAttribute::*;
|
||||
use SyntheticAttr::*;
|
||||
let features = self.cx.ecfg.features;
|
||||
let mut attrs = attrs.iter().peekable();
|
||||
let mut span: Option<Span> = None;
|
||||
@@ -2264,7 +2264,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||
);
|
||||
}
|
||||
AttrKind::Normal(_) => {}
|
||||
AttrKind::Parsed(CfgTrace(_) | CfgAttrTrace) => {}
|
||||
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => {}
|
||||
AttrKind::DocComment(..) => unreachable!(), // handled above
|
||||
}
|
||||
}
|
||||
@@ -2295,10 +2295,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||
|
||||
let res = eval_config_entry(self.cfg().sess, &cfg);
|
||||
if res.as_bool() {
|
||||
// A trace attribute left in AST in place of the original `cfg` attribute.
|
||||
// A synthetic trace attribute left in AST in place of the original `cfg` attribute.
|
||||
// It can later be used by lints or other diagnostics.
|
||||
let mut trace_attr = attr;
|
||||
trace_attr.convert_normal_to_parsed(EarlyParsedAttribute::CfgTrace(cfg));
|
||||
trace_attr.convert_normal_to_synthetic(SyntheticAttr::CfgTrace(cfg));
|
||||
node.visit_attrs(|attrs| attrs.insert(pos, trace_attr));
|
||||
}
|
||||
|
||||
|
||||
@@ -776,7 +776,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
|
||||
AttrKind::DocComment(CommentKind::Block, _) => {
|
||||
BuiltinUnusedDocCommentSub::BlockHelp
|
||||
}
|
||||
AttrKind::Parsed(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) => unreachable!(),
|
||||
};
|
||||
cx.emit_span_lint(
|
||||
UNUSED_DOC_COMMENTS,
|
||||
|
||||
@@ -403,9 +403,9 @@ fn needs_tokens(attrs: &[ast::Attribute]) -> bool {
|
||||
Some(name) => name == sym::cfg_attr || !rustc_feature::is_builtin_attr_name(name),
|
||||
}
|
||||
}
|
||||
// These attributes are created only during expansion, and can't re-enter the parser
|
||||
// Synthetic attributes are created only during expansion, and can't re-enter the parser
|
||||
// because they have no token form.
|
||||
AttrKind::Parsed(_) => unreachable!(),
|
||||
AttrKind::Synthetic(_) => unreachable!(),
|
||||
AttrKind::DocComment(..) => false,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ impl<'a> Parser<'a> {
|
||||
for attr in attrs.take_for_recovery(self.psess) {
|
||||
match attr.kind {
|
||||
AttrKind::Normal(..) => spans.attrs.push(attr.span),
|
||||
AttrKind::Parsed(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) => unreachable!(),
|
||||
// `parse_outer_attributes` already emitted E0753 for inner doc comments before
|
||||
// recovering them as outer doc-comment attributes.
|
||||
AttrKind::DocComment(comment_kind, _)
|
||||
|
||||
@@ -773,7 +773,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
|
||||
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
|
||||
record_variants!(
|
||||
(self, attr, attr.kind, None, ast, Attribute, AttrKind),
|
||||
[Normal, Parsed, DocComment]
|
||||
[Normal, Synthetic, DocComment]
|
||||
);
|
||||
ast_visit::walk_attribute(self, attr)
|
||||
}
|
||||
|
||||
@@ -557,7 +557,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_attribute(&mut self, attr: &'a Attribute) {
|
||||
use EarlyParsedAttribute::*;
|
||||
use SyntheticAttr::*;
|
||||
let orig_in_attr = mem::replace(&mut self.invocation_parent.in_attr, true);
|
||||
match &attr.kind {
|
||||
AttrKind::Normal(normal) => {
|
||||
@@ -567,7 +567,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
|
||||
.push((normal.item.path.segments[0].ident, self.parent_scope));
|
||||
}
|
||||
}
|
||||
AttrKind::Parsed(CfgTrace(_) | CfgAttrTrace) => {}
|
||||
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => {}
|
||||
AttrKind::DocComment(..) => {}
|
||||
}
|
||||
visit::walk_attribute(self, attr);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::MIXED_ATTRIBUTES_STYLE;
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_ast::{AttrKind, AttrStyle, Attribute, EarlyParsedAttribute};
|
||||
use rustc_ast::{AttrKind, AttrStyle, Attribute, SyntheticAttr};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_lint::{EarlyContext, LintContext};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
@@ -29,10 +29,10 @@ impl From<&AttrKind> for SimpleAttrKind {
|
||||
.collect::<Vec<_>>();
|
||||
Self::Normal(path_symbols)
|
||||
},
|
||||
AttrKind::Parsed(parsed) => {
|
||||
match &**parsed {
|
||||
EarlyParsedAttribute::CfgTrace(_) => Self::CfgTrace,
|
||||
EarlyParsedAttribute::CfgAttrTrace => Self::CfgAttrTrace,
|
||||
AttrKind::Synthetic(synthetic) => {
|
||||
match &**synthetic {
|
||||
SyntheticAttr::CfgTrace(_) => Self::CfgTrace,
|
||||
SyntheticAttr::CfgAttrTrace => Self::CfgAttrTrace,
|
||||
}
|
||||
}
|
||||
AttrKind::DocComment(..) => Self::Doc,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use rustc_ast::attr::data_structures::CfgEntry;
|
||||
use rustc_ast::{AttrKind, EarlyParsedAttribute};
|
||||
use rustc_ast::{AttrKind, SyntheticAttr};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::sym;
|
||||
@@ -34,8 +34,8 @@ declare_lint_pass!(CfgNotTest => [CFG_NOT_TEST]);
|
||||
|
||||
impl EarlyLintPass for CfgNotTest {
|
||||
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &rustc_ast::Attribute) {
|
||||
if let AttrKind::Parsed(parsed) = &attr.kind
|
||||
&& let EarlyParsedAttribute::CfgTrace(cfg) = &**parsed
|
||||
if let AttrKind::Synthetic(synthetic) = &attr.kind
|
||||
&& let SyntheticAttr::CfgTrace(cfg) = &**synthetic
|
||||
&& contains_not_test(cfg, false)
|
||||
{
|
||||
span_lint_and_then(
|
||||
|
||||
@@ -251,7 +251,7 @@ impl Stop {
|
||||
Some(Self {
|
||||
span: attr.span,
|
||||
kind: match attr.kind {
|
||||
AttrKind::Normal(_) | AttrKind::Parsed(_) => StopKind::Attr,
|
||||
AttrKind::Normal(_) | AttrKind::Synthetic(_) => StopKind::Attr,
|
||||
AttrKind::DocComment(comment_kind, _) => StopKind::Doc(comment_kind),
|
||||
},
|
||||
first: file.lookup_line(file.relative_position(lo))?,
|
||||
|
||||
@@ -1006,7 +1006,7 @@ fn eq_attr(l: &Attribute, r: &Attribute) -> bool {
|
||||
(Normal(l), Normal(r)) => {
|
||||
eq_path(&l.item.path, &r.item.path) && eq_attr_args(&l.item.args, &r.item.args)
|
||||
},
|
||||
(Parsed(..), _) | (_, Parsed(..)) => unreachable!(),
|
||||
(Synthetic(..), _) | (_, Synthetic(..)) => unreachable!(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -1035,8 +1035,8 @@ pub fn is_cfg_test(item: &impl HasAttrs) -> bool {
|
||||
&& item_list.iter().any(|item| item.has_name(sym::test))
|
||||
{
|
||||
true
|
||||
} else if let AttrKind::Parsed(parsed) = &attr.kind
|
||||
&& let EarlyParsedAttribute::CfgTrace(cfg) = &**parsed
|
||||
} else if let AttrKind::Synthetic(synthetic) = &attr.kind
|
||||
&& let SyntheticAttr::CfgTrace(cfg) = &**synthetic
|
||||
{
|
||||
requires_test_cfg(cfg)
|
||||
} else {
|
||||
|
||||
@@ -369,7 +369,7 @@ fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) {
|
||||
(Pat::Str("#"), Pat::Str("]"))
|
||||
}
|
||||
},
|
||||
AttrKind::Parsed(..) => unreachable!(),
|
||||
AttrKind::Synthetic(..) => unreachable!(),
|
||||
AttrKind::DocComment(_kind @ CommentKind::Line, ..) => {
|
||||
if attr.style == AttrStyle::Outer {
|
||||
(Pat::Str("///"), Pat::Str(""))
|
||||
|
||||
@@ -43,7 +43,7 @@ ast-stats Param 160 (NN.N%) 4 40
|
||||
ast-stats Block 144 (NN.N%) 6 24
|
||||
ast-stats Attribute 128 (NN.N%) 4 32
|
||||
ast-stats - DocComment 32 (NN.N%) 1
|
||||
ast-stats - Parsed 32 (NN.N%) 1
|
||||
ast-stats - Synthetic 32 (NN.N%) 1
|
||||
ast-stats - Normal 64 (NN.N%) 2
|
||||
ast-stats InlineAsm 120 (NN.N%) 1 120
|
||||
ast-stats FnDecl 120 (NN.N%) 5 24
|
||||
|
||||
Reference in New Issue
Block a user