Skip to content

Commit 783bc62

Browse files
committed
Auto merge of #10438 - Jarcho:use_snip_ctxt, r=dswij
Use `snippet_with_context` more No tests at the moment. Need to find a way to write macro tests without writing a pile of macros. changelog: None
2 parents 70e85d1 + efbcb99 commit 783bc62

17 files changed

+159
-129
lines changed

clippy_lints/src/casts/cast_slice_from_raw_parts.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::msrvs::{self, Msrv};
3-
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::source::snippet_with_context;
44
use clippy_utils::{match_def_path, paths};
55
use if_chain::if_chain;
66
use rustc_errors::Applicability;
@@ -34,15 +34,17 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
3434
if let ExprKind::Path(ref qpath) = fun.kind;
3535
if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id();
3636
if let Some(rpk) = raw_parts_kind(cx, fun_def_id);
37+
let ctxt = expr.span.ctxt();
38+
if cast_expr.span.ctxt() == ctxt;
3739
then {
3840
let func = match rpk {
3941
RawPartsKind::Immutable => "from_raw_parts",
4042
RawPartsKind::Mutable => "from_raw_parts_mut"
4143
};
4244
let span = expr.span;
4345
let mut applicability = Applicability::MachineApplicable;
44-
let ptr = snippet_with_applicability(cx, ptr_arg.span, "ptr", &mut applicability);
45-
let len = snippet_with_applicability(cx, len_arg.span, "len", &mut applicability);
46+
let ptr = snippet_with_context(cx, ptr_arg.span, ctxt, "ptr", &mut applicability).0;
47+
let len = snippet_with_context(cx, len_arg.span, ctxt, "len", &mut applicability).0;
4648
span_lint_and_sugg(
4749
cx,
4850
CAST_SLICE_FROM_RAW_PARTS,

clippy_lints/src/default_instead_of_iter_empty.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::last_path_segment;
3-
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::source::snippet_with_context;
44
use clippy_utils::{match_def_path, paths};
55
use rustc_errors::Applicability;
66
use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind};
77
use rustc_lint::{LateContext, LateLintPass};
88
use rustc_session::{declare_lint_pass, declare_tool_lint};
9+
use rustc_span::SyntaxContext;
910

1011
declare_clippy_lint! {
1112
/// ### What it does
@@ -38,9 +39,11 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty {
3839
&& let QPath::Resolved(None, path) = ty_path
3940
&& let def::Res::Def(_, def_id) = &path.res
4041
&& match_def_path(cx, *def_id, &paths::ITER_EMPTY)
42+
&& let ctxt = expr.span.ctxt()
43+
&& ty.span.ctxt() == ctxt
4144
{
4245
let mut applicability = Applicability::MachineApplicable;
43-
let sugg = make_sugg(cx, ty_path, &mut applicability);
46+
let sugg = make_sugg(cx, ty_path, ctxt, &mut applicability);
4447
span_lint_and_sugg(
4548
cx,
4649
DEFAULT_INSTEAD_OF_ITER_EMPTY,
@@ -54,14 +57,19 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty {
5457
}
5558
}
5659

57-
fn make_sugg(cx: &LateContext<'_>, ty_path: &rustc_hir::QPath<'_>, applicability: &mut Applicability) -> String {
60+
fn make_sugg(
61+
cx: &LateContext<'_>,
62+
ty_path: &rustc_hir::QPath<'_>,
63+
ctxt: SyntaxContext,
64+
applicability: &mut Applicability,
65+
) -> String {
5866
if let Some(last) = last_path_segment(ty_path).args
5967
&& let Some(iter_ty) = last.args.iter().find_map(|arg| match arg {
6068
GenericArg::Type(ty) => Some(ty),
6169
_ => None,
6270
})
6371
{
64-
format!("std::iter::empty::<{}>()", snippet_with_applicability(cx, iter_ty.span, "..", applicability))
72+
format!("std::iter::empty::<{}>()", snippet_with_context(cx, iter_ty.span, ctxt, "..", applicability).0)
6573
} else {
6674
"std::iter::empty()".to_owned()
6775
}

clippy_lints/src/format.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn};
3-
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::source::snippet_with_context;
44
use clippy_utils::sugg::Sugg;
55
use if_chain::if_chain;
66
use rustc_errors::Applicability;
@@ -84,9 +84,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
8484
_ => false,
8585
};
8686
let sugg = if is_new_string {
87-
snippet_with_applicability(cx, value.span, "..", &mut applicability).into_owned()
87+
snippet_with_context(cx, value.span, call_site.ctxt(), "..", &mut applicability).0.into_owned()
8888
} else {
89-
let sugg = Sugg::hir_with_applicability(cx, value, "<arg>", &mut applicability);
89+
let sugg = Sugg::hir_with_context(cx, value, call_site.ctxt(), "<arg>", &mut applicability);
9090
format!("{}.to_string()", sugg.maybe_par())
9191
};
9292
span_useless_format(cx, call_site, sugg, applicability);

clippy_lints/src/implicit_saturating_add.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_utils::consts::{constant, Constant};
22
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::get_parent_expr;
4-
use clippy_utils::source::snippet_with_applicability;
4+
use clippy_utils::source::snippet_with_context;
55
use if_chain::if_chain;
66
use rustc_ast::ast::{LitIntType, LitKind};
77
use rustc_errors::Applicability;
@@ -55,15 +55,25 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd {
5555
if let ExprKind::AssignOp(op1, target, value) = ex.kind;
5656
let ty = cx.typeck_results().expr_ty(target);
5757
if Some(c) == get_int_max(ty);
58+
let ctxt = expr.span.ctxt();
59+
if ex.span.ctxt() == ctxt;
60+
if expr1.span.ctxt() == ctxt;
5861
if clippy_utils::SpanlessEq::new(cx).eq_expr(l, target);
5962
if BinOpKind::Add == op1.node;
6063
if let ExprKind::Lit(ref lit) = value.kind;
6164
if let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node;
6265
if block.expr.is_none();
6366
then {
6467
let mut app = Applicability::MachineApplicable;
65-
let code = snippet_with_applicability(cx, target.span, "_", &mut app);
66-
let sugg = if let Some(parent) = get_parent_expr(cx, expr) && let ExprKind::If(_cond, _then, Some(else_)) = parent.kind && else_.hir_id == expr.hir_id {format!("{{{code} = {code}.saturating_add(1); }}")} else {format!("{code} = {code}.saturating_add(1);")};
68+
let code = snippet_with_context(cx, target.span, ctxt, "_", &mut app).0;
69+
let sugg = if let Some(parent) = get_parent_expr(cx, expr)
70+
&& let ExprKind::If(_cond, _then, Some(else_)) = parent.kind
71+
&& else_.hir_id == expr.hir_id
72+
{
73+
format!("{{{code} = {code}.saturating_add(1); }}")
74+
} else {
75+
format!("{code} = {code}.saturating_add(1);")
76+
};
6777
span_lint_and_sugg(cx, IMPLICIT_SATURATING_ADD, expr.span, "manual saturating add detected", "use instead", sugg, app);
6878
}
6979
}

clippy_lints/src/instant_subtraction.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::{self, span_lint_and_sugg};
22
use clippy_utils::msrvs::{self, Msrv};
3-
use clippy_utils::source;
3+
use clippy_utils::source::snippet_with_context;
44
use clippy_utils::sugg::Sugg;
55
use clippy_utils::ty;
66
use rustc_errors::Applicability;
@@ -161,14 +161,9 @@ fn print_unchecked_duration_subtraction_sugg(
161161
) {
162162
let mut applicability = Applicability::MachineApplicable;
163163

164-
let left_expr =
165-
source::snippet_with_applicability(cx, left_expr.span, "std::time::Instant::now()", &mut applicability);
166-
let right_expr = source::snippet_with_applicability(
167-
cx,
168-
right_expr.span,
169-
"std::time::Duration::from_secs(1)",
170-
&mut applicability,
171-
);
164+
let ctxt = expr.span.ctxt();
165+
let left_expr = snippet_with_context(cx, left_expr.span, ctxt, "<instant>", &mut applicability).0;
166+
let right_expr = snippet_with_context(cx, right_expr.span, ctxt, "<duration>", &mut applicability).0;
172167

173168
diagnostics::span_lint_and_sugg(
174169
cx,

clippy_lints/src/len_zero.rs

+5-12
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
2-
use clippy_utils::source::snippet_with_applicability;
3-
use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators};
2+
use clippy_utils::source::snippet_with_context;
3+
use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators, sugg::Sugg};
44
use if_chain::if_chain;
55
use rustc_ast::ast::LitKind;
66
use rustc_errors::Applicability;
77
use rustc_hir::def_id::DefIdSet;
88
use rustc_hir::{
99
def_id::DefId, AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, ImplItem, ImplItemKind, ImplicitSelfKind, Item,
10-
ItemKind, Mutability, Node, TraitItemRef, TyKind, UnOp,
10+
ItemKind, Mutability, Node, TraitItemRef, TyKind,
1111
};
1212
use rustc_lint::{LateContext, LateLintPass};
1313
use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
@@ -16,7 +16,6 @@ use rustc_span::{
1616
source_map::{Span, Spanned, Symbol},
1717
symbol::sym,
1818
};
19-
use std::borrow::Cow;
2019

2120
declare_clippy_lint! {
2221
/// ### What it does
@@ -431,7 +430,7 @@ fn check_len(
431430
&format!("using `{op}is_empty` is clearer and more explicit"),
432431
format!(
433432
"{op}{}.is_empty()",
434-
snippet_with_applicability(cx, receiver.span, "_", &mut applicability)
433+
snippet_with_context(cx, receiver.span, span.ctxt(), "_", &mut applicability).0,
435434
),
436435
applicability,
437436
);
@@ -444,13 +443,7 @@ fn check_empty_expr(cx: &LateContext<'_>, span: Span, lit1: &Expr<'_>, lit2: &Ex
444443
let mut applicability = Applicability::MachineApplicable;
445444

446445
let lit1 = peel_ref_operators(cx, lit1);
447-
let mut lit_str = snippet_with_applicability(cx, lit1.span, "_", &mut applicability);
448-
449-
// Wrap the expression in parentheses if it's a deref expression. Otherwise operator precedence will
450-
// cause the code to dereference boolean(won't compile).
451-
if let ExprKind::Unary(UnOp::Deref, _) = lit1.kind {
452-
lit_str = Cow::from(format!("({lit_str})"));
453-
}
446+
let lit_str = Sugg::hir_with_context(cx, lit1, span.ctxt(), "_", &mut applicability).maybe_par();
454447

455448
span_lint_and_sugg(
456449
cx,

clippy_lints/src/manual_bits.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::get_parent_expr;
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 rustc_ast::ast::LitKind;
66
use rustc_errors::Applicability;
77
use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath};
8-
use rustc_lint::{LateContext, LateLintPass};
8+
use rustc_lint::{LateContext, LateLintPass, LintContext};
9+
use rustc_middle::lint::in_external_macro;
910
use rustc_middle::ty::{self, Ty};
1011
use rustc_session::{declare_tool_lint, impl_lint_pass};
1112
use rustc_span::sym;
@@ -55,13 +56,17 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits {
5556
if_chain! {
5657
if let ExprKind::Binary(bin_op, left_expr, right_expr) = expr.kind;
5758
if let BinOpKind::Mul = &bin_op.node;
59+
if !in_external_macro(cx.sess(), expr.span);
60+
let ctxt = expr.span.ctxt();
61+
if left_expr.span.ctxt() == ctxt;
62+
if right_expr.span.ctxt() == ctxt;
5863
if let Some((real_ty, resolved_ty, other_expr)) = get_one_size_of_ty(cx, left_expr, right_expr);
5964
if matches!(resolved_ty.kind(), ty::Int(_) | ty::Uint(_));
6065
if let ExprKind::Lit(lit) = &other_expr.kind;
6166
if let LitKind::Int(8, _) = lit.node;
6267
then {
6368
let mut app = Applicability::MachineApplicable;
64-
let ty_snip = snippet_with_applicability(cx, real_ty.span, "..", &mut app);
69+
let ty_snip = snippet_with_context(cx, real_ty.span, ctxt, "..", &mut app).0;
6570
let sugg = create_sugg(cx, expr, format!("{ty_snip}::BITS"));
6671

6772
span_lint_and_sugg(

clippy_lints/src/manual_is_ascii_check.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::msrvs::{self, Msrv};
2-
use clippy_utils::{diagnostics::span_lint_and_sugg, higher, in_constant, macros::root_macro_call, source::snippet};
2+
use clippy_utils::{diagnostics::span_lint_and_sugg, higher, in_constant, macros::root_macro_call, sugg::Sugg};
33
use rustc_ast::ast::RangeLimits;
44
use rustc_ast::LitKind::{Byte, Char};
55
use rustc_errors::Applicability;
@@ -115,15 +115,8 @@ fn check_is_ascii(cx: &LateContext<'_>, span: Span, recv: &Expr<'_>, range: &Cha
115115
CharRange::Otherwise => None,
116116
} {
117117
let default_snip = "..";
118-
// `snippet_with_applicability` may set applicability to `MaybeIncorrect` for
119-
// macro span, so we check applicability manually by comparing `recv` is not default.
120-
let recv = snippet(cx, recv.span, default_snip);
121-
122-
let applicability = if recv == default_snip {
123-
Applicability::HasPlaceholders
124-
} else {
125-
Applicability::MachineApplicable
126-
};
118+
let mut app = Applicability::MachineApplicable;
119+
let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), default_snip, &mut app).maybe_par();
127120

128121
span_lint_and_sugg(
129122
cx,
@@ -132,7 +125,7 @@ fn check_is_ascii(cx: &LateContext<'_>, span: Span, recv: &Expr<'_>, range: &Cha
132125
"manual check for common ascii range",
133126
"try",
134127
format!("{recv}.{sugg}()"),
135-
applicability,
128+
app,
136129
);
137130
}
138131
}

clippy_lints/src/manual_rem_euclid.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_utils::consts::{constant_full_int, FullInt};
22
use clippy_utils::diagnostics::span_lint_and_sugg;
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::{in_constant, path_to_local};
66
use rustc_errors::Applicability;
77
use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
@@ -60,12 +60,16 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
6060
return;
6161
}
6262

63+
// (x % c + c) % c
6364
if let ExprKind::Binary(op1, expr1, right) = expr.kind
6465
&& op1.node == BinOpKind::Rem
66+
&& let ctxt = expr.span.ctxt()
67+
&& expr1.span.ctxt() == ctxt
6568
&& let Some(const1) = check_for_unsigned_int_constant(cx, right)
6669
&& let ExprKind::Binary(op2, left, right) = expr1.kind
6770
&& op2.node == BinOpKind::Add
6871
&& let Some((const2, expr2)) = check_for_either_unsigned_int_constant(cx, left, right)
72+
&& expr2.span.ctxt() == ctxt
6973
&& let ExprKind::Binary(op3, expr3, right) = expr2.kind
7074
&& op3.node == BinOpKind::Rem
7175
&& let Some(const3) = check_for_unsigned_int_constant(cx, right)
@@ -86,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
8690
};
8791

8892
let mut app = Applicability::MachineApplicable;
89-
let rem_of = snippet_with_applicability(cx, expr3.span, "_", &mut app);
93+
let rem_of = snippet_with_context(cx, expr3.span, ctxt, "_", &mut app).0;
9094
span_lint_and_sugg(
9195
cx,
9296
MANUAL_REM_EUCLID,

clippy_lints/src/match_result_ok.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::higher;
3-
use clippy_utils::method_chain_args;
4-
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::is_res_lang_ctor;
4+
use clippy_utils::source::snippet_with_context;
55
use clippy_utils::ty::is_type_diagnostic_item;
66
use if_chain::if_chain;
77
use rustc_errors::Applicability;
8-
use rustc_hir::{Expr, ExprKind, PatKind, QPath};
8+
use rustc_hir::{Expr, ExprKind, LangItem, PatKind};
99
use rustc_lint::{LateContext, LateLintPass};
1010
use rustc_session::{declare_lint_pass, declare_tool_lint};
1111
use rustc_span::sym;
@@ -58,17 +58,18 @@ impl<'tcx> LateLintPass<'tcx> for MatchResultOk {
5858
};
5959

6060
if_chain! {
61-
if let ExprKind::MethodCall(ok_path, result_types_0, ..) = let_expr.kind; //check is expr.ok() has type Result<T,E>.ok(, _)
62-
if let PatKind::TupleStruct(QPath::Resolved(_, x), y, _) = let_pat.kind; //get operation
63-
if method_chain_args(let_expr, &["ok"]).is_some(); //test to see if using ok() method use std::marker::Sized;
64-
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(result_types_0), sym::Result);
65-
if rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(x, false)) == "Some";
66-
61+
if let ExprKind::MethodCall(ok_path, recv, [], ..) = let_expr.kind; //check is expr.ok() has type Result<T,E>.ok(, _)
62+
if let PatKind::TupleStruct(ref pat_path, [ok_pat], _) = let_pat.kind; //get operation
63+
if ok_path.ident.as_str() == "ok";
64+
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
65+
if is_res_lang_ctor(cx, cx.qpath_res(pat_path, let_pat.hir_id), LangItem::OptionSome);
66+
let ctxt = expr.span.ctxt();
67+
if let_expr.span.ctxt() == ctxt;
68+
if let_pat.span.ctxt() == ctxt;
6769
then {
68-
6970
let mut applicability = Applicability::MachineApplicable;
70-
let some_expr_string = snippet_with_applicability(cx, y[0].span, "", &mut applicability);
71-
let trimmed_ok = snippet_with_applicability(cx, let_expr.span.until(ok_path.ident.span), "", &mut applicability);
71+
let some_expr_string = snippet_with_context(cx, ok_pat.span, ctxt, "", &mut applicability).0;
72+
let trimmed_ok = snippet_with_context(cx, recv.span, ctxt, "", &mut applicability).0;
7273
let sugg = format!(
7374
"{ifwhile} let Ok({some_expr_string}) = {}",
7475
trimmed_ok.trim().trim_end_matches('.'),

clippy_lints/src/neg_multiply.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::consts::{self, Constant};
22
use clippy_utils::diagnostics::span_lint_and_sugg;
3-
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::source::snippet_with_context;
44
use clippy_utils::sugg::has_enclosing_paren;
55
use if_chain::if_chain;
66
use rustc_ast::util::parser::PREC_PREFIX;
@@ -60,8 +60,8 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
6060

6161
then {
6262
let mut applicability = Applicability::MachineApplicable;
63-
let snip = snippet_with_applicability(cx, exp.span, "..", &mut applicability);
64-
let suggestion = if exp.precedence().order() < PREC_PREFIX && !has_enclosing_paren(&snip) {
63+
let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability);
64+
let suggestion = if !from_macro && exp.precedence().order() < PREC_PREFIX && !has_enclosing_paren(&snip) {
6565
format!("-({snip})")
6666
} else {
6767
format!("-{snip}")

clippy_lints/src/non_octal_unix_permissions.rs

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
5353
|| is_type_diagnostic_item(cx, obj_ty, sym::DirBuilder)))
5454
|| (path.ident.name == sym!(set_mode) && match_type(cx, obj_ty, &paths::PERMISSIONS));
5555
if let ExprKind::Lit(_) = param.kind;
56+
if param.span.ctxt() == expr.span.ctxt();
5657

5758
then {
5859
let Some(snip) = snippet_opt(cx, param.span) else {
@@ -71,6 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
7172
if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
7273
if match_def_path(cx, def_id, &paths::PERMISSIONS_FROM_MODE);
7374
if let ExprKind::Lit(_) = param.kind;
75+
if param.span.ctxt() == expr.span.ctxt();
7476
if let Some(snip) = snippet_opt(cx, param.span);
7577
if !snip.starts_with("0o");
7678
then {

0 commit comments

Comments
 (0)