Auto merge of #9046 - xFrednet:rust-97660-expection-something-something, r=Jarcho

Fix `#[expect]` for most clippy lints

This PR fixes most `#[expect]` - lint interactions listed in rust-lang/rust#97660. [My comment in the issue](https://github.com/rust-lang/rust/issues/97660#issuecomment-1147269504) shows the current progress (Once this is merged). I plan to work on `duplicate_mod` and `multiple_inherent_impl` and leave the rest for later. I feel like stabilizing the feature is more important than fixing the last few nits, which currently also don't work with `#[allow]`.

---

changelog: none

r? `@Jarcho`

cc: rust-lang/rust#97660
This commit is contained in:
bors
2022-06-28 18:28:38 +00:00
34 changed files with 467 additions and 234 deletions

View File

@@ -78,10 +78,17 @@ declare_clippy_lint! {
/// Checks for `extern crate` and `use` items annotated with
/// lint attributes.
///
/// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,
/// `#[allow(unreachable_pub)]`, `#[allow(clippy::wildcard_imports)]` and
/// `#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on
/// `extern crate` items with a `#[macro_use]` attribute.
/// This lint permits lint attributes for lints emitted on the items themself.
/// For `use` items these lints are:
/// * deprecated
/// * unreachable_pub
/// * unused_imports
/// * clippy::enum_glob_use
/// * clippy::macro_use_imports
/// * clippy::wildcard_imports
///
/// For `extern crate` items these lints are:
/// * `unused_imports` on items with `#[macro_use]`
///
/// ### Why is this bad?
/// Lint attributes have no effect on crate imports. Most
@@ -347,7 +354,10 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
|| extract_clippy_lint(lint).map_or(false, |s| {
matches!(
s.as_str(),
"wildcard_imports" | "enum_glob_use" | "redundant_pub_crate",
"wildcard_imports"
| "enum_glob_use"
| "redundant_pub_crate"
| "macro_use_imports",
)
})
{

View File

@@ -1,4 +1,4 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
use clippy_utils::{eq_expr_value, get_trait_def_id, paths};
@@ -394,9 +394,10 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
continue 'simplified;
}
if stats.terminals[i] != 0 && simplified_stats.terminals[i] == 0 {
span_lint_and_then(
span_lint_hir_and_then(
self.cx,
LOGIC_BUG,
e.hir_id,
e.span,
"this boolean expression contains a logic bug",
|diag| {
@@ -429,9 +430,10 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
}
}
let nonminimal_bool_lint = |suggestions: Vec<_>| {
span_lint_and_then(
span_lint_hir_and_then(
self.cx,
NONMINIMAL_BOOL,
e.hir_id,
e.span,
"this boolean expression can be simplified",
|diag| {

View File

@@ -1,4 +1,4 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::diagnostics::span_lint_hir;
use clippy_utils::ty::contains_ty;
use rustc_hir::intravisit;
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node};
@@ -118,9 +118,10 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
});
for node in v.set {
span_lint(
span_lint_hir(
cx,
BOXED_LOCAL,
node,
cx.tcx.hir().span(node),
"local variable doesn't need to be boxed here",
);

View File

@@ -1,5 +1,5 @@
use clippy_utils::{
diagnostics::span_lint_and_sugg,
diagnostics::span_lint_hir_and_then,
get_async_fn_body, is_async_fn,
source::{snippet_with_applicability, snippet_with_context, walk_span_to_context},
visitors::expr_visitor_no_bodies,
@@ -43,32 +43,39 @@ declare_clippy_lint! {
declare_lint_pass!(ImplicitReturn => [IMPLICIT_RETURN]);
fn lint_return(cx: &LateContext<'_>, span: Span) {
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_and_sugg(
span_lint_hir_and_then(
cx,
IMPLICIT_RETURN,
emission_place,
span,
"missing `return` statement",
"add `return` as shown",
format!("return {}", snip),
app,
|diag| {
diag.span_suggestion(span, "add `return` as shown", format!("return {}", snip), app);
},
);
}
fn lint_break(cx: &LateContext<'_>, break_span: Span, expr_span: Span) {
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_and_sugg(
span_lint_hir_and_then(
cx,
IMPLICIT_RETURN,
emission_place,
break_span,
"missing `return` statement",
|diag| {
diag.span_suggestion(
break_span,
"change `break` to `return` as shown",
format!("return {}", snip),
app,
);
},
);
}
#[derive(Clone, Copy, PartialEq, Eq)]
@@ -152,7 +159,7 @@ fn lint_implicit_returns(
// At this point sub_expr can be `None` in async functions which either diverge, or return
// the unit type.
if let Some(sub_expr) = sub_expr {
lint_break(cx, e.span, sub_expr.span);
lint_break(cx, e.hir_id, e.span, sub_expr.span);
}
} else {
// the break expression is from a macro call, add a return to the loop
@@ -166,10 +173,10 @@ fn lint_implicit_returns(
if add_return {
#[expect(clippy::option_if_let_else)]
if let Some(span) = call_site_span {
lint_return(cx, span);
lint_return(cx, expr.hir_id, span);
LintLocation::Parent
} else {
lint_return(cx, expr.span);
lint_return(cx, expr.hir_id, expr.span);
LintLocation::Inner
}
} else {
@@ -198,10 +205,10 @@ fn lint_implicit_returns(
{
#[expect(clippy::option_if_let_else)]
if let Some(span) = call_site_span {
lint_return(cx, span);
lint_return(cx, expr.hir_id, span);
LintLocation::Parent
} else {
lint_return(cx, expr.span);
lint_return(cx, expr.hir_id, expr.span);
LintLocation::Inner
}
},

View File

@@ -1,4 +1,4 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::source::snippet;
use hir::def::{DefKind, Res};
use if_chain::if_chain;
@@ -51,8 +51,9 @@ impl MacroRefData {
#[derive(Default)]
#[expect(clippy::module_name_repetitions)]
pub struct MacroUseImports {
/// the actual import path used and the span of the attribute above it.
imports: Vec<(String, Span)>,
/// the actual import path used and the span of the attribute above it. The value is
/// the location, where the lint should be emitted.
imports: Vec<(String, Span, hir::HirId)>,
/// the span of the macro reference, kept to ensure only one reference is used per macro call.
collected: FxHashSet<Span>,
mac_refs: Vec<MacroRefData>,
@@ -91,7 +92,8 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
if_chain! {
if cx.sess().opts.edition >= Edition::Edition2018;
if let hir::ItemKind::Use(path, _kind) = &item.kind;
let attrs = cx.tcx.hir().attrs(item.hir_id());
let hir_id = item.hir_id();
let attrs = cx.tcx.hir().attrs(hir_id);
if let Some(mac_attr) = attrs.iter().find(|attr| attr.has_name(sym::macro_use));
if let Res::Def(DefKind::Mod, id) = path.res;
if !id.is_local();
@@ -100,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res {
let span = mac_attr.span;
let def_path = cx.tcx.def_path_str(mac_id);
self.imports.push((def_path, span));
self.imports.push((def_path, span, hir_id));
}
}
} else {
@@ -138,7 +140,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
fn check_crate_post(&mut self, cx: &LateContext<'_>) {
let mut used = FxHashMap::default();
let mut check_dup = vec![];
for (import, span) in &self.imports {
for (import, span, hir_id) in &self.imports {
let found_idx = self.mac_refs.iter().position(|mac| import.ends_with(&mac.name));
if let Some(idx) = found_idx {
@@ -151,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
[] | [_] => return,
[root, item] => {
if !check_dup.contains(&(*item).to_string()) {
used.entry(((*root).to_string(), span))
used.entry(((*root).to_string(), span, hir_id))
.or_insert_with(Vec::new)
.push((*item).to_string());
check_dup.push((*item).to_string());
@@ -169,13 +171,13 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
}
})
.collect::<Vec<_>>();
used.entry(((*root).to_string(), span))
used.entry(((*root).to_string(), span, hir_id))
.or_insert_with(Vec::new)
.push(filtered.join("::"));
check_dup.extend(filtered);
} else {
let rest = rest.to_vec();
used.entry(((*root).to_string(), span))
used.entry(((*root).to_string(), span, hir_id))
.or_insert_with(Vec::new)
.push(rest.join("::"));
check_dup.extend(rest.iter().map(ToString::to_string));
@@ -186,28 +188,34 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
}
let mut suggestions = vec![];
for ((root, span), path) in used {
for ((root, span, hir_id), path) in used {
if path.len() == 1 {
suggestions.push((span, format!("{}::{}", root, path[0])));
suggestions.push((span, format!("{}::{}", root, path[0]), hir_id));
} else {
suggestions.push((span, format!("{}::{{{}}}", root, path.join(", "))));
suggestions.push((span, format!("{}::{{{}}}", root, path.join(", ")), hir_id));
}
}
// If mac_refs is not empty we have encountered an import we could not handle
// such as `std::prelude::v1::foo` or some other macro that expands to an import.
if self.mac_refs.is_empty() {
for (span, import) in suggestions {
for (span, import, hir_id) in suggestions {
let help = format!("use {};", import);
span_lint_and_sugg(
span_lint_hir_and_then(
cx,
MACRO_USE_IMPORTS,
*hir_id,
*span,
"`macro_use` attributes are no longer needed in the Rust 2018 edition",
|diag| {
diag.span_suggestion(
*span,
"remove the attribute and import the macro directly, try",
help,
Applicability::MaybeIncorrect,
);
},
);
}
}
}

View File

@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
use clippy_utils::source::snippet_opt;
use clippy_utils::{is_doc_hidden, is_lint_allowed, meets_msrv, msrvs};
use clippy_utils::{is_doc_hidden, meets_msrv, msrvs};
use rustc_ast::ast::{self, VisibilityKind};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
@@ -190,12 +190,13 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
!self
.constructed_enum_variants
.contains(&(enum_id.to_def_id(), variant_id.to_def_id()))
&& !is_lint_allowed(cx, MANUAL_NON_EXHAUSTIVE, cx.tcx.hir().local_def_id_to_hir_id(enum_id))
})
{
span_lint_and_then(
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(enum_id);
span_lint_hir_and_then(
cx,
MANUAL_NON_EXHAUSTIVE,
hir_id,
enum_span,
"this seems like a manual implementation of the non-exhaustive pattern",
|diag| {

View File

@@ -1,6 +1,6 @@
//! Checks for usage of `&Vec[_]` and `&String`.
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::expr_sig;
use clippy_utils::visitors::contains_unsafe_block;
@@ -166,15 +166,14 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
)
.filter(|arg| arg.mutability() == Mutability::Not)
{
span_lint_and_sugg(
cx,
PTR_ARG,
span_lint_hir_and_then(cx, PTR_ARG, arg.emission_id, arg.span, &arg.build_msg(), |diag| {
diag.span_suggestion(
arg.span,
&arg.build_msg(),
"change this to",
format!("{}{}", arg.ref_prefix, arg.deref_ty.display(cx)),
Applicability::Unspecified,
);
});
}
}
}
@@ -221,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
let results = check_ptr_arg_usage(cx, body, &lint_args);
for (result, args) in results.iter().zip(lint_args.iter()).filter(|(r, _)| !r.skip) {
span_lint_and_then(cx, PTR_ARG, args.span, &args.build_msg(), |diag| {
span_lint_hir_and_then(cx, PTR_ARG, args.emission_id, args.span, &args.build_msg(), |diag| {
diag.multipart_suggestion(
"change this to",
iter::once((args.span, format!("{}{}", args.ref_prefix, args.deref_ty.display(cx))))
@@ -315,6 +314,7 @@ struct PtrArgReplacement {
struct PtrArg<'tcx> {
idx: usize,
emission_id: hir::HirId,
span: Span,
ty_did: DefId,
ty_name: Symbol,
@@ -419,10 +419,8 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
if let [.., name] = path.segments;
if cx.tcx.item_name(adt.did()) == name.ident.name;
if !is_lint_allowed(cx, PTR_ARG, hir_ty.hir_id);
if params.get(i).map_or(true, |p| !is_lint_allowed(cx, PTR_ARG, p.hir_id));
then {
let emission_id = params.get(i).map_or(hir_ty.hir_id, |param| param.hir_id);
let (method_renames, deref_ty) = match cx.tcx.get_diagnostic_name(adt.did()) {
Some(sym::Vec) => (
[("clone", ".to_owned()")].as_slice(),
@@ -455,21 +453,28 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
})
.and_then(|arg| snippet_opt(cx, arg.span))
.unwrap_or_else(|| substs.type_at(1).to_string());
span_lint_and_sugg(
span_lint_hir_and_then(
cx,
PTR_ARG,
emission_id,
hir_ty.span,
"using a reference to `Cow` is not recommended",
|diag| {
diag.span_suggestion(
hir_ty.span,
"change this to",
format!("&{}{}", mutability.prefix_str(), ty_name),
Applicability::Unspecified,
);
}
);
return None;
},
_ => return None,
};
return Some(PtrArg {
idx: i,
emission_id,
span: hir_ty.span,
ty_did: adt.did(),
ty_name: name.ident.name,

View File

@@ -1,4 +1,4 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::source::{snippet_opt, snippet_with_context};
use clippy_utils::{fn_def_id, path_to_local_id};
use if_chain::if_chain;
@@ -94,9 +94,10 @@ impl<'tcx> LateLintPass<'tcx> for Return {
if !in_external_macro(cx.sess(), retexpr.span);
if !local.span.from_expansion();
then {
span_lint_and_then(
span_lint_hir_and_then(
cx,
LET_AND_RETURN,
retexpr.hir_id,
retexpr.span,
"returning the result of a `let` binding from a block",
|err| {
@@ -185,6 +186,7 @@ fn check_final_expr<'tcx>(
if !borrows {
emit_return_lint(
cx,
inner.map_or(expr.hir_id, |inner| inner.hir_id),
span.expect("`else return` is not possible"),
inner.as_ref().map(|i| i.span),
replacement,
@@ -220,52 +222,83 @@ fn check_final_expr<'tcx>(
}
}
fn emit_return_lint(cx: &LateContext<'_>, ret_span: Span, inner_span: Option<Span>, replacement: RetReplacement) {
fn emit_return_lint(
cx: &LateContext<'_>,
emission_place: HirId,
ret_span: Span,
inner_span: Option<Span>,
replacement: RetReplacement,
) {
if ret_span.from_expansion() {
return;
}
match inner_span {
Some(inner_span) => {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_then(cx, NEEDLESS_RETURN, ret_span, "unneeded `return` statement", |diag| {
span_lint_hir_and_then(
cx,
NEEDLESS_RETURN,
emission_place,
ret_span,
"unneeded `return` statement",
|diag| {
let (snippet, _) = snippet_with_context(cx, inner_span, ret_span.ctxt(), "..", &mut applicability);
diag.span_suggestion(ret_span, "remove `return`", snippet, applicability);
});
},
);
},
None => match replacement {
RetReplacement::Empty => {
span_lint_and_sugg(
span_lint_hir_and_then(
cx,
NEEDLESS_RETURN,
emission_place,
ret_span,
"unneeded `return` statement",
|diag| {
diag.span_suggestion(
ret_span,
"remove `return`",
String::new(),
Applicability::MachineApplicable,
);
},
);
},
RetReplacement::Block => {
span_lint_and_sugg(
span_lint_hir_and_then(
cx,
NEEDLESS_RETURN,
emission_place,
ret_span,
"unneeded `return` statement",
|diag| {
diag.span_suggestion(
ret_span,
"replace `return` with an empty block",
"{}".to_string(),
Applicability::MachineApplicable,
);
},
);
},
RetReplacement::Unit => {
span_lint_and_sugg(
span_lint_hir_and_then(
cx,
NEEDLESS_RETURN,
emission_place,
ret_span,
"unneeded `return` statement",
|diag| {
diag.span_suggestion(
ret_span,
"replace `return` with a unit value",
"()".to_string(),
Applicability::MachineApplicable,
);
},
);
},
},
}
}

View File

@@ -1,4 +1,4 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::higher;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{path_to_local, usage::is_potentially_mutated};
@@ -251,9 +251,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
unwrappable.kind.error_variant_pattern()
};
span_lint_and_then(
span_lint_hir_and_then(
self.cx,
UNNECESSARY_UNWRAP,
expr.hir_id,
expr.span,
&format!(
"called `{}` on `{}` after checking its variant with `{}`",
@@ -283,9 +284,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
},
);
} else {
span_lint_and_then(
span_lint_hir_and_then(
self.cx,
PANICKING_UNWRAP,
expr.hir_id,
expr.span,
&format!("this call to `{}()` will always panic",
method_name.ident.name),

View File

@@ -1539,9 +1539,13 @@ pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tc
None
}
/// Returns `true` if the lint is allowed in the current context
/// Returns `true` if the lint is allowed in the current context. This is useful for
/// skipping long running code when it's unnecessary
///
/// Useful for skipping long running code when it's unnecessary
/// This function should check the lint level for the same node, that the lint will
/// be emitted at. If the information is buffered to be emitted at a later point, please
/// make sure to use `span_lint_hir` functions to emit the lint. This ensures that
/// expectations at the checked nodes will be fulfilled.
pub fn is_lint_allowed(cx: &LateContext<'_>, lint: &'static Lint, id: HirId) -> bool {
cx.tcx.lint_level_at_node(lint, id).0 == Level::Allow
}

View File

@@ -1,4 +1,5 @@
#![feature(box_syntax)]
#![feature(lint_reasons)]
#![allow(
clippy::borrowed_box,
clippy::needless_pass_by_value,
@@ -202,3 +203,7 @@ mod issue4804 {
fn foo(x: Box<u32>) {}
}
}
fn check_expect(#[expect(clippy::boxed_local)] x: Box<A>) {
x.foo();
}

View File

@@ -1,5 +1,5 @@
error: local variable doesn't need to be boxed here
--> $DIR/escape_analysis.rs:40:13
--> $DIR/boxed_local.rs:41:13
|
LL | fn warn_arg(x: Box<A>) {
| ^
@@ -7,19 +7,19 @@ LL | fn warn_arg(x: Box<A>) {
= note: `-D clippy::boxed-local` implied by `-D warnings`
error: local variable doesn't need to be boxed here
--> $DIR/escape_analysis.rs:131:12
--> $DIR/boxed_local.rs:132:12
|
LL | pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}
| ^^^^^^^^^^^
error: local variable doesn't need to be boxed here
--> $DIR/escape_analysis.rs:195:44
--> $DIR/boxed_local.rs:196:44
|
LL | fn default_impl_x(self: Box<Self>, x: Box<u32>) -> u32 {
| ^
error: local variable doesn't need to be boxed here
--> $DIR/escape_analysis.rs:202:16
--> $DIR/boxed_local.rs:203:16
|
LL | fn foo(x: Box<u32>) {}
| ^

View File

@@ -1,3 +1,4 @@
#![feature(lint_reasons)]
#![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
#![allow(clippy::if_same_then_else, clippy::branches_sharing_code)]
@@ -84,3 +85,18 @@ fn main() {
assert!(x.is_ok(), "{:?}", x.unwrap_err()); // ok, it's a common test pattern
}
fn check_expect() {
let x = Some(());
if x.is_some() {
#[expect(clippy::unnecessary_unwrap)]
x.unwrap(); // unnecessary
#[expect(clippy::unnecessary_unwrap)]
x.expect("an error message"); // unnecessary
} else {
#[expect(clippy::panicking_unwrap)]
x.unwrap(); // will panic
#[expect(clippy::panicking_unwrap)]
x.expect("an error message"); // will panic
}
}

View File

@@ -1,5 +1,5 @@
error: called `unwrap` on `x` after checking its variant with `is_some`
--> $DIR/simple_conditionals.rs:39:9
--> $DIR/simple_conditionals.rs:40:9
|
LL | if x.is_some() {
| -------------- help: try: `if let Some(..) = x`
@@ -7,13 +7,13 @@ LL | x.unwrap(); // unnecessary
| ^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/simple_conditionals.rs:1:35
--> $DIR/simple_conditionals.rs:2:35
|
LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `expect` on `x` after checking its variant with `is_some`
--> $DIR/simple_conditionals.rs:40:9
--> $DIR/simple_conditionals.rs:41:9
|
LL | if x.is_some() {
| -------------- help: try: `if let Some(..) = x`
@@ -22,7 +22,7 @@ LL | x.expect("an error message"); // unnecessary
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
--> $DIR/simple_conditionals.rs:42:9
--> $DIR/simple_conditionals.rs:43:9
|
LL | if x.is_some() {
| ----------- because of this check
@@ -31,13 +31,13 @@ LL | x.unwrap(); // will panic
| ^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/simple_conditionals.rs:1:9
--> $DIR/simple_conditionals.rs:2:9
|
LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `expect()` will always panic
--> $DIR/simple_conditionals.rs:43:9
--> $DIR/simple_conditionals.rs:44:9
|
LL | if x.is_some() {
| ----------- because of this check
@@ -46,7 +46,7 @@ LL | x.expect("an error message"); // will panic
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
--> $DIR/simple_conditionals.rs:46:9
--> $DIR/simple_conditionals.rs:47:9
|
LL | if x.is_none() {
| ----------- because of this check
@@ -54,7 +54,7 @@ LL | x.unwrap(); // will panic
| ^^^^^^^^^^
error: called `unwrap` on `x` after checking its variant with `is_none`
--> $DIR/simple_conditionals.rs:48:9
--> $DIR/simple_conditionals.rs:49:9
|
LL | if x.is_none() {
| -------------- help: try: `if let Some(..) = x`
@@ -63,7 +63,7 @@ LL | x.unwrap(); // unnecessary
| ^^^^^^^^^^
error: called `unwrap` on `x` after checking its variant with `is_some`
--> $DIR/simple_conditionals.rs:7:13
--> $DIR/simple_conditionals.rs:8:13
|
LL | if $a.is_some() {
| --------------- help: try: `if let Some(..) = x`
@@ -76,7 +76,7 @@ LL | m!(x);
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: called `unwrap` on `x` after checking its variant with `is_ok`
--> $DIR/simple_conditionals.rs:56:9
--> $DIR/simple_conditionals.rs:57:9
|
LL | if x.is_ok() {
| ------------ help: try: `if let Ok(..) = x`
@@ -84,7 +84,7 @@ LL | x.unwrap(); // unnecessary
| ^^^^^^^^^^
error: called `expect` on `x` after checking its variant with `is_ok`
--> $DIR/simple_conditionals.rs:57:9
--> $DIR/simple_conditionals.rs:58:9
|
LL | if x.is_ok() {
| ------------ help: try: `if let Ok(..) = x`
@@ -93,7 +93,7 @@ LL | x.expect("an error message"); // unnecessary
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap_err()` will always panic
--> $DIR/simple_conditionals.rs:58:9
--> $DIR/simple_conditionals.rs:59:9
|
LL | if x.is_ok() {
| --------- because of this check
@@ -102,7 +102,7 @@ LL | x.unwrap_err(); // will panic
| ^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
--> $DIR/simple_conditionals.rs:60:9
--> $DIR/simple_conditionals.rs:61:9
|
LL | if x.is_ok() {
| --------- because of this check
@@ -111,7 +111,7 @@ LL | x.unwrap(); // will panic
| ^^^^^^^^^^
error: this call to `expect()` will always panic
--> $DIR/simple_conditionals.rs:61:9
--> $DIR/simple_conditionals.rs:62:9
|
LL | if x.is_ok() {
| --------- because of this check
@@ -120,7 +120,7 @@ LL | x.expect("an error message"); // will panic
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `unwrap_err` on `x` after checking its variant with `is_ok`
--> $DIR/simple_conditionals.rs:62:9
--> $DIR/simple_conditionals.rs:63:9
|
LL | if x.is_ok() {
| ------------ help: try: `if let Err(..) = x`
@@ -129,7 +129,7 @@ LL | x.unwrap_err(); // unnecessary
| ^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
--> $DIR/simple_conditionals.rs:65:9
--> $DIR/simple_conditionals.rs:66:9
|
LL | if x.is_err() {
| ---------- because of this check
@@ -137,7 +137,7 @@ LL | x.unwrap(); // will panic
| ^^^^^^^^^^
error: called `unwrap_err` on `x` after checking its variant with `is_err`
--> $DIR/simple_conditionals.rs:66:9
--> $DIR/simple_conditionals.rs:67:9
|
LL | if x.is_err() {
| ------------- help: try: `if let Err(..) = x`
@@ -146,7 +146,7 @@ LL | x.unwrap_err(); // unnecessary
| ^^^^^^^^^^^^^^
error: called `unwrap` on `x` after checking its variant with `is_err`
--> $DIR/simple_conditionals.rs:68:9
--> $DIR/simple_conditionals.rs:69:9
|
LL | if x.is_err() {
| ------------- help: try: `if let Ok(..) = x`
@@ -155,7 +155,7 @@ LL | x.unwrap(); // unnecessary
| ^^^^^^^^^^
error: this call to `unwrap_err()` will always panic
--> $DIR/simple_conditionals.rs:69:9
--> $DIR/simple_conditionals.rs:70:9
|
LL | if x.is_err() {
| ---------- because of this check

View File

@@ -1,5 +1,5 @@
// run-rustfix
#![feature(lint_reasons)]
#![warn(clippy::implicit_return)]
#![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)]
@@ -128,3 +128,13 @@ async fn foo() -> bool {
}
fn main() {}
fn check_expect() -> bool {
if true {
// no error!
return true;
}
#[expect(clippy::implicit_return)]
true
}

View File

@@ -1,5 +1,5 @@
// run-rustfix
#![feature(lint_reasons)]
#![warn(clippy::implicit_return)]
#![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)]
@@ -128,3 +128,13 @@ async fn foo() -> bool {
}
fn main() {}
fn check_expect() -> bool {
if true {
// no error!
return true;
}
#[expect(clippy::implicit_return)]
true
}

View File

@@ -1,3 +1,4 @@
#![feature(lint_reasons)]
#![allow(unused, clippy::diverging_sub_expression)]
#![warn(clippy::logic_bug)]
@@ -24,3 +25,10 @@ fn equality_stuff() {
let _ = a > b && a <= b;
let _ = a > b && a == b;
}
fn check_expect() {
let a: i32 = unimplemented!();
let b: i32 = unimplemented!();
#[expect(clippy::logic_bug)]
let _ = a < b && a >= b;
}

View File

@@ -1,60 +1,60 @@
error: this boolean expression contains a logic bug
--> $DIR/logic_bug.rs:10:13
--> $DIR/logic_bug.rs:11:13
|
LL | let _ = a && b || a;
| ^^^^^^^^^^^ help: it would look like the following: `a`
|
= note: `-D clippy::logic-bug` implied by `-D warnings`
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/logic_bug.rs:10:18
--> $DIR/logic_bug.rs:11:18
|
LL | let _ = a && b || a;
| ^
error: this boolean expression contains a logic bug
--> $DIR/logic_bug.rs:12:13
--> $DIR/logic_bug.rs:13:13
|
LL | let _ = false && a;
| ^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/logic_bug.rs:12:22
--> $DIR/logic_bug.rs:13:22
|
LL | let _ = false && a;
| ^
error: this boolean expression contains a logic bug
--> $DIR/logic_bug.rs:22:13
--> $DIR/logic_bug.rs:23:13
|
LL | let _ = a == b && a != b;
| ^^^^^^^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/logic_bug.rs:22:13
--> $DIR/logic_bug.rs:23:13
|
LL | let _ = a == b && a != b;
| ^^^^^^
error: this boolean expression contains a logic bug
--> $DIR/logic_bug.rs:23:13
--> $DIR/logic_bug.rs:24:13
|
LL | let _ = a < b && a >= b;
| ^^^^^^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/logic_bug.rs:23:13
--> $DIR/logic_bug.rs:24:13
|
LL | let _ = a < b && a >= b;
| ^^^^^
error: this boolean expression contains a logic bug
--> $DIR/logic_bug.rs:24:13
--> $DIR/logic_bug.rs:25:13
|
LL | let _ = a > b && a <= b;
| ^^^^^^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/logic_bug.rs:24:13
--> $DIR/logic_bug.rs:25:13
|
LL | let _ = a > b && a <= b;
| ^^^^^

View File

@@ -4,6 +4,7 @@
// run-rustfix
// ignore-32bit
#![feature(lint_reasons)]
#![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)]
#![allow(clippy::single_component_path_imports)]
#![warn(clippy::macro_use_imports)]

View File

@@ -4,6 +4,7 @@
// run-rustfix
// ignore-32bit
#![feature(lint_reasons)]
#![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)]
#![allow(clippy::single_component_path_imports)]
#![warn(clippy::macro_use_imports)]

View File

@@ -1,28 +1,28 @@
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:18:5
--> $DIR/macro_use_imports.rs:23:5
|
LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, function_macro, ty_macro, inner_mod_macro, pub_in_private_macro};`
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};`
|
= note: `-D clippy::macro-use-imports` implied by `-D warnings`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:20:5
--> $DIR/macro_use_imports.rs:21:5
|
LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:22:5
|
LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:24:5
--> $DIR/macro_use_imports.rs:25:5
|
LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:19:5
|
LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, function_macro, ty_macro, inner_mod_macro, pub_in_private_macro};`
error: aborting due to 4 previous errors

View File

@@ -0,0 +1,51 @@
// aux-build:macro_rules.rs
// aux-build:macro_use_helper.rs
// aux-build:proc_macro_derive.rs
// ignore-32bit
#![feature(lint_reasons)]
#![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)]
#![allow(clippy::single_component_path_imports)]
#![warn(clippy::macro_use_imports)]
#[macro_use]
extern crate macro_use_helper as mac;
#[macro_use]
extern crate proc_macro_derive as mini_mac;
mod a {
#[expect(clippy::macro_use_imports)]
#[macro_use]
use mac;
#[expect(clippy::macro_use_imports)]
#[macro_use]
use mini_mac;
#[expect(clippy::macro_use_imports)]
#[macro_use]
use mac::inner;
#[expect(clippy::macro_use_imports)]
#[macro_use]
use mac::inner::nested;
#[derive(ClippyMiniMacroTest)]
struct Test;
fn test() {
pub_macro!();
inner_mod_macro!();
pub_in_private_macro!(_var);
function_macro!();
let v: ty_macro!() = Vec::default();
inner::try_err!();
inner::foofoo!();
nested::string_add!();
}
}
// issue #7015, ICE due to calling `module_children` with local `DefId`
#[macro_use]
use a as b;
fn main() {}

View File

@@ -1,3 +1,4 @@
#![feature(lint_reasons)]
#![warn(clippy::manual_non_exhaustive)]
#![allow(unused)]
@@ -75,4 +76,12 @@ fn foo(x: &mut UsedHidden) {
}
}
#[expect(clippy::manual_non_exhaustive)]
enum ExpectLint {
A,
B,
#[doc(hidden)]
_C,
}
fn main() {}

View File

@@ -1,5 +1,5 @@
error: this seems like a manual implementation of the non-exhaustive pattern
--> $DIR/manual_non_exhaustive_enum.rs:4:1
--> $DIR/manual_non_exhaustive_enum.rs:5:1
|
LL | enum E {
| ^-----
@@ -15,13 +15,13 @@ LL | | }
|
= note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
help: remove this variant
--> $DIR/manual_non_exhaustive_enum.rs:8:5
--> $DIR/manual_non_exhaustive_enum.rs:9:5
|
LL | _C,
| ^^
error: this seems like a manual implementation of the non-exhaustive pattern
--> $DIR/manual_non_exhaustive_enum.rs:13:1
--> $DIR/manual_non_exhaustive_enum.rs:14:1
|
LL | / enum Ep {
LL | | A,
@@ -32,7 +32,7 @@ LL | | }
| |_^
|
help: remove this variant
--> $DIR/manual_non_exhaustive_enum.rs:17:5
--> $DIR/manual_non_exhaustive_enum.rs:18:5
|
LL | _C,
| ^^

View File

@@ -1,5 +1,6 @@
// run-rustfix
#![feature(lint_reasons)]
#![feature(let_else)]
#![allow(unused)]
#![allow(
@@ -227,4 +228,13 @@ fn needless_return_macro() -> String {
format!("Hello {}", "world!")
}
fn check_expect() -> bool {
if true {
// no error!
return true;
}
#[expect(clippy::needless_return)]
return true;
}
fn main() {}

View File

@@ -1,5 +1,6 @@
// run-rustfix
#![feature(lint_reasons)]
#![feature(let_else)]
#![allow(unused)]
#![allow(
@@ -227,4 +228,13 @@ fn needless_return_macro() -> String {
return format!("Hello {}", "world!");
}
fn check_expect() -> bool {
if true {
// no error!
return true;
}
#[expect(clippy::needless_return)]
return true;
}
fn main() {}

View File

@@ -1,5 +1,5 @@
error: unneeded `return` statement
--> $DIR/needless_return.rs:26:5
--> $DIR/needless_return.rs:27:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
@@ -7,217 +7,217 @@ LL | return true;
= note: `-D clippy::needless-return` implied by `-D warnings`
error: unneeded `return` statement
--> $DIR/needless_return.rs:30:5
--> $DIR/needless_return.rs:31:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:35:9
--> $DIR/needless_return.rs:36:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:37:9
--> $DIR/needless_return.rs:38:9
|
LL | return false;
| ^^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded `return` statement
--> $DIR/needless_return.rs:43:17
--> $DIR/needless_return.rs:44:17
|
LL | true => return false,
| ^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded `return` statement
--> $DIR/needless_return.rs:45:13
--> $DIR/needless_return.rs:46:13
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:52:9
--> $DIR/needless_return.rs:53:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:54:16
--> $DIR/needless_return.rs:55:16
|
LL | let _ = || return true;
| ^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:58:5
--> $DIR/needless_return.rs:59:5
|
LL | return the_answer!();
| ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `the_answer!()`
error: unneeded `return` statement
--> $DIR/needless_return.rs:62:5
--> $DIR/needless_return.rs:63:5
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
--> $DIR/needless_return.rs:67:9
--> $DIR/needless_return.rs:68:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
--> $DIR/needless_return.rs:69:9
--> $DIR/needless_return.rs:70:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
--> $DIR/needless_return.rs:76:14
--> $DIR/needless_return.rs:77:14
|
LL | _ => return,
| ^^^^^^ help: replace `return` with a unit value: `()`
error: unneeded `return` statement
--> $DIR/needless_return.rs:85:13
--> $DIR/needless_return.rs:86:13
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
--> $DIR/needless_return.rs:87:14
--> $DIR/needless_return.rs:88:14
|
LL | _ => return,
| ^^^^^^ help: replace `return` with a unit value: `()`
error: unneeded `return` statement
--> $DIR/needless_return.rs:100:9
--> $DIR/needless_return.rs:101:9
|
LL | return String::from("test");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")`
error: unneeded `return` statement
--> $DIR/needless_return.rs:102:9
--> $DIR/needless_return.rs:103:9
|
LL | return String::new();
| ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()`
error: unneeded `return` statement
--> $DIR/needless_return.rs:124:32
--> $DIR/needless_return.rs:125:32
|
LL | bar.unwrap_or_else(|_| return)
| ^^^^^^ help: replace `return` with an empty block: `{}`
error: unneeded `return` statement
--> $DIR/needless_return.rs:129:13
--> $DIR/needless_return.rs:130:13
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
--> $DIR/needless_return.rs:131:20
--> $DIR/needless_return.rs:132:20
|
LL | let _ = || return;
| ^^^^^^ help: replace `return` with an empty block: `{}`
error: unneeded `return` statement
--> $DIR/needless_return.rs:137:32
--> $DIR/needless_return.rs:138:32
|
LL | res.unwrap_or_else(|_| return Foo)
| ^^^^^^^^^^ help: remove `return`: `Foo`
error: unneeded `return` statement
--> $DIR/needless_return.rs:146:5
--> $DIR/needless_return.rs:147:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:150:5
--> $DIR/needless_return.rs:151:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:155:9
--> $DIR/needless_return.rs:156:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:157:9
--> $DIR/needless_return.rs:158:9
|
LL | return false;
| ^^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded `return` statement
--> $DIR/needless_return.rs:163:17
--> $DIR/needless_return.rs:164:17
|
LL | true => return false,
| ^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded `return` statement
--> $DIR/needless_return.rs:165:13
--> $DIR/needless_return.rs:166:13
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:172:9
--> $DIR/needless_return.rs:173:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:174:16
--> $DIR/needless_return.rs:175:16
|
LL | let _ = || return true;
| ^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded `return` statement
--> $DIR/needless_return.rs:178:5
--> $DIR/needless_return.rs:179:5
|
LL | return the_answer!();
| ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `the_answer!()`
error: unneeded `return` statement
--> $DIR/needless_return.rs:182:5
--> $DIR/needless_return.rs:183:5
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
--> $DIR/needless_return.rs:187:9
--> $DIR/needless_return.rs:188:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
--> $DIR/needless_return.rs:189:9
--> $DIR/needless_return.rs:190:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded `return` statement
--> $DIR/needless_return.rs:196:14
--> $DIR/needless_return.rs:197:14
|
LL | _ => return,
| ^^^^^^ help: replace `return` with a unit value: `()`
error: unneeded `return` statement
--> $DIR/needless_return.rs:209:9
--> $DIR/needless_return.rs:210:9
|
LL | return String::from("test");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")`
error: unneeded `return` statement
--> $DIR/needless_return.rs:211:9
--> $DIR/needless_return.rs:212:9
|
LL | return String::new();
| ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()`
error: unneeded `return` statement
--> $DIR/needless_return.rs:227:5
--> $DIR/needless_return.rs:228:5
|
LL | return format!("Hello {}", "world!");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `format!("Hello {}", "world!")`

View File

@@ -1,3 +1,4 @@
#![feature(lint_reasons)]
#![allow(unused, clippy::diverging_sub_expression)]
#![warn(clippy::nonminimal_bool)]
@@ -50,3 +51,9 @@ fn issue4548() {
if i != j && f(i, j) != 0 || i == j && f(i, j) != 1 {}
}
fn check_expect() {
let a: bool = unimplemented!();
#[expect(clippy::nonminimal_bool)]
let _ = !!a;
}

View File

@@ -1,5 +1,5 @@
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:10:13
--> $DIR/nonminimal_bool.rs:11:13
|
LL | let _ = !true;
| ^^^^^ help: try: `false`
@@ -7,43 +7,43 @@ LL | let _ = !true;
= note: `-D clippy::nonminimal-bool` implied by `-D warnings`
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:11:13
--> $DIR/nonminimal_bool.rs:12:13
|
LL | let _ = !false;
| ^^^^^^ help: try: `true`
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:12:13
--> $DIR/nonminimal_bool.rs:13:13
|
LL | let _ = !!a;
| ^^^ help: try: `a`
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:13:13
--> $DIR/nonminimal_bool.rs:14:13
|
LL | let _ = false || a;
| ^^^^^^^^^^ help: try: `a`
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:17:13
--> $DIR/nonminimal_bool.rs:18:13
|
LL | let _ = !(!a && b);
| ^^^^^^^^^^ help: try: `a || !b`
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:18:13
--> $DIR/nonminimal_bool.rs:19:13
|
LL | let _ = !(!a || b);
| ^^^^^^^^^^ help: try: `a && !b`
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:19:13
--> $DIR/nonminimal_bool.rs:20:13
|
LL | let _ = !a && !(b && c);
| ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)`
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:27:13
--> $DIR/nonminimal_bool.rs:28:13
|
LL | let _ = a == b && c == 5 && a == b;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL | let _ = a == b && c == 5;
| ~~~~~~~~~~~~~~~~
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:28:13
--> $DIR/nonminimal_bool.rs:29:13
|
LL | let _ = a == b || c == 5 || a == b;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,7 +69,7 @@ LL | let _ = a == b || c == 5;
| ~~~~~~~~~~~~~~~~
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:29:13
--> $DIR/nonminimal_bool.rs:30:13
|
LL | let _ = a == b && c == 5 && b == a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -82,7 +82,7 @@ LL | let _ = a == b && c == 5;
| ~~~~~~~~~~~~~~~~
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:30:13
--> $DIR/nonminimal_bool.rs:31:13
|
LL | let _ = a != b || !(a != b || c == d);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -95,7 +95,7 @@ LL | let _ = a != b || c != d;
| ~~~~~~~~~~~~~~~~
error: this boolean expression can be simplified
--> $DIR/nonminimal_bool.rs:31:13
--> $DIR/nonminimal_bool.rs:32:13
|
LL | let _ = a != b && !(a != b && c == d);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -1,3 +1,4 @@
#![feature(lint_reasons)]
#![allow(unused, clippy::many_single_char_names, clippy::redundant_clone)]
#![warn(clippy::ptr_arg)]
@@ -109,9 +110,12 @@ mod issue_5644 {
#[allow(clippy::ptr_arg)] _s: &String,
#[allow(clippy::ptr_arg)] _p: &PathBuf,
#[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
#[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
) {
}
fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
struct S;
impl S {
fn allowed(
@@ -119,6 +123,7 @@ mod issue_5644 {
#[allow(clippy::ptr_arg)] _s: &String,
#[allow(clippy::ptr_arg)] _p: &PathBuf,
#[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
#[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
) {
}
}
@@ -129,6 +134,7 @@ mod issue_5644 {
#[allow(clippy::ptr_arg)] _s: &String,
#[allow(clippy::ptr_arg)] _p: &PathBuf,
#[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
#[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
) {
}
}

View File

@@ -1,5 +1,5 @@
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:7:14
--> $DIR/ptr_arg.rs:8:14
|
LL | fn do_vec(x: &Vec<i64>) {
| ^^^^^^^^^ help: change this to: `&[i64]`
@@ -7,43 +7,43 @@ LL | fn do_vec(x: &Vec<i64>) {
= note: `-D clippy::ptr-arg` implied by `-D warnings`
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:11:18
--> $DIR/ptr_arg.rs:12:18
|
LL | fn do_vec_mut(x: &mut Vec<i64>) {
| ^^^^^^^^^^^^^ help: change this to: `&mut [i64]`
error: writing `&String` instead of `&str` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:15:14
--> $DIR/ptr_arg.rs:16:14
|
LL | fn do_str(x: &String) {
| ^^^^^^^ help: change this to: `&str`
error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:19:18
--> $DIR/ptr_arg.rs:20:18
|
LL | fn do_str_mut(x: &mut String) {
| ^^^^^^^^^^^ help: change this to: `&mut str`
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:23:15
--> $DIR/ptr_arg.rs:24:15
|
LL | fn do_path(x: &PathBuf) {
| ^^^^^^^^ help: change this to: `&Path`
error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:27:19
--> $DIR/ptr_arg.rs:28:19
|
LL | fn do_path_mut(x: &mut PathBuf) {
| ^^^^^^^^^^^^ help: change this to: `&mut Path`
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:35:18
--> $DIR/ptr_arg.rs:36:18
|
LL | fn do_vec(x: &Vec<i64>);
| ^^^^^^^^^ help: change this to: `&[i64]`
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:48:14
--> $DIR/ptr_arg.rs:49:14
|
LL | fn cloned(x: &Vec<u8>) -> Vec<u8> {
| ^^^^^^^^
@@ -59,7 +59,7 @@ LL | let i = (e).clone();
...
error: writing `&String` instead of `&str` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:57:18
--> $DIR/ptr_arg.rs:58:18
|
LL | fn str_cloned(x: &String) -> String {
| ^^^^^^^
@@ -75,7 +75,7 @@ LL ~ x.to_owned()
|
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:65:19
--> $DIR/ptr_arg.rs:66:19
|
LL | fn path_cloned(x: &PathBuf) -> PathBuf {
| ^^^^^^^^
@@ -91,7 +91,7 @@ LL ~ x.to_path_buf()
|
error: writing `&String` instead of `&str` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:73:44
--> $DIR/ptr_arg.rs:74:44
|
LL | fn false_positive_capacity(x: &Vec<u8>, y: &String) {
| ^^^^^^^
@@ -105,13 +105,19 @@ LL ~ let c = y;
|
error: using a reference to `Cow` is not recommended
--> $DIR/ptr_arg.rs:87:25
--> $DIR/ptr_arg.rs:88:25
|
LL | fn test_cow_with_ref(c: &Cow<[i32]>) {}
| ^^^^^^^^^^^ help: change this to: `&[i32]`
error: writing `&String` instead of `&str` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:117:66
|
LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
| ^^^^^^^ help: change this to: `&str`
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:140:21
--> $DIR/ptr_arg.rs:146:21
|
LL | fn foo_vec(vec: &Vec<u8>) {
| ^^^^^^^^
@@ -124,7 +130,7 @@ LL ~ let _ = vec.to_owned().clone();
|
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:145:23
--> $DIR/ptr_arg.rs:151:23
|
LL | fn foo_path(path: &PathBuf) {
| ^^^^^^^^
@@ -137,7 +143,7 @@ LL ~ let _ = path.to_path_buf().clone();
|
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:150:21
--> $DIR/ptr_arg.rs:156:21
|
LL | fn foo_str(str: &PathBuf) {
| ^^^^^^^^
@@ -150,10 +156,10 @@ LL ~ let _ = str.to_path_buf().clone();
|
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
--> $DIR/ptr_arg.rs:156:29
--> $DIR/ptr_arg.rs:162:29
|
LL | fn mut_vec_slice_methods(v: &mut Vec<u32>) {
| ^^^^^^^^^^^^^ help: change this to: `&mut [u32]`
error: aborting due to 16 previous errors
error: aborting due to 17 previous errors

View File

@@ -1,6 +1,7 @@
// run-rustfix
// rustfix-only-machine-applicable
#![feature(lint_reasons)]
#![allow(clippy::implicit_clone, clippy::drop_non_drop)]
use std::ffi::OsString;
use std::path::Path;
@@ -29,6 +30,10 @@ fn main() {
#[allow(clippy::redundant_clone)]
let _s = String::new().to_string();
// Check that lint level works
#[expect(clippy::redundant_clone)]
let _s = String::new().to_string();
let tup = (String::from("foo"),);
let _t = tup.0;

View File

@@ -1,6 +1,7 @@
// run-rustfix
// rustfix-only-machine-applicable
#![feature(lint_reasons)]
#![allow(clippy::implicit_clone, clippy::drop_non_drop)]
use std::ffi::OsString;
use std::path::Path;
@@ -29,6 +30,10 @@ fn main() {
#[allow(clippy::redundant_clone)]
let _s = String::new().to_string();
// Check that lint level works
#[expect(clippy::redundant_clone)]
let _s = String::new().to_string();
let tup = (String::from("foo"),);
let _t = tup.0.clone();

View File

@@ -1,180 +1,180 @@
error: redundant clone
--> $DIR/redundant_clone.rs:9:42
--> $DIR/redundant_clone.rs:10:42
|
LL | let _s = ["lorem", "ipsum"].join(" ").to_string();
| ^^^^^^^^^^^^ help: remove this
|
= note: `-D clippy::redundant-clone` implied by `-D warnings`
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:9:14
--> $DIR/redundant_clone.rs:10:14
|
LL | let _s = ["lorem", "ipsum"].join(" ").to_string();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant clone
--> $DIR/redundant_clone.rs:12:15
--> $DIR/redundant_clone.rs:13:15
|
LL | let _s = s.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:12:14
--> $DIR/redundant_clone.rs:13:14
|
LL | let _s = s.clone();
| ^
error: redundant clone
--> $DIR/redundant_clone.rs:15:15
--> $DIR/redundant_clone.rs:16:15
|
LL | let _s = s.to_string();
| ^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:15:14
--> $DIR/redundant_clone.rs:16:14
|
LL | let _s = s.to_string();
| ^
error: redundant clone
--> $DIR/redundant_clone.rs:18:15
--> $DIR/redundant_clone.rs:19:15
|
LL | let _s = s.to_owned();
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:18:14
--> $DIR/redundant_clone.rs:19:14
|
LL | let _s = s.to_owned();
| ^
error: redundant clone
--> $DIR/redundant_clone.rs:20:42
--> $DIR/redundant_clone.rs:21:42
|
LL | let _s = Path::new("/a/b/").join("c").to_owned();
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:20:14
--> $DIR/redundant_clone.rs:21:14
|
LL | let _s = Path::new("/a/b/").join("c").to_owned();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant clone
--> $DIR/redundant_clone.rs:22:42
--> $DIR/redundant_clone.rs:23:42
|
LL | let _s = Path::new("/a/b/").join("c").to_path_buf();
| ^^^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:22:14
--> $DIR/redundant_clone.rs:23:14
|
LL | let _s = Path::new("/a/b/").join("c").to_path_buf();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant clone
--> $DIR/redundant_clone.rs:24:29
--> $DIR/redundant_clone.rs:25:29
|
LL | let _s = OsString::new().to_owned();
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:24:14
--> $DIR/redundant_clone.rs:25:14
|
LL | let _s = OsString::new().to_owned();
| ^^^^^^^^^^^^^^^
error: redundant clone
--> $DIR/redundant_clone.rs:26:29
--> $DIR/redundant_clone.rs:27:29
|
LL | let _s = OsString::new().to_os_string();
| ^^^^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:26:14
--> $DIR/redundant_clone.rs:27:14
|
LL | let _s = OsString::new().to_os_string();
| ^^^^^^^^^^^^^^^
error: redundant clone
--> $DIR/redundant_clone.rs:33:19
--> $DIR/redundant_clone.rs:38:19
|
LL | let _t = tup.0.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:33:14
--> $DIR/redundant_clone.rs:38:14
|
LL | let _t = tup.0.clone();
| ^^^^^
error: redundant clone
--> $DIR/redundant_clone.rs:65:25
--> $DIR/redundant_clone.rs:70:25
|
LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) }
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:65:24
--> $DIR/redundant_clone.rs:70:24
|
LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) }
| ^
error: redundant clone
--> $DIR/redundant_clone.rs:122:15
--> $DIR/redundant_clone.rs:127:15
|
LL | let _s = s.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:122:14
--> $DIR/redundant_clone.rs:127:14
|
LL | let _s = s.clone();
| ^
error: redundant clone
--> $DIR/redundant_clone.rs:123:15
--> $DIR/redundant_clone.rs:128:15
|
LL | let _t = t.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:123:14
--> $DIR/redundant_clone.rs:128:14
|
LL | let _t = t.clone();
| ^
error: redundant clone
--> $DIR/redundant_clone.rs:133:19
--> $DIR/redundant_clone.rs:138:19
|
LL | let _f = f.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:133:18
--> $DIR/redundant_clone.rs:138:18
|
LL | let _f = f.clone();
| ^
error: redundant clone
--> $DIR/redundant_clone.rs:145:14
--> $DIR/redundant_clone.rs:150:14
|
LL | let y = x.clone().join("matthias");
| ^^^^^^^^ help: remove this
|
note: cloned value is neither consumed nor mutated
--> $DIR/redundant_clone.rs:145:13
--> $DIR/redundant_clone.rs:150:13
|
LL | let y = x.clone().join("matthias");
| ^^^^^^^^^
error: redundant clone
--> $DIR/redundant_clone.rs:199:11
--> $DIR/redundant_clone.rs:204:11
|
LL | foo(&x.clone(), move || {
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> $DIR/redundant_clone.rs:199:10
--> $DIR/redundant_clone.rs:204:10
|
LL | foo(&x.clone(), move || {
| ^