From 8d4f2ac38195567ee8eca0123d428951821db507 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Tue, 9 Aug 2022 03:26:08 +0200 Subject: [PATCH 1/3] Use `check_proc_macro` for `missing_const_for_fn` --- clippy_lints/src/missing_const_for_fn.rs | 14 +++++-- clippy_utils/src/check_proc_macro.rs | 39 +++++++++++++++++-- .../ui/missing_const_for_fn/cant_be_const.rs | 9 +++++ 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index 2bd920db3025..bc304c081b90 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -1,7 +1,9 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::qualify_min_const_fn::is_min_const_fn; use clippy_utils::ty::has_drop; -use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, meets_msrv, msrvs, trait_ref_of_method}; +use clippy_utils::{ + fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, meets_msrv, msrvs, trait_ref_of_method, +}; use rustc_hir as hir; use rustc_hir::def_id::CRATE_DEF_ID; use rustc_hir::intravisit::FnKind; @@ -86,10 +88,10 @@ impl MissingConstForFn { impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { fn check_fn( &mut self, - cx: &LateContext<'_>, - kind: FnKind<'_>, + cx: &LateContext<'tcx>, + kind: FnKind<'tcx>, _: &FnDecl<'_>, - _: &Body<'_>, + body: &Body<'tcx>, span: Span, hir_id: HirId, ) { @@ -144,6 +146,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { } } + if is_from_proc_macro(cx, &(&kind, body, hir_id, span)) { + return; + } + let mir = cx.tcx.optimized_mir(def_id); if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, self.msrv) { diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 0f00a1cdf0fa..1062f223912f 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -14,9 +14,9 @@ use rustc_ast::ast::{IntTy, LitIntType, LitKind, StrStyle, UintTy}; use rustc_hir::{ - Block, BlockCheckMode, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, Impl, ImplItem, ImplItemKind, - IsAuto, Item, ItemKind, LoopSource, MatchSource, QPath, TraitItem, TraitItemKind, UnOp, UnsafeSource, Unsafety, - Variant, VariantData, YieldSource, + intravisit::FnKind, Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, HirId, + Impl, ImplItem, ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, QPath, TraitItem, TraitItemKind, + UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource, }; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty::TyCtxt; @@ -250,6 +250,27 @@ fn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) { } } +fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirId) -> (Pat, Pat) { + let (start_pat, end_pat, visibility) = match kind { + FnKind::ItemFn(.., header) => ( + fn_header_search_pat(*header), + Pat::Str(""), + tcx.visibility(tcx.hir().local_def_id(hir_id)), + ), + FnKind::Method(.., sig) => ( + fn_header_search_pat(sig.header), + Pat::Str(""), + tcx.visibility(tcx.hir().local_def_id(hir_id)), + ), + FnKind::Closure => return (Pat::Str(""), expr_search_pat(tcx, &body.value).1), + }; + if visibility.is_public() { + (Pat::Str("pub"), end_pat) + } else { + (start_pat, end_pat) + } +} + pub trait WithSearchPat { type Context: LintContext; fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat); @@ -277,6 +298,18 @@ impl_with_search_pat!(LateContext: ImplItem with impl_item_search_pat); impl_with_search_pat!(LateContext: FieldDef with field_def_search_pat); impl_with_search_pat!(LateContext: Variant with variant_search_pat); +impl<'cx> WithSearchPat for (&FnKind<'cx>, &Body<'cx>, HirId, Span) { + type Context = LateContext<'cx>; + + fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat) { + fn_kind_pat(cx.tcx, self.0, self.1, self.2) + } + + fn span(&self) -> Span { + self.3 + } +} + /// Checks if the item likely came from a proc-macro. /// /// This should be called after `in_external_macro` and the initial pattern matching of the ast as diff --git a/tests/ui/missing_const_for_fn/cant_be_const.rs b/tests/ui/missing_const_for_fn/cant_be_const.rs index aa60d0504e5e..b950248ef942 100644 --- a/tests/ui/missing_const_for_fn/cant_be_const.rs +++ b/tests/ui/missing_const_for_fn/cant_be_const.rs @@ -3,12 +3,16 @@ //! The .stderr output of this test should be empty. Otherwise it's a bug somewhere. // aux-build:helper.rs +// aux-build:../../auxiliary/proc_macro_with_span.rs #![warn(clippy::missing_const_for_fn)] #![feature(start)] #![feature(custom_inner_attributes)] extern crate helper; +extern crate proc_macro_with_span; + +use proc_macro_with_span::with_span; struct Game; @@ -119,3 +123,8 @@ mod const_fn_stabilized_after_msrv { byte.is_ascii_digit(); } } + +with_span! { + span + fn dont_check_in_proc_macro() {} +} From 6f5d64842bfce445cbe251bec492c80481bca7f3 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Tue, 9 Aug 2022 04:48:05 +0200 Subject: [PATCH 2/3] Address review --- clippy_utils/src/check_proc_macro.rs | 29 +++++++++++++--------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 1062f223912f..da3db9230a0c 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -15,8 +15,8 @@ use rustc_ast::ast::{IntTy, LitIntType, LitKind, StrStyle, UintTy}; use rustc_hir::{ intravisit::FnKind, Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, HirId, - Impl, ImplItem, ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, QPath, TraitItem, TraitItemKind, - UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource, + Impl, ImplItem, ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, Node, QPath, TraitItem, + TraitItemKind, UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource, }; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty::TyCtxt; @@ -251,23 +251,20 @@ fn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) { } fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirId) -> (Pat, Pat) { - let (start_pat, end_pat, visibility) = match kind { - FnKind::ItemFn(.., header) => ( - fn_header_search_pat(*header), - Pat::Str(""), - tcx.visibility(tcx.hir().local_def_id(hir_id)), - ), - FnKind::Method(.., sig) => ( - fn_header_search_pat(sig.header), - Pat::Str(""), - tcx.visibility(tcx.hir().local_def_id(hir_id)), - ), + let (start_pat, end_pat) = match kind { + FnKind::ItemFn(.., header) => (fn_header_search_pat(*header), Pat::Str("")), + FnKind::Method(.., sig) => (fn_header_search_pat(sig.header), Pat::Str("")), FnKind::Closure => return (Pat::Str(""), expr_search_pat(tcx, &body.value).1), }; - if visibility.is_public() { - (Pat::Str("pub"), end_pat) - } else { + let vis_span = match tcx.hir().get(hir_id) { + Node::Item(Item { vis_span, .. }) | Node::ImplItem(ImplItem { vis_span, .. }) => Some(vis_span), + Node::TraitItem(_) => None, + _ => unreachable!(), + }; + if matches!(vis_span, Some(span) if span.is_empty()) { (start_pat, end_pat) + } else { + (Pat::Str("pub"), end_pat) } } From fd605816287de96486066accf4e3a10e412ff055 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Tue, 9 Aug 2022 05:14:03 +0200 Subject: [PATCH 3/3] Address review take 2 --- clippy_utils/src/check_proc_macro.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index da3db9230a0c..8335ffae81eb 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -256,16 +256,18 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI FnKind::Method(.., sig) => (fn_header_search_pat(sig.header), Pat::Str("")), FnKind::Closure => return (Pat::Str(""), expr_search_pat(tcx, &body.value).1), }; - let vis_span = match tcx.hir().get(hir_id) { - Node::Item(Item { vis_span, .. }) | Node::ImplItem(ImplItem { vis_span, .. }) => Some(vis_span), - Node::TraitItem(_) => None, - _ => unreachable!(), + let start_pat = match tcx.hir().get(hir_id) { + Node::Item(Item { vis_span, .. }) | Node::ImplItem(ImplItem { vis_span, .. }) => { + if vis_span.is_empty() { + start_pat + } else { + Pat::Str("pub") + } + }, + Node::TraitItem(_) => start_pat, + _ => Pat::Str(""), }; - if matches!(vis_span, Some(span) if span.is_empty()) { - (start_pat, end_pat) - } else { - (Pat::Str("pub"), end_pat) - } + (start_pat, end_pat) } pub trait WithSearchPat {