mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-27 07:00:55 +00:00
Auto merge of #79519 - cjgillot:noattr, r=wesleywiser
Store HIR attributes in a side table Same idea as #72015 but for attributes. The objective is to reduce incr-comp invalidations due to modified attributes. Notably, those due to modified doc comments. Implementation: - collect attributes during AST->HIR lowering, in `LocalDefId -> ItemLocalId -> &[Attributes]` nested tables; - access the attributes through a `hir_owner_attrs` query; - local refactorings to use this access; - remove `attrs` from HIR data structures one-by-one. Change in behaviour: - the HIR visitor traverses all attributes at once instead of parent-by-parent; - attribute arrays are sometimes duplicated: for statements and variant constructors; - as a consequence, attributes are marked as used after unused-attribute lint emission to avoid duplicate lints. ~~Current bug: the lint level is not correctly applied in `std::backtrace_rs`, triggering an unused attribute warning on `#![no_std]`. I welcome suggestions.~~
This commit is contained in:
commit
36a27ecaac
26 changed files with 103 additions and 81 deletions
|
@ -276,14 +276,15 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
|
|||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
if is_relevant_item(cx, item) {
|
||||
check_attrs(cx, item.span, item.ident.name, &item.attrs)
|
||||
check_attrs(cx, item.span, item.ident.name, attrs)
|
||||
}
|
||||
match item.kind {
|
||||
ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
|
||||
let skip_unused_imports = item.attrs.iter().any(|attr| attr.has_name(sym::macro_use));
|
||||
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
|
||||
|
||||
for attr in item.attrs {
|
||||
for attr in attrs {
|
||||
if in_external_macro(cx.sess(), attr.span) {
|
||||
return;
|
||||
}
|
||||
|
@ -353,13 +354,13 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
|
|||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
|
||||
if is_relevant_impl(cx, item) {
|
||||
check_attrs(cx, item.span, item.ident.name, &item.attrs)
|
||||
check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()))
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
|
||||
if is_relevant_trait(cx, item) {
|
||||
check_attrs(cx, item.span, item.ident.name, &item.attrs)
|
||||
check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,8 +76,8 @@ impl CognitiveComplexity {
|
|||
|
||||
if rust_cc > self.limit.limit() {
|
||||
let fn_span = match kind {
|
||||
FnKind::ItemFn(ident, _, _, _, _) | FnKind::Method(ident, _, _, _) => ident.span,
|
||||
FnKind::Closure(_) => {
|
||||
FnKind::ItemFn(ident, _, _, _) | FnKind::Method(ident, _, _) => ident.span,
|
||||
FnKind::Closure => {
|
||||
let header_span = body_span.with_hi(decl.output.span().lo());
|
||||
let pos = snippet_opt(cx, header_span).and_then(|snip| {
|
||||
let low_offset = snip.find('|')?;
|
||||
|
|
|
@ -170,7 +170,8 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
|
|||
}) = item.kind
|
||||
{
|
||||
let ty = cx.tcx.type_of(item.def_id);
|
||||
let is_automatically_derived = is_automatically_derived(&*item.attrs);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let is_automatically_derived = is_automatically_derived(attrs);
|
||||
|
||||
check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
|
||||
check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived);
|
||||
|
|
|
@ -208,12 +208,14 @@ impl_lint_pass!(DocMarkdown =>
|
|||
);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
||||
fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) {
|
||||
check_attrs(cx, &self.valid_idents, &krate.item.attrs);
|
||||
fn check_crate(&mut self, cx: &LateContext<'tcx>, _: &'tcx hir::Crate<'_>) {
|
||||
let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID);
|
||||
check_attrs(cx, &self.valid_idents, attrs);
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let headers = check_attrs(cx, &self.valid_idents, attrs);
|
||||
match item.kind {
|
||||
hir::ItemKind::Fn(ref sig, _, body_id) => {
|
||||
if !(is_entrypoint_fn(cx, item.def_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
|
||||
|
@ -249,7 +251,8 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
|||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
|
||||
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let headers = check_attrs(cx, &self.valid_idents, attrs);
|
||||
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
|
||||
if !in_external_macro(cx.tcx.sess, item.span) {
|
||||
lint_for_missing_headers(cx, item.hir_id(), item.span, sig, headers, None, None);
|
||||
|
@ -258,7 +261,8 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
|||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
|
||||
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let headers = check_attrs(cx, &self.valid_idents, attrs);
|
||||
if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,8 @@ impl LateLintPass<'_> for ExhaustiveItems {
|
|||
if_chain! {
|
||||
if let ItemKind::Enum(..) | ItemKind::Struct(..) = item.kind;
|
||||
if cx.access_levels.is_exported(item.hir_id());
|
||||
if !item.attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
|
||||
then {
|
||||
let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind {
|
||||
if v.fields().iter().any(|f| !f.vis.node.is_pub()) {
|
||||
|
|
|
@ -251,9 +251,9 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
|||
hir_id: hir::HirId,
|
||||
) {
|
||||
let unsafety = match kind {
|
||||
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety,
|
||||
intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety,
|
||||
intravisit::FnKind::Closure(_) => return,
|
||||
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _) => unsafety,
|
||||
intravisit::FnKind::Method(_, sig, _) => sig.header.unsafety,
|
||||
intravisit::FnKind::Closure => return,
|
||||
};
|
||||
|
||||
// don't warn for implementations, it's not their fault
|
||||
|
@ -267,9 +267,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
|||
..
|
||||
},
|
||||
_,
|
||||
_,
|
||||
)
|
||||
| intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => {
|
||||
| intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _) => {
|
||||
self.check_arg_number(cx, decl, span.with_hi(decl.output.span().hi()))
|
||||
},
|
||||
_ => {},
|
||||
|
@ -281,7 +280,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
|||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
let attr = must_use_attr(&item.attrs);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let attr = must_use_attr(attrs);
|
||||
if let hir::ItemKind::Fn(ref sig, ref _generics, ref body_id) = item.kind {
|
||||
let is_public = cx.access_levels.is_exported(item.hir_id());
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
|
@ -292,7 +292,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
|||
check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr);
|
||||
return;
|
||||
}
|
||||
if is_public && !is_proc_macro(cx.sess(), &item.attrs) && attr_by_name(&item.attrs, "no_mangle").is_none() {
|
||||
if is_public && !is_proc_macro(cx.sess(), attrs) && attr_by_name(attrs, "no_mangle").is_none() {
|
||||
check_must_use_candidate(
|
||||
cx,
|
||||
&sig.decl,
|
||||
|
@ -313,11 +313,12 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
|||
if is_public && trait_ref_of_method(cx, item.hir_id()).is_none() {
|
||||
check_result_unit_err(cx, &sig.decl, item.span, fn_header_span);
|
||||
}
|
||||
let attr = must_use_attr(&item.attrs);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let attr = must_use_attr(attrs);
|
||||
if let Some(attr) = attr {
|
||||
check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr);
|
||||
} else if is_public
|
||||
&& !is_proc_macro(cx.sess(), &item.attrs)
|
||||
&& !is_proc_macro(cx.sess(), attrs)
|
||||
&& trait_ref_of_method(cx, item.hir_id()).is_none()
|
||||
{
|
||||
check_must_use_candidate(
|
||||
|
@ -345,7 +346,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
|||
check_result_unit_err(cx, &sig.decl, item.span, fn_header_span);
|
||||
}
|
||||
|
||||
let attr = must_use_attr(&item.attrs);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let attr = must_use_attr(attrs);
|
||||
if let Some(attr) = attr {
|
||||
check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr);
|
||||
}
|
||||
|
@ -353,7 +355,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
|||
let body = cx.tcx.hir().body(eid);
|
||||
Self::check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.hir_id());
|
||||
|
||||
if attr.is_none() && is_public && !is_proc_macro(cx.sess(), &item.attrs) {
|
||||
if attr.is_none() && is_public && !is_proc_macro(cx.sess(), attrs) {
|
||||
check_must_use_candidate(
|
||||
cx,
|
||||
&sig.decl,
|
||||
|
|
|
@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
|
|||
_: Span,
|
||||
hir_id: HirId,
|
||||
) {
|
||||
if let FnKind::Closure(_) = kind {
|
||||
if let FnKind::Closure = kind {
|
||||
return;
|
||||
}
|
||||
let ret_ty = utils::return_ty(cx, hir_id);
|
||||
|
|
|
@ -34,7 +34,8 @@ declare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]);
|
|||
impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody {
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
|
||||
if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind {
|
||||
check_attrs(cx, item.ident.name, &item.attrs);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
check_attrs(cx, item.ident.name, attrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -578,7 +578,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
|
|||
// also check for empty `loop {}` statements, skipping those in #[panic_handler]
|
||||
if block.stmts.is_empty() && block.expr.is_none() && !is_in_panic_handler(cx, expr) {
|
||||
let msg = "empty `loop {}` wastes CPU cycles";
|
||||
let help = if is_no_std_crate(cx.tcx.hir().krate()) {
|
||||
let help = if is_no_std_crate(cx) {
|
||||
"you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body"
|
||||
} else {
|
||||
"you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body"
|
||||
|
|
|
@ -107,8 +107,8 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
|
|||
if_chain! {
|
||||
if cx.sess().opts.edition >= Edition::Edition2018;
|
||||
if let hir::ItemKind::Use(path, _kind) = &item.kind;
|
||||
if let Some(mac_attr) = item
|
||||
.attrs
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
if let Some(mac_attr) = attrs
|
||||
.iter()
|
||||
.find(|attr| attr.ident().map(|s| s.to_string()) == Some("macro_use".to_string()));
|
||||
if let Res::Def(DefKind::Mod, id) = path.res;
|
||||
|
|
|
@ -32,8 +32,8 @@ pub struct MainRecursion {
|
|||
impl_lint_pass!(MainRecursion => [MAIN_RECURSION]);
|
||||
|
||||
impl LateLintPass<'_> for MainRecursion {
|
||||
fn check_crate(&mut self, _: &LateContext<'_>, krate: &Crate<'_>) {
|
||||
self.has_no_std_attr = is_no_std_crate(krate);
|
||||
fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
|
||||
self.has_no_std_attr = is_no_std_crate(cx);
|
||||
}
|
||||
|
||||
fn check_expr_post(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
|
|
|
@ -1207,11 +1207,11 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr
|
|||
if b0 != b1;
|
||||
let if_guard = &b0_arms[0].guard;
|
||||
if if_guard.is_none() || b0_arms.len() == 1;
|
||||
if b0_arms[0].attrs.is_empty();
|
||||
if cx.tcx.hir().attrs(b0_arms[0].hir_id).is_empty();
|
||||
if b0_arms[1..].iter()
|
||||
.all(|arm| {
|
||||
find_bool_lit(&arm.body.kind, desugared).map_or(false, |b| b == b0) &&
|
||||
arm.guard.is_none() && arm.attrs.is_empty()
|
||||
arm.guard.is_none() && cx.tcx.hir().attrs(arm.hir_id).is_empty()
|
||||
});
|
||||
then {
|
||||
// The suggestion may be incorrect, because some arms can have `cfg` attributes
|
||||
|
|
|
@ -278,7 +278,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
|
|||
span: Span,
|
||||
_: HirId,
|
||||
) {
|
||||
if let FnKind::Closure(_) = k {
|
||||
if let FnKind::Closure = k {
|
||||
// Does not apply to closures
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
|
|||
return;
|
||||
}
|
||||
},
|
||||
FnKind::Closure(..) => return,
|
||||
FnKind::Closure => return,
|
||||
}
|
||||
|
||||
let mir = cx.tcx.optimized_mir(def_id);
|
||||
|
|
|
@ -127,7 +127,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||
}
|
||||
|
||||
fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) {
|
||||
self.check_missing_docs_attrs(cx, &krate.item.attrs, krate.item.span, "the", "crate");
|
||||
let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID);
|
||||
self.check_missing_docs_attrs(cx, attrs, krate.item.span, "the", "crate");
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
|
||||
|
@ -160,13 +161,15 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||
|
||||
let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
|
||||
|
||||
self.check_missing_docs_attrs(cx, &it.attrs, it.span, article, desc);
|
||||
let attrs = cx.tcx.hir().attrs(it.hir_id());
|
||||
self.check_missing_docs_attrs(cx, attrs, it.span, article, desc);
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) {
|
||||
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
|
||||
|
||||
self.check_missing_docs_attrs(cx, &trait_item.attrs, trait_item.span, article, desc);
|
||||
let attrs = cx.tcx.hir().attrs(trait_item.hir_id());
|
||||
self.check_missing_docs_attrs(cx, attrs, trait_item.span, article, desc);
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
|
||||
|
@ -181,16 +184,19 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||
}
|
||||
|
||||
let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
|
||||
self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, article, desc);
|
||||
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
|
||||
self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
|
||||
}
|
||||
|
||||
fn check_struct_field(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::StructField<'_>) {
|
||||
if !sf.is_positional() {
|
||||
self.check_missing_docs_attrs(cx, &sf.attrs, sf.span, "a", "struct field");
|
||||
let attrs = cx.tcx.hir().attrs(sf.hir_id);
|
||||
self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
|
||||
}
|
||||
}
|
||||
|
||||
fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) {
|
||||
self.check_missing_docs_attrs(cx, &v.attrs, v.span, "a", "variant");
|
||||
let attrs = cx.tcx.hir().attrs(v.id);
|
||||
self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
|||
match it.kind {
|
||||
hir::ItemKind::Fn(..) => {
|
||||
let desc = "a function";
|
||||
check_missing_inline_attrs(cx, &it.attrs, it.span, desc);
|
||||
let attrs = cx.tcx.hir().attrs(it.hir_id());
|
||||
check_missing_inline_attrs(cx, attrs, it.span, desc);
|
||||
},
|
||||
hir::ItemKind::Trait(ref _is_auto, ref _unsafe, ref _generics, ref _bounds, trait_items) => {
|
||||
// note: we need to check if the trait is exported so we can't use
|
||||
|
@ -108,7 +109,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
|||
// an impl is not provided
|
||||
let desc = "a default trait method";
|
||||
let item = cx.tcx.hir().trait_item(tit.id);
|
||||
check_missing_inline_attrs(cx, &item.attrs, item.span, desc);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
check_missing_inline_attrs(cx, attrs, item.span, desc);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -160,6 +162,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
|||
}
|
||||
}
|
||||
|
||||
check_missing_inline_attrs(cx, &impl_item.attrs, impl_item.span, desc);
|
||||
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
|
||||
check_missing_inline_attrs(cx, attrs, impl_item.span, desc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,8 +115,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
if is_automatically_derived(item.attrs) {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
if is_automatically_derived(attrs) {
|
||||
debug_assert!(self.derived_item.is_none());
|
||||
self.derived_item = Some(item.def_id);
|
||||
}
|
||||
|
|
|
@ -80,13 +80,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
|||
}
|
||||
|
||||
match kind {
|
||||
FnKind::ItemFn(.., header, _, attrs) => {
|
||||
FnKind::ItemFn(.., header, _) => {
|
||||
let attrs = cx.tcx.hir().attrs(hir_id);
|
||||
if header.abi != Abi::Rust || requires_exact_signature(attrs) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
FnKind::Method(..) => (),
|
||||
FnKind::Closure(..) => return,
|
||||
FnKind::Closure => return,
|
||||
}
|
||||
|
||||
// Exclude non-inherent impls
|
||||
|
|
|
@ -43,9 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicInResultFn {
|
|||
span: Span,
|
||||
hir_id: hir::HirId,
|
||||
) {
|
||||
if !matches!(fn_kind, FnKind::Closure(_))
|
||||
&& is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type)
|
||||
{
|
||||
if !matches!(fn_kind, FnKind::Closure) && is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type) {
|
||||
lint_impl_body(cx, span, body);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
|
|||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
if_chain! {
|
||||
if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), items: impl_items, .. }) = item.kind;
|
||||
if !is_automatically_derived(&*item.attrs);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
if !is_automatically_derived(attrs);
|
||||
if let Some(eq_trait) = cx.tcx.lang_items().eq_trait();
|
||||
if trait_ref.path.res.def_id() == eq_trait;
|
||||
then {
|
||||
|
|
|
@ -224,10 +224,11 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
|
|||
}
|
||||
|
||||
match kind {
|
||||
FnKind::ItemFn(.., header, _, attrs) => {
|
||||
FnKind::ItemFn(.., header, _) => {
|
||||
if header.abi != Abi::Rust {
|
||||
return;
|
||||
}
|
||||
let attrs = cx.tcx.hir().attrs(hir_id);
|
||||
for a in attrs {
|
||||
if let Some(meta_items) = a.meta_item_list() {
|
||||
if a.has_name(sym::proc_macro_derive)
|
||||
|
@ -239,7 +240,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
|
|||
}
|
||||
},
|
||||
FnKind::Method(..) => (),
|
||||
FnKind::Closure(..) => return,
|
||||
FnKind::Closure => return,
|
||||
}
|
||||
|
||||
// Exclude non-inherent impls
|
||||
|
|
|
@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
|
|||
if let Some(stmt) = block.stmts.iter().last();
|
||||
if let StmtKind::Local(local) = &stmt.kind;
|
||||
if local.ty.is_none();
|
||||
if local.attrs.is_empty();
|
||||
if cx.tcx.hir().attrs(local.hir_id).is_empty();
|
||||
if let Some(initexpr) = &local.init;
|
||||
if let PatKind::Binding(.., ident, _) = local.pat.kind;
|
||||
if let ExprKind::Path(qpath) = &retexpr.kind;
|
||||
|
@ -131,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
|
|||
_: HirId,
|
||||
) {
|
||||
match kind {
|
||||
FnKind::Closure(_) => {
|
||||
FnKind::Closure => {
|
||||
// when returning without value in closure, replace this `return`
|
||||
// with an empty block to prevent invalid suggestion (see #6501)
|
||||
let replacement = if let ExprKind::Ret(None) = &body.value.kind {
|
||||
|
@ -177,7 +177,8 @@ fn check_final_expr<'tcx>(
|
|||
// simple return is always "bad"
|
||||
ExprKind::Ret(ref inner) => {
|
||||
// allow `#[cfg(a)] return a; #[cfg(b)] return b;`
|
||||
if !expr.attrs.iter().any(attr_is_cfg) {
|
||||
let attrs = cx.tcx.hir().attrs(expr.hir_id);
|
||||
if !attrs.iter().any(attr_is_cfg) {
|
||||
let borrows = inner.map_or(false, |inner| last_statement_borrows(cx, inner));
|
||||
if !borrows {
|
||||
emit_return_lint(
|
||||
|
|
|
@ -66,12 +66,12 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
|
|||
) {
|
||||
// Abort if public function/method or closure.
|
||||
match fn_kind {
|
||||
FnKind::ItemFn(.., visibility, _) | FnKind::Method(.., Some(visibility), _) => {
|
||||
FnKind::ItemFn(.., visibility) | FnKind::Method(.., Some(visibility)) => {
|
||||
if visibility.node.is_pub() {
|
||||
return;
|
||||
}
|
||||
},
|
||||
FnKind::Closure(..) => return,
|
||||
FnKind::Closure => return,
|
||||
_ => (),
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//! to generate a clippy lint detecting said code automatically.
|
||||
|
||||
use crate::utils::get_attr;
|
||||
use rustc_ast::ast::{Attribute, LitFloatType, LitKind};
|
||||
use rustc_ast::ast::{LitFloatType, LitKind};
|
||||
use rustc_ast::walk_list;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir as hir;
|
||||
|
@ -10,7 +10,6 @@ use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
|
|||
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, Pat, PatKind, QPath, Stmt, StmtKind, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -66,7 +65,7 @@ fn done() {
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for Author {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
if !has_attr(cx.sess(), &item.attrs) {
|
||||
if !has_attr(cx, item.hir_id()) {
|
||||
return;
|
||||
}
|
||||
prelude();
|
||||
|
@ -75,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
|
|||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
|
||||
if !has_attr(cx.sess(), &item.attrs) {
|
||||
if !has_attr(cx, item.hir_id()) {
|
||||
return;
|
||||
}
|
||||
prelude();
|
||||
|
@ -84,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
|
|||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
|
||||
if !has_attr(cx.sess(), &item.attrs) {
|
||||
if !has_attr(cx, item.hir_id()) {
|
||||
return;
|
||||
}
|
||||
prelude();
|
||||
|
@ -93,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
|
|||
}
|
||||
|
||||
fn check_variant(&mut self, cx: &LateContext<'tcx>, var: &'tcx hir::Variant<'_>) {
|
||||
if !has_attr(cx.sess(), &var.attrs) {
|
||||
if !has_attr(cx, var.id) {
|
||||
return;
|
||||
}
|
||||
prelude();
|
||||
|
@ -103,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
|
|||
}
|
||||
|
||||
fn check_struct_field(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::StructField<'_>) {
|
||||
if !has_attr(cx.sess(), &field.attrs) {
|
||||
if !has_attr(cx, field.hir_id) {
|
||||
return;
|
||||
}
|
||||
prelude();
|
||||
|
@ -112,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
|
|||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
|
||||
if !has_attr(cx.sess(), &expr.attrs) {
|
||||
if !has_attr(cx, expr.hir_id) {
|
||||
return;
|
||||
}
|
||||
prelude();
|
||||
|
@ -121,7 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
|
|||
}
|
||||
|
||||
fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx hir::Arm<'_>) {
|
||||
if !has_attr(cx.sess(), &arm.attrs) {
|
||||
if !has_attr(cx, arm.hir_id) {
|
||||
return;
|
||||
}
|
||||
prelude();
|
||||
|
@ -130,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
|
|||
}
|
||||
|
||||
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) {
|
||||
if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id))) {
|
||||
if !has_attr(cx, stmt.hir_id) {
|
||||
return;
|
||||
}
|
||||
prelude();
|
||||
|
@ -139,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for Author {
|
|||
}
|
||||
|
||||
fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ForeignItem<'_>) {
|
||||
if !has_attr(cx.sess(), &item.attrs) {
|
||||
if !has_attr(cx, item.hir_id()) {
|
||||
return;
|
||||
}
|
||||
prelude();
|
||||
|
@ -719,8 +718,9 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
fn has_attr(sess: &Session, attrs: &[Attribute]) -> bool {
|
||||
get_attr(sess, attrs, "author").count() > 0
|
||||
fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool {
|
||||
let attrs = cx.tcx.hir().attrs(hir_id);
|
||||
get_attr(cx.sess(), attrs, "author").count() > 0
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
|
|
@ -33,14 +33,14 @@ declare_lint_pass!(DeepCodeInspector => [DEEP_CODE_INSPECTION]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
if !has_attr(cx.sess(), &item.attrs) {
|
||||
if !has_attr(cx.sess(), cx.tcx.hir().attrs(item.hir_id())) {
|
||||
return;
|
||||
}
|
||||
print_item(cx, item);
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
|
||||
if !has_attr(cx.sess(), &item.attrs) {
|
||||
if !has_attr(cx.sess(), cx.tcx.hir().attrs(item.hir_id())) {
|
||||
return;
|
||||
}
|
||||
println!("impl item `{}`", item.ident.name);
|
||||
|
@ -89,14 +89,14 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
|
|||
//
|
||||
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
|
||||
if !has_attr(cx.sess(), &expr.attrs) {
|
||||
if !has_attr(cx.sess(), cx.tcx.hir().attrs(expr.hir_id)) {
|
||||
return;
|
||||
}
|
||||
print_expr(cx, expr, 0);
|
||||
}
|
||||
|
||||
fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx hir::Arm<'_>) {
|
||||
if !has_attr(cx.sess(), &arm.attrs) {
|
||||
if !has_attr(cx.sess(), cx.tcx.hir().attrs(arm.hir_id)) {
|
||||
return;
|
||||
}
|
||||
print_pat(cx, &arm.pat, 1);
|
||||
|
@ -109,7 +109,7 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
|
|||
}
|
||||
|
||||
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) {
|
||||
if !has_attr(cx.sess(), stmt.kind.attrs(|id| cx.tcx.hir().item(id))) {
|
||||
if !has_attr(cx.sess(), cx.tcx.hir().attrs(stmt.hir_id)) {
|
||||
return;
|
||||
}
|
||||
match stmt.kind {
|
||||
|
|
|
@ -61,7 +61,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
|||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::Node;
|
||||
use rustc_hir::{
|
||||
def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, HirId, ImplItem, ImplItemKind, Item, ItemKind,
|
||||
def, Arm, Block, Body, Constness, Expr, ExprKind, FnDecl, HirId, ImplItem, ImplItemKind, Item, ItemKind,
|
||||
MatchSource, Param, Pat, PatKind, Path, PathSegment, QPath, TraitItem, TraitItemKind, TraitRef, TyKind, Unsafety,
|
||||
};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
|
@ -1510,8 +1510,8 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
did.map_or(false, |did| must_use_attr(&cx.tcx.get_attrs(did)).is_some())
|
||||
}
|
||||
|
||||
pub fn is_no_std_crate(krate: &Crate<'_>) -> bool {
|
||||
krate.item.attrs.iter().any(|attr| {
|
||||
pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
|
||||
cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
|
||||
if let ast::AttrKind::Normal(ref attr, _) = attr.kind {
|
||||
attr.path == sym::no_std
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue