mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-04 09:53:04 +03:00
make tools on AttributeParser hold reference to RegisteredTools
This commit is contained in:
@@ -3586,6 +3586,7 @@ dependencies = [
|
||||
"rustc_feature",
|
||||
"rustc_hir",
|
||||
"rustc_lexer",
|
||||
"rustc_lint_defs",
|
||||
"rustc_macros",
|
||||
"rustc_parse",
|
||||
"rustc_parse_format",
|
||||
|
||||
@@ -164,7 +164,6 @@ struct LoweringContext<'a, 'hir> {
|
||||
|
||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>) -> Self {
|
||||
let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect();
|
||||
Self {
|
||||
tcx,
|
||||
resolver,
|
||||
@@ -220,7 +219,7 @@ fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>) -> Self {
|
||||
attribute_parser: AttributeParser::new(
|
||||
tcx.sess,
|
||||
tcx.features(),
|
||||
registered_tools,
|
||||
tcx.registered_tools(()),
|
||||
ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },
|
||||
),
|
||||
delayed_lints: Vec::new(),
|
||||
|
||||
@@ -13,6 +13,7 @@ rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_feature = { path = "../rustc_feature" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_lexer = { path = "../rustc_lexer" }
|
||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_parse = { path = "../rustc_parse" }
|
||||
rustc_parse_format = { path = "../rustc_parse_format" }
|
||||
|
||||
@@ -265,10 +265,18 @@ fn finalize(self, cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
|
||||
|
||||
let span = self.span?;
|
||||
|
||||
let Some(tools) = cx.tools else {
|
||||
unreachable!("tools required while parsing attributes");
|
||||
};
|
||||
|
||||
// only if we found a naked attribute do we do the somewhat expensive check
|
||||
'outer: for other_attr in cx.all_attrs {
|
||||
for allowed_attr in ALLOW_LIST {
|
||||
if other_attr.segments().next().is_some_and(|i| cx.tools.contains(&i.name)) {
|
||||
if other_attr
|
||||
.segments()
|
||||
.next()
|
||||
.is_some_and(|i| tools.iter().any(|tool| tool.name == i.name))
|
||||
{
|
||||
// effectively skips the error message being emitted below
|
||||
// if it's a tool attribute
|
||||
continue 'outer;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
use rustc_feature::{AttributeTemplate, Features};
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId, Target};
|
||||
use rustc_lint_defs::RegisteredTools;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::lint::LintId;
|
||||
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
|
||||
@@ -33,7 +34,7 @@ pub struct EmitAttribute(
|
||||
/// Context created once, for example as part of the ast lowering
|
||||
/// context, through which all attributes can be lowered.
|
||||
pub struct AttributeParser<'sess> {
|
||||
pub(crate) tools: Vec<Symbol>,
|
||||
pub(crate) tools: Option<&'sess RegisteredTools>,
|
||||
pub(crate) features: Option<&'sess Features>,
|
||||
pub(crate) sess: &'sess Session,
|
||||
pub(crate) should_emit: ShouldEmit,
|
||||
@@ -59,6 +60,8 @@ impl<'sess> AttributeParser<'sess> {
|
||||
/// No diagnostics will be emitted when parsing limited. Lints are not emitted at all, while
|
||||
/// errors will be emitted as a delayed bugs. in other words, we *expect* attributes parsed
|
||||
/// with `parse_limited` to be reparsed later during ast lowering where we *do* emit the errors
|
||||
///
|
||||
/// Due to this function not taking in RegisteredTools, *do not* use this for parsing any lint attributes
|
||||
pub fn parse_limited(
|
||||
sess: &'sess Session,
|
||||
attrs: &[ast::Attribute],
|
||||
@@ -79,6 +82,8 @@ pub fn parse_limited(
|
||||
|
||||
/// This does the same as `parse_limited`, except it has a `should_emit` parameter which allows it to emit errors.
|
||||
/// Usually you want `parse_limited`, which emits no errors.
|
||||
///
|
||||
/// Due to this function not taking in RegisteredTools, *do not* use this for parsing any lint attributes
|
||||
pub fn parse_limited_should_emit(
|
||||
sess: &'sess Session,
|
||||
attrs: &[ast::Attribute],
|
||||
@@ -98,6 +103,7 @@ pub fn parse_limited_should_emit(
|
||||
target_node_id,
|
||||
features,
|
||||
should_emit,
|
||||
None,
|
||||
);
|
||||
assert!(parsed.len() <= 1);
|
||||
parsed.pop()
|
||||
@@ -119,8 +125,9 @@ pub fn parse_limited_all(
|
||||
target_node_id: NodeId,
|
||||
features: Option<&'sess Features>,
|
||||
should_emit: ShouldEmit,
|
||||
tools: Option<&'sess RegisteredTools>,
|
||||
) -> Vec<Attribute> {
|
||||
let mut p = Self { features, tools: Vec::new(), parse_only, sess, should_emit };
|
||||
let mut p = Self { features, tools, parse_only, sess, should_emit };
|
||||
p.parse_attribute_list(
|
||||
attrs,
|
||||
target_span,
|
||||
@@ -202,7 +209,7 @@ pub fn parse_single_args<T, I>(
|
||||
parse_fn: fn(cx: &mut AcceptContext<'_, '_>, item: &I) -> T,
|
||||
template: &AttributeTemplate,
|
||||
) -> T {
|
||||
let mut parser = Self { features, tools: Vec::new(), parse_only: None, sess, should_emit };
|
||||
let mut parser = Self { features, tools: None, parse_only: None, sess, should_emit };
|
||||
let mut emit_lint = |lint_id: LintId, span: MultiSpan, kind: EmitAttribute| {
|
||||
sess.psess.dyn_buffer_lint_sess(lint_id.lint, span, target_node_id, kind.0)
|
||||
};
|
||||
@@ -237,10 +244,10 @@ impl<'sess> AttributeParser<'sess> {
|
||||
pub fn new(
|
||||
sess: &'sess Session,
|
||||
features: &'sess Features,
|
||||
tools: Vec<Symbol>,
|
||||
tools: &'sess RegisteredTools,
|
||||
should_emit: ShouldEmit,
|
||||
) -> Self {
|
||||
Self { features: Some(features), tools, parse_only: None, sess, should_emit }
|
||||
Self { features: Some(features), tools: Some(tools), parse_only: None, sess, should_emit }
|
||||
}
|
||||
|
||||
pub(crate) fn sess(&self) -> &'sess Session {
|
||||
@@ -432,12 +439,13 @@ pub fn parse_attribute_list(
|
||||
|
||||
let attr = Attribute::Unparsed(Box::new(attr));
|
||||
|
||||
if self.tools.contains(&parts[0])
|
||||
if self.tools.is_some_and(|tools| {
|
||||
tools.iter().any(|tool| tool.name == parts[0])
|
||||
// FIXME: this can be removed once #152369 has been merged.
|
||||
// https://github.com/rust-lang/rust/pull/152369
|
||||
|| [sym::allow, sym::deny, sym::expect, sym::forbid, sym::warn]
|
||||
.contains(&parts[0])
|
||||
{
|
||||
}) {
|
||||
attributes.push(attr);
|
||||
} else {
|
||||
dropped_attributes.push(attr);
|
||||
|
||||
@@ -2250,6 +2250,7 @@ fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
|
||||
self.cx.current_expansion.lint_node_id,
|
||||
Some(self.cx.ecfg.features),
|
||||
ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },
|
||||
Some(self.cx.resolver.registered_tools()),
|
||||
);
|
||||
|
||||
let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
|
||||
|
||||
@@ -149,7 +149,7 @@ fn visit_item(&mut self, i: &'a Item) {
|
||||
let mut parser = AttributeParser::new(
|
||||
&self.r.tcx.sess,
|
||||
self.r.tcx.features(),
|
||||
Vec::new(),
|
||||
self.r.tcx().registered_tools(()),
|
||||
ShouldEmit::Nothing,
|
||||
);
|
||||
let attrs = parser.parse_attribute_list(
|
||||
|
||||
Reference in New Issue
Block a user