Skip to content

Commit 08fa871

Browse files
authored
Even more fixes for handling of macros (#16443)
*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust-clippy/pull/16443)* Continuation rust-lang/rust-clippy#16337 Even more fixes for handling macros changelog: [`manual_rotate`] fix wrongly unmangled macros changelog: [`map_with_unused_argument_over_ranges`] fix wrongly unmangled macros changelog: [`needless_bool`] fix wrongly unmangled macros changelog: [`manual_is_power_of_two`] fix wrongly unmangled macros changelog: [`manual_div_ceil`] fix wrongly unmangled macros changelog: [`implicit_saturating_sub`] fix wrongly unmangled macros changelog: [`range_minus_one`] fix wrongly unmangled macros changelog: [`range_plus_one`] fix wrongly unmangled macros changelog: [`manual_swap`] fix wrongly unmangled macros changelog: [`let_and_return`] fix wrongly unmangled macros
2 parents d588ba3 + ede468a commit 08fa871

42 files changed

Lines changed: 555 additions & 135 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

clippy_lints/src/implicit_saturating_sub.rs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::borrow::Cow;
33
use clippy_config::Conf;
44
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
55
use clippy_utils::msrvs::{self, Msrv};
6-
use clippy_utils::source::snippet_with_applicability;
6+
use clippy_utils::source::snippet_with_context;
77
use clippy_utils::sugg::{Sugg, make_binop};
88
use clippy_utils::{
99
SpanlessEq, eq_expr_value, higher, is_in_const_context, is_integer_literal, is_integer_literal_untyped,
@@ -246,33 +246,35 @@ fn check_subtraction(
246246
// This part of the condition is voluntarily split from the one before to ensure that
247247
// if `snippet_opt` fails, it won't try the next conditions.
248248
if !is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST) {
249-
let mut applicability = Applicability::MachineApplicable;
250-
let big_expr_sugg = (if is_integer_literal_untyped(big_expr) {
251-
let get_snippet = |span: Span| {
252-
let snippet = snippet_with_applicability(cx, span, "..", &mut applicability);
253-
let big_expr_ty = cx.typeck_results().expr_ty(big_expr);
254-
Cow::Owned(format!("{snippet}_{big_expr_ty}"))
255-
};
256-
Sugg::hir_from_snippet(cx, big_expr, get_snippet)
257-
} else {
258-
Sugg::hir_with_applicability(cx, big_expr, "..", &mut applicability)
259-
})
260-
.maybe_paren();
261-
let little_expr_sugg = Sugg::hir_with_applicability(cx, little_expr, "..", &mut applicability);
262-
263-
let sugg = format!(
264-
"{}{big_expr_sugg}.saturating_sub({little_expr_sugg}){}",
265-
if is_composited { "{ " } else { "" },
266-
if is_composited { " }" } else { "" }
267-
);
268-
span_lint_and_sugg(
249+
span_lint_and_then(
269250
cx,
270251
IMPLICIT_SATURATING_SUB,
271252
expr_span,
272253
"manual arithmetic check found",
273-
"replace it with",
274-
sugg,
275-
applicability,
254+
|diag| {
255+
let mut applicability = Applicability::MachineApplicable;
256+
let expr_span_ctxt = expr_span.ctxt();
257+
let big_expr_sugg = (if is_integer_literal_untyped(big_expr) {
258+
let get_snippet = |span: Span| {
259+
let (snippet, _) =
260+
snippet_with_context(cx, span, expr_span_ctxt, "..", &mut applicability);
261+
let big_expr_ty = cx.typeck_results().expr_ty(big_expr);
262+
Cow::Owned(format!("{snippet}_{big_expr_ty}"))
263+
};
264+
Sugg::hir_from_snippet(cx, big_expr, get_snippet)
265+
} else {
266+
Sugg::hir_with_context(cx, big_expr, expr_span_ctxt, "..", &mut applicability)
267+
})
268+
.maybe_paren();
269+
let little_expr_sugg =
270+
Sugg::hir_with_context(cx, little_expr, expr_span_ctxt, "..", &mut applicability);
271+
let sugg = format!(
272+
"{}{big_expr_sugg}.saturating_sub({little_expr_sugg}){}",
273+
if is_composited { "{ " } else { "" },
274+
if is_composited { " }" } else { "" }
275+
);
276+
diag.span_suggestion(expr_span, "replace it with", sugg, applicability);
277+
},
276278
);
277279
}
278280
} else if eq_expr_value(cx, left, little_expr)

clippy_lints/src/manual_is_power_of_two.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl ManualIsPowerOfTwo {
5151
}
5252

5353
let mut applicability = Applicability::MachineApplicable;
54-
let snippet = Sugg::hir_with_applicability(cx, receiver, "_", &mut applicability);
54+
let snippet = Sugg::hir_with_context(cx, receiver, expr.span.ctxt(), "_", &mut applicability);
5555

5656
span_lint_and_sugg(
5757
cx,

clippy_lints/src/manual_rotate.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt::Display;
22

33
use clippy_utils::consts::{ConstEvalCtxt, Constant};
4-
use clippy_utils::diagnostics::span_lint_and_sugg;
4+
use clippy_utils::diagnostics::span_lint_and_then;
55
use clippy_utils::sugg;
66
use rustc_errors::Applicability;
77
use rustc_hir::{BinOpKind, Expr, ExprKind};
@@ -116,17 +116,23 @@ impl LateLintPass<'_> for ManualRotate {
116116
}
117117
};
118118

