Skip to content

Commit

Permalink
Auto merge of rust-lang#8694 - Jarcho:check_proc_macro, r=xFrednet
Browse files Browse the repository at this point in the history
More proc-macro detection

fixes rust-lang#6514
fixes rust-lang#8683
fixes rust-lang#6858
fixes rust-lang#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.
  • Loading branch information
bors committed Aug 8, 2022
2 parents 97a0cf2 + 745b194 commit 10853f7
Show file tree
Hide file tree
Showing 21 changed files with 439 additions and 93 deletions.
5 changes: 4 additions & 1 deletion clippy_lints/src/default.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
use clippy_utils::source::snippet_with_macro_callsite;
use clippy_utils::ty::{has_drop, is_copy};
use clippy_utils::{any_parent_is_automatically_derived, contains_name, get_parent_expr, match_def_path, paths};
use clippy_utils::{
any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro, match_def_path, paths,
};
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
Expand Down Expand Up @@ -94,6 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
if let QPath::Resolved(None, _path) = qpath;
let expr_ty = cx.typeck_results().expr_ty(expr);
if let ty::Adt(def, ..) = expr_ty.kind();
if !is_from_proc_macro(cx, expr);
then {
// TODO: Work out a way to put "whatever the imported way of referencing
// this type in this file" rather than a fully-qualified type.
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/formatting.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};
use clippy_utils::is_span_if;
use clippy_utils::source::snippet_opt;
use if_chain::if_chain;
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp};
Expand Down Expand Up @@ -297,12 +298,11 @@ fn check_array(cx: &EarlyContext<'_>, expr: &Expr) {
fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) {
if_chain! {
if !first.span.from_expansion() && !second.span.from_expansion();
if let ExprKind::If(cond_expr, ..) = &first.kind;
if matches!(first.kind, ExprKind::If(..));
if is_block(second) || is_if(second);

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

// If there is a line break between the two expressions, don't lint.
// If there is a non-whitespace character, this span came from a proc-macro.
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ mod single_match;
mod try_err;
mod wild_in_or_pats;

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

if let ExprKind::Match(ex, arms, source) = expr.kind {
if source == MatchSource::Normal && !span_starts_with(cx, expr.span, "match") {
if source == MatchSource::Normal && !is_span_match(cx, expr.span) {
return;
}
if matches!(source, MatchSource::Normal | MatchSource::ForLoopDesugar) {
Expand Down
21 changes: 16 additions & 5 deletions clippy_lints/src/missing_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

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

let attrs = cx.tcx.hir().attrs(it.hir_id());
self.check_missing_docs_attrs(cx, attrs, it.span, article, desc);
if !is_from_proc_macro(cx, it) {
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());

let attrs = cx.tcx.hir().attrs(trait_item.hir_id());
self.check_missing_docs_attrs(cx, attrs, trait_item.span, article, desc);
if !is_from_proc_macro(cx, trait_item) {
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<'_>) {
Expand All @@ -181,18 +186,24 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {

let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
if !is_from_proc_macro(cx, impl_item) {
self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
}
}

fn check_field_def(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::FieldDef<'_>) {
if !sf.is_positional() {
let attrs = cx.tcx.hir().attrs(sf.hir_id);
self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
if !is_from_proc_macro(cx, sf) {
self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
}
}
}

fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) {
let attrs = cx.tcx.hir().attrs(v.id);
self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
if !is_from_proc_macro(cx, v) {
self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
}
}
}
2 changes: 1 addition & 1 deletion clippy_lints/src/unit_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for UnitTypes {
let_unit_value::check(cx, local);
}

fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
unit_cmp::check(cx, expr);
unit_arg::check(cx, expr);
}
Expand Down
5 changes: 3 additions & 2 deletions clippy_lints/src/unit_types/unit_arg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
use if_chain::if_chain;
use rustc_errors::Applicability;
Expand All @@ -7,7 +8,7 @@ use rustc_lint::LateContext;

use super::{utils, UNIT_ARG};

pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if expr.span.from_expansion() {
return;
}
Expand Down Expand Up @@ -44,7 +45,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
}
})
.collect::<Vec<_>>();
if !args_to_recover.is_empty() {
if !args_to_recover.is_empty() && !is_from_proc_macro(cx, expr) {
lint_unit_args(cx, expr, &args_to_recover);
}
},
Expand Down
Loading

0 comments on commit 10853f7

Please sign in to comment.