Skip to content

Commit 10853f7

Browse files
committed
Auto merge of #8694 - Jarcho:check_proc_macro, r=xFrednet
More proc-macro detection fixes #6514 fixes #8683 fixes #6858 fixes #6594 This is a more general way of checking if an expression comes from a macro and could be trivially applied to other lints. Ideally this would be fixed in rustc's proc-macro api, but I don't see that happening any time soon. changelog: FPs: [`unit_arg`] [`default_trait_access`] [`missing_docs_in_private_items`]: No longer trigger in code generated from proc-macros.
2 parents 97a0cf2 + 745b194 commit 10853f7

21 files changed

+439
-93
lines changed

clippy_lints/src/default.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
22
use clippy_utils::source::snippet_with_macro_callsite;
33
use clippy_utils::ty::{has_drop, is_copy};
4-
use clippy_utils::{any_parent_is_automatically_derived, contains_name, get_parent_expr, match_def_path, paths};
4+
use clippy_utils::{
5+
any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro, match_def_path, paths,
6+
};
57
use if_chain::if_chain;
68
use rustc_data_structures::fx::FxHashSet;
79
use rustc_errors::Applicability;
@@ -94,6 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
9496
if let QPath::Resolved(None, _path) = qpath;
9597
let expr_ty = cx.typeck_results().expr_ty(expr);
9698
if let ty::Adt(def, ..) = expr_ty.kind();
99+
if !is_from_proc_macro(cx, expr);
97100
then {
98101
// TODO: Work out a way to put "whatever the imported way of referencing
99102
// this type in this file" rather than a fully-qualified type.

clippy_lints/src/formatting.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};
2+
use clippy_utils::is_span_if;
23
use clippy_utils::source::snippet_opt;
34
use if_chain::if_chain;
45
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp};
@@ -297,12 +298,11 @@ fn check_array(cx: &EarlyContext<'_>, expr: &Expr) {
297298
fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) {
298299
if_chain! {
299300
if !first.span.from_expansion() && !second.span.from_expansion();
300-
if let ExprKind::If(cond_expr, ..) = &first.kind;
301+
if matches!(first.kind, ExprKind::If(..));
301302
if is_block(second) || is_if(second);
302303

303304
// Proc-macros can give weird spans. Make sure this is actually an `if`.
304-
if let Some(if_snip) = snippet_opt(cx, first.span.until(cond_expr.span));
305-
if if_snip.starts_with("if");
305+
if is_span_if(cx, first.span);
306306

307307
// If there is a line break between the two expressions, don't lint.
308308
// If there is a non-whitespace character, this span came from a proc-macro.

clippy_lints/src/matches/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ mod single_match;
2121
mod try_err;
2222
mod wild_in_or_pats;
2323

24-
use clippy_utils::source::{snippet_opt, span_starts_with, walk_span_to_context};
25-
use clippy_utils::{higher, in_constant, meets_msrv, msrvs};
24+
use clippy_utils::source::{snippet_opt, walk_span_to_context};
25+
use clippy_utils::{higher, in_constant, is_span_match, meets_msrv, msrvs};
2626
use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};
2727
use rustc_lexer::{tokenize, TokenKind};
2828
use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -949,7 +949,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
949949
let from_expansion = expr.span.from_expansion();
950950

951951
if let ExprKind::Match(ex, arms, source) = expr.kind {
952-
if source == MatchSource::Normal && !span_starts_with(cx, expr.span, "match") {
952+
if source == MatchSource::Normal && !is_span_match(cx, expr.span) {
953953
return;
954954
}
955955
if matches!(source, MatchSource::Normal | MatchSource::ForLoopDesugar) {

clippy_lints/src/missing_doc.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use clippy_utils::attrs::is_doc_hidden;
99
use clippy_utils::diagnostics::span_lint;
10+
use clippy_utils::is_from_proc_macro;
1011
use if_chain::if_chain;
1112
use rustc_ast::ast::{self, MetaItem, MetaItemKind};
1213
use rustc_hir as hir;
@@ -158,14 +159,18 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
158159
let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
159160

160161
let attrs = cx.tcx.hir().attrs(it.hir_id());
161-
self.check_missing_docs_attrs(cx, attrs, it.span, article, desc);
162+
if !is_from_proc_macro(cx, it) {
163+
self.check_missing_docs_attrs(cx, attrs, it.span, article, desc);
164+
}
162165
}
163166

164167
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) {
165168
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
166169

167170
let attrs = cx.tcx.hir().attrs(trait_item.hir_id());
168-
self.check_missing_docs_attrs(cx, attrs, trait_item.span, article, desc);
171+
if !is_from_proc_macro(cx, trait_item) {
172+
self.check_missing_docs_attrs(cx, attrs, trait_item.span, article, desc);
173+
}
169174
}
170175

171176
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
@@ -181,18 +186,24 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
181186

182187
let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
183188
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
184-
self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
189+
if !is_from_proc_macro(cx, impl_item) {
190+
self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
191+
}
185192
}
186193

187194
fn check_field_def(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::FieldDef<'_>) {
188195
if !sf.is_positional() {
189196
let attrs = cx.tcx.hir().attrs(sf.hir_id);
190-
self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
197+
if !is_from_proc_macro(cx, sf) {
198+
self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
199+
}
191200
}
192201
}
193202

194203
fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) {
195204
let attrs = cx.tcx.hir().attrs(v.id);
196-
self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
205+
if !is_from_proc_macro(cx, v) {
206+
self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
207+
}
197208
}
198209
}

clippy_lints/src/unit_types/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for UnitTypes {
103103
let_unit_value::check(cx, local);
104104
}
105105

106-
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
106+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
107107
unit_cmp::check(cx, expr);
108108
unit_arg::check(cx, expr);
109109
}

clippy_lints/src/unit_types/unit_arg.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
2+
use clippy_utils::is_from_proc_macro;
23
use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
34
use if_chain::if_chain;
45
use rustc_errors::Applicability;
@@ -7,7 +8,7 @@ use rustc_lint::LateContext;
78

89
use super::{utils, UNIT_ARG};
910

10-
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
11+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
1112
if expr.span.from_expansion() {
1213
return;
1314
}
@@ -44,7 +45,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
4445
}
4546
})
4647
.collect::<Vec<_>>();
47-
if !args_to_recover.is_empty() {
48+
if !args_to_recover.is_empty() && !is_from_proc_macro(cx, expr) {
4849
lint_unit_args(cx, expr, &args_to_recover);
4950
}
5051
},

0 commit comments

Comments
 (0)