Skip to content

Commit 59cb7f1

Browse files
committed
WIP
1 parent c0b9f66 commit 59cb7f1

10 files changed

+81
-47
lines changed

clippy_lints/src/blocks_in_if_conditions.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::utils::{differing_macro_contexts, higher, snippet_block_with_applicability, span_lint, span_lint_and_sugg};
1+
use crate::utils::{
2+
differing_macro_contexts, higher, in_macro, snippet_block_with_applicability, span_lint, span_lint_and_sugg,
3+
};
24
use rustc_errors::Applicability;
35
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
46
use rustc_hir::{BlockCheckMode, Expr, ExprKind};
@@ -55,7 +57,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
5557
if let ExprKind::Closure(_, _, eid, _, _) = expr.kind {
5658
let body = self.cx.tcx.hir().body(eid);
5759
let ex = &body.value;
58-
if matches!(ex.kind, ExprKind::Block(_, _)) && !body.value.span.from_expansion() {
60+
if matches!(ex.kind, ExprKind::Block(_, _)) && !in_macro(body.value.span) {
5961
self.found_block = Some(ex);
6062
return;
6163
}
@@ -83,7 +85,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlocksInIfConditions {
8385
if let Some(ex) = &block.expr {
8486
// don't dig into the expression here, just suggest that they remove
8587
// the block
86-
if expr.span.from_expansion() || differing_macro_contexts(expr.span, ex.span) {
88+
if in_macro(expr.span) || differing_macro_contexts(expr.span, ex.span) {
8789
return;
8890
}
8991
let mut applicability = Applicability::MachineApplicable;
@@ -108,7 +110,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlocksInIfConditions {
108110
}
109111
} else {
110112
let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
111-
if span.from_expansion() || differing_macro_contexts(expr.span, span) {
113+
if in_macro(span) || differing_macro_contexts(expr.span, span) {
112114
return;
113115
}
114116
// move block higher

clippy_lints/src/booleans.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
107107
}
108108

109109
// prevent folding of `cfg!` macros and the like
110-
if !e.span.from_expansion() {
110+
if !in_macro(e.span) {
111111
match &e.kind {
112112
ExprKind::Unary(UnOp::UnNot, inner) => return Ok(Bool::Not(box self.run(inner)?)),
113113
ExprKind::Binary(binop, lhs, rhs) => match &binop.node {

clippy_lints/src/eq_op.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
5656
#[allow(clippy::similar_names, clippy::too_many_lines)]
5757
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) {
5858
if let ExprKind::Binary(op, ref left, ref right) = e.kind {
59-
if e.span.from_expansion() {
59+
if in_macro(e.span) {
6060
return;
6161
}
6262
let macro_with_not_op = |expr_kind: &ExprKind<'_>| {

clippy_lints/src/erasing_op.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
44
use rustc_span::source_map::Span;
55

66
use crate::consts::{constant_simple, Constant};
7-
use crate::utils::span_lint;
7+
use crate::utils::{in_macro, span_lint};
88

99
declare_clippy_lint! {
1010
/// **What it does:** Checks for erasing operations, e.g., `x * 0`.
@@ -31,7 +31,7 @@ declare_lint_pass!(ErasingOp => [ERASING_OP]);
3131

3232
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ErasingOp {
3333
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) {
34-
if e.span.from_expansion() {
34+
if in_macro(e.span) {
3535
return;
3636
}
3737
if let ExprKind::Binary(ref cmp, ref left, ref right) = e.kind {

clippy_lints/src/identity_op.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
66
use rustc_span::source_map::Span;
77

88
use crate::consts::{constant_simple, Constant};
9-
use crate::utils::{clip, snippet, span_lint, unsext};
9+
use crate::utils::{clip, in_macro, snippet, span_lint, unsext};
1010

1111
declare_clippy_lint! {
1212
/// **What it does:** Checks for identity operations, e.g., `x + 0`.
@@ -30,7 +30,7 @@ declare_lint_pass!(IdentityOp => [IDENTITY_OP]);
3030

3131
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp {
3232
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) {
33-
if e.span.from_expansion() {
33+
if in_macro(e.span) {
3434
return;
3535
}
3636
if let ExprKind::Binary(cmp, ref left, ref right) = e.kind {

clippy_lints/src/len_zero.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::utils::{get_item_name, higher, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty};
1+
use crate::utils::{
2+
get_item_name, higher, in_macro, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty,
3+
};
24
use rustc_ast::ast::LitKind;
35
use rustc_data_structures::fx::FxHashSet;
46
use rustc_errors::Applicability;
@@ -72,7 +74,7 @@ declare_lint_pass!(LenZero => [LEN_ZERO, LEN_WITHOUT_IS_EMPTY]);
7274

7375
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero {
7476
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) {
75-
if item.span.from_expansion() {
77+
if in_macro(item.span) {
7678
return;
7779
}
7880

@@ -88,7 +90,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero {
8890
}
8991

9092
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
91-
if expr.span.from_expansion() {
93+
if in_macro(expr.span) {
9294
return;
9395
}
9496

clippy_lints/src/needless_bool.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
//! This lint is **warn** by default
44
55
use crate::utils::sugg::Sugg;
6-
use crate::utils::{higher, parent_node_is_if_expr, snippet_with_applicability, span_lint, span_lint_and_sugg};
6+
use crate::utils::{
7+
higher, in_macro, parent_node_is_if_expr, snippet_with_applicability, span_lint, span_lint_and_sugg,
8+
};
79
use if_chain::if_chain;
810
use rustc_ast::ast::LitKind;
911
use rustc_errors::Applicability;
@@ -129,7 +131,7 @@ declare_lint_pass!(BoolComparison => [BOOL_COMPARISON]);
129131

130132
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
131133
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) {
132-
if e.span.from_expansion() {
134+
if in_macro(e.span) {
133135
return;
134136
}
135137

clippy_lints/src/no_effect.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::utils::{has_drop, qpath_res, snippet_opt, span_lint, span_lint_and_sugg};
1+
use crate::utils::{has_drop, in_macro, qpath_res, snippet_opt, span_lint, span_lint_and_sugg};
22
use rustc_errors::Applicability;
33
use rustc_hir::def::{DefKind, Res};
44
use rustc_hir::{BinOpKind, BlockCheckMode, Expr, ExprKind, Stmt, StmtKind, UnsafeSource};
@@ -43,7 +43,7 @@ declare_clippy_lint! {
4343
}
4444

4545
fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
46-
if expr.span.from_expansion() {
46+
if in_macro(expr.span) {
4747
return false;
4848
}
4949
match expr.kind {
@@ -95,7 +95,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoEffect {
9595
} else if let Some(reduced) = reduce_expression(cx, expr) {
9696
let mut snippet = String::new();
9797
for e in reduced {
98-
if e.span.from_expansion() {
98+
if in_macro(e.span) {
9999
return;
100100
}
101101
if let Some(snip) = snippet_opt(cx, e.span) {
@@ -120,7 +120,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoEffect {
120120
}
121121

122122
fn reduce_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<Vec<&'a Expr<'a>>> {
123-
if expr.span.from_expansion() {
123+
if in_macro(expr.span) {
124124
return None;
125125
}
126126
match expr.kind {

clippy_lints/src/types.rs

+29-26
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ use rustc_typeck::hir_ty_to_ty;
2929
use crate::consts::{constant, Constant};
3030
use crate::utils::paths;
3131
use crate::utils::{
32-
clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_type_diagnostic_item,
33-
last_path_segment, match_def_path, match_path, method_chain_args, multispan_sugg, numeric_literal::NumericLiteral,
34-
qpath_res, sext, snippet, snippet_block_with_applicability, snippet_opt, snippet_with_applicability,
35-
snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext,
32+
clip, comparisons, differing_macro_contexts, higher, in_constant, in_macro, indent_of, int_bits,
33+
is_type_diagnostic_item, last_path_segment, match_def_path, match_path, method_chain_args, multispan_sugg,
34+
numeric_literal::NumericLiteral, qpath_res, sext, snippet, snippet_block_with_applicability, snippet_opt,
35+
snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg,
36+
span_lint_and_then, unsext,
3637
};
3738

3839
declare_clippy_lint! {
@@ -1965,35 +1966,37 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AbsurdExtremeComparisons {
19651966
use crate::types::AbsurdComparisonResult::{AlwaysFalse, AlwaysTrue, InequalityImpossible};
19661967
use crate::types::ExtremeType::{Maximum, Minimum};
19671968

1969+
if in_macro(expr.span) {
1970+
return;
1971+
}
1972+
19681973
if let ExprKind::Binary(ref cmp, ref lhs, ref rhs) = expr.kind {
19691974
if let Some((culprit, result)) = detect_absurd_comparison(cx, cmp.node, lhs, rhs) {
1970-
if !expr.span.from_expansion() {
1971-
let msg = "this comparison involving the minimum or maximum element for this \
1975+
let msg = "this comparison involving the minimum or maximum element for this \
19721976
type contains a case that is always true or always false";
19731977

1974-
let conclusion = match result {
1975-
AlwaysFalse => "this comparison is always false".to_owned(),
1976-
AlwaysTrue => "this comparison is always true".to_owned(),
1977-
InequalityImpossible => format!(
1978-
"the case where the two sides are not equal never occurs, consider using `{} == {}` \
1978+
let conclusion = match result {
1979+
AlwaysFalse => "this comparison is always false".to_owned(),
1980+
AlwaysTrue => "this comparison is always true".to_owned(),
1981+
InequalityImpossible => format!(
1982+
"the case where the two sides are not equal never occurs, consider using `{} == {}` \
19791983
instead",
1980-
snippet(cx, lhs.span, "lhs"),
1981-
snippet(cx, rhs.span, "rhs")
1982-
),
1983-
};
1984+
snippet(cx, lhs.span, "lhs"),
1985+
snippet(cx, rhs.span, "rhs")
1986+
),
1987+
};
19841988

1985-
let help = format!(
1986-
"because `{}` is the {} value for this type, {}",
1987-
snippet(cx, culprit.expr.span, "x"),
1988-
match culprit.which {
1989-
Minimum => "minimum",
1990-
Maximum => "maximum",
1991-
},
1992-
conclusion
1993-
);
1989+
let help = format!(
1990+
"because `{}` is the {} value for this type, {}",
1991+
snippet(cx, culprit.expr.span, "x"),
1992+
match culprit.which {
1993+
Minimum => "minimum",
1994+
Maximum => "maximum",
1995+
},
1996+
conclusion
1997+
);
19941998

1995-
span_lint_and_help(cx, ABSURD_EXTREME_COMPARISONS, expr.span, msg, None, &help);
1996-
}
1999+
span_lint_and_help(cx, ABSURD_EXTREME_COMPARISONS, expr.span, msg, None, &help);
19972000
}
19982001
}
19992002
}

clippy_lints/src/utils/mod.rs

+27-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use rustc_infer::infer::TyCtxtInferExt;
4343
use rustc_lint::{LateContext, Level, Lint, LintContext};
4444
use rustc_middle::hir::map::Map;
4545
use rustc_middle::ty::{self, layout::IntegerExt, subst::GenericArg, Ty, TyCtxt, TypeFoldable};
46-
use rustc_span::hygiene::{ExpnKind, MacroKind};
46+
use rustc_span::hygiene::{DesugaringKind, ExpnKind, MacroKind};
4747
use rustc_span::source_map::original_sp;
4848
use rustc_span::symbol::{self, kw, Symbol};
4949
use rustc_span::{BytePos, Pos, Span, DUMMY_SP};
@@ -58,7 +58,31 @@ use crate::reexport::Name;
5858
/// from a macro and one isn't).
5959
#[must_use]
6060
pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool {
61-
rhs.ctxt() != lhs.ctxt()
61+
let lhs_op_expn = from_operator_expansion(lhs);
62+
let rhs_op_expn = from_operator_expansion(rhs);
63+
64+
if lhs_op_expn && rhs_op_expn {
65+
// Ignore if both sides are just from operator expansions
66+
false
67+
} else if lhs_op_expn {
68+
// if only LHS is from operator expansion and RHS is from another expansion kind
69+
// => return true
70+
rhs.from_expansion()
71+
} else if rhs_op_expn {
72+
// if only RHS is from operator expansion and LHS is from another expansion kind
73+
// => return true
74+
lhs.from_expansion()
75+
} else {
76+
// of neither side is from an operator expansion, compare the `SpanContext`s
77+
rhs.ctxt() != lhs.ctxt()
78+
}
79+
}
80+
81+
fn from_operator_expansion(span: Span) -> bool {
82+
matches!(
83+
span.ctxt().outer_expn_data().kind,
84+
ExpnKind::Desugaring(DesugaringKind::Operator)
85+
)
6286
}
6387

6488
/// Returns `true` if the given `NodeId` is inside a constant context
@@ -111,6 +135,7 @@ pub fn in_macro(span: Span) -> bool {
111135
false
112136
}
113137
}
138+
114139
// If the snippet is empty, it's an attribute that was inserted during macro
115140
// expansion and we want to ignore those, because they could come from external
116141
// sources that the user has no control over.

0 commit comments

Comments
 (0)