119-
let mut applicability = Applicability::MachineApplicable;
120-
let expr_sugg = sugg::Sugg::hir_with_applicability(cx, l_expr, "_", &mut applicability).maybe_paren();
121-
let amount = sugg::Sugg::hir_with_applicability(cx, amount, "_", &mut applicability);
122-
span_lint_and_sugg(
119+
span_lint_and_then(
123120
cx,
124121
MANUAL_ROTATE,
125122
expr.span,
126123
"there is no need to manually implement bit rotation",
127-
"this expression can be rewritten as",
128-
format!("{expr_sugg}.{shift_function}({amount})"),
129-
Applicability::MachineApplicable,
124+
|diag| {
125+
let mut applicability = Applicability::MachineApplicable;
126+
let expr_sugg = sugg::Sugg::hir_with_context(cx, l_expr, expr.span.ctxt(), "_", &mut applicability)
127+
.maybe_paren();
128+
let amount = sugg::Sugg::hir_with_context(cx, amount, expr.span.ctxt(), "_", &mut applicability);
129+
diag.span_suggestion(
130+
expr.span,
131+
"this expression can be rewritten as",
132+
format!("{expr_sugg}.{shift_function}({amount})"),
133+
applicability,
134+
);
135+
},
130136
);
131137
}
132138
}

clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES;
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::msrvs::{self, Msrv};
4-
use clippy_utils::source::snippet_with_applicability;
4+
use clippy_utils::source::snippet_with_context;
55
use clippy_utils::sugg::Sugg;
66
use clippy_utils::{eager_or_lazy, higher, std_or_core, usage};
77
use rustc_ast::LitKind;
@@ -10,12 +10,13 @@ use rustc_data_structures::packed::Pu128;
1010
use rustc_errors::Applicability;
1111
use rustc_hir::{Body, Closure, Expr, ExprKind};
1212
use rustc_lint::LateContext;
13-
use rustc_span::Span;
13+
use rustc_span::{Span, SyntaxContext};
1414

