Make cfg and cfg_attr trace attributes into early parsed attributes
This commit is contained in:
parent
03fb7eeced
commit
5590fc034c
15 changed files with 247 additions and 143 deletions
|
|
@ -7,8 +7,8 @@ use rustc_ast::tokenstream::{
|
|||
AttrTokenStream, AttrTokenTree, LazyAttrTokenStream, Spacing, TokenTree,
|
||||
};
|
||||
use rustc_ast::{
|
||||
self as ast, AttrKind, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner,
|
||||
NodeId, NormalAttr,
|
||||
self as ast, AttrItemKind, AttrKind, AttrStyle, Attribute, EarlyParsedAttribute, HasAttrs,
|
||||
HasTokens, MetaItem, MetaItemInner, NodeId, NormalAttr,
|
||||
};
|
||||
use rustc_attr_parsing as attr;
|
||||
use rustc_attr_parsing::{
|
||||
|
|
@ -288,7 +288,9 @@ impl<'a> StripUnconfigured<'a> {
|
|||
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.
|
||||
// It can later be used by lints or other diagnostics.
|
||||
let trace_attr = attr_into_trace(cfg_attr.clone(), sym::cfg_attr_trace);
|
||||
let mut trace_attr = cfg_attr.clone();
|
||||
trace_attr.replace_args(AttrItemKind::Parsed(EarlyParsedAttribute::CfgAttrTrace));
|
||||
let trace_attr = attr_into_trace(trace_attr, sym::cfg_attr_trace);
|
||||
|
||||
let Some((cfg_predicate, expanded_attrs)) =
|
||||
rustc_attr_parsing::parse_cfg_attr(cfg_attr, &self.sess, self.features)
|
||||
|
|
|
|||
|
|
@ -7,12 +7,16 @@ use rustc_ast::mut_visit::*;
|
|||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
|
||||
use rustc_ast::{
|
||||
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, DUMMY_NODE_ID,
|
||||
ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner,
|
||||
MetaItemKind, ModKind, NodeId, PatKind, StmtKind, TyKind, token,
|
||||
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrItemKind, AttrStyle, AttrVec,
|
||||
DUMMY_NODE_ID, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline,
|
||||
ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId, PatKind, StmtKind,
|
||||
TyKind, token,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_attr_parsing::{AttributeParser, Early, EvalConfigResult, ShouldEmit, validate_attr};
|
||||
use rustc_attr_parsing::{
|
||||
AttributeParser, CFG_TEMPLATE, Early, EvalConfigResult, ShouldEmit, eval_config_entry,
|
||||
parse_cfg, validate_attr,
|
||||
};
|
||||
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::PResult;
|
||||
|
|
@ -2188,21 +2192,17 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
&& !AttributeParser::<Early>::is_parsed_attribute(&attr.path())
|
||||
{
|
||||
let attr_name = attr.name().unwrap();
|
||||
// `#[cfg]` and `#[cfg_attr]` are special - they are
|
||||
// eagerly evaluated.
|
||||
if attr_name != sym::cfg_trace && attr_name != sym::cfg_attr_trace {
|
||||
self.cx.sess.psess.buffer_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
attr.span,
|
||||
self.cx.current_expansion.lint_node_id,
|
||||
crate::errors::UnusedBuiltinAttribute {
|
||||
attr_name,
|
||||
macro_name: pprust::path_to_string(&call.path),
|
||||
invoc_span: call.path.span,
|
||||
attr_span: attr.span,
|
||||
},
|
||||
);
|
||||
}
|
||||
self.cx.sess.psess.buffer_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
attr.span,
|
||||
self.cx.current_expansion.lint_node_id,
|
||||
crate::errors::UnusedBuiltinAttribute {
|
||||
attr_name,
|
||||
macro_name: pprust::path_to_string(&call.path),
|
||||
invoc_span: call.path.span,
|
||||
attr_span: attr.span,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2213,11 +2213,26 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
attr: ast::Attribute,
|
||||
pos: usize,
|
||||
) -> EvalConfigResult {
|
||||
let res = self.cfg().cfg_true(&attr, ShouldEmit::ErrorsAndLints);
|
||||
let Some(cfg) = AttributeParser::parse_single(
|
||||
self.cfg().sess,
|
||||
&attr,
|
||||
attr.span,
|
||||
self.cfg().lint_node_id,
|
||||
self.cfg().features,
|
||||
ShouldEmit::ErrorsAndLints,
|
||||
parse_cfg,
|
||||
&CFG_TEMPLATE,
|
||||
) else {
|
||||
// Cfg attribute was not parsable, give up
|
||||
return EvalConfigResult::True;
|
||||
};
|
||||
|
||||
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.
|
||||
// It can later be used by lints or other diagnostics.
|
||||
let trace_attr = attr_into_trace(attr, sym::cfg_trace);
|
||||
let mut trace_attr = attr_into_trace(attr, sym::cfg_trace);
|
||||
trace_attr.replace_args(AttrItemKind::Parsed(EarlyParsedAttribute::CfgTrace(cfg)));
|
||||
node.visit_attrs(|attrs| attrs.insert(pos, trace_attr));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue