Remove Session.used_attrs and move logic to CheckAttrVisitor
Instead of updating global state to mark attributes as used, we now explicitly emit a warning when an attribute is used in an unsupported position. As a side effect, we are to emit more detailed warning messages (instead of just a generic "unused" message). `Session.check_name` is removed, since its only purpose was to mark the attribute as used. All of the callers are modified to use `Attribute.has_name` Additionally, `AttributeType::AssumedUsed` is removed - an 'assumed used' attribute is implemented by simply not performing any checks in `CheckAttrVisitor` for a particular attribute. We no longer emit unused attribute warnings for the `#[rustc_dummy]` attribute - it's an internal attribute used for tests, so it doesn't mark sense to treat it as 'unused'. With this commit, a large source of global untracked state is removed.
This commit is contained in:
@@ -4,21 +4,16 @@ use rustc_ast as ast;
|
||||
use rustc_ast::util::parser;
|
||||
use rustc_ast::{ExprKind, StmtKind};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{pluralize, Applicability};
|
||||
use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::adjustment;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_session::lint::builtin::UNUSED_ATTRIBUTES;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
|
||||
use tracing::debug;
|
||||
|
||||
declare_lint! {
|
||||
/// The `unused_must_use` lint detects unused result of a type flagged as
|
||||
/// `#[must_use]`.
|
||||
@@ -308,7 +303,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
descr_post_path: &str,
|
||||
) -> bool {
|
||||
for attr in cx.tcx.get_attrs(def_id).iter() {
|
||||
if cx.sess().check_name(attr, sym::must_use) {
|
||||
if attr.has_name(sym::must_use) {
|
||||
cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
|
||||
let msg = format!(
|
||||
"unused {}`{}`{} that must be used",
|
||||
@@ -382,62 +377,6 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct UnusedAttributes {
|
||||
builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>,
|
||||
}
|
||||
|
||||
impl UnusedAttributes {
|
||||
pub fn new() -> Self {
|
||||
UnusedAttributes { builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP }
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(UnusedAttributes => [UNUSED_ATTRIBUTES]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for UnusedAttributes {
|
||||
fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
|
||||
debug!("checking attribute: {:?}", attr);
|
||||
|
||||
if attr.is_doc_comment() {
|
||||
return;
|
||||
}
|
||||
|
||||
let attr_info = attr.ident().and_then(|ident| self.builtin_attributes.get(&ident.name));
|
||||
|
||||
if let Some(&&(name, ty, ..)) = attr_info {
|
||||
if let AttributeType::AssumedUsed = ty {
|
||||
debug!("{:?} is AssumedUsed", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if !cx.sess().is_attr_used(attr) {
|
||||
debug!("emitting warning for: {:?}", attr);
|
||||
cx.struct_span_lint(UNUSED_ATTRIBUTES, attr.span, |lint| {
|
||||
// Mark as used to avoid duplicate warnings.
|
||||
cx.sess().mark_attr_used(attr);
|
||||
lint.build("unused attribute").emit()
|
||||
});
|
||||
// Is it a builtin attribute that must be used at the crate level?
|
||||
if attr_info.map_or(false, |(_, ty, ..)| ty == &AttributeType::CrateLevel) {
|
||||
cx.struct_span_lint(UNUSED_ATTRIBUTES, attr.span, |lint| {
|
||||
let msg = match attr.style {
|
||||
ast::AttrStyle::Outer => {
|
||||
"crate-level attribute should be an inner attribute: add an exclamation \
|
||||
mark: `#![foo]`"
|
||||
}
|
||||
ast::AttrStyle::Inner => "crate-level attribute should be in the root module",
|
||||
};
|
||||
lint.build(msg).emit()
|
||||
});
|
||||
}
|
||||
} else {
|
||||
debug!("Attr was used: {:?}", attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
enum UnusedDelimsCtx {
|
||||
FunctionArg,
|
||||
|
||||
Reference in New Issue
Block a user