Skip to content

Commit

Permalink
Turn back to visitor
Browse files Browse the repository at this point in the history
  • Loading branch information
blyxyas committed May 15, 2024
1 parent 7606f89 commit 828cd60
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 85 deletions.
80 changes: 54 additions & 26 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_ast as ast;
use rustc_ast_pretty::pprust;
use rustc_data_structures::{
fx::FxIndexMap,
sync::{join, Lock, Lrc},
sync::Lrc,
};
use rustc_errors::{Diag, DiagMessage, LintDiagnostic, MultiSpan};
use rustc_feature::{Features, GateIssue};
Expand Down Expand Up @@ -162,9 +162,9 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
pub fn lints_that_can_emit(tcx: TyCtxt<'_>, (): ()) -> Lrc<(Vec<String>, Vec<String>)> {
let mut visitor = LintLevelMinimum::new(tcx);
visitor.process_opts();
visitor.lint_level_minimums();
tcx.hir().walk_attributes(&mut visitor);

Lrc::new((visitor.lints_to_emit.into_inner(), visitor.lints_allowed.into_inner()))
Lrc::new((visitor.lints_to_emit, visitor.lints_allowed))
}

#[instrument(level = "trace", skip(tcx), ret)]
Expand Down Expand Up @@ -474,49 +474,77 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'
struct LintLevelMinimum<'tcx> {
tcx: TyCtxt<'tcx>,
/// The actual list of detected lints.
lints_to_emit: Lock<Vec<String>>,
lints_allowed: Lock<Vec<String>>,
lints_to_emit: Vec<String>,
lints_allowed: Vec<String>,
}

impl<'tcx> LintLevelMinimum<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
Self {
tcx,
// That magic number is the current number of lints + some more for possible future lints
lints_to_emit: Lock::new(Vec::with_capacity(230)),
lints_allowed: Lock::new(Vec::with_capacity(100)),
lints_to_emit: Vec::with_capacity(230),
lints_allowed: Vec::with_capacity(100),
}
}

fn process_opts(&mut self) {
for (lint, level) in &self.tcx.sess.opts.lint_opts {
if *level == Level::Allow {
self.lints_allowed.with_lock(|lints_allowed| lints_allowed.push(lint.to_string()));
self.lints_allowed.push(lint.clone());
} else {
self.lints_to_emit.with_lock(|lints_to_emit| lints_to_emit.push(lint.to_string()));
self.lints_to_emit.push(lint.to_string());
}
}
}
}

impl<'tcx> Visitor<'tcx> for LintLevelMinimum<'tcx> {
type NestedFilter = nested_filter::All;

fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
}

