Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions clippy_lints/src/casts/unnecessary_cast.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::numeric_literal::NumericLiteral;
use clippy_utils::source::{SpanRangeExt, snippet_opt};
use clippy_utils::source::SpanRangeExt;
use clippy_utils::visitors::{Visitable, for_each_expr_without_closures};
use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local};
use rustc_ast::{LitFloatType, LitIntType, LitKind};
Expand All @@ -23,7 +23,8 @@ pub(super) fn check<'tcx>(
cast_from: Ty<'tcx>,
cast_to: Ty<'tcx>,
) -> bool {
let cast_str = snippet_opt(cx, cast_expr.span).unwrap_or_default();
let cast_str = cast_expr.span.get_source_text(cx);
let cast_str = cast_str.as_deref().unwrap_or("");

if let ty::RawPtr(..) = cast_from.kind()
// check both mutability and type are the same
Expand Down Expand Up @@ -56,7 +57,7 @@ pub(super) fn check<'tcx>(
"casting raw pointers to the same type and constness is unnecessary (`{cast_from}` -> `{cast_to}`)"
),
"try",
cast_str.clone(),
cast_str.to_string(),
Applicability::MaybeIncorrect,
);
}
Expand Down Expand Up @@ -102,7 +103,7 @@ pub(super) fn check<'tcx>(
}

if let Some(lit) = get_numeric_literal(cast_expr) {
let literal_str = &cast_str;
let literal_str = cast_str;

if let LitKind::Int(n, _) = lit.node
&& let Some(src) = cast_expr.span.get_source_text(cx)
Expand Down Expand Up @@ -167,7 +168,7 @@ pub(super) fn check<'tcx>(
sym::assert_ne_macro,
sym::debug_assert_ne_macro,
];
matches!(expr.span.ctxt().outer_expn_data().macro_def_id, Some(def_id) if
matches!(expr.span.ctxt().outer_expn_data().macro_def_id, Some(def_id) if
cx.tcx.get_diagnostic_name(def_id).is_some_and(|sym| ALLOWED_MACROS.contains(&sym)))
}

Expand Down Expand Up @@ -198,7 +199,7 @@ pub(super) fn check<'tcx>(
match surrounding {
MaybeParenOrBlock::Paren => format!("({cast_str})"),
MaybeParenOrBlock::Block => format!("{{ {cast_str} }}"),
MaybeParenOrBlock::Nothing => cast_str,
MaybeParenOrBlock::Nothing => cast_str.to_string(),
},
Applicability::MachineApplicable,
);
Expand Down
12 changes: 7 additions & 5 deletions clippy_lints/src/default_numeric_fallback.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::numeric_literal;
use clippy_utils::source::snippet_opt;
use clippy_utils::source::SpanRangeExt;
use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{Visitor, walk_expr, walk_pat, walk_stmt};
Expand All @@ -11,6 +11,7 @@ use rustc_hir::{
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
use rustc_session::declare_lint_pass;
use std::borrow::Cow;
use std::iter;

declare_clippy_lint! {
Expand Down Expand Up @@ -103,12 +104,13 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
lit.span,
"default numeric fallback might occur",
|diag| {
let src = if let Some(src) = snippet_opt(self.cx, lit.span) {
src
let src = lit.span.get_source_text(self.cx);
let src: Cow<'_, str> = if let Some(src) = src.as_deref() {
src.into()
} else {
match lit.node {
LitKind::Int(src, _) => format!("{src}"),
LitKind::Float(src, _) => format!("{src}"),
LitKind::Int(src, _) => format!("{src}").into(),
LitKind::Float(src, _) => format!("{src}").into(),
_ => unreachable!("Default numeric fallback never results in other types"),
}
};
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/doc/include_in_doc_without_cfg.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt;
use clippy_utils::source::SpanRangeExt;
use rustc_ast::{AttrArgs, AttrKind, AttrStyle, Attribute};
use rustc_errors::Applicability;
use rustc_lint::EarlyContext;
Expand All @@ -15,7 +15,7 @@ pub fn check(cx: &EarlyContext<'_>, attrs: &[Attribute]) {
&& !attr.span.contains(meta.span)
// Since the `include_str` is already expanded at this point, we can only take the
// whole attribute snippet and then modify for our suggestion.
&& let Some(snippet) = snippet_opt(cx, attr.span)
&& let Some(snippet) = attr.span.get_source_text(cx)
// We cannot remove this because a `#[doc = include_str!("...")]` attribute can occupy
// several lines.
&& let Some(start) = snippet.find('[')
Expand Down
13 changes: 4 additions & 9 deletions clippy_lints/src/doc/too_long_first_doc_paragraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_lint::LateContext;

use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use clippy_utils::source::snippet_opt;
use clippy_utils::source::SpanRangeExt;

use super::TOO_LONG_FIRST_DOC_PARAGRAPH;

Expand Down Expand Up @@ -81,15 +81,10 @@ pub(super) fn check(
if should_suggest_empty_doc
&& let Some(second_span) = spans.get(1)
&& let new_span = first_span.with_hi(second_span.lo()).with_lo(first_span.hi())
&& let Some(snippet) = snippet_opt(cx, new_span)
&& let Some(snippet) = new_span.get_source_text(cx)
&& let Some(first) = first_span.get_source_text(cx)
&& let Some(comment_form) = first.get(..3)
{
let Some(first) = snippet_opt(cx, *first_span) else {
return;
};
let Some(comment_form) = first.get(..3) else {
return;
};

diag.span_suggestion(
new_span,
"add an empty line",
Expand Down
35 changes: 17 additions & 18 deletions clippy_lints/src/eta_reduction.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::higher::VecArgs;
use clippy_utils::source::{snippet_opt, snippet_with_applicability};
use clippy_utils::source::{SpanRangeExt, snippet_with_applicability};
use clippy_utils::ty::get_type_diagnostic_name;
use clippy_utils::usage::{local_used_after_expr, local_used_in};
use clippy_utils::{
Expand Down Expand Up @@ -217,8 +217,8 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
expr.span,
"redundant closure",
|diag| {
if let Some(mut snippet) = snippet_opt(cx, callee.span) {
if path_to_local(callee).is_some_and(|l| {
if let Some(snippet) = callee.span.get_source_text(cx) {
let snippet = if path_to_local(callee).is_some_and(|l| {
// FIXME: Do we really need this `local_used_in` check?
// Isn't it checking something like... `callee(callee)`?
// If somehow this check is needed, add some test for it,
Expand All @@ -227,25 +227,24 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
}) {
match closure_kind {
// Mutable closure is used after current expr; we cannot consume it.
ClosureKind::FnMut => snippet = format!("&mut {snippet}"),
ClosureKind::Fn if !callee_ty_raw.is_ref() => {
snippet = format!("&{snippet}");
},
_ => (),
ClosureKind::FnMut => format!("&mut {snippet}"),
ClosureKind::Fn if !callee_ty_raw.is_ref() => format!("&{snippet}"),
_ => snippet.to_owned(),
}
} else if let n_refs =
callee_ty_adjustments
.iter()
.rev()
.fold(0, |acc, adjustment| match adjustment.kind {
} else {
let n_refs = callee_ty_adjustments.iter().rev().fold(0, |acc, adjustment| {
match adjustment.kind {
Adjust::Deref(Some(_)) => acc + 1,
Adjust::Deref(_) if acc > 0 => acc + 1,
_ => acc,
})
&& n_refs > 0
{
snippet = format!("{}{snippet}", "*".repeat(n_refs));
}
}
});
if n_refs > 0 {
format!("{}{snippet}", "*".repeat(n_refs))
} else {
snippet.to_owned()
}
};

let replace_with = match callee_ty_adjusted.kind() {
ty::FnDef(def, _) => cx.tcx.def_descr(*def),
Expand Down
46 changes: 22 additions & 24 deletions clippy_lints/src/formatting.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
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 clippy_utils::source::SpanRangeExt;
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_session::declare_lint_pass;
Expand Down Expand Up @@ -170,23 +170,21 @@ fn check_assign(cx: &EarlyContext<'_>, expr: &Expr) {
{
let eq_span = lhs.span.between(rhs.span);
if let ExprKind::Unary(op, ref sub_rhs) = rhs.kind
&& let Some(eq_snippet) = snippet_opt(cx, eq_span)
&& eq_span.check_source_text(cx, |eq_snippet| eq_snippet.ends_with('='))
{
let op = op.as_str();
let eqop_span = lhs.span.between(sub_rhs.span);
if eq_snippet.ends_with('=') {
span_lint_and_note(
cx,
SUSPICIOUS_ASSIGNMENT_FORMATTING,
eqop_span,
format!(
"this looks like you are trying to use `.. {op}= ..`, but you \
span_lint_and_note(
cx,
SUSPICIOUS_ASSIGNMENT_FORMATTING,
eqop_span,
format!(
"this looks like you are trying to use `.. {op}= ..`, but you \
really are doing `.. = ({op} ..)`"
),
None,
format!("to remove this lint, use either `{op}=` or `= {op}`"),
);
}
),
None,
format!("to remove this lint, use either `{op}=` or `= {op}`"),
);
}
}
}
Expand All @@ -201,11 +199,11 @@ fn check_unop(cx: &EarlyContext<'_>, expr: &Expr) {
&& let ExprKind::Unary(op, ref un_rhs) = rhs.kind
// from UnOp operator to UnOp operand
&& let unop_operand_span = rhs.span.until(un_rhs.span)
&& let Some(binop_snippet) = snippet_opt(cx, binop_span)
&& let Some(unop_operand_snippet) = snippet_opt(cx, unop_operand_span)
&& let binop_str = binop.node.as_str()
// no space after BinOp operator and space after UnOp operator
&& binop_snippet.ends_with(binop_str) && unop_operand_snippet.ends_with(' ')
// no space after BinOp operator
&& binop_span.check_source_text(cx, |binop_snippet| binop_snippet.ends_with(binop_str))
// ... and space after UnOp operator
&& unop_operand_span.check_source_text(cx, |unop_operand_snippet| unop_operand_snippet.ends_with(' '))
{
let unop_str = op.as_str();
let eqop_span = lhs.span.between(un_rhs.span);
Expand Down Expand Up @@ -239,7 +237,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) {

// the snippet should look like " else \n " with maybe comments anywhere
// it’s bad when there is a ‘\n’ after the “else”
&& let Some(else_snippet) = snippet_opt(cx, else_span)
&& let Some(else_snippet) = else_span.get_source_text(cx)
&& let Some((pre_else, post_else)) = else_snippet.split_once("else")
&& !else_snippet.contains('/')
&& let Some((_, post_else_post_eol)) = post_else.split_once('\n')
Expand Down Expand Up @@ -293,11 +291,10 @@ fn check_array(cx: &EarlyContext<'_>, expr: &Expr) {
&& has_unary_equivalent(op.node)
&& lhs.span.eq_ctxt(op.span)
&& let space_span = lhs.span.between(op.span)
&& let Some(space_snippet) = snippet_opt(cx, space_span)
&& let lint_span = lhs.span.with_lo(lhs.span.hi())
&& space_snippet.contains('\n')
&& space_span.check_source_text(cx, |space_snippet| space_snippet.contains('\n'))
&& indentation(cx, op.span) <= indentation(cx, lhs.span)
{
let lint_span = lhs.span.shrink_to_hi();
span_lint_and_note(
cx,
POSSIBLE_MISSING_COMMA,
Expand All @@ -322,8 +319,9 @@ fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) {
// 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.
&& let else_span = first.span.between(second.span)
&& let Some(else_snippet) = snippet_opt(cx, else_span)
&& !else_snippet.chars().any(|c| c == '\n' || !c.is_whitespace())
&& else_span.check_source_text(cx, |else_snippet| {
!else_snippet.chars().any(|c| c == '\n' || !c.is_whitespace())
})
{
let (looks_like, next_thing) = if is_if(second) {
("an `else if`", "the second `if`")
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/implicit_saturating_sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ fn check_subtraction(
{
if eq_expr_value(cx, left, big_expr) && eq_expr_value(cx, right, little_expr) {
// This part of the condition is voluntarily split from the one before to ensure that
// if `snippet_opt` fails, it won't try the next conditions.
// if `Sugg::hir_opt` fails, it won't try the next conditions.
if (!is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST))
&& let Some(big_expr_sugg) = Sugg::hir_opt(cx, big_expr).map(Sugg::maybe_paren)
&& let Some(little_expr_sugg) = Sugg::hir_opt(cx, little_expr)
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/large_include_file.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::macros::root_macro_call_first_node;
use clippy_utils::source::snippet_opt;
use clippy_utils::source::SpanRangeExt;
use rustc_ast::{AttrArgs, AttrKind, Attribute, LitKind};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
Expand Down Expand Up @@ -96,7 +96,7 @@ impl EarlyLintPass for LargeIncludeFile {
&& !attr.span.contains(meta.span)
// Since the `include_str` is already expanded at this point, we can only take the
// whole attribute snippet and then modify for our suggestion.
&& let Some(snippet) = snippet_opt(cx, attr.span)
&& let Some(snippet) = attr.span.get_source_text(cx)
// We cannot remove this because a `#[doc = include_str!("...")]` attribute can
// occupy several lines.
&& let Some(start) = snippet.find('[')
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/loops/while_let_loop.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::WHILE_LET_LOOP;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::{snippet, snippet_indent, snippet_opt};
use clippy_utils::source::{SpanRangeExt, snippet, snippet_indent};
use clippy_utils::ty::needs_ordered_drop;
use clippy_utils::visitors::any_temporaries_need_ordered_drop;
use clippy_utils::{higher, peel_blocks};
Expand Down Expand Up @@ -89,8 +89,8 @@ fn could_be_while_let<'tcx>(
// Prevent trivial reassignments such as `let x = x;` or `let _ = …;`, but
// keep them if the type has been explicitly specified.
&& (!is_trivial_assignment(pat, peel_blocks(inner_expr)) || ty.is_some())
&& let Some(pat_str) = snippet_opt(cx, pat.span)
&& let Some(init_str) = snippet_opt(cx, peel_blocks(inner_expr).span)
&& let Some(pat_str) = pat.span.get_source_text(cx)
&& let Some(init_str) = peel_blocks(inner_expr).span.get_source_text(cx)
{
let ty_str = ty
.map(|ty| format!(": {}", snippet(cx, ty.span, "_")))
Expand Down
32 changes: 18 additions & 14 deletions clippy_lints/src/manual_option_as_slice.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::Msrv;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::{is_none_pattern, msrvs, peel_hir_expr_refs, sym};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
Expand Down Expand Up @@ -134,19 +135,22 @@ fn check_as_ref(cx: &LateContext<'_>, expr: &Expr<'_>, span: Span, msrv: Msrv) {
},
)
{
if let Some(snippet) = clippy_utils::source::snippet_opt(cx, callee.span) {
span_lint_and_sugg(
cx,
MANUAL_OPTION_AS_SLICE,
span,
"use `Option::as_slice`",
"use",
format!("{snippet}.as_slice()"),
Applicability::MachineApplicable,
);
} else {
span_lint(cx, MANUAL_OPTION_AS_SLICE, span, "use `Option_as_slice`");
}
span_lint_and_then(
cx,
MANUAL_OPTION_AS_SLICE,
span,
"manual implementation of `Option::as_slice`",
|diag| {
if let Some(snippet) = callee.span.get_source_text(cx) {
diag.span_suggestion(
span,
"use",
format!("{snippet}.as_slice()"),
Applicability::MachineApplicable,
);
}
},
);
}
}

Expand Down
Loading