Auto merge of #13136 - xFrednet:07797-restriction-and-then, r=blyxyas
Make restriction lint's use `span_lint_and_then` (a -> e) This migrates a few restriction lints to use `span_lint_and_then`. This change is motivated by https://github.com/rust-lang/rust-clippy/issues/7797. I'm also interested if it will have an impact on performance. With some of these lints, like [`clippy::implicit_return`](https://rust-lang.github.io/rust-clippy/master/index.html#/implicit_return) I expect an impact, as it was previously creating a suggestion **for every implicit return** which is just wild. I've also cleaned up some lint message. Mostly minor stuff. For example: suggestions with a longer message than `"try"` now use `SuggestionStyle::ShowAlways` --- `@blyxyas` Could you benchmark this PR? I want to get all the numbers :3 --- This also crashed our new lintcheck CI with the following message: > Error: $GITHUB_STEP_SUMMARY upload aborted, supports content up to a size of 1024k, got 46731k. For more information see: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary Which is just wild. Like, I've [tested the first 20 lints](https://github.com/xFrednet/rust-clippy/actions/runs/10027528172) and got like four changes and then this. 50 MB of changed lint messages o.O. Looks like I'll create a separate PR to fix that step ^^ --- cc: https://github.com/rust-lang/rust-clippy/issues/7797 changelog: none r? `@blyxyas`
This commit is contained in:
commit
c082bc2cb8
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
@ -52,13 +52,15 @@ impl<'tcx> LateLintPass<'tcx> for AsConversions {
|
||||
&& !in_external_macro(cx.sess(), expr.span)
|
||||
&& !is_from_proc_macro(cx, expr)
|
||||
{
|
||||
span_lint_and_help(
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
AS_CONVERSIONS,
|
||||
expr.span,
|
||||
"using a potentially dangerous silent `as` conversion",
|
||||
None,
|
||||
"consider using a safe wrapper for this conversion",
|
||||
|diag| {
|
||||
diag.help("consider using a safe wrapper for this conversion");
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::macros::{find_assert_args, root_macro_call_first_node, PanicExpn};
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::ty::{has_debug_impl, is_copy, is_type_diagnostic_item};
|
||||
@ -68,39 +68,28 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
|
||||
return;
|
||||
}
|
||||
}
|
||||
let semicolon = if is_expr_final_block_expr(cx.tcx, e) { ";" } else { "" };
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
match method_segment.ident.as_str() {
|
||||
let (message, replacement) = match method_segment.ident.as_str() {
|
||||
"is_ok" if type_suitable_to_unwrap(cx, args.type_at(1)) => {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
ASSERTIONS_ON_RESULT_STATES,
|
||||
macro_call.span,
|
||||
"called `assert!` with `Result::is_ok`",
|
||||
"replace with",
|
||||
format!(
|
||||
"{}.unwrap(){semicolon}",
|
||||
snippet_with_context(cx, recv.span, condition.span.ctxt(), "..", &mut app).0
|
||||
),
|
||||
app,
|
||||
);
|
||||
("called `assert!` with `Result::is_ok`", "unwrap")
|
||||
},
|
||||
"is_err" if type_suitable_to_unwrap(cx, args.type_at(0)) => {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
ASSERTIONS_ON_RESULT_STATES,
|
||||
macro_call.span,
|
||||
"called `assert!` with `Result::is_err`",
|
||||
"replace with",
|
||||
format!(
|
||||
"{}.unwrap_err(){semicolon}",
|
||||
snippet_with_context(cx, recv.span, condition.span.ctxt(), "..", &mut app).0
|
||||
),
|
||||
app,
|
||||
);
|
||||
("called `assert!` with `Result::is_err`", "unwrap_err")
|
||||
},
|
||||
_ => (),
|
||||
_ => return,
|
||||
};
|
||||
span_lint_and_then(cx, ASSERTIONS_ON_RESULT_STATES, macro_call.span, message, |diag| {
|
||||
let semicolon = if is_expr_final_block_expr(cx.tcx, e) { ";" } else { "" };
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
diag.span_suggestion(
|
||||
macro_call.span,
|
||||
"replace with",
|
||||
format!(
|
||||
"{}.{replacement}(){semicolon}",
|
||||
snippet_with_context(cx, recv.span, condition.span.ctxt(), "..", &mut app).0
|
||||
),
|
||||
app,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::ALLOW_ATTRIBUTES;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use rustc_ast::{AttrStyle, Attribute};
|
||||
use rustc_errors::Applicability;
|
||||
@ -13,14 +13,14 @@ pub fn check<'cx>(cx: &LateContext<'cx>, attr: &'cx Attribute) {
|
||||
&& let Some(ident) = attr.ident()
|
||||
&& !is_from_proc_macro(cx, attr)
|
||||
{
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
ALLOW_ATTRIBUTES,
|
||||
ident.span,
|
||||
"#[allow] attribute found",
|
||||
"replace it with",
|
||||
"expect".into(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(cx, ALLOW_ATTRIBUTES, ident.span, "#[allow] attribute found", |diag| {
|
||||
diag.span_suggestion(
|
||||
ident.span,
|
||||
"replace it with",
|
||||
"expect",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::{Attribute, ALLOW_ATTRIBUTES_WITHOUT_REASON};
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use rustc_ast::{MetaItemKind, NestedMetaItem};
|
||||
use rustc_lint::{LateContext, LintContext};
|
||||
@ -21,12 +21,14 @@ pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMet
|
||||
return;
|
||||
}
|
||||
|
||||
span_lint_and_help(
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
ALLOW_ATTRIBUTES_WITHOUT_REASON,
|
||||
attr.span,
|
||||
format!("`{}` attribute without specifying a reason", name.as_str()),
|
||||
None,
|
||||
"try adding a reason at the end with `, reason = \"..\"`",
|
||||
|diag| {
|
||||
diag.help("try adding a reason at the end with `, reason = \"..\"`");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_errors::{Applicability, SuggestionStyle};
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
@ -14,21 +14,24 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
|
||||
_ => { /* continue to checks */ },
|
||||
}
|
||||
|
||||
match cast_from.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
let mut applicability = Applicability::MaybeIncorrect;
|
||||
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "..", &mut applicability);
|
||||
if let ty::FnDef(..) | ty::FnPtr(_) = cast_from.kind() {
|
||||
let mut applicability = Applicability::MaybeIncorrect;
|
||||
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "..", &mut applicability);
|
||||
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
FN_TO_NUMERIC_CAST_ANY,
|
||||
expr.span,
|
||||
format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
|
||||
"did you mean to invoke the function?",
|
||||
format!("{from_snippet}() as {cast_to}"),
|
||||
applicability,
|
||||
);
|
||||
},
|
||||
_ => {},
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
FN_TO_NUMERIC_CAST_ANY,
|
||||
expr.span,
|
||||
format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
|
||||
|diag| {
|
||||
diag.span_suggestion_with_style(
|
||||
expr.span,
|
||||
"did you mean to invoke the function?",
|
||||
format!("{from_snippet}() as {cast_to}"),
|
||||
applicability,
|
||||
SuggestionStyle::ShowAlways,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet;
|
||||
use rustc_errors::Applicability;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use rustc_errors::{Applicability, SuggestionStyle};
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
@ -39,14 +39,24 @@ impl LateLintPass<'_> for CreateDir {
|
||||
&& let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
|
||||
&& cx.tcx.is_diagnostic_item(sym::fs_create_dir, def_id)
|
||||
{
|
||||
span_lint_and_sugg(
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
CREATE_DIR,
|
||||
expr.span,
|
||||
"calling `std::fs::create_dir` where there may be a better way",
|
||||
"consider calling `std::fs::create_dir_all` instead",
|
||||
format!("create_dir_all({})", snippet(cx, arg.span, "..")),
|
||||
Applicability::MaybeIncorrect,
|
||||
|diag| {
|
||||
let mut app = Applicability::MaybeIncorrect;
|
||||
diag.span_suggestion_with_style(
|
||||
expr.span,
|
||||
"consider calling `std::fs::create_dir_all` instead",
|
||||
format!(
|
||||
"create_dir_all({})",
|
||||
snippet_with_applicability(cx, arg.span, "..", &mut app)
|
||||
),
|
||||
app,
|
||||
SuggestionStyle::ShowAlways,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_in_test;
|
||||
use clippy_utils::macros::{macro_backtrace, MacroCall};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
@ -65,61 +65,67 @@ impl LateLintPass<'_> for DbgMacro {
|
||||
// allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
|
||||
!(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id))
|
||||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
||||
let (sugg_span, suggestion) = match expr.peel_drop_temps().kind {
|
||||
// dbg!()
|
||||
ExprKind::Block(..) => {
|
||||
// If the `dbg!` macro is a "free" statement and not contained within other expressions,
|
||||
// remove the whole statement.
|
||||
if let Node::Stmt(_) = cx.tcx.parent_hir_node(expr.hir_id)
|
||||
&& let Some(semi_span) = cx.sess().source_map().mac_call_stmt_semi_span(macro_call.span)
|
||||
{
|
||||
(macro_call.span.to(semi_span), String::new())
|
||||
} else {
|
||||
(macro_call.span, String::from("()"))
|
||||
}
|
||||
},
|
||||
// dbg!(1)
|
||||
ExprKind::Match(val, ..) => (
|
||||
macro_call.span,
|
||||
snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability).to_string(),
|
||||
),
|
||||
// dbg!(2, 3)
|
||||
ExprKind::Tup(
|
||||
[
|
||||
Expr {
|
||||
kind: ExprKind::Match(first, ..),
|
||||
..
|
||||
},
|
||||
..,
|
||||
Expr {
|
||||
kind: ExprKind::Match(last, ..),
|
||||
..
|
||||
},
|
||||
],
|
||||
) => {
|
||||
let snippet = snippet_with_applicability(
|
||||
cx,
|
||||
first.span.source_callsite().to(last.span.source_callsite()),
|
||||
"..",
|
||||
&mut applicability,
|
||||
);
|
||||
(macro_call.span, format!("({snippet})"))
|
||||
},
|
||||
_ => return,
|
||||
};
|
||||
|
||||
self.prev_ctxt = cur_syntax_ctxt;
|
||||
|
||||
span_lint_and_sugg(
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
DBG_MACRO,
|
||||
sugg_span,
|
||||
macro_call.span,
|
||||
"the `dbg!` macro is intended as a debugging tool",
|
||||
"remove the invocation before committing it to a version control system",
|
||||
suggestion,
|
||||
applicability,
|
||||
|diag| {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
||||
let (sugg_span, suggestion) = match expr.peel_drop_temps().kind {
|
||||
// dbg!()
|
||||
ExprKind::Block(..) => {
|
||||
// If the `dbg!` macro is a "free" statement and not contained within other expressions,
|
||||
// remove the whole statement.
|
||||
if let Node::Stmt(_) = cx.tcx.parent_hir_node(expr.hir_id)
|
||||
&& let Some(semi_span) = cx.sess().source_map().mac_call_stmt_semi_span(macro_call.span)
|
||||
{
|
||||
(macro_call.span.to(semi_span), String::new())
|
||||
} else {
|
||||
(macro_call.span, String::from("()"))
|
||||
}
|
||||
},
|
||||
// dbg!(1)
|
||||
ExprKind::Match(val, ..) => (
|
||||
macro_call.span,
|
||||
snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability)
|
||||
.to_string(),
|
||||
),
|
||||
// dbg!(2, 3)
|
||||
ExprKind::Tup(
|
||||
[
|
||||
Expr {
|
||||
kind: ExprKind::Match(first, ..),
|
||||
..
|
||||
},
|
||||
..,
|
||||
Expr {
|
||||
kind: ExprKind::Match(last, ..),
|
||||
..
|
||||
},
|
||||
],
|
||||
) => {
|
||||
let snippet = snippet_with_applicability(
|
||||
cx,
|
||||
first.span.source_callsite().to(last.span.source_callsite()),
|
||||
"..",
|
||||
&mut applicability,
|
||||
);
|
||||
(macro_call.span, format!("({snippet})"))
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
diag.span_suggestion(
|
||||
sugg_span,
|
||||
"remove the invocation before committing it to a version control system",
|
||||
suggestion,
|
||||
applicability,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -92,20 +92,8 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
|
||||
let (suffix, is_float) = match lit_ty.kind() {
|
||||
ty::Int(IntTy::I32) => ("i32", false),
|
||||
ty::Float(FloatTy::F64) => ("f64", true),
|
||||
// Default numeric fallback never results in other types.
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let src = if let Some(src) = snippet_opt(self.cx, lit.span) {
|
||||
src
|
||||
} else {
|
||||
match lit.node {
|
||||
LitKind::Int(src, _) => format!("{src}"),
|
||||
LitKind::Float(src, _) => format!("{src}"),
|
||||
_ => return,
|
||||
}
|
||||
};
|
||||
let sugg = numeric_literal::format(&src, Some(suffix), is_float);
|
||||
span_lint_hir_and_then(
|
||||
self.cx,
|
||||
DEFAULT_NUMERIC_FALLBACK,
|
||||
@ -113,6 +101,17 @@ 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
|
||||
} else {
|
||||
match lit.node {
|
||||
LitKind::Int(src, _) => format!("{src}"),
|
||||
LitKind::Float(src, _) => format!("{src}"),
|
||||
_ => unreachable!("Default numeric fallback never results in other types"),
|
||||
}
|
||||
};
|
||||
|
||||
let sugg = numeric_literal::format(&src, Some(suffix), is_float);
|
||||
diag.span_suggestion(lit.span, "consider adding suffix", sugg, Applicability::MaybeIncorrect);
|
||||
},
|
||||
);
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use rustc_hir::{HirId, Item, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
@ -56,16 +56,18 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
|
||||
&& is_union_with_two_non_zst_fields(cx, item)
|
||||
&& !has_c_repr_attr(cx, item.hir_id())
|
||||
{
|
||||
span_lint_and_help(
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
DEFAULT_UNION_REPRESENTATION,
|
||||
item.span,
|
||||
"this union has the default representation",
|
||||
None,
|
||||
format!(
|
||||
"consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout",
|
||||
cx.tcx.def_path_str(item.owner_id)
|
||||
),
|
||||
|diag| {
|
||||
diag.help(format!(
|
||||
"consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout",
|
||||
cx.tcx.def_path_str(item.owner_id)
|
||||
));
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Lint on if expressions with an else if, but without a final else branch.
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use rustc_ast::ast::{Expr, ExprKind};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
@ -54,13 +54,15 @@ impl EarlyLintPass for ElseIfWithoutElse {
|
||||
&& let ExprKind::If(_, _, None) = els.kind
|
||||
&& !in_external_macro(cx.sess(), item.span)
|
||||
{
|
||||
span_lint_and_help(
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
ELSE_IF_WITHOUT_ELSE,
|
||||
els.span,
|
||||
"`if` expression with an `else if`, but without a final `else`",
|
||||
None,
|
||||
"add an `else` block here",
|
||||
|diag| {
|
||||
diag.help("add an `else` block here");
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::peel_blocks;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Body, ExprKind, Impl, ImplItemKind, Item, ItemKind, Node};
|
||||
@ -50,15 +50,14 @@ impl LateLintPass<'_> for EmptyDrop {
|
||||
&& block.stmts.is_empty()
|
||||
&& block.expr.is_none()
|
||||
{
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
EMPTY_DROP,
|
||||
item.span,
|
||||
"empty drop implementation",
|
||||
"try removing this impl",
|
||||
String::new(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
span_lint_and_then(cx, EMPTY_DROP, item.span, "empty drop implementation", |diag| {
|
||||
diag.span_suggestion_hidden(
|
||||
item.span,
|
||||
"try removing this impl",
|
||||
String::new(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::Symbol;
|
||||
use std::borrow::Cow;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
@ -141,52 +140,6 @@ fn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: Prefix
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let mut help = None;
|
||||
|
||||
'build_help: {
|
||||
// all lints disallowed, don't give help here
|
||||
if [&[lint], other_lints.as_slice()]
|
||||
.concat()
|
||||
.iter()
|
||||
.all(|lint| !lint.allowed(cx, expr))
|
||||
{
|
||||
break 'build_help;
|
||||
}
|
||||
|
||||
// ne_bytes and all other lints allowed
|
||||
if lint.as_name(prefix) == ne && other_lints.iter().all(|lint| lint.allowed(cx, expr)) {
|
||||
help = Some(Cow::Borrowed("specify the desired endianness explicitly"));
|
||||
break 'build_help;
|
||||
}
|
||||
|
||||
// le_bytes where ne_bytes allowed but be_bytes is not, or le_bytes where ne_bytes allowed but
|
||||
// le_bytes is not
|
||||
if (lint.as_name(prefix) == le || lint.as_name(prefix) == be) && LintKind::Host.allowed(cx, expr) {
|
||||
help = Some(Cow::Borrowed("use the native endianness instead"));
|
||||
break 'build_help;
|
||||
}
|
||||
|
||||
let allowed_lints = other_lints.iter().filter(|lint| lint.allowed(cx, expr));
|
||||
let len = allowed_lints.clone().count();
|
||||
|
||||
let mut help_str = "use ".to_owned();
|
||||
|
||||
for (i, lint) in allowed_lints.enumerate() {
|
||||
let only_one = len == 1;
|
||||
if !only_one {
|
||||
help_str.push_str("either of ");
|
||||
}
|
||||
|
||||
help_str.push_str(&format!("`{ty}::{}` ", lint.as_name(prefix)));
|
||||
|
||||
if i != len && !only_one {
|
||||
help_str.push_str("or ");
|
||||
}
|
||||
}
|
||||
|
||||
help = Some(Cow::Owned(help_str + "instead"));
|
||||
}
|
||||
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
lint.as_lint(),
|
||||
@ -198,9 +151,47 @@ fn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: Prefix
|
||||
if prefix == Prefix::To { " method" } else { "" },
|
||||
),
|
||||
move |diag| {
|
||||
if let Some(help) = help {
|
||||
diag.help(help);
|
||||
// all lints disallowed, don't give help here
|
||||
if [&[lint], other_lints.as_slice()]
|
||||
.concat()
|
||||
.iter()
|
||||
.all(|lint| !lint.allowed(cx, expr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// ne_bytes and all other lints allowed
|
||||
if lint.as_name(prefix) == ne && other_lints.iter().all(|lint| lint.allowed(cx, expr)) {
|
||||
diag.help("specify the desired endianness explicitly");
|
||||
return;
|
||||
}
|
||||
|
||||
// le_bytes where ne_bytes allowed but be_bytes is not, or le_bytes where ne_bytes allowed but
|
||||
// le_bytes is not
|
||||
if (lint.as_name(prefix) == le || lint.as_name(prefix) == be) && LintKind::Host.allowed(cx, expr) {
|
||||
diag.help("use the native endianness instead");
|
||||
return;
|
||||
}
|
||||
|
||||
let allowed_lints = other_lints.iter().filter(|lint| lint.allowed(cx, expr));
|
||||
let len = allowed_lints.clone().count();
|
||||
|
||||
let mut help_str = "use ".to_owned();
|
||||
|
||||
for (i, lint) in allowed_lints.enumerate() {
|
||||
let only_one = len == 1;
|
||||
if !only_one {
|
||||
help_str.push_str("either of ");
|
||||
}
|
||||
|
||||
help_str.push_str(&format!("`{ty}::{}` ", lint.as_name(prefix)));
|
||||
|
||||
if i != len && !only_one {
|
||||
help_str.push_str("or ");
|
||||
}
|
||||
}
|
||||
help_str.push_str("instead");
|
||||
diag.help(help_str);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -88,11 +88,11 @@ impl LateLintPass<'_> for ExhaustiveItems {
|
||||
&& !attrs.iter().any(|a| a.has_name(sym::non_exhaustive))
|
||||
&& fields.iter().all(|f| cx.tcx.visibility(f.def_id).is_public())
|
||||
{
|
||||
let suggestion_span = item.span.shrink_to_lo();
|
||||
let indent = " ".repeat(indent_of(cx, item.span).unwrap_or(0));
|
||||
span_lint_and_then(cx, lint, item.span, msg, |diag| {
|
||||
let suggestion_span = item.span.shrink_to_lo();
|
||||
let indent = " ".repeat(indent_of(cx, item.span).unwrap_or(0));
|
||||
let sugg = format!("#[non_exhaustive]\n{indent}");
|
||||
diag.span_suggestion(
|
||||
diag.span_suggestion_verbose(
|
||||
suggestion_span,
|
||||
"try adding #[non_exhaustive]",
|
||||
sugg,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use rustc_ast::ast::{Item, ItemKind, VisibilityKind};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
@ -62,13 +62,15 @@ impl EarlyLintPass for FieldScopedVisibilityModifiers {
|
||||
// pub(self) is equivalent to not using pub at all, so we ignore it
|
||||
continue;
|
||||
}
|
||||
span_lint_and_help(
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
FIELD_SCOPED_VISIBILITY_MODIFIERS,
|
||||
field.vis.span,
|
||||
"scoped visibility modifier on a field",
|
||||
None,
|
||||
"consider making the field private and adding a scoped visibility method for it",
|
||||
|diag| {
|
||||
diag.help("consider making the field private and adding a scoped visibility method for it");
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{higher, match_def_path, paths};
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem, MatchSource};
|
||||
@ -81,13 +81,15 @@ impl<'tcx> LateLintPass<'tcx> for FormatPushString {
|
||||
_ => return,
|
||||
};
|
||||
if is_format(cx, arg) {
|
||||
span_lint_and_help(
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
FORMAT_PUSH_STRING,
|
||||
expr.span,
|
||||
"`format!(..)` appended to existing `String`",
|
||||
None,
|
||||
"consider using `write!` to avoid the extra allocation",
|
||||
|diag| {
|
||||
diag.help("consider using `write!` to avoid the extra allocation");
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_config::msrvs::{self, Msrv};
|
||||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
@ -81,32 +81,39 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
|
||||
&& self.msrv.meets(msrvs::BOOL_THEN)
|
||||
&& !contains_return(then_block.stmts)
|
||||
{
|
||||
let mut app = Applicability::Unspecified;
|
||||
let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app)
|
||||
.maybe_par()
|
||||
.to_string();
|
||||
let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0;
|
||||
let mut method_body = if then_block.stmts.is_empty() {
|
||||
arg_snip.into_owned()
|
||||
} else {
|
||||
format!("{{ /* snippet */ {arg_snip} }}")
|
||||
};
|
||||
let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(msrvs::BOOL_THEN_SOME) {
|
||||
"then_some"
|
||||
} else {
|
||||
method_body.insert_str(0, "|| ");
|
||||
"then"
|
||||
};
|
||||
|
||||
let help =
|
||||
format!("consider using `bool::{method_name}` like: `{cond_snip}.{method_name}({method_body})`",);
|
||||
span_lint_and_help(
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
IF_THEN_SOME_ELSE_NONE,
|
||||
expr.span,
|
||||
format!("this could be simplified with `bool::{method_name}`"),
|
||||
None,
|
||||
help,
|
||||
|diag| {
|
||||
let mut app = Applicability::Unspecified;
|
||||
let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app)
|
||||
.maybe_par()
|
||||
.to_string();
|
||||
let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0;
|
||||
let method_body = if let Some(first_stmt) = then_block.stmts.first() {
|
||||
let (block_snippet, _) =
|
||||
snippet_with_context(cx, first_stmt.span.until(then_arg.span), ctxt, "..", &mut app);
|
||||
let closure = if method_name == "then" { "|| " } else { "" };
|
||||
format!("{closure} {{ {block_snippet}; {arg_snip} }}")
|
||||
} else {
|
||||
arg_snip.into_owned()
|
||||
};
|
||||
|
||||
diag.span_suggestion(
|
||||
expr.span,
|
||||
"try",
|
||||
format!("{cond_snip}.{method_name}({method_body})"),
|
||||
app,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use clippy_utils::source::{snippet_with_applicability, snippet_with_context, wal
|
||||
use clippy_utils::visitors::for_each_expr_without_closures;
|
||||
use clippy_utils::{get_async_fn_body, is_async_fn, is_from_proc_macro};
|
||||
use core::ops::ControlFlow;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_errors::{Applicability, SuggestionStyle};
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
@ -45,8 +45,6 @@ declare_clippy_lint! {
|
||||
declare_lint_pass!(ImplicitReturn => [IMPLICIT_RETURN]);
|
||||
|
||||
fn lint_return(cx: &LateContext<'_>, emission_place: HirId, span: Span) {
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let snip = snippet_with_applicability(cx, span, "..", &mut app);
|
||||
span_lint_hir_and_then(
|
||||
cx,
|
||||
IMPLICIT_RETURN,
|
||||
@ -54,14 +52,20 @@ fn lint_return(cx: &LateContext<'_>, emission_place: HirId, span: Span) {
|
||||
span,
|
||||
"missing `return` statement",
|
||||
|diag| {
|
||||
diag.span_suggestion(span, "add `return` as shown", format!("return {snip}"), app);
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let snip = snippet_with_applicability(cx, span, "..", &mut app);
|
||||
diag.span_suggestion_with_style(
|
||||
span,
|
||||
"add `return` as shown",
|
||||
format!("return {snip}"),
|
||||
app,
|
||||
SuggestionStyle::ShowAlways,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn lint_break(cx: &LateContext<'_>, emission_place: HirId, break_span: Span, expr_span: Span) {
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let snip = snippet_with_context(cx, expr_span, break_span.ctxt(), "..", &mut app).0;
|
||||
span_lint_hir_and_then(
|
||||
cx,
|
||||
IMPLICIT_RETURN,
|
||||
@ -69,11 +73,14 @@ fn lint_break(cx: &LateContext<'_>, emission_place: HirId, break_span: Span, exp
|
||||
break_span,
|
||||
"missing `return` statement",
|
||||
|diag| {
|
||||
diag.span_suggestion(
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let snip = snippet_with_context(cx, expr_span, break_span.ctxt(), "..", &mut app).0;
|
||||
diag.span_suggestion_with_style(
|
||||
break_span,
|
||||
"change `break` to `return` as shown",
|
||||
format!("return {snip}"),
|
||||
app,
|
||||
SuggestionStyle::ShowAlways,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -2,13 +2,13 @@
|
||||
//! floating-point literal expressions.
|
||||
|
||||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::numeric_literal::{NumericLiteral, Radix};
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use rustc_ast::ast::{Expr, ExprKind, LitKind};
|
||||
use rustc_ast::token;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::Span;
|
||||
@ -159,63 +159,39 @@ enum WarningType {
|
||||
}
|
||||
|
||||
impl WarningType {
|
||||
fn display(&self, suggested_format: String, cx: &EarlyContext<'_>, span: Span) {
|
||||
fn lint_and_text(&self) -> (&'static Lint, &'static str, &'static str) {
|
||||
match self {
|
||||
Self::MistypedLiteralSuffix => span_lint_and_sugg(
|
||||
cx,
|
||||
Self::MistypedLiteralSuffix => (
|
||||
MISTYPED_LITERAL_SUFFIXES,
|
||||
span,
|
||||
"mistyped literal suffix",
|
||||
"did you mean to write",
|
||||
suggested_format,
|
||||
Applicability::MaybeIncorrect,
|
||||
),
|
||||
Self::UnreadableLiteral => span_lint_and_sugg(
|
||||
cx,
|
||||
UNREADABLE_LITERAL,
|
||||
span,
|
||||
"long literal lacking separators",
|
||||
"consider",
|
||||
suggested_format,
|
||||
Applicability::MachineApplicable,
|
||||
),
|
||||
Self::LargeDigitGroups => span_lint_and_sugg(
|
||||
cx,
|
||||
LARGE_DIGIT_GROUPS,
|
||||
span,
|
||||
"digit groups should be smaller",
|
||||
"consider",
|
||||
suggested_format,
|
||||
Applicability::MachineApplicable,
|
||||
),
|
||||
Self::InconsistentDigitGrouping => span_lint_and_sugg(
|
||||
cx,
|
||||
Self::UnreadableLiteral => (UNREADABLE_LITERAL, "long literal lacking separators", "consider"),
|
||||
Self::LargeDigitGroups => (LARGE_DIGIT_GROUPS, "digit groups should be smaller", "consider"),
|
||||
Self::InconsistentDigitGrouping => (
|
||||
INCONSISTENT_DIGIT_GROUPING,
|
||||
span,
|
||||
"digits grouped inconsistently by underscores",
|
||||
"consider",
|
||||
suggested_format,
|
||||
Applicability::MachineApplicable,
|
||||
),
|
||||
Self::DecimalRepresentation => span_lint_and_sugg(
|
||||
cx,
|
||||
Self::DecimalRepresentation => (
|
||||
DECIMAL_LITERAL_REPRESENTATION,
|
||||
span,
|
||||
"integer literal has a better hexadecimal representation",
|
||||
"consider",
|
||||
suggested_format,
|
||||
Applicability::MachineApplicable,
|
||||
),
|
||||
Self::UnusualByteGroupings => span_lint_and_sugg(
|
||||
cx,
|
||||
Self::UnusualByteGroupings => (
|
||||
UNUSUAL_BYTE_GROUPINGS,
|
||||
span,
|
||||
"digits of hex, binary or octal literal not in groups of equal size",
|
||||
"consider",
|
||||
suggested_format,
|
||||
Applicability::MachineApplicable,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn display(&self, num_lit: &NumericLiteral<'_>, cx: &EarlyContext<'_>, span: Span) {
|
||||
let (lint, message, try_msg) = self.lint_and_text();
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(cx, lint, span, message, |diag| {
|
||||
diag.span_suggestion(span, try_msg, num_lit.format(), Applicability::MaybeIncorrect);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,7 +269,7 @@ impl LiteralDigitGrouping {
|
||||
WarningType::DecimalRepresentation | WarningType::MistypedLiteralSuffix => true,
|
||||
};
|
||||
if should_warn {
|
||||
warning_type.display(num_lit.format(), cx, span);
|
||||
warning_type.display(&num_lit, cx, span);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -346,11 +322,14 @@ impl LiteralDigitGrouping {
|
||||
}
|
||||
}
|
||||
*part = main_part;
|
||||
let mut sugg = num_lit.format();
|
||||
sugg.push('_');
|
||||
sugg.push(missing_char);
|
||||
sugg.push_str(last_group);
|
||||
WarningType::MistypedLiteralSuffix.display(sugg, cx, span);
|
||||
let (lint, message, try_msg) = WarningType::MistypedLiteralSuffix.lint_and_text();
|
||||
span_lint_and_then(cx, lint, span, message, |diag| {
|
||||
let mut sugg = num_lit.format();
|
||||
sugg.push('_');
|
||||
sugg.push(missing_char);
|
||||
sugg.push_str(last_group);
|
||||
diag.span_suggestion(span, try_msg, sugg, Applicability::MaybeIncorrect);
|
||||
});
|
||||
false
|
||||
} else {
|
||||
true
|
||||
@ -471,7 +450,7 @@ impl DecimalLiteralRepresentation {
|
||||
let hex = format!("{val:#X}");
|
||||
let num_lit = NumericLiteral::new(&hex, num_lit.suffix, false);
|
||||
let _: Result<(), ()> = Self::do_lint(num_lit.integer).map_err(|warning_type| {
|
||||
warning_type.display(num_lit.format(), cx, span);
|
||||
warning_type.display(&num_lit, cx, span);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
@ -29,19 +29,22 @@ pub(super) fn check(
|
||||
sym::RcWeak | sym::ArcWeak => "Weak",
|
||||
_ => return,
|
||||
};
|
||||
|
||||
// Sometimes unnecessary ::<_> after Rc/Arc/Weak
|
||||
let mut app = Applicability::Unspecified;
|
||||
let snippet = snippet_with_context(cx, receiver.span, expr.span.ctxt(), "..", &mut app).0;
|
||||
|
||||
span_lint_and_sugg(
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
CLONE_ON_REF_PTR,
|
||||
expr.span,
|
||||
"using `.clone()` on a ref-counted pointer",
|
||||
"try",
|
||||
format!("{caller_type}::<{}>::clone(&{snippet})", subst.type_at(0)),
|
||||
app,
|
||||
|diag| {
|
||||
// Sometimes unnecessary ::<_> after Rc/Arc/Weak
|
||||
let mut app = Applicability::Unspecified;
|
||||
let snippet = snippet_with_context(cx, receiver.span, expr.span.ctxt(), "..", &mut app).0;
|
||||
diag.span_suggestion(
|
||||
expr.span,
|
||||
"try",
|
||||
format!("{caller_type}::<{}>::clone(&{snippet})", subst.type_at(0)),
|
||||
app,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::get_parent_expr;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use rustc_hir as hir;
|
||||
@ -33,6 +33,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
|
||||
span = expr.span;
|
||||
}
|
||||
let lint_msg = format!("`{lint_unary}FileType::is_file()` only {verb} regular files");
|
||||
let help_msg = format!("use `{help_unary}FileType::is_dir()` instead");
|
||||
span_lint_and_help(cx, FILETYPE_IS_FILE, span, lint_msg, None, help_msg);
|
||||
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(cx, FILETYPE_IS_FILE, span, lint_msg, |diag| {
|
||||
diag.help(format!("use `{help_unary}FileType::is_dir()` instead"));
|
||||
});
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::utils::derefs_to_slice;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::get_parent_expr;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
@ -19,9 +19,7 @@ pub(super) fn check<'tcx>(
|
||||
) {
|
||||
// Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`,
|
||||
// because they do not implement `IndexMut`
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let expr_ty = cx.typeck_results().expr_ty(recv);
|
||||
let get_args_str = snippet_with_applicability(cx, get_arg.span, "..", &mut applicability);
|
||||
let caller_type = if derefs_to_slice(cx, recv, expr_ty).is_some() {
|
||||
"slice"
|
||||
} else if is_type_diagnostic_item(cx, expr_ty, sym::Vec) {
|
||||
@ -58,24 +56,34 @@ pub(super) fn check<'tcx>(
|
||||
};
|
||||
|
||||
let mut_str = if is_mut { "_mut" } else { "" };
|
||||
let borrow_str = if !needs_ref {
|
||||
""
|
||||
} else if is_mut {
|
||||
"&mut "
|
||||
} else {
|
||||
"&"
|
||||
};
|
||||
|
||||
span_lint_and_sugg(
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
GET_UNWRAP,
|
||||
span,
|
||||
format!("called `.get{mut_str}().unwrap()` on a {caller_type}. Using `[]` is more clear and more concise"),
|
||||
"try",
|
||||
format!(
|
||||
"{borrow_str}{}[{get_args_str}]",
|
||||
snippet_with_applicability(cx, recv.span, "..", &mut applicability)
|
||||
),
|
||||
applicability,
|
||||
format!("called `.get{mut_str}().unwrap()` on a {caller_type}"),
|
||||
|diag| {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let get_args_str = snippet_with_applicability(cx, get_arg.span, "..", &mut applicability);
|
||||
|
||||
let borrow_str = if !needs_ref {
|
||||
""
|
||||
} else if is_mut {
|
||||
"&mut "
|
||||
} else {
|
||||
"&"
|
||||
};
|
||||
|
||||
diag.span_suggestion_with_style(
|
||||
span,
|
||||
"using `[]` is clearer and more concise",
|
||||
format!(
|
||||
"{borrow_str}{}[{get_args_str}]",
|
||||
snippet_with_applicability(cx, recv.span, "..", &mut applicability)
|
||||
),
|
||||
applicability,
|
||||
rustc_errors::SuggestionStyle::ShowAlways,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{get_parent_expr, peel_middle_ty_refs};
|
||||
@ -86,9 +86,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
|
||||
let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed));
|
||||
let parent_expr = get_parent_expr(cx, expr);
|
||||
let needs_parens_for_prefix = parent_expr.map_or(false, |parent| parent.precedence().order() > PREC_PREFIX);
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
|
||||
let ((lint, msg), help, sugg) = if expr_ty == indexed_ty {
|
||||
if expr_ty == indexed_ty {
|
||||
if expr_ref_count > indexed_ref_count {
|
||||
// Indexing takes self by reference and can't return a reference to that
|
||||
// reference as it's a local variable. The only way this could happen is if
|
||||
@ -99,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
|
||||
}
|
||||
let deref_count = indexed_ref_count - expr_ref_count;
|
||||
|
||||
let (lint, reborrow_str, help_str) = if mutability == Mutability::Mut {
|
||||
let ((lint, msg), reborrow_str, help_msg) = if mutability == Mutability::Mut {
|
||||
// The slice was used to reborrow the mutable reference.
|
||||
(DEREF_BY_SLICING_LINT, "&mut *", "reborrow the original value instead")
|
||||
} else if matches!(
|
||||
@ -125,38 +124,36 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
|
||||
(REDUNDANT_SLICING_LINT, "", "use the original value instead")
|
||||
};
|
||||
|
||||
let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;
|
||||
let sugg = if (deref_count != 0 || !reborrow_str.is_empty()) && needs_parens_for_prefix {
|
||||
format!("({reborrow_str}{}{snip})", "*".repeat(deref_count))
|
||||
} else {
|
||||
format!("{reborrow_str}{}{snip}", "*".repeat(deref_count))
|
||||
};
|
||||
|
||||
(lint, help_str, sugg)
|
||||
span_lint_and_then(cx, lint, expr.span, msg, |diag| {
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;
|
||||
let sugg = if (deref_count != 0 || !reborrow_str.is_empty()) && needs_parens_for_prefix {
|
||||
format!("({reborrow_str}{}{snip})", "*".repeat(deref_count))
|
||||
} else {
|
||||
format!("{reborrow_str}{}{snip}", "*".repeat(deref_count))
|
||||
};
|
||||
diag.span_suggestion(expr.span, help_msg, sugg, app);
|
||||
});
|
||||
} else if let Some(target_id) = cx.tcx.lang_items().deref_target() {
|
||||
if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(
|
||||
cx.param_env,
|
||||
Ty::new_projection_from_args(cx.tcx, target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])),
|
||||
) {
|
||||
if deref_ty == expr_ty {
|
||||
let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;
|
||||
let sugg = if needs_parens_for_prefix {
|
||||
format!("(&{}{}*{snip})", mutability.prefix_str(), "*".repeat(indexed_ref_count))
|
||||
} else {
|
||||
format!("&{}{}*{snip}", mutability.prefix_str(), "*".repeat(indexed_ref_count))
|
||||
};
|
||||
(DEREF_BY_SLICING_LINT, "dereference the original value instead", sugg)
|
||||
} else {
|
||||
return;
|
||||
let (lint, msg) = DEREF_BY_SLICING_LINT;
|
||||
span_lint_and_then(cx, lint, expr.span, msg, |diag| {
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;
|
||||
let sugg = if needs_parens_for_prefix {
|
||||
format!("(&{}{}*{snip})", mutability.prefix_str(), "*".repeat(indexed_ref_count))
|
||||
} else {
|
||||
format!("&{}{}*{snip}", mutability.prefix_str(), "*".repeat(indexed_ref_count))
|
||||
};
|
||||
diag.span_suggestion(expr.span, "dereference the original value instead", sugg, app);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
span_lint_and_sugg(cx, lint, expr.span, msg, help, sugg, app);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_config::msrvs::Msrv;
|
||||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use rustc_attr::{StabilityLevel, StableSince};
|
||||
use rustc_errors::Applicability;
|
||||
@ -136,14 +136,20 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
|
||||
_ => return,
|
||||
};
|
||||
if first_segment.ident.span != self.prev_span {
|
||||
span_lint_and_sugg(
|
||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
lint,
|
||||
first_segment.ident.span,
|
||||
format!("used import from `{used_mod}` instead of `{replace_with}`"),
|
||||
format!("consider importing the item from `{replace_with}`"),
|
||||
replace_with.to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
|diag| {
|
||||
diag.span_suggestion(
|
||||
first_segment.ident.span,
|
||||
format!("consider importing the item from `{replace_with}`"),
|
||||
replace_with.to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
},
|
||||
);
|
||||
self.prev_span = first_segment.ident.span;
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:38:17
|
||||
|
|
||||
LL | let _ = boxed_slice.get(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&boxed_slice[1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::get-unwrap` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::get_unwrap)]`
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &boxed_slice[1];
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:38:17
|
||||
@ -18,11 +22,16 @@ LL | let _ = boxed_slice.get(1).unwrap();
|
||||
= note: `-D clippy::unwrap-used` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`
|
||||
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:39:17
|
||||
|
|
||||
LL | let _ = some_slice.get(0).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_slice[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_slice[0];
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:39:17
|
||||
@ -33,11 +42,16 @@ LL | let _ = some_slice.get(0).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a Vec
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:40:17
|
||||
|
|
||||
LL | let _ = some_vec.get(0).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vec[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_vec[0];
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:40:17
|
||||
@ -48,11 +62,16 @@ LL | let _ = some_vec.get(0).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a VecDeque
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17
|
||||
|
|
||||
LL | let _ = some_vecdeque.get(0).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vecdeque[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_vecdeque[0];
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17
|
||||
@ -63,11 +82,16 @@ LL | let _ = some_vecdeque.get(0).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a HashMap
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:42:17
|
||||
|
|
||||
LL | let _ = some_hashmap.get(&1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_hashmap[&1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_hashmap[&1];
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:42:17
|
||||
@ -78,11 +102,16 @@ LL | let _ = some_hashmap.get(&1).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a BTreeMap
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:43:17
|
||||
|
|
||||
LL | let _ = some_btreemap.get(&1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_btreemap[&1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_btreemap[&1];
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:43:17
|
||||
@ -93,11 +122,16 @@ LL | let _ = some_btreemap.get(&1).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:47:21
|
||||
|
|
||||
LL | let _: u8 = *boxed_slice.get(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _: u8 = boxed_slice[1];
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:47:22
|
||||
@ -108,11 +142,16 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a slice
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:52:9
|
||||
|
|
||||
LL | *boxed_slice.get_mut(0).unwrap() = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | boxed_slice[0] = 1;
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:52:10
|
||||
@ -123,11 +162,16 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1;
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a slice
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:53:9
|
||||
|
|
||||
LL | *some_slice.get_mut(0).unwrap() = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_slice[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | some_slice[0] = 1;
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:53:10
|
||||
@ -138,11 +182,16 @@ LL | *some_slice.get_mut(0).unwrap() = 1;
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a Vec
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:54:9
|
||||
|
|
||||
LL | *some_vec.get_mut(0).unwrap() = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | some_vec[0] = 1;
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:54:10
|
||||
@ -153,11 +202,16 @@ LL | *some_vec.get_mut(0).unwrap() = 1;
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a VecDeque
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:55:9
|
||||
|
|
||||
LL | *some_vecdeque.get_mut(0).unwrap() = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vecdeque[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | some_vecdeque[0] = 1;
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:55:10
|
||||
@ -168,11 +222,16 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1;
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a Vec
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:67:17
|
||||
|
|
||||
LL | let _ = some_vec.get(0..1).unwrap().to_vec();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = some_vec[0..1].to_vec();
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:67:17
|
||||
@ -183,11 +242,16 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a Vec
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:68:17
|
||||
|
|
||||
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = some_vec[0..1].to_vec();
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:68:17
|
||||
@ -198,17 +262,27 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:75:13
|
||||
|
|
||||
LL | let _ = boxed_slice.get(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&boxed_slice[1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &boxed_slice[1];
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:93:17
|
||||
|
|
||||
LL | let _ = Box::new([0]).get(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&Box::new([0])[1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &Box::new([0])[1];
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 28 previous errors
|
||||
|
||||
|
@ -2,16 +2,25 @@ error: calling `std::fs::create_dir` where there may be a better way
|
||||
--> tests/ui/create_dir.rs:10:5
|
||||
|
|
||||
LL | std::fs::create_dir("foo");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `create_dir_all("foo")`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::create-dir` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::create_dir)]`
|
||||
help: consider calling `std::fs::create_dir_all` instead
|
||||
|
|
||||
LL | create_dir_all("foo");
|
||||
| ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: calling `std::fs::create_dir` where there may be a better way
|
||||
--> tests/ui/create_dir.rs:11:5
|
||||
|
|
||||
LL | std::fs::create_dir("bar").unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `create_dir_all("bar")`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider calling `std::fs::create_dir_all` instead
|
||||
|
|
||||
LL | create_dir_all("bar").unwrap();
|
||||
| ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -81,7 +81,7 @@ error: the `dbg!` macro is intended as a debugging tool
|
||||
--> tests/ui/dbg_macro/dbg_macro.rs:48:5
|
||||
|
|
||||
LL | dbg!();
|
||||
| ^^^^^^^
|
||||
| ^^^^^^
|
||||
|
|
||||
help: remove the invocation before committing it to a version control system
|
||||
|
|
||||
@ -136,7 +136,7 @@ error: the `dbg!` macro is intended as a debugging tool
|
||||
--> tests/ui/dbg_macro/dbg_macro.rs:43:13
|
||||
|
|
||||
LL | dbg!();
|
||||
| ^^^^^^^
|
||||
| ^^^^^^
|
||||
...
|
||||
LL | expand_to_dbg!();
|
||||
| ---------------- in this macro invocation
|
||||
|
@ -2,7 +2,7 @@ error: the `dbg!` macro is intended as a debugging tool
|
||||
--> tests/ui/dbg_macro/auxiliary/submodule.rs:2:5
|
||||
|
|
||||
LL | dbg!();
|
||||
| ^^^^^^^
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: `-D clippy::dbg-macro` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]`
|
||||
|
@ -4,10 +4,11 @@ error: empty drop implementation
|
||||
LL | / impl Drop for Foo {
|
||||
LL | | fn drop(&mut self) {}
|
||||
LL | | }
|
||||
| |_^ help: try removing this impl
|
||||
| |_^
|
||||
|
|
||||
= note: `-D clippy::empty-drop` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::empty_drop)]`
|
||||
= help: try removing this impl
|
||||
|
||||
error: empty drop implementation
|
||||
--> tests/ui/empty_drop.rs:23:1
|
||||
@ -17,7 +18,9 @@ LL | | fn drop(&mut self) {
|
||||
LL | | {}
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^ help: try removing this impl
|
||||
| |_^
|
||||
|
|
||||
= help: try removing this impl
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -2,106 +2,190 @@ error: casting function pointer `foo` to `i8`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:23:13
|
||||
|
|
||||
LL | let _ = foo as i8;
|
||||
| ^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i8`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::fn-to-numeric-cast-any` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_any)]`
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as i8;
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `i16`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:26:13
|
||||
|
|
||||
LL | let _ = foo as i16;
|
||||
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i16`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as i16;
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `i32`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:28:13
|
||||
|
|
||||
LL | let _ = foo as i32;
|
||||
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i32`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as i32;
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `i64`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:30:13
|
||||
|
|
||||
LL | let _ = foo as i64;
|
||||
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i64`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as i64;
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `i128`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:32:13
|
||||
|
|
||||
LL | let _ = foo as i128;
|
||||
| ^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i128`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as i128;
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `isize`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:34:13
|
||||
|
|
||||
LL | let _ = foo as isize;
|
||||
| ^^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as isize`
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as isize;
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `u8`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:37:13
|
||||
|
|
||||
LL | let _ = foo as u8;
|
||||
| ^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u8`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as u8;
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `u16`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:39:13
|
||||
|
|
||||
LL | let _ = foo as u16;
|
||||
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u16`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as u16;
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `u32`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:41:13
|
||||
|
|
||||
LL | let _ = foo as u32;
|
||||
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u32`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as u32;
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `u64`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:43:13
|
||||
|
|
||||
LL | let _ = foo as u64;
|
||||
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u64`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as u64;
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `u128`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:45:13
|
||||
|
|
||||
LL | let _ = foo as u128;
|
||||
| ^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u128`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as u128;
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `usize`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:47:13
|
||||
|
|
||||
LL | let _ = foo as usize;
|
||||
| ^^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as usize`
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as usize;
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `Struct::static_method` to `usize`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:52:13
|
||||
|
|
||||
LL | let _ = Struct::static_method as usize;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to invoke the function?: `Struct::static_method() as usize`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = Struct::static_method() as usize;
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `f` to `usize`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:57:5
|
||||
|
|
||||
LL | f as usize
|
||||
| ^^^^^^^^^^ help: did you mean to invoke the function?: `f() as usize`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | f() as usize
|
||||
|
|
||||
|
||||
error: casting function pointer `T::static_method` to `usize`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:62:5
|
||||
|
|
||||
LL | T::static_method as usize
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to invoke the function?: `T::static_method() as usize`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | T::static_method() as usize
|
||||
|
|
||||
|
||||
error: casting function pointer `(clos as fn(u32) -> u32)` to `usize`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:69:13
|
||||
|
|
||||
LL | let _ = (clos as fn(u32) -> u32) as usize;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to invoke the function?: `(clos as fn(u32) -> u32)() as usize`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = (clos as fn(u32) -> u32)() as usize;
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: casting function pointer `foo` to `*const ()`
|
||||
--> tests/ui/fn_to_numeric_cast_any.rs:74:13
|
||||
|
|
||||
LL | let _ = foo as *const ();
|
||||
| ^^^^^^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as *const ()`
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: did you mean to invoke the function?
|
||||
|
|
||||
LL | let _ = foo() as *const ();
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
|
@ -1,14 +1,18 @@
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:37:17
|
||||
|
|
||||
LL | let _ = boxed_slice.get(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&boxed_slice[1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> tests/ui/get_unwrap.rs:9:9
|
||||
|
|
||||
LL | #![deny(clippy::get_unwrap)]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &boxed_slice[1];
|
||||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:37:17
|
||||
@ -21,11 +25,16 @@ LL | let _ = boxed_slice.get(1).unwrap();
|
||||
= note: `-D clippy::unwrap-used` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`
|
||||
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:38:17
|
||||
|
|
||||
LL | let _ = some_slice.get(0).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_slice[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_slice[0];
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:38:17
|
||||
@ -36,11 +45,16 @@ LL | let _ = some_slice.get(0).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a Vec
|
||||
--> tests/ui/get_unwrap.rs:39:17
|
||||
|
|
||||
LL | let _ = some_vec.get(0).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vec[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_vec[0];
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:39:17
|
||||
@ -51,11 +65,16 @@ LL | let _ = some_vec.get(0).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a VecDeque
|
||||
--> tests/ui/get_unwrap.rs:40:17
|
||||
|
|
||||
LL | let _ = some_vecdeque.get(0).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vecdeque[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_vecdeque[0];
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:40:17
|
||||
@ -66,11 +85,16 @@ LL | let _ = some_vecdeque.get(0).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a HashMap
|
||||
--> tests/ui/get_unwrap.rs:41:17
|
||||
|
|
||||
LL | let _ = some_hashmap.get(&1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_hashmap[&1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_hashmap[&1];
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:41:17
|
||||
@ -81,11 +105,16 @@ LL | let _ = some_hashmap.get(&1).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a BTreeMap
|
||||
--> tests/ui/get_unwrap.rs:42:17
|
||||
|
|
||||
LL | let _ = some_btreemap.get(&1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_btreemap[&1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = &some_btreemap[&1];
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:42:17
|
||||
@ -96,11 +125,16 @@ LL | let _ = some_btreemap.get(&1).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:46:21
|
||||
|
|
||||
LL | let _: u8 = *boxed_slice.get(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _: u8 = boxed_slice[1];
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:46:22
|
||||
@ -111,11 +145,16 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:51:9
|
||||
|
|
||||
LL | *boxed_slice.get_mut(0).unwrap() = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | boxed_slice[0] = 1;
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:51:10
|
||||
@ -126,11 +165,16 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1;
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:52:9
|
||||
|
|
||||
LL | *some_slice.get_mut(0).unwrap() = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_slice[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | some_slice[0] = 1;
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:52:10
|
||||
@ -141,11 +185,16 @@ LL | *some_slice.get_mut(0).unwrap() = 1;
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a Vec
|
||||
--> tests/ui/get_unwrap.rs:53:9
|
||||
|
|
||||
LL | *some_vec.get_mut(0).unwrap() = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | some_vec[0] = 1;
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:53:10
|
||||
@ -156,11 +205,16 @@ LL | *some_vec.get_mut(0).unwrap() = 1;
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a VecDeque
|
||||
--> tests/ui/get_unwrap.rs:54:9
|
||||
|
|
||||
LL | *some_vecdeque.get_mut(0).unwrap() = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vecdeque[0]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | some_vecdeque[0] = 1;
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:54:10
|
||||
@ -171,11 +225,16 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1;
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a Vec
|
||||
--> tests/ui/get_unwrap.rs:66:17
|
||||
|
|
||||
LL | let _ = some_vec.get(0..1).unwrap().to_vec();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = some_vec[0..1].to_vec();
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:66:17
|
||||
@ -186,11 +245,16 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a Vec
|
||||
--> tests/ui/get_unwrap.rs:67:17
|
||||
|
|
||||
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _ = some_vec[0..1].to_vec();
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: used `unwrap()` on an `Option` value
|
||||
--> tests/ui/get_unwrap.rs:67:17
|
||||
@ -201,29 +265,49 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
|
||||
= note: if this value is `None`, it will panic
|
||||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:77:24
|
||||
|
|
||||
LL | let _x: &i32 = f.get(1 + 2).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `&f[1 + 2]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _x: &i32 = &f[1 + 2];
|
||||
| ~~~~~~~~~
|
||||
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:80:18
|
||||
|
|
||||
LL | let _x = f.get(1 + 2).unwrap().to_string();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `f[1 + 2]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _x = f[1 + 2].to_string();
|
||||
| ~~~~~~~~
|
||||
|
||||
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:83:18
|
||||
|
|
||||
LL | let _x = f.get(1 + 2).unwrap().abs();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `f[1 + 2]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let _x = f[1 + 2].abs();
|
||||
| ~~~~~~~~
|
||||
|
||||
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||
error: called `.get_mut().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:100:33
|
||||
|
|
||||
LL | let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut rest[linidx(j, k) - linidx(i, k) - 1]`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: using `[]` is clearer and more concise
|
||||
|
|
||||
LL | let b = &mut rest[linidx(j, k) - linidx(i, k) - 1];
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 30 previous errors
|
||||
|
||||
|
119
tests/ui/if_then_some_else_none.fixed
Normal file
119
tests/ui/if_then_some_else_none.fixed
Normal file
@ -0,0 +1,119 @@
|
||||
#![warn(clippy::if_then_some_else_none)]
|
||||
#![allow(clippy::redundant_pattern_matching, clippy::unnecessary_lazy_evaluations)]
|
||||
|
||||
fn main() {
|
||||
// Should issue an error.
|
||||
let _ = foo().then(|| { println!("true!"); "foo" });
|
||||
|
||||
// Should issue an error when macros are used.
|
||||
let _ = matches!(true, true).then(|| { println!("true!"); matches!(true, false) });
|
||||
|
||||
// Should issue an error. Binary expression `o < 32` should be parenthesized.
|
||||
let x = Some(5);
|
||||
let _ = x.and_then(|o| (o < 32).then_some(o));
|
||||
//~^ ERROR: this could be simplified with `bool::then_some`
|
||||
|
||||
// Should issue an error. Unary expression `!x` should be parenthesized.
|
||||
let x = true;
|
||||
let _ = (!x).then_some(0);
|
||||
//~^ ERROR: this could be simplified with `bool::then_some`
|
||||
|
||||
// Should not issue an error since the `else` block has a statement besides `None`.
|
||||
let _ = if foo() {
|
||||
println!("true!");
|
||||
Some("foo")
|
||||
} else {
|
||||
eprintln!("false...");
|
||||
None
|
||||
};
|
||||
|
||||
// Should not issue an error since there are more than 2 blocks in the if-else chain.
|
||||
let _ = if foo() {
|
||||
println!("foo true!");
|
||||
Some("foo")
|
||||
} else if bar() {
|
||||
println!("bar true!");
|
||||
Some("bar")
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let _ = if foo() {
|
||||
println!("foo true!");
|
||||
Some("foo")
|
||||
} else {
|
||||
bar().then(|| {
|
||||
println!("bar true!");
|
||||
"bar"
|
||||
})
|
||||
};
|
||||
|
||||
// Should not issue an error since the `then` block has `None`, not `Some`.
|
||||
let _ = if foo() { None } else { Some("foo is false") };
|
||||
|
||||
// Should not issue an error since the `else` block doesn't use `None` directly.
|
||||
let _ = if foo() { Some("foo is true") } else { into_none() };
|
||||
|
||||
// Should not issue an error since the `then` block doesn't use `Some` directly.
|
||||
let _ = if foo() { into_some("foo") } else { None };
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.49"]
|
||||
fn _msrv_1_49() {
|
||||
// `bool::then` was stabilized in 1.50. Do not lint this
|
||||
let _ = if foo() {
|
||||
println!("true!");
|
||||
Some(149)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.50"]
|
||||
fn _msrv_1_50() {
|
||||
let _ = foo().then(|| { println!("true!"); 150 });
|
||||
}
|
||||
|
||||
fn foo() -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn bar() -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn into_some<T>(v: T) -> Option<T> {
|
||||
Some(v)
|
||||
}
|
||||
|
||||
fn into_none<T>() -> Option<T> {
|
||||
None
|
||||
}
|
||||
|
||||
// Should not warn
|
||||
fn f(b: bool, v: Option<()>) -> Option<()> {
|
||||
if b {
|
||||
v?; // This is a potential early return, is not equivalent with `bool::then`
|
||||
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn issue11394(b: bool, v: Result<(), ()>) -> Result<(), ()> {
|
||||
let x = if b {
|
||||
#[allow(clippy::let_unit_value)]
|
||||
let _ = v?;
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
const fn issue12103(x: u32) -> Option<u32> {
|
||||
// Should not issue an error in `const` context
|
||||
if x > 42 { Some(150) } else { None }
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#![warn(clippy::if_then_some_else_none)]
|
||||
#![allow(clippy::redundant_pattern_matching)]
|
||||
#![allow(clippy::redundant_pattern_matching, clippy::unnecessary_lazy_evaluations)]
|
||||
|
||||
fn main() {
|
||||
// Should issue an error.
|
||||
|
@ -9,9 +9,8 @@ LL | | Some("foo")
|
||||
LL | | } else {
|
||||
LL | | None
|
||||
LL | | };
|
||||
| |_____^
|
||||
| |_____^ help: try: `foo().then(|| { println!("true!"); "foo" })`
|
||||
|
|
||||
= help: consider using `bool::then` like: `foo().then(|| { /* snippet */ "foo" })`
|
||||
= note: `-D clippy::if-then-some-else-none` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::if_then_some_else_none)]`
|
||||
|
||||
@ -26,25 +25,19 @@ LL | | Some(matches!(true, false))
|
||||
LL | | } else {
|
||||
LL | | None
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
= help: consider using `bool::then` like: `matches!(true, true).then(|| { /* snippet */ matches!(true, false) })`
|
||||
| |_____^ help: try: `matches!(true, true).then(|| { println!("true!"); matches!(true, false) })`
|
||||
|
||||
error: this could be simplified with `bool::then_some`
|
||||
--> tests/ui/if_then_some_else_none.rs:25:28
|
||||
|
|
||||
LL | let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider using `bool::then_some` like: `(o < 32).then_some(o)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(o < 32).then_some(o)`
|
||||
|
||||
error: this could be simplified with `bool::then_some`
|
||||
--> tests/ui/if_then_some_else_none.rs:30:13
|
||||
|
|
||||
LL | let _ = if !x { Some(0) } else { None };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider using `bool::then_some` like: `(!x).then_some(0)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(!x).then_some(0)`
|
||||
|
||||
error: this could be simplified with `bool::then`
|
||||
--> tests/ui/if_then_some_else_none.rs:86:13
|
||||
@ -57,9 +50,7 @@ LL | | Some(150)
|
||||
LL | | } else {
|
||||
LL | | None
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
= help: consider using `bool::then` like: `foo().then(|| { /* snippet */ 150 })`
|
||||
| |_____^ help: try: `foo().then(|| { println!("true!"); 150 })`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
@ -2,88 +2,157 @@ error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:15:5
|
||||
|
|
||||
LL | true
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
| ^^^^
|
||||
|
|
||||
= note: `-D clippy::implicit-return` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::implicit_return)]`
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | return true
|
||||
|
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:19:15
|
||||
|
|
||||
LL | if true { true } else { false }
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
| ^^^^
|
||||
|
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | if true { return true } else { false }
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:19:29
|
||||
|
|
||||
LL | if true { true } else { false }
|
||||
| ^^^^^ help: add `return` as shown: `return false`
|
||||
| ^^^^^
|
||||
|
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | if true { true } else { return false }
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:25:17
|
||||
|
|
||||
LL | true => false,
|
||||
| ^^^^^ help: add `return` as shown: `return false`
|
||||
| ^^^^^
|
||||
|
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | true => return false,
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:26:20
|
||||
|
|
||||
LL | false => { true },
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
| ^^^^
|
||||
|
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | false => { return true },
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:39:9
|
||||
|
|
||||
LL | break true;
|
||||
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: change `break` to `return` as shown
|
||||
|
|
||||
LL | return true;
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:46:13
|
||||
|
|
||||
LL | break true;
|
||||
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: change `break` to `return` as shown
|
||||
|
|
||||
LL | return true;
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:54:13
|
||||
|
|
||||
LL | break true;
|
||||
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: change `break` to `return` as shown
|
||||
|
|
||||
LL | return true;
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:72:18
|
||||
|
|
||||
LL | let _ = || { true };
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
| ^^^^
|
||||
|
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | let _ = || { return true };
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:73:16
|
||||
|
|
||||
LL | let _ = || true;
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
| ^^^^
|
||||
|
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | let _ = || return true;
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:81:5
|
||||
|
|
||||
LL | format!("test {}", "test")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `return` as shown: `return format!("test {}", "test")`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | return format!("test {}", "test")
|
||||
|
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:90:5
|
||||
|
|
||||
LL | m!(true, false)
|
||||
| ^^^^^^^^^^^^^^^ help: add `return` as shown: `return m!(true, false)`
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | return m!(true, false)
|
||||
|
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:96:13
|
||||
|
|
||||
LL | break true;
|
||||
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: change `break` to `return` as shown
|
||||
|
|
||||
LL | return true;
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:101:17
|
||||
|
|
||||
LL | break 'outer false;
|
||||
| ^^^^^^^^^^^^^^^^^^ help: change `break` to `return` as shown: `return false`
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: change `break` to `return` as shown
|
||||
|
|
||||
LL | return false;
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:116:5
|
||||
@ -104,7 +173,12 @@ error: missing `return` statement
|
||||
--> tests/ui/implicit_return.rs:130:5
|
||||
|
|
||||
LL | true
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
| ^^^^
|
||||
|
|
||||
help: add `return` as shown
|
||||
|
|
||||
LL | return true
|
||||
|
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user