1515
fn extract_count_with_applicability(
1616
cx: &LateContext<'_>,
1717
range: higher::Range<'_>,
1818
applicability: &mut Applicability,
19+
ctxt: SyntaxContext,
1920
) -> Option<String> {
2021
let start = range.start?;
2122
let end = range.end?;
@@ -40,7 +41,7 @@ fn extract_count_with_applicability(
4041
};
4142
return Some(format!("{count}"));
4243
}
43-
let end_snippet = Sugg::hir_with_applicability(cx, end, "...", applicability)
44+
let end_snippet = Sugg::hir_with_context(cx, end, ctxt, "...", applicability)
4445
.maybe_paren()
4546
.into_string();
4647
if lower_bound == 0 {
@@ -74,52 +75,43 @@ pub(super) fn check(
7475
value: body_expr,
7576
} = body_hir
7677
&& !usage::BindingUsageFinder::are_params_used(cx, body_hir)
77-
&& let Some(count) = extract_count_with_applicability(cx, range, &mut applicability)
78+
&& let ctxt = ex.span.ctxt()
79+
&& let Some(count) = extract_count_with_applicability(cx, range, &mut applicability, ctxt)
7880
&& let Some(exec_context) = std_or_core(cx)
7981
{
80-
let method_to_use_name;
81-
let new_span;
82-
let use_take;
83-
84-
if eager_or_lazy::switch_to_eager_eval(cx, body_expr) {
82+
let (method_to_use_name, new_span, use_take) = if eager_or_lazy::switch_to_eager_eval(cx, body_expr) {
8583
if msrv.meets(cx, msrvs::REPEAT_N) {
86-
method_to_use_name = "repeat_n";
87-
let body_snippet = snippet_with_applicability(cx, body_expr.span, "..", &mut applicability);
88-
new_span = (arg.span, format!("{body_snippet}, {count}"));
89-
use_take = false;
84+
let (body_snippet, _) = snippet_with_context(cx, body_expr.span, ctxt, "..", &mut applicability);
85+
("repeat_n", (arg.span, format!("{body_snippet}, {count}")), false)
9086
} else {
91-
method_to_use_name = "repeat";
92-
let body_snippet = snippet_with_applicability(cx, body_expr.span, "..", &mut applicability);
93-
new_span = (arg.span, body_snippet.to_string());
94-
use_take = true;
87+
let (body_snippet, _) = snippet_with_context(cx, body_expr.span, ctxt, "..", &mut applicability);
88+
("repeat", (arg.span, body_snippet.to_string()), true)
9589
}
9690
} else if msrv.meets(cx, msrvs::REPEAT_WITH) {
97-
method_to_use_name = "repeat_with";
98-
new_span = (param.span, String::new());
99-
use_take = true;
91+
("repeat_with", (param.span, String::new()), true)
10092
} else {
10193
return;
102-
}
103-
104-
// We need to provide nonempty parts to diag.multipart_suggestion so we
105-
// collate all our parts here and then remove those that are empty.
106-
let mut parts = vec![
107-
(
108-
ex.span.with_hi(method_name_span.hi()),
109-
format!("{exec_context}::iter::{method_to_use_name}"),
110-
),
111-
new_span,
112-
];
113-
if use_take {
114-
parts.push((ex.span.shrink_to_hi(), format!(".take({count})")));
115-
}
94+
};
11695

11796
span_lint_and_then(
11897
cx,
11998
MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
12099
ex.span,
121100
"map of a closure that does not depend on its parameter over a range",
122101
|diag| {
102+
// We need to provide nonempty parts to diag.multipart_suggestion so we
103+
// collate all our parts here and then remove those that are empty.
104+
let mut parts = vec![
105+
(
106+
ex.span.with_hi(method_name_span.hi()),
107+
format!("{exec_context}::iter::{method_to_use_name}"),
108+
),
109+
new_span,
110+
];
111+
if use_take {
112+
parts.push((ex.span.shrink_to_hi(), format!(".take({count})")));
113+
}
114+
123115
diag.multipart_suggestion(
124116
if use_take {
125117
format!("remove the explicit range and use `{method_to_use_name}` and `take`")

clippy_lints/src/needless_bool.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
112112
{
113113
let reduce = |ret, not| {
114114
let mut applicability = Applicability::MachineApplicable;
115-
let snip = Sugg::hir_with_applicability(cx, cond, "<predicate>", &mut applicability);
115+
let snip = Sugg::hir_with_context(cx, cond, e.span.ctxt(), "<predicate>", &mut applicability);
116116
let mut snip = if not { !snip } else { snip };
117117

118118
if ret {

clippy_lints/src/operators/manual_div_ceil.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ fn build_suggestion(
148148
rhs: &Expr<'_>,
149149
applicability: &mut Applicability,
150150
) {
151-
let dividend_sugg = Sugg::hir_with_applicability(cx, lhs, "..", applicability).maybe_paren();
151+
let ctxt = expr.span.ctxt();
152+
let dividend_sugg = Sugg::hir_with_context(cx, lhs, ctxt, "..", applicability).maybe_paren();
152153
let rhs_ty = cx.typeck_results().expr_ty(rhs);
153154
let type_suffix = if cx.typeck_results().expr_ty(lhs).is_numeric()
154155
&& matches!(
@@ -186,7 +187,7 @@ fn build_suggestion(
186187
};
187188

188189
// Dereference the RHS if it is a reference type
189-
let divisor_snippet = match Sugg::hir_with_context(cx, rhs, expr.span.ctxt(), "_", applicability) {
190+
let divisor_snippet = match Sugg::hir_with_context(cx, rhs, ctxt, "_", applicability) {
190191
sugg if rhs_ty.is_ref() => sugg.deref(),
191192
sugg => sugg,
192193
};

clippy_lints/src/operators/needless_bitwise_bool.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
2-
use clippy_utils::source::SpanRangeExt;
2+
use clippy_utils::source::snippet_with_context;
33
use rustc_errors::Applicability;
44
use rustc_hir::{BinOpKind, Expr, ExprKind};
55
use rustc_lint::LateContext;
@@ -24,12 +24,12 @@ pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, op: BinOpKind, lhs: &Exp
2424
e.span,
2525
"use of bitwise operator instead of lazy operator between booleans",
2626
|diag| {
27-
if let Some(lhs_snip) = lhs.span.get_source_text(cx)
28-
&& let Some(rhs_snip) = rhs.span.get_source_text(cx)
29-
{
30-
let sugg = format!("{lhs_snip} {op_str} {rhs_snip}");
31-
diag.span_suggestion(e.span, "try", sugg, Applicability::MachineApplicable);
32-
}
27+
let mut applicability = Applicability::MachineApplicable;
28+
let expr_span_ctxt = e.span.ctxt();
29+
let (lhs_snip, _) = snippet_with_context(cx, lhs.span, expr_span_ctxt, "..", &mut applicability);
30+
let (rhs_snip, _) = snippet_with_context(cx, rhs.span, expr_span_ctxt, "..", &mut applicability);
31+
32+
diag.span_suggestion(e.span, "try", format!("{lhs_snip} {op_str} {rhs_snip}"), applicability);
3333
},
3434
);
3535
}

clippy_lints/src/ranges.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,11 +518,11 @@ fn check_range_switch<'tcx>(
518518
span_lint_and_then(cx, lint, span, msg, |diag| {
519519
let mut app = Applicability::MachineApplicable;
520520
let start = start.map_or(String::new(), |x| {
521-
Sugg::hir_with_applicability(cx, x, "<x>", &mut app)
521+
Sugg::hir_with_context(cx, x, span.ctxt(), "<x>", &mut app)
522522
.maybe_paren()
523523
.to_string()
524524
});
525-
let end = Sugg::hir_with_applicability(cx, y, "<y>", &mut app).maybe_paren();
525+
let end = Sugg::hir_with_context(cx, y, span.ctxt(), "<y>", &mut app).maybe_paren();
526526
match span.with_source_text(cx, |src| src.starts_with('(') && src.ends_with(')')) {
527527
Some(true) => {
528528
diag.span_suggestion(span, "use", format!("({start}{operator}{end})"), app);

clippy_lints/src/returns/let_and_return.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_hir_and_then;
22
use clippy_utils::res::MaybeResPath;
3-
use clippy_utils::source::SpanRangeExt;
3+
use clippy_utils::source::snippet_with_context;
44
use clippy_utils::sugg::has_enclosing_paren;
55
use clippy_utils::visitors::for_each_expr;
66
use clippy_utils::{binary_expr_needs_parentheses, fn_def_id, span_contains_non_whitespace};
@@ -38,30 +38,29 @@ pub(super) fn check_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'_>)
3838
|err| {
3939
err.span_label(local.span, "unnecessary `let` binding");
4040

41-
if let Some(src) = initexpr.span.get_source_text(cx) {
42-
let sugg = if binary_expr_needs_parentheses(initexpr) {
43-
if has_enclosing_paren(&src) {
44-
src.to_owned()
45-
} else {
46-
format!("({src})")
47-
}
48-
} else if !cx.typeck_results().expr_adjustments(retexpr).is_empty() {
49-
if has_enclosing_paren(&src) {
50-
format!("{src} as _")
51-
} else {
52-
format!("({src}) as _")
53-
}
41+
let mut app = Applicability::MachineApplicable;
42+
let (src, _) = snippet_with_context(cx, initexpr.span, local.span.ctxt(), "..", &mut app);
43+
44+
let sugg = if binary_expr_needs_parentheses(initexpr) {
45+
if has_enclosing_paren(&src) {
46+
src.to_string()
47+
} else {
48+
format!("({src})")
49+
}
50+
} else if !cx.typeck_results().expr_adjustments(retexpr).is_empty() {
51+
if has_enclosing_paren(&src) {
52+
format!("{src} as _")
5453
} else {
55-
src.to_owned()
56-
};
57-
err.multipart_suggestion(
58-
"return the expression directly",
59-
vec![(local.span, String::new()), (retexpr.span, sugg)],
60-
Applicability::MachineApplicable,
61-
);
54+
format!("({src}) as _")
55+
}
6256
} else {
63-
err.span_help(initexpr.span, "this expression can be directly returned");
64-
}
57+
src.to_string()
58+
};
59+
err.multipart_suggestion(
60+
"return the expression directly",
61+
vec![(local.span, String::new()), (retexpr.span, sugg)],
62+
app,
63+
);
6564
},
6665
);
6766
}

clippy_lints/src/swap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fn generate_swap_warning<'tcx>(
112112
|| ty.is_diag_item(cx, sym::Vec)
113113
|| ty.is_diag_item(cx, sym::VecDeque)
114114
{
115-
let slice = Sugg::hir_with_applicability(cx, lhs1, "<slice>", &mut applicability);
115+
let slice = Sugg::hir_with_context(cx, lhs1, ctxt, "<slice>", &mut applicability);
116116

117117
span_lint_and_sugg(
118118
cx,

0 commit comments

Comments
 (0)