fn lint_level_minimums(&mut self) {
join(
|| {
self.tcx.sess.psess.lints_that_can_emit.with_lock(|vec| {
for lint_symbol in vec {
self.lints_to_emit
.with_lock(|lints_to_emit| lints_to_emit.push(lint_symbol.to_string()));
fn visit_attribute(&mut self, attribute: &'tcx ast::Attribute) {
if let Some(meta) = attribute.meta() {
if [sym::warn, sym::deny, sym::forbid, sym::expect]
.iter()
.any(|kind| meta.has_name(*kind))
{
// SAFETY: Lint attributes are always a metalist inside a
// metalist (even with just one lint).
for meta_list in meta.meta_item_list().unwrap() {
// If it's a tool lint (e.g. clippy::my_clippy_lint)
if let ast::NestedMetaItem::MetaItem(meta_item) = meta_list {
if meta_item.path.segments.len() == 1 {
self.lints_to_emit.push(
// SAFETY: Lint attributes can only have literals
meta_list.ident().unwrap().name.as_str().to_string(),
);
} else {
self.lints_to_emit
.push(meta_item.path.segments[1].ident.name.as_str().to_string());
}
}
});
},
|| {
self.tcx.sess.psess.lints_allowed.with_lock(|vec| {
for lint_symbol in vec {
self.lints_allowed
.with_lock(|lints_allowed| lints_allowed.push(lint_symbol.to_string()));
}
// We handle #![allow]s differently, as these remove checking rather than adding.
} else if meta.has_name(sym::allow)
&& let ast::AttrStyle::Inner = attribute.style
{
for meta_list in meta.meta_item_list().unwrap() {
// If it's a tool lint (e.g. clippy::my_clippy_lint)
if let ast::NestedMetaItem::MetaItem(meta_item) = meta_list {
if meta_item.path.segments.len() == 1 {
self.lints_allowed.push(meta_list.name_or_empty().as_str().to_string())
} else {
self.lints_allowed
.push(meta_item.path.segments[1].ident.name.as_str().to_string());
}
}
});
},
);
}
}
}
}
}

Expand Down
52 changes: 2 additions & 50 deletions compiler/rustc_parse/src/parser/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl<'a> Parser<'a> {
);
let lo = self.token.span;
// Attributes can't have attributes of their own [Editor's note: not with that attitude]
let attribute_result = self.collect_tokens_no_attrs(|this| {
self.collect_tokens_no_attrs(|this| {
assert!(this.eat(&token::Pound), "parse_attribute called in non-attribute position");

let style =
Expand All @@ -133,55 +133,7 @@ impl<'a> Parser<'a> {
this.error_on_forbidden_inner_attr(attr_sp, inner_parse_policy);
}
Ok(attr::mk_attr_from_item(&self.psess.attr_id_generator, item, None, style, attr_sp))
});

if let Ok(ref attr) = attribute_result
&& let Some(meta) = attr.meta()
{
if let Some(first) = meta.path.segments.first() {
if [sym::warn, sym::deny, sym::forbid, sym::expect]
.iter()
.any(|symbol| first.ident.name == *symbol)
{
for meta_list in attr.meta_item_list().unwrap() {
// If it's a tool lint (e.g. clippy::my_clippy_lint)
if let ast::NestedMetaItem::MetaItem(ref meta_item) = meta_list {
if meta_item.path.segments.len() == 1 {
self.psess.lints_that_can_emit.with_lock(|lints_that_can_emit| {
lints_that_can_emit
.push(meta_list.ident().unwrap().name.as_str().to_string());
})
} else {
self.psess.lints_that_can_emit.with_lock(|lints_that_can_emit| {
lints_that_can_emit.push(
meta_item.path.segments[1].ident.name.as_str().to_string(),
);
})
}
}
}
} else if first.ident.name == sym::allow && attr.style == ast::AttrStyle::Inner {
for meta_list in attr.meta_item_list().unwrap() {
// If it's a tool lint (e.g. clippy::my_clippy_lint)
if let ast::NestedMetaItem::MetaItem(ref meta_item) = meta_list {
if meta_item.path.segments.len() == 1 {
self.psess.lints_allowed.with_lock(|lints_allowed| {
lints_allowed
.push(meta_list.name_or_empty().as_str().to_string())
})
} else {
self.psess.lints_allowed.with_lock(|lints_allowed| {
lints_allowed.push(
meta_item.path.segments[1].ident.name.as_str().to_string(),
);
})
}
}
}
}
}
}
attribute_result
})
}

fn annotate_following_item_if_applicable(
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,6 @@ pub struct ParseSess {
proc_macro_quoted_spans: AppendOnlyVec<Span>,
/// Used to generate new `AttrId`s. Every `AttrId` is unique.
pub attr_id_generator: AttrIdGenerator,
/// All lints that can emit, even if not emitted (i.e. lints that are mentioned
/// in e.g. #![warn] attributes)
pub lints_that_can_emit: Lock<Vec<String>>,
/// The list of lints that cannot emit, maybe because they are allowed
/// globally, or the default level is Allow and they are not activated
/// manually
pub lints_allowed: Lock<Vec<String>>,
}

impl ParseSess {
Expand Down Expand Up @@ -273,8 +266,6 @@ impl ParseSess {
assume_incomplete_release: false,
proc_macro_quoted_spans: Default::default(),
attr_id_generator: AttrIdGenerator::new(),
lints_that_can_emit: Lock::new(Vec::with_capacity(230)),
lints_allowed: Lock::new(Vec::with_capacity(100)),
}
}

Expand Down

0 comments on commit 828cd60

Please sign in to comment.