Merge remote-tracking branch 'upstream/master' into rustup

This commit is contained in:
Philipp Krones 2025-05-15 19:19:08 +02:00
commit 0bb1b5bd3b
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
263 changed files with 5325 additions and 4470 deletions

View file

@ -1,4 +1,4 @@
#![feature(rustc_private, let_chains)]
#![feature(rustc_private)]
#![warn(rust_2018_idioms, unused_lifetimes)]
#![allow(unused_extern_crates)]

View file

@ -44,8 +44,8 @@ fn dogfood() {
"rustc_tools_util",
] {
println!("linting {package}");
if !run_clippy_for_package(package, &["-D", "clippy::all", "-D", "clippy::pedantic"]) {
failed_packages.push(if package.is_empty() { "root" } else { package });
if !run_clippy_for_package(package) {
failed_packages.push(package);
}
}
@ -57,7 +57,7 @@ fn dogfood() {
}
#[must_use]
fn run_clippy_for_package(project: &str, args: &[&str]) -> bool {
fn run_clippy_for_package(project: &str) -> bool {
let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut command = Command::new(&*test_utils::CARGO_CLIPPY_PATH);
@ -79,15 +79,17 @@ fn run_clippy_for_package(project: &str, args: &[&str]) -> bool {
}
}
command.arg("--").args(args);
command.arg("--");
command.arg("-Cdebuginfo=0"); // disable debuginfo to generate less data in the target dir
command.args(["-D", "clippy::dbg_macro"]);
command.args(["-D", "clippy::all", "-D", "clippy::pedantic", "-D", "clippy::dbg_macro"]);
if !cfg!(feature = "internal") {
// running a clippy built without internal lints on the clippy source
// that contains e.g. `allow(clippy::invalid_paths)`
// that contains e.g. `allow(clippy::symbol_as_str)`
command.args(["-A", "unknown_lints"]);
}
// Workaround for not being a workspace, add the crate's directory back to the path
command.args(["--remap-path-prefix", &format!("={project}")]);
command.status().unwrap().success()
}

View file

@ -30,7 +30,7 @@ fn integration_test() {
let repo_dir = tempfile::tempdir()
.expect("couldn't create temp dir")
.into_path()
.keep()
.join(crate_name);
let st = Command::new("git")

View file

@ -1,4 +0,0 @@
#![allow(clippy::unnecessary_def_path)]
pub static OPTION: [&str; 3] = ["core", "option", "Option"];
pub const RESULT: &[&str] = &["core", "result", "Result"];

View file

@ -0,0 +1,60 @@
#![deny(clippy::derive_deserialize_allowing_unknown)]
use serde::{Deserialize, Deserializer};
#[derive(Deserialize)] //~ derive_deserialize_allowing_unknown
struct Struct {
flag: bool,
limit: u64,
}
#[derive(Deserialize)] //~ derive_deserialize_allowing_unknown
enum Enum {
A(bool),
B { limit: u64 },
}
// negative tests
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct StructWithDenyUnknownFields {
flag: bool,
limit: u64,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
enum EnumWithDenyUnknownFields {
A(bool),
B { limit: u64 },
}
#[derive(Deserialize)]
#[serde(untagged, deny_unknown_fields)]
enum MultipleSerdeAttributes {
A(bool),
B { limit: u64 },
}
#[derive(Deserialize)]
struct TupleStruct(u64, bool);
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
enum EnumWithOnlyTupleVariants {
A(bool),
B(u64),
}
struct ManualSerdeImplementation;
impl<'de> Deserialize<'de> for ManualSerdeImplementation {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let () = <() as Deserialize>::deserialize(deserializer)?;
Ok(ManualSerdeImplementation)
}
}

View file

@ -0,0 +1,23 @@
error: `#[derive(serde::Deserialize)]` without `#[serde(deny_unknown_fields)]`
--> tests/ui-internal/derive_deserialize_allowing_unknown.rs:5:10
|
LL | #[derive(Deserialize)]
| ^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/ui-internal/derive_deserialize_allowing_unknown.rs:1:9
|
LL | #![deny(clippy::derive_deserialize_allowing_unknown)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `#[derive(serde::Deserialize)]` without `#[serde(deny_unknown_fields)]`
--> tests/ui-internal/derive_deserialize_allowing_unknown.rs:11:10
|
LL | #[derive(Deserialize)]
| ^^^^^^^^^^^
|
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors

View file

@ -4,9 +4,10 @@ error: interning a string literal
LL | let _ = Symbol::intern("f32");
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: add the symbol to `clippy_utils/src/sym.rs` if needed
= note: `-D clippy::interning-literals` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::interning_literals)]`
help: use the preinterned symbol
help: use a preinterned symbol instead
|
LL - let _ = Symbol::intern("f32");
LL + let _ = sym::f32;
@ -18,7 +19,8 @@ error: interning a string literal
LL | let _ = Symbol::intern("proc-macro");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use the preinterned symbol
= help: add the symbol to `clippy_utils/src/sym.rs` if needed
help: use a preinterned symbol instead
|
LL - let _ = Symbol::intern("proc-macro");
LL + let _ = sym::proc_dash_macro;
@ -30,7 +32,8 @@ error: interning a string literal
LL | let _ = Symbol::intern("self");
| ^^^^^^^^^^^^^^^^^^^^^^
|
help: use the preinterned symbol
= help: add the symbol to `clippy_utils/src/sym.rs` if needed
help: use a preinterned symbol instead
|
LL - let _ = Symbol::intern("self");
LL + let _ = kw::SelfLower;
@ -42,7 +45,8 @@ error: interning a string literal
LL | let _ = Symbol::intern("msrv");
| ^^^^^^^^^^^^^^^^^^^^^^
|
help: use the preinterned symbol
= help: add the symbol to `clippy_utils/src/sym.rs` if needed
help: use a preinterned symbol instead
|
LL - let _ = Symbol::intern("msrv");
LL + let _ = sym::msrv;
@ -54,7 +58,8 @@ error: interning a string literal
LL | let _ = Symbol::intern("Cargo.toml");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use the preinterned symbol
= help: add the symbol to `clippy_utils/src/sym.rs` if needed
help: use a preinterned symbol instead
|
LL - let _ = Symbol::intern("Cargo.toml");
LL + let _ = sym::Cargo_toml;

View file

@ -4,9 +4,10 @@ error: interning a string literal
LL | let _ = Symbol::intern("xyz123");
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add the symbol to `clippy_utils/src/sym.rs` if needed
= note: `-D clippy::interning-literals` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::interning_literals)]`
help: add the symbol to `clippy_utils/src/sym.rs` and use it
help: use a preinterned symbol instead
|
LL - let _ = Symbol::intern("xyz123");
LL + let _ = sym::xyz123;
@ -18,7 +19,8 @@ error: interning a string literal
LL | let _ = Symbol::intern("with-dash");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: add the symbol to `clippy_utils/src/sym.rs` and use it
= help: add the symbol to `clippy_utils/src/sym.rs` if needed
help: use a preinterned symbol instead
|
LL - let _ = Symbol::intern("with-dash");
LL + let _ = sym::with_dash;
@ -30,7 +32,8 @@ error: interning a string literal
LL | let _ = Symbol::intern("with.dot");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: add the symbol to `clippy_utils/src/sym.rs` and use it
= help: add the symbol to `clippy_utils/src/sym.rs` if needed
help: use a preinterned symbol instead
|
LL - let _ = Symbol::intern("with.dot");
LL + let _ = sym::with_dot;

View file

@ -1,30 +0,0 @@
#![deny(clippy::invalid_paths)]
#![allow(clippy::missing_clippy_version_attribute, clippy::unnecessary_def_path)]
mod paths {
// Good path
pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"];
// Path to method on inherent impl of a primitive type
pub const F32_EPSILON: [&str; 4] = ["core", "f32", "<impl f32>", "EPSILON"];
// Path to method on inherent impl
pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
// Path with empty segment
pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
//~^ invalid_paths
// Path with bad crate
pub const BAD_CRATE_PATH: [&str; 2] = ["bad", "path"];
//~^ invalid_paths
// Path with bad module
pub const BAD_MOD_PATH: [&str; 2] = ["std", "xxx"];
//~^ invalid_paths
// Path to method on an enum inherent impl
pub const OPTION_IS_SOME: [&str; 4] = ["core", "option", "Option", "is_some"];
}
fn main() {}

View file

@ -1,26 +0,0 @@
error: invalid path
--> tests/ui-internal/invalid_paths.rs:15:5
|
LL | pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/ui-internal/invalid_paths.rs:1:9
|
LL | #![deny(clippy::invalid_paths)]
| ^^^^^^^^^^^^^^^^^^^^^
error: invalid path
--> tests/ui-internal/invalid_paths.rs:19:5
|
LL | pub const BAD_CRATE_PATH: [&str; 2] = ["bad", "path"];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: invalid path
--> tests/ui-internal/invalid_paths.rs:23:5
|
LL | pub const BAD_MOD_PATH: [&str; 2] = ["std", "xxx"];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors

View file

@ -18,4 +18,11 @@ fn f(s: Symbol) {
//~^ symbol_as_str
sym::get == s;
//~^ symbol_as_str
let _ = match s {
//~^ symbol_as_str
sym::unwrap_err => 1,
sym::unwrap_or_default | sym::unwrap_or_else => 2,
_ => 3,
};
}

View file

@ -18,4 +18,11 @@ fn f(s: Symbol) {
//~^ symbol_as_str
"get" == s.as_str();
//~^ symbol_as_str
let _ = match s.as_str() {
//~^ symbol_as_str
"unwrap_err" => 1,
"unwrap_or_default" | "unwrap_or_else" => 2,
_ => 3,
};
}

View file

@ -4,9 +4,10 @@ error: converting a Symbol to a string
LL | s.as_str() == "f32";
| ^^^^^^^^^^
|
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
= note: `-D clippy::symbol-as-str` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::symbol_as_str)]`
help: use the preinterned symbol
help: use preinterned symbols instead
|
LL - s.as_str() == "f32";
LL + s == sym::f32;
@ -18,7 +19,8 @@ error: converting a Symbol to a string
LL | s.as_str() == "proc-macro";
| ^^^^^^^^^^
|
help: use the preinterned symbol
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
help: use preinterned symbols instead
|
LL - s.as_str() == "proc-macro";
LL + s == sym::proc_dash_macro;
@ -30,7 +32,8 @@ error: converting a Symbol to a string
LL | s.as_str() == "self";
| ^^^^^^^^^^
|
help: use the preinterned symbol
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
help: use preinterned symbols instead
|
LL - s.as_str() == "self";
LL + s == kw::SelfLower;
@ -42,7 +45,8 @@ error: converting a Symbol to a string
LL | s.as_str() == "msrv";
| ^^^^^^^^^^
|
help: use the preinterned symbol
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
help: use preinterned symbols instead
|
LL - s.as_str() == "msrv";
LL + s == sym::msrv;
@ -54,7 +58,8 @@ error: converting a Symbol to a string
LL | s.as_str() == "Cargo.toml";
| ^^^^^^^^^^
|
help: use the preinterned symbol
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
help: use preinterned symbols instead
|
LL - s.as_str() == "Cargo.toml";
LL + s == sym::Cargo_toml;
@ -66,11 +71,27 @@ error: converting a Symbol to a string
LL | "get" == s.as_str();
| ^^^^^^^^^^
|
help: use the preinterned symbol
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
help: use preinterned symbols instead
|
LL - "get" == s.as_str();
LL + sym::get == s;
|
error: aborting due to 6 previous errors
error: converting a Symbol to a string
--> tests/ui-internal/symbol_as_str.rs:22:19
|
LL | let _ = match s.as_str() {
| ^^^^^^^^^^
|
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
help: use preinterned symbols instead
|
LL ~ let _ = match s {
LL |
LL ~ sym::unwrap_err => 1,
LL ~ sym::unwrap_or_default | sym::unwrap_or_else => 2,
|
error: aborting due to 7 previous errors

View file

@ -4,9 +4,10 @@ error: converting a Symbol to a string
LL | s.as_str() == "xyz123";
| ^^^^^^^^^^
|
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
= note: `-D clippy::symbol-as-str` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::symbol_as_str)]`
help: add the symbol to `clippy_utils/src/sym.rs` and use it
help: use preinterned symbols instead
|
LL - s.as_str() == "xyz123";
LL + s == sym::xyz123;
@ -18,7 +19,8 @@ error: converting a Symbol to a string
LL | s.as_str() == "with-dash";
| ^^^^^^^^^^
|
help: add the symbol to `clippy_utils/src/sym.rs` and use it
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
help: use preinterned symbols instead
|
LL - s.as_str() == "with-dash";
LL + s == sym::with_dash;
@ -30,7 +32,8 @@ error: converting a Symbol to a string
LL | s.as_str() == "with.dot";
| ^^^^^^^^^^
|
help: add the symbol to `clippy_utils/src/sym.rs` and use it
= help: add the symbols to `clippy_utils/src/sym.rs` if needed
help: use preinterned symbols instead
|
LL - s.as_str() == "with.dot";
LL + s == sym::with_dot;

View file

@ -1,77 +0,0 @@
//@aux-build:paths.rs
#![deny(clippy::unnecessary_def_path)]
#![feature(rustc_private)]
#![allow(clippy::unnecessary_map_or)]
extern crate clippy_utils;
extern crate paths;
extern crate rustc_hir;
extern crate rustc_lint;
extern crate rustc_middle;
extern crate rustc_span;
#[allow(unused)]
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item, match_type};
#[allow(unused)]
use clippy_utils::{
is_enum_variant_ctor, is_expr_path_def_path, is_path_diagnostic_item, is_res_lang_ctor, is_trait_method,
match_def_path, match_trait_method, path_res,
};
#[allow(unused)]
use rustc_hir::LangItem;
#[allow(unused)]
use rustc_span::sym;
use rustc_hir::Expr;
use rustc_hir::def_id::DefId;
use rustc_lint::LateContext;
use rustc_middle::ty::Ty;
#[allow(unused, clippy::unnecessary_def_path)]
static OPTION: [&str; 3] = ["core", "option", "Option"];
#[allow(unused, clippy::unnecessary_def_path)]
const RESULT: &[&str] = &["core", "result", "Result"];
fn _f<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, did: DefId, expr: &Expr<'_>) {
let _ = is_type_diagnostic_item(cx, ty, sym::Option);
//~^ unnecessary_def_path
let _ = is_type_diagnostic_item(cx, ty, sym::Result);
//~^ unnecessary_def_path
let _ = is_type_diagnostic_item(cx, ty, sym::Result);
//~^ unnecessary_def_path
#[allow(unused, clippy::unnecessary_def_path)]
let rc_path = &["alloc", "rc", "Rc"];
let _ = is_type_diagnostic_item(cx, ty, sym::Rc);
//~^ unnecessary_def_path
let _ = is_type_diagnostic_item(cx, ty, sym::Option);
//~^ unnecessary_def_path
let _ = is_type_diagnostic_item(cx, ty, sym::Result);
//~^ unnecessary_def_path
let _ = is_type_lang_item(cx, ty, LangItem::OwnedBox);
//~^ unnecessary_def_path
let _ = is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit);
//~^ unnecessary_def_path
let _ = cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did);
//~^ unnecessary_def_path
let _ = cx.tcx.is_diagnostic_item(sym::Option, did);
//~^ unnecessary_def_path
let _ = cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did);
//~^ unnecessary_def_path
let _ = is_trait_method(cx, expr, sym::AsRef);
//~^ unnecessary_def_path
let _ = is_path_diagnostic_item(cx, expr, sym::Option);
//~^ unnecessary_def_path
let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id));
//~^ unnecessary_def_path
let _ = is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome);
//~^ unnecessary_def_path
}
fn main() {}

View file

@ -1,77 +1,20 @@
//@aux-build:paths.rs
#![deny(clippy::unnecessary_def_path)]
#![feature(rustc_private)]
#![allow(clippy::unnecessary_map_or)]
extern crate clippy_utils;
extern crate paths;
extern crate rustc_hir;
extern crate rustc_lint;
extern crate rustc_middle;
extern crate rustc_span;
use clippy_utils::paths::{PathLookup, PathNS};
use clippy_utils::{macro_path, sym, type_path, value_path};
#[allow(unused)]
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item, match_type};
#[allow(unused)]
use clippy_utils::{
is_enum_variant_ctor, is_expr_path_def_path, is_path_diagnostic_item, is_res_lang_ctor, is_trait_method,
match_def_path, match_trait_method, path_res,
};
static OPTION: PathLookup = type_path!(core::option::Option);
//~^ unnecessary_def_path
static SOME: PathLookup = type_path!(core::option::Option::Some);
//~^ unnecessary_def_path
#[allow(unused)]
use rustc_hir::LangItem;
#[allow(unused)]
use rustc_span::sym;
static RESULT: PathLookup = type_path!(core::result::Result);
//~^ unnecessary_def_path
static RESULT_VIA_STD: PathLookup = type_path!(std::result::Result);
//~^ unnecessary_def_path
use rustc_hir::Expr;
use rustc_hir::def_id::DefId;
use rustc_lint::LateContext;
use rustc_middle::ty::Ty;
static VEC_NEW: PathLookup = value_path!(alloc::vec::Vec::new);
//~^ unnecessary_def_path
#[allow(unused, clippy::unnecessary_def_path)]
static OPTION: [&str; 3] = ["core", "option", "Option"];
#[allow(unused, clippy::unnecessary_def_path)]
const RESULT: &[&str] = &["core", "result", "Result"];
fn _f<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, did: DefId, expr: &Expr<'_>) {
let _ = match_type(cx, ty, &OPTION);
//~^ unnecessary_def_path
let _ = match_type(cx, ty, RESULT);
//~^ unnecessary_def_path
let _ = match_type(cx, ty, &["core", "result", "Result"]);
//~^ unnecessary_def_path
#[allow(unused, clippy::unnecessary_def_path)]
let rc_path = &["alloc", "rc", "Rc"];
let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
//~^ unnecessary_def_path
let _ = match_type(cx, ty, &paths::OPTION);
//~^ unnecessary_def_path
let _ = match_type(cx, ty, paths::RESULT);
//~^ unnecessary_def_path
let _ = match_type(cx, ty, &["alloc", "boxed", "Box"]);
//~^ unnecessary_def_path
let _ = match_type(cx, ty, &["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"]);
//~^ unnecessary_def_path
let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
//~^ unnecessary_def_path
let _ = match_def_path(cx, did, &["core", "option", "Option"]);
//~^ unnecessary_def_path
let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
//~^ unnecessary_def_path
let _ = match_trait_method(cx, expr, &["core", "convert", "AsRef"]);
//~^ unnecessary_def_path
let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option"]);
//~^ unnecessary_def_path
let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
//~^ unnecessary_def_path
let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option", "Some"]);
//~^ unnecessary_def_path
}
fn main() {}
static VEC_MACRO: PathLookup = macro_path!(std::vec);
//~^ unnecessary_def_path

View file

@ -1,100 +1,58 @@
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:37:13
error: a diagnostic name exists for this path: sym::Option
--> tests/ui-internal/unnecessary_def_path.rs:6:29
|
LL | let _ = match_type(cx, ty, &OPTION);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Option)`
LL | static OPTION: PathLookup = type_path!(core::option::Option);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/ui-internal/unnecessary_def_path.rs:2:9
|
LL | #![deny(clippy::unnecessary_def_path)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead
= help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils
= note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_def_path)]`
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:39:13
error: a language item exists for this path: LangItem::OptionSome
--> tests/ui-internal/unnecessary_def_path.rs:8:27
|
LL | let _ = match_type(cx, ty, RESULT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:41:13
LL | static SOME: PathLookup = type_path!(core::option::Option::Some);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
LL | let _ = match_type(cx, ty, &["core", "result", "Result"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
= help: remove the `PathLookup` and use utilities such as `cx.tcx.lang_items` instead
= help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=lang&filter-crate=clippy_utils
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:46:13
error: a diagnostic name exists for this path: sym::Result
--> tests/ui-internal/unnecessary_def_path.rs:11:29
|
LL | let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Rc)`
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:49:13
LL | static RESULT: PathLookup = type_path!(core::result::Result);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
LL | let _ = match_type(cx, ty, &paths::OPTION);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Option)`
= help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead
= help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:51:13
error: a diagnostic name exists for this path: sym::Result
--> tests/ui-internal/unnecessary_def_path.rs:13:37
|
LL | let _ = match_type(cx, ty, paths::RESULT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
error: use of a def path to a `LangItem`
--> tests/ui-internal/unnecessary_def_path.rs:54:13
LL | static RESULT_VIA_STD: PathLookup = type_path!(std::result::Result);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
LL | let _ = match_type(cx, ty, &["alloc", "boxed", "Box"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_lang_item(cx, ty, LangItem::OwnedBox)`
= help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead
= help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:56:13
error: a diagnostic name exists for this path: sym::vec_new
--> tests/ui-internal/unnecessary_def_path.rs:16:30
|
LL | let _ = match_type(cx, ty, &["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit)`
error: use of a def path to a `LangItem`
--> tests/ui-internal/unnecessary_def_path.rs:59:13
LL | static VEC_NEW: PathLookup = value_path!(alloc::vec::Vec::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
LL | let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did)`
= help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead
= help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:61:13
error: a diagnostic name exists for this path: sym::vec_macro
--> tests/ui-internal/unnecessary_def_path.rs:19:32
|
LL | let _ = match_def_path(cx, did, &["core", "option", "Option"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.is_diagnostic_item(sym::Option, did)`
error: use of a def path to a `LangItem`
--> tests/ui-internal/unnecessary_def_path.rs:63:13
LL | static VEC_MACRO: PathLookup = macro_path!(std::vec);
| ^^^^^^^^^^^^^^^^^^^^^
|
LL | let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did)`
|
= help: if this `DefId` came from a constructor expression or pattern then the parent `DefId` should be used instead
= help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead
= help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:66:13
|
LL | let _ = match_trait_method(cx, expr, &["core", "convert", "AsRef"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_trait_method(cx, expr, sym::AsRef)`
error: use of a def path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path.rs:69:13
|
LL | let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_path_diagnostic_item(cx, expr, sym::Option)`
error: use of a def path to a `LangItem`
--> tests/ui-internal/unnecessary_def_path.rs:71:13
|
LL | let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id))`
error: use of a def path to a `LangItem`
--> tests/ui-internal/unnecessary_def_path.rs:73:13
|
LL | let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option", "Some"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome)`
error: aborting due to 15 previous errors
error: aborting due to 6 previous errors

View file

@ -1,19 +0,0 @@
#![feature(rustc_private)]
#![allow(unused)]
#![deny(clippy::unnecessary_def_path)]
extern crate rustc_hir;
use rustc_hir::LangItem;
fn main() {
const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
//~^ unnecessary_def_path
const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
//~^ unnecessary_def_path
const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
//~^ unnecessary_def_path
// Don't lint, not a diagnostic or language item
const OPS_MOD: [&str; 2] = ["core", "ops"];
}

View file

@ -1,31 +0,0 @@
error: hardcoded path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path_hardcoded_path.rs:10:36
|
LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: convert all references to use `sym::Deref`
note: the lint level is defined here
--> tests/ui-internal/unnecessary_def_path_hardcoded_path.rs:3:9
|
LL | #![deny(clippy::unnecessary_def_path)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: hardcoded path to a language item
--> tests/ui-internal/unnecessary_def_path_hardcoded_path.rs:12:40
|
LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: convert all references to use `LangItem::DerefMut`
error: hardcoded path to a diagnostic item
--> tests/ui-internal/unnecessary_def_path_hardcoded_path.rs:14:43
|
LL | const OPS_MOD: [&str; 5] = ["core", "ops"];
| ^^^^^^^^^^^^^^^
|
= help: convert all references to use `sym::deref_method`
error: aborting due to 3 previous errors

View file

@ -1,4 +1,3 @@
#![feature(let_chains)]
#![warn(clippy::collapsible_if)]
fn main() {

View file

@ -1,4 +1,3 @@
#![feature(let_chains)]
#![warn(clippy::collapsible_if)]
fn main() {

View file

@ -1,5 +1,5 @@
error: this `if` statement can be collapsed
--> tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs:5:5
--> tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs:4:5
|
LL | / if let Some(a) = Some(3) {
LL | | // with comment
@ -21,7 +21,7 @@ LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs:13:5
--> tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs:12:5
|
LL | / if let Some(a) = Some(3) {
LL | | // with comment
@ -41,7 +41,7 @@ LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs:21:5
--> tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs:20:5
|
LL | / if Some(3) == Some(4).map(|x| x - 1) {
LL | | // with comment

View file

@ -0,0 +1 @@
allow-exact-repetitions = false

View file

@ -0,0 +1,13 @@
#![warn(clippy::module_name_repetitions)]
#![allow(dead_code)]
pub mod foo {
// this line should produce a warning:
pub fn foo() {}
//~^ module_name_repetitions
// but this line shouldn't
pub fn to_foo() {}
}
fn main() {}

View file

@ -0,0 +1,11 @@
error: item name is the same as its containing module's name
--> tests/ui-toml/item_name_repetitions/allow_exact_repetitions/item_name_repetitions.rs:6:12
|
LL | pub fn foo() {}
| ^^^
|
= note: `-D clippy::module-name-repetitions` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]`
error: aborting due to 1 previous error

View file

@ -0,0 +1 @@
missing-docs-allow-unused = true

View file

@ -0,0 +1,26 @@
//! Test file for missing_docs_in_private_items lint with allow_unused configuration
#![warn(clippy::missing_docs_in_private_items)]
#![allow(dead_code)]
/// A struct with some documented and undocumented fields
struct Test {
/// This field is documented
field1: i32,
_unused: i32, // This should not trigger a warning because it starts with an underscore
field3: i32, //~ missing_docs_in_private_items
}
struct Test2 {
//~^ missing_docs_in_private_items
_field1: i32, // This should not trigger a warning
_field2: i32, // This should not trigger a warning
}
struct Test3 {
//~^ missing_docs_in_private_items
/// This field is documented although this is not mandatory
_unused: i32, // This should not trigger a warning because it starts with an underscore
field2: i32, //~ missing_docs_in_private_items
}
fn main() {}

View file

@ -0,0 +1,38 @@
error: missing documentation for a struct field
--> tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs:10:5
|
LL | field3: i32,
| ^^^^^^^^^^^
|
= note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]`
error: missing documentation for a struct
--> tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs:13:1
|
LL | / struct Test2 {
LL | |
LL | | _field1: i32, // This should not trigger a warning
LL | | _field2: i32, // This should not trigger a warning
LL | | }
| |_^
error: missing documentation for a struct
--> tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs:19:1
|
LL | / struct Test3 {
LL | |
LL | | /// This field is documented although this is not mandatory
LL | | _unused: i32, // This should not trigger a warning because it starts with an underscore
LL | | field2: i32,
LL | | }
| |_^
error: missing documentation for a struct field
--> tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs:23:5
|
LL | field2: i32,
| ^^^^^^^^^^^
error: aborting due to 4 previous errors

View file

@ -14,4 +14,7 @@ disallowed-methods = [
"conf_disallowed_methods::Struct::method",
"conf_disallowed_methods::Trait::provided_method",
"conf_disallowed_methods::Trait::implemented_method",
# re-exports
"conf_disallowed_methods::identity",
"conf_disallowed_methods::renamed",
]

View file

@ -8,6 +8,9 @@ extern crate regex;
use futures::stream::{empty, select_all};
use regex::Regex;
use std::convert::identity;
use std::hint::black_box as renamed;
fn local_fn() {}
struct Struct;
@ -71,4 +74,9 @@ fn main() {
//~^ disallowed_methods
s.implemented_method();
//~^ disallowed_methods
identity(());
//~^ disallowed_methods
renamed(1);
//~^ disallowed_methods
}

View file

@ -1,5 +1,5 @@
error: use of a disallowed method `regex::Regex::new`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:33:14
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:36:14
|
LL | let re = Regex::new(r"ab.*c").unwrap();
| ^^^^^^^^^^
@ -8,7 +8,7 @@ LL | let re = Regex::new(r"ab.*c").unwrap();
= help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
error: use of a disallowed method `regex::Regex::is_match`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:35:8
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:38:8
|
LL | re.is_match("abc");
| ^^^^^^^^
@ -16,76 +16,88 @@ LL | re.is_match("abc");
= note: no matching allowed
error: use of a disallowed method `std::iter::Iterator::sum`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:39:14
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:42:14
|
LL | a.iter().sum::<i32>();
| ^^^
error: use of a disallowed method `slice::sort_unstable`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:42:7
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:45:7
|
LL | a.sort_unstable();
| ^^^^^^^^^^^^^
error: use of a disallowed method `f32::clamp`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:46:20
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:49:20
|
LL | let _ = 2.0f32.clamp(3.0f32, 4.0f32);
| ^^^^^
error: use of a disallowed method `regex::Regex::new`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:50:61
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:53:61
|
LL | let indirect: fn(&str) -> Result<Regex, regex::Error> = Regex::new;
| ^^^^^^^^^^
error: use of a disallowed method `f32::clamp`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:54:28
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:57:28
|
LL | let in_call = Box::new(f32::clamp);
| ^^^^^^^^^^
error: use of a disallowed method `regex::Regex::new`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:56:53
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:59:53
|
LL | let in_method_call = ["^", "$"].into_iter().map(Regex::new);
| ^^^^^^^^^^
error: use of a disallowed method `futures::stream::select_all`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:60:31
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:63:31
|
LL | let same_name_as_module = select_all(vec![empty::<()>()]);
| ^^^^^^^^^^
error: use of a disallowed method `conf_disallowed_methods::local_fn`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:63:5
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:66:5
|
LL | local_fn();
| ^^^^^^^^
error: use of a disallowed method `conf_disallowed_methods::local_mod::f`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:65:5
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:68:5
|
LL | local_mod::f();
| ^^^^^^^^^^^^
error: use of a disallowed method `conf_disallowed_methods::Struct::method`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:68:7
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:71:7
|
LL | s.method();
| ^^^^^^
error: use of a disallowed method `conf_disallowed_methods::Trait::provided_method`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:70:7
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:73:7
|
LL | s.provided_method();
| ^^^^^^^^^^^^^^^
error: use of a disallowed method `conf_disallowed_methods::Trait::implemented_method`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:72:7
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:75:7
|
LL | s.implemented_method();
| ^^^^^^^^^^^^^^^^^^
error: aborting due to 14 previous errors
error: use of a disallowed method `conf_disallowed_methods::identity`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:78:5
|
LL | identity(());
| ^^^^^^^^
error: use of a disallowed method `conf_disallowed_methods::renamed`
--> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:80:5
|
LL | renamed(1);
| ^^^^^^^
error: aborting due to 16 previous errors

View file

@ -6,7 +6,7 @@ disallowed-types = [
"std::thread::Thread",
"std::time::Instant",
"std::io::Read",
"std::primitive::usize",
"usize",
"bool",
# can give path and reason with an inline table
{ path = "std::net::Ipv4Addr", reason = "no IPv4 allowed" },

View file

@ -37,7 +37,7 @@ error: use of a disallowed type `std::io::Read`
LL | fn trait_obj(_: &dyn std::io::Read) {}
| ^^^^^^^^^^^^^
error: use of a disallowed type `std::primitive::usize`
error: use of a disallowed type `usize`
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:26:33
|
LL | fn full_and_single_path_prim(_: usize, _: bool) {}
@ -49,13 +49,13 @@ error: use of a disallowed type `bool`
LL | fn full_and_single_path_prim(_: usize, _: bool) {}
| ^^^^
error: use of a disallowed type `std::primitive::usize`
error: use of a disallowed type `usize`
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:30:28
|
LL | fn const_generics<const C: usize>() {}
| ^^^^^
error: use of a disallowed type `std::primitive::usize`
error: use of a disallowed type `usize`
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:33:24
|
LL | struct GenArg<const U: usize>([u8; U]);
@ -123,7 +123,7 @@ error: use of a disallowed type `proc_macro2::Ident`
LL | let _ = syn::Ident::new("", todo!());
| ^^^^^^^^^^
error: use of a disallowed type `std::primitive::usize`
error: use of a disallowed type `usize`
--> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:61:12
|
LL | let _: usize = 64_usize;

View file

@ -1,12 +1,15 @@
[[disallowed-types]]
path = "std::result::Result::Err"
[[disallowed-macros]]
path = "bool"
[[disallowed-methods]]
path = "std::process::current_exe"
[[disallowed-methods]]
path = ""
[[disallowed-types]]
path = "std::result::Result::Err"
# negative test
[[disallowed-methods]]

View file

@ -1,5 +1,6 @@
//@error-in-other-file: expected a macro, found a primitive type
//@error-in-other-file: `std::process::current_exe` does not refer to an existing function
//@error-in-other-file: expected a type, found a tuple variant
//@error-in-other-file: `std::process::current_exe` does not refer to a reachable function
//@error-in-other-file: `` does not refer to a reachable function
//@error-in-other-file: expected a type, found a variant
fn main() {}

View file

@ -1,23 +1,38 @@
warning: expected a macro, found a primitive type
--> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:4:1
--> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:1:1
|
LL | / [[disallowed-macros]]
LL | | path = "bool"
| |_____________^
|
= help: add `allow-invalid = true` to the entry to suppress this warning
warning: `std::process::current_exe` does not refer to an existing function
--> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:7:1
warning: `std::process::current_exe` does not refer to a reachable function
--> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:4:1
|
LL | / [[disallowed-methods]]
LL | | path = "std::process::current_exe"
| |__________________________________^
|
= help: add `allow-invalid = true` to the entry to suppress this warning
warning: expected a type, found a tuple variant
--> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:1:1
warning: `` does not refer to a reachable function
--> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:7:1
|
LL | / [[disallowed-methods]]
LL | | path = ""
| |_________^
|
= help: add `allow-invalid = true` to the entry to suppress this warning
warning: expected a type, found a variant
--> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:10:1
|
LL | / [[disallowed-types]]
LL | | path = "std::result::Result::Err"
| |_________________________________^
|
= help: add `allow-invalid = true` to the entry to suppress this warning
warning: 3 warnings emitted
warning: 4 warnings emitted

View file

@ -0,0 +1,4 @@
# In the following configuration, "recommendation" should be "reason" or "replacement".
disallowed-macros = [
{ path = "std::panic", recommendation = "return a `std::result::Result::Error` instead" },
]

View file

@ -0,0 +1,5 @@
#[rustfmt::skip]
//@error-in-other-file: error reading Clippy's configuration file: data did not match any variant of untagged enum DisallowedPathEnum
fn main() {
panic!();
}

View file

@ -0,0 +1,8 @@
error: error reading Clippy's configuration file: data did not match any variant of untagged enum DisallowedPathEnum
--> $DIR/tests/ui-toml/toml_unknown_config_struct_field/clippy.toml:3:5
|
LL | { path = "std::panic", recommendation = "return a `std::result::Result::Error` instead" },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -5,6 +5,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
accept-comment-above-statement
allow-comparison-to-zero
allow-dbg-in-tests
allow-exact-repetitions
allow-expect-in-consts
allow-expect-in-tests
allow-indexing-slicing-in-tests
@ -57,6 +58,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
max-suggested-slice-pattern-length
max-trait-bounds
min-ident-chars-threshold
missing-docs-allow-unused
missing-docs-in-crate-items
module-item-order-groupings
module-items-ordered-within-groupings
@ -97,6 +99,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
accept-comment-above-statement
allow-comparison-to-zero
allow-dbg-in-tests
allow-exact-repetitions
allow-expect-in-consts
allow-expect-in-tests
allow-indexing-slicing-in-tests
@ -149,6 +152,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
max-suggested-slice-pattern-length
max-trait-bounds
min-ident-chars-threshold
missing-docs-allow-unused
missing-docs-in-crate-items
module-item-order-groupings
module-items-ordered-within-groupings
@ -189,6 +193,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
accept-comment-above-statement
allow-comparison-to-zero
allow-dbg-in-tests
allow-exact-repetitions
allow-expect-in-consts
allow-expect-in-tests
allow-indexing-slicing-in-tests
@ -241,6 +246,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
max-suggested-slice-pattern-length
max-trait-bounds
min-ident-chars-threshold
missing-docs-allow-unused
missing-docs-in-crate-items
module-item-order-groupings
module-items-ordered-within-groupings

View file

@ -0,0 +1,10 @@
# The first two `disallowed-methods` paths should generate warnings, but the third should not.
[[disallowed-methods]]
path = "regex::Regex::new_"
[[disallowed-methods]]
path = "regex::Regex_::new"
[[disallowed-methods]]
path = "regex_::Regex::new"

View file

@ -0,0 +1,6 @@
//@error-in-other-file: `regex::Regex::new_` does not refer to a reachable function
//@error-in-other-file: `regex::Regex_::new` does not refer to a reachable function
extern crate regex;
fn main() {}

View file

@ -0,0 +1,20 @@
warning: `regex::Regex::new_` does not refer to a reachable function
--> $DIR/tests/ui-toml/toml_unloaded_crate/clippy.toml:3:1
|
LL | / [[disallowed-methods]]
LL | | path = "regex::Regex::new_"
| |___________________________^
|
= help: add `allow-invalid = true` to the entry to suppress this warning
warning: `regex::Regex_::new` does not refer to a reachable function
--> $DIR/tests/ui-toml/toml_unloaded_crate/clippy.toml:6:1
|
LL | / [[disallowed-methods]]
LL | | path = "regex::Regex_::new"
| |___________________________^
|
= help: add `allow-invalid = true` to the entry to suppress this warning
warning: 2 warnings emitted

View file

@ -12,7 +12,7 @@ fn f2<T>()
where
T: Copy + Clone + Sync + Send + ?Sized,
T: Unpin + PartialEq,
//~^ ERROR: this type has already been used as a bound predicate
//~^ type_repetition_in_bounds
{
}

View file

@ -1,4 +1,4 @@
error: this type has already been used as a bound predicate
error: type `T` has already been used as a bound predicate
--> tests/ui-toml/type_repetition_in_bounds/main.rs:14:5
|
LL | T: Unpin + PartialEq,

View file

@ -1,8 +1,6 @@
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Cast(expr, cast_ty) = init.kind
&& let TyKind::Path(ref qpath) = cast_ty.kind
&& match_qpath(qpath, &["char"])
&& let ExprKind::Lit(ref lit) = expr.kind
&& let LitKind::Int(69, LitIntType::Unsuffixed) = lit.node
&& let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind

View file

@ -14,8 +14,6 @@ if let ExprKind::Block(block, None) = expr.kind
&& name1.as_str() == "_t"
&& let StmtKind::Semi(e) = block.stmts[2].kind
&& let ExprKind::Unary(UnOp::Neg, inner) = e.kind
&& let ExprKind::Path(ref qpath) = inner.kind
&& match_qpath(qpath, &["x"])
&& block.expr.is_none()
{
// report your lint here
@ -25,18 +23,14 @@ if let ExprKind::Block(block, None) = expr.kind
&& let StmtKind::Let(local) = block.stmts[0].kind
&& let Some(init) = local.init
&& let ExprKind::Call(func, args) = init.kind
&& let ExprKind::Path(ref qpath) = func.kind
&& match_qpath(qpath, &["String", "new"])
&& is_path_diagnostic_item(cx, func, sym::string_new)
&& args.is_empty()
&& let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind
&& name.as_str() == "expr"
&& let Some(trailing_expr) = block.expr
&& let ExprKind::Call(func1, args1) = trailing_expr.kind
&& let ExprKind::Path(ref qpath1) = func1.kind
&& match_qpath(qpath1, &["drop"])
&& is_path_diagnostic_item(cx, func1, sym::mem_drop)
&& args1.len() == 1
&& let ExprKind::Path(ref qpath2) = args1[0].kind
&& match_qpath(qpath2, &["expr"])
{
// report your lint here
}

View file

@ -1,8 +1,7 @@
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Call(func, args) = init.kind
&& let ExprKind::Path(ref qpath) = func.kind
&& match_qpath(qpath, &["{{root}}", "std", "cmp", "min"])
&& is_path_diagnostic_item(cx, func, sym::cmp_min)
&& args.len() == 2
&& let ExprKind::Lit(ref lit) = args[0].kind
&& let LitKind::Int(3, LitIntType::Unsuffixed) = lit.node

View file

@ -31,10 +31,8 @@ if let StmtKind::Let(local) = stmt.kind
if let ExprKind::If(cond, then, Some(else_expr)) = expr.kind
&& let ExprKind::Let(let_expr) = cond.kind
&& let PatKind::Expr(lit_expr) = let_expr.pat.kind
&& let PatExprKind::Lit{ref lit, negated } = lit_expr.kind
&& let PatExprKind::Lit { ref lit, negated } = lit_expr.kind
&& let LitKind::Bool(true) = lit.node
&& let ExprKind::Path(ref qpath) = let_expr.init.kind
&& match_qpath(qpath, &["a"])
&& let ExprKind::Block(block, None) = then.kind
&& block.stmts.is_empty()
&& block.expr.is_none()

View file

@ -1,11 +1,8 @@
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Call(func, args) = init.kind
&& let ExprKind::Path(ref qpath) = func.kind
&& match_qpath(qpath, &["std", "mem", "transmute"])
&& is_path_diagnostic_item(cx, func, sym::transmute)
&& args.len() == 1
&& let ExprKind::Path(ref qpath1) = args[0].kind
&& match_qpath(qpath1, &["ZPTR"])
&& let PatKind::Wild = local.pat.kind
{
// report your lint here

View file

@ -14,8 +14,6 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo
&& block.stmts.len() == 1
&& let StmtKind::Let(local) = block.stmts[0].kind
&& let Some(init) = local.init
&& let ExprKind::Path(ref qpath1) = init.kind
&& match_qpath(qpath1, &["y"])
&& let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind
&& name1.as_str() == "z"
&& block.expr.is_none()
@ -64,8 +62,6 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo
// report your lint here
}
if let Some(higher::While { condition: condition, body: body }) = higher::While::hir(expr)
&& let ExprKind::Path(ref qpath) = condition.kind
&& match_qpath(qpath, &["a"])
&& let ExprKind::Block(block, None) = body.kind
&& block.stmts.len() == 1
&& let StmtKind::Semi(e) = block.stmts[0].kind
@ -77,10 +73,8 @@ if let Some(higher::While { condition: condition, body: body }) = higher::While:
}
if let Some(higher::WhileLet { let_pat: let_pat, let_expr: let_expr, if_then: if_then }) = higher::WhileLet::hir(expr)
&& let PatKind::Expr(lit_expr) = let_pat.kind
&& let PatExprKind::Lit{ref lit, negated } = lit_expr.kind
&& let PatExprKind::Lit { ref lit, negated } = lit_expr.kind
&& let LitKind::Bool(true) = lit.node
&& let ExprKind::Path(ref qpath) = let_expr.kind
&& match_qpath(qpath, &["a"])
&& let ExprKind::Block(block, None) = if_then.kind
&& block.stmts.len() == 1
&& let StmtKind::Semi(e) = block.stmts[0].kind

View file

@ -7,12 +7,10 @@ if let StmtKind::Let(local) = stmt.kind
&& block.stmts.len() == 1
&& let StmtKind::Semi(e) = block.stmts[0].kind
&& let ExprKind::Call(func, args) = e.kind
&& let ExprKind::Path(ref qpath) = func.kind
&& match_qpath(qpath, &["$crate", "io", "_print"])
&& paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed
&& args.len() == 1
&& let ExprKind::Call(func1, args1) = args[0].kind
&& let ExprKind::Path(ref qpath1) = func1.kind
&& match_qpath(qpath1, &["format_arguments", "new_v1"])
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
&& args1.len() == 2
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind
&& let ExprKind::Array(elements) = inner.kind
@ -27,12 +25,9 @@ if let StmtKind::Let(local) = stmt.kind
&& let ExprKind::Array(elements1) = inner1.kind
&& elements1.len() == 1
&& let ExprKind::Call(func2, args2) = elements1[0].kind
&& let ExprKind::Path(ref qpath2) = func2.kind
&& match_qpath(qpath2, &["format_argument", "new_display"])
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
&& args2.len() == 1
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind
&& let ExprKind::Path(ref qpath3) = inner2.kind
&& match_qpath(qpath3, &["x"])
&& block.expr.is_none()
&& let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind
&& name.as_str() == "print_text"

View file

@ -17,12 +17,10 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo
&& block1.stmts.len() == 1
&& let StmtKind::Semi(e1) = block1.stmts[0].kind
&& let ExprKind::Call(func, args) = e1.kind
&& let ExprKind::Path(ref qpath1) = func.kind
&& match_qpath(qpath1, &["$crate", "io", "_print"])
&& paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed
&& args.len() == 1
&& let ExprKind::Call(func1, args1) = args[0].kind
&& let ExprKind::Path(ref qpath2) = func1.kind
&& match_qpath(qpath2, &["format_arguments", "new_v1"])
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
&& args1.len() == 2
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind
&& let ExprKind::Array(elements) = inner.kind
@ -37,12 +35,9 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo
&& let ExprKind::Array(elements1) = inner1.kind
&& elements1.len() == 1
&& let ExprKind::Call(func2, args2) = elements1[0].kind
&& let ExprKind::Path(ref qpath3) = func2.kind
&& match_qpath(qpath3, &["format_argument", "new_display"])
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
&& args2.len() == 1
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind
&& let ExprKind::Path(ref qpath4) = inner2.kind
&& match_qpath(qpath4, &["i"])
&& block1.expr.is_none()
&& block.expr.is_none()
{

View file

@ -5,13 +5,13 @@ if let StmtKind::Let(local) = stmt.kind
&& let LitKind::Int(42, LitIntType::Unsuffixed) = lit.node
&& arms.len() == 3
&& let PatKind::Expr(lit_expr) = arms[0].pat.kind
&& let PatExprKind::Lit{ref lit1, negated } = lit_expr.kind
&& let PatExprKind::Lit { ref lit1, negated } = lit_expr.kind
&& let LitKind::Int(16, LitIntType::Unsuffixed) = lit1.node
&& arms[0].guard.is_none()
&& let ExprKind::Lit(ref lit2) = arms[0].body.kind
&& let LitKind::Int(5, LitIntType::Unsuffixed) = lit2.node
&& let PatKind::Expr(lit_expr1) = arms[1].pat.kind
&& let PatExprKind::Lit{ref lit3, negated1 } = lit_expr1.kind
&& let PatExprKind::Lit { ref lit3, negated1 } = lit_expr1.kind
&& let LitKind::Int(17, LitIntType::Unsuffixed) = lit3.node
&& arms[1].guard.is_none()
&& let ExprKind::Block(block, None) = arms[1].body.kind
@ -23,8 +23,6 @@ if let StmtKind::Let(local) = stmt.kind
&& let PatKind::Binding(BindingMode::NONE, _, name, None) = local1.pat.kind
&& name.as_str() == "x"
&& let Some(trailing_expr) = block.expr
&& let ExprKind::Path(ref qpath) = trailing_expr.kind
&& match_qpath(qpath, &["x"])
&& let PatKind::Wild = arms[2].pat.kind
&& arms[2].guard.is_none()
&& let ExprKind::Lit(ref lit5) = arms[2].body.kind

View file

@ -1,5 +1,4 @@
if let ExprKind::Struct(qpath, fields, None) = expr.kind
&& match_qpath(qpath, &["Test"])
&& fields.len() == 1
&& fields[0].ident.as_str() == "field"
&& let ExprKind::If(cond, then, Some(else_expr)) = fields[0].expr.kind
@ -20,11 +19,10 @@ if let ExprKind::Struct(qpath, fields, None) = expr.kind
// report your lint here
}
if let PatKind::Struct(ref qpath, fields, false) = arm.pat.kind
&& match_qpath(qpath, &["Test"])
&& fields.len() == 1
&& fields[0].ident.as_str() == "field"
&& let PatKind::Expr(lit_expr) = fields[0].pat.kind
&& let PatExprKind::Lit{ref lit, negated } = lit_expr.kind
&& let PatExprKind::Lit { ref lit, negated } = lit_expr.kind
&& let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node
&& arm.guard.is_none()
&& let ExprKind::Block(block, None) = arm.body.kind
@ -34,10 +32,9 @@ if let PatKind::Struct(ref qpath, fields, false) = arm.pat.kind
// report your lint here
}
if let PatKind::TupleStruct(ref qpath, fields, None) = arm.pat.kind
&& match_qpath(qpath, &["TestTuple"])
&& fields.len() == 1
&& let PatKind::Expr(lit_expr) = fields[0].kind
&& let PatExprKind::Lit{ref lit, negated } = lit_expr.kind
&& let PatExprKind::Lit { ref lit, negated } = lit_expr.kind
&& let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node
&& arm.guard.is_none()
&& let ExprKind::Block(block, None) = arm.body.kind
@ -48,8 +45,6 @@ if let PatKind::TupleStruct(ref qpath, fields, None) = arm.pat.kind
}
if let ExprKind::MethodCall(method_name, receiver, args, _) = expr.kind
&& method_name.ident.as_str() == "test"
&& let ExprKind::Path(ref qpath) = receiver.kind
&& match_qpath(qpath, &["test_method_call"])
&& args.is_empty()
{
// report your lint here

View file

@ -51,14 +51,14 @@ pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStrea
fn mut_receiver_of(sig: &mut Signature) -> Option<&mut FnArg> {
let arg = sig.inputs.first_mut()?;
if let FnArg::Typed(PatType { pat, .. }) = arg {
if let Pat::Ident(PatIdent { ident, .. }) = &**pat {
if ident == "self" {
return Some(arg);
}
}
if let FnArg::Typed(PatType { pat, .. }) = arg
&& let Pat::Ident(PatIdent { ident, .. }) = &**pat
&& ident == "self"
{
Some(arg)
} else {
None
}
None
}
let mut elided = 0;
@ -66,30 +66,29 @@ pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStrea
// Look for methods having arbitrary self type taken by &mut ref
for inner in &mut item.items {
if let ImplItem::Fn(method) = inner {
if let Some(FnArg::Typed(pat_type)) = mut_receiver_of(&mut method.sig) {
if let box Type::Reference(reference) = &mut pat_type.ty {
// Target only unnamed lifetimes
let name = match &reference.lifetime {
Some(lt) if lt.ident == "_" => make_name(elided),
None => make_name(elided),
_ => continue,
};
elided += 1;
if let ImplItem::Fn(method) = inner
&& let Some(FnArg::Typed(pat_type)) = mut_receiver_of(&mut method.sig)
&& let box Type::Reference(reference) = &mut pat_type.ty
{
// Target only unnamed lifetimes
let name = match &reference.lifetime {
Some(lt) if lt.ident == "_" => make_name(elided),
None => make_name(elided),
_ => continue,
};
elided += 1;
// HACK: Syn uses `Span` from the proc_macro2 crate, and does not seem to reexport it.
// In order to avoid adding the dependency, get a default span from a nonexistent token.
// A default span is needed to mark the code as coming from expansion.
let span = Star::default().span();
// HACK: Syn uses `Span` from the proc_macro2 crate, and does not seem to reexport it.
// In order to avoid adding the dependency, get a default span from a nonexistent token.
// A default span is needed to mark the code as coming from expansion.
let span = Star::default().span();
// Replace old lifetime with the named one
let lifetime = Lifetime::new(&name, span);
reference.lifetime = Some(parse_quote!(#lifetime));
// Replace old lifetime with the named one
let lifetime = Lifetime::new(&name, span);
reference.lifetime = Some(parse_quote!(#lifetime));
// Add lifetime to the generics of the method
method.sig.generics.params.push(parse_quote!(#lifetime));
}
}
// Add lifetime to the generics of the method
method.sig.generics.params.push(parse_quote!(#lifetime));
}
}
@ -129,15 +128,15 @@ pub fn fake_desugar_await(_args: TokenStream, input: TokenStream) -> TokenStream
let mut async_fn = parse_macro_input!(input as syn::ItemFn);
for stmt in &mut async_fn.block.stmts {
if let syn::Stmt::Expr(syn::Expr::Match(syn::ExprMatch { expr: scrutinee, .. }), _) = stmt {
if let syn::Expr::Await(syn::ExprAwait { base, await_token, .. }) = scrutinee.as_mut() {
let blc = quote_spanned!( await_token.span => {
#[allow(clippy::let_and_return)]
let __pinned = #base;
__pinned
});
*scrutinee = parse_quote!(#blc);
}
if let syn::Stmt::Expr(syn::Expr::Match(syn::ExprMatch { expr: scrutinee, .. }), _) = stmt
&& let syn::Expr::Await(syn::ExprAwait { base, await_token, .. }) = scrutinee.as_mut()
{
let blc = quote_spanned!( await_token.span => {
#[allow(clippy::let_and_return)]
let __pinned = #base;
__pinned
});
*scrutinee = parse_quote!(#blc);
}
}

View file

@ -1,4 +1,3 @@
#![feature(let_chains)]
#![feature(proc_macro_span)]
#![allow(clippy::needless_if, dead_code)]

View file

@ -1,4 +1,3 @@
#![feature(let_chains)]
#![warn(clippy::bool_to_int_with_if)]
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]

View file

@ -1,4 +1,3 @@
#![feature(let_chains)]
#![warn(clippy::bool_to_int_with_if)]
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]

View file

@ -1,5 +1,5 @@
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:14:5
--> tests/ui/bool_to_int_with_if.rs:13:5
|
LL | / if a {
LL | |
@ -14,7 +14,7 @@ LL | | };
= help: to override `-D warnings` add `#[allow(clippy::bool_to_int_with_if)]`
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:20:5
--> tests/ui/bool_to_int_with_if.rs:19:5
|
LL | / if a {
LL | |
@ -27,7 +27,7 @@ LL | | };
= note: `!a as i32` or `(!a).into()` can also be valid options
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:26:5
--> tests/ui/bool_to_int_with_if.rs:25:5
|
LL | / if !a {
LL | |
@ -40,7 +40,7 @@ LL | | };
= note: `!a as i32` or `(!a).into()` can also be valid options
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:32:5
--> tests/ui/bool_to_int_with_if.rs:31:5
|
LL | / if a || b {
LL | |
@ -53,7 +53,7 @@ LL | | };
= note: `(a || b) as i32` or `(a || b).into()` can also be valid options
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:38:5
--> tests/ui/bool_to_int_with_if.rs:37:5
|
LL | / if cond(a, b) {
LL | |
@ -66,7 +66,7 @@ LL | | };
= note: `cond(a, b) as i32` or `cond(a, b).into()` can also be valid options
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:44:5
--> tests/ui/bool_to_int_with_if.rs:43:5
|
LL | / if x + y < 4 {
LL | |
@ -79,7 +79,7 @@ LL | | };
= note: `(x + y < 4) as i32` or `(x + y < 4).into()` can also be valid options
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:54:12
--> tests/ui/bool_to_int_with_if.rs:53:12
|
LL | } else if b {
| ____________^
@ -93,7 +93,7 @@ LL | | };
= note: `b as i32` or `b.into()` can also be valid options
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:64:12
--> tests/ui/bool_to_int_with_if.rs:63:12
|
LL | } else if b {
| ____________^
@ -107,7 +107,7 @@ LL | | };
= note: `!b as i32` or `(!b).into()` can also be valid options
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:130:5
--> tests/ui/bool_to_int_with_if.rs:129:5
|
LL | if a { 1 } else { 0 }
| ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)`
@ -115,7 +115,7 @@ LL | if a { 1 } else { 0 }
= note: `a as u8` or `a.into()` can also be valid options
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:174:13
--> tests/ui/bool_to_int_with_if.rs:173:13
|
LL | let _ = if dbg!(4 > 0) { 1 } else { 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `i32::from(dbg!(4 > 0))`
@ -123,7 +123,7 @@ LL | let _ = if dbg!(4 > 0) { 1 } else { 0 };
= note: `dbg!(4 > 0) as i32` or `dbg!(4 > 0).into()` can also be valid options
error: boolean to int conversion using if
--> tests/ui/bool_to_int_with_if.rs:177:18
--> tests/ui/bool_to_int_with_if.rs:176:18
|
LL | let _ = dbg!(if 4 > 0 { 1 } else { 0 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `i32::from(4 > 0)`

View file

@ -188,6 +188,91 @@ fn issue11371() {
}
}
fn gen_option() -> Option<()> {
Some(())
// Or None
}
fn gen_result() -> Result<(), ()> {
Ok(())
// Or Err(())
}
fn issue14725() {
let option = Some(());
if option.is_some() {
let _ = option.as_ref().unwrap();
//~^ unnecessary_unwrap
} else {
let _ = option.as_ref().unwrap();
//~^ panicking_unwrap
}
let result = Ok::<(), ()>(());
if result.is_ok() {
let _y = 1;
result.as_ref().unwrap();
//~^ unnecessary_unwrap
} else {
let _y = 1;
result.as_ref().unwrap();
//~^ panicking_unwrap
}
let mut option = Some(());
if option.is_some() {
option = gen_option();
option.as_mut().unwrap();
} else {
option = gen_option();
option.as_mut().unwrap();
}
let mut result = Ok::<(), ()>(());
if result.is_ok() {
result = gen_result();
result.as_mut().unwrap();
} else {
result = gen_result();
result.as_mut().unwrap();
}
}
fn issue14763(x: Option<String>, r: Result<(), ()>) {
_ = || {
if x.is_some() {
_ = x.unwrap();
//~^ unnecessary_unwrap
} else {
_ = x.unwrap();
//~^ panicking_unwrap
}
};
_ = || {
if r.is_ok() {
_ = r.as_ref().unwrap();
//~^ unnecessary_unwrap
} else {
_ = r.as_ref().unwrap();
//~^ panicking_unwrap
}
};
}
const ISSUE14763: fn(Option<String>) = |x| {
_ = || {
if x.is_some() {
_ = x.unwrap();
//~^ unnecessary_unwrap
} else {
_ = x.unwrap();
//~^ panicking_unwrap
}
}
};
fn check_expect() {
let x = Some(());
if x.is_some() {

View file

@ -236,6 +236,92 @@ LL | if result.is_ok() {
LL | result.as_mut().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: called `unwrap` on `option` after checking its variant with `is_some`
--> tests/ui/checked_unwrap/simple_conditionals.rs:205:17
|
LL | if option.is_some() {
| ------------------- help: try: `if let Some(<item>) = &option`
LL | let _ = option.as_ref().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
--> tests/ui/checked_unwrap/simple_conditionals.rs:208:17
|
LL | if option.is_some() {
| ---------------- because of this check
...
LL | let _ = option.as_ref().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: called `unwrap` on `result` after checking its variant with `is_ok`
--> tests/ui/checked_unwrap/simple_conditionals.rs:216:9
|
LL | if result.is_ok() {
| ----------------- help: try: `if let Ok(<item>) = &result`
LL | let _y = 1;
LL | result.as_ref().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
--> tests/ui/checked_unwrap/simple_conditionals.rs:220:9
|
LL | if result.is_ok() {
| -------------- because of this check
...
LL | result.as_ref().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: called `unwrap` on `x` after checking its variant with `is_some`
--> tests/ui/checked_unwrap/simple_conditionals.rs:246:17
|
LL | if x.is_some() {
| -------------- help: try: `if let Some(<item>) = x`
LL | _ = x.unwrap();
| ^^^^^^^^^^
error: this call to `unwrap()` will always panic
--> tests/ui/checked_unwrap/simple_conditionals.rs:249:17
|
LL | if x.is_some() {
| ----------- because of this check
...
LL | _ = x.unwrap();
| ^^^^^^^^^^
error: called `unwrap` on `r` after checking its variant with `is_ok`
--> tests/ui/checked_unwrap/simple_conditionals.rs:255:17
|
LL | if r.is_ok() {
| ------------ help: try: `if let Ok(<item>) = &r`
LL | _ = r.as_ref().unwrap();
| ^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
--> tests/ui/checked_unwrap/simple_conditionals.rs:258:17
|
LL | if r.is_ok() {
| --------- because of this check
...
LL | _ = r.as_ref().unwrap();
| ^^^^^^^^^^^^^^^^^^^
error: called `unwrap` on `x` after checking its variant with `is_some`
--> tests/ui/checked_unwrap/simple_conditionals.rs:267:17
|
LL | if x.is_some() {
| -------------- help: try: `if let Some(<item>) = x`
LL | _ = x.unwrap();
| ^^^^^^^^^^
error: this call to `unwrap()` will always panic
--> tests/ui/checked_unwrap/simple_conditionals.rs:270:17
|
LL | if x.is_some() {
| ----------- because of this check
...
LL | _ = x.unwrap();
| ^^^^^^^^^^
error: creating a shared reference to mutable static
--> tests/ui/checked_unwrap/simple_conditionals.rs:183:12
|
@ -246,5 +332,5 @@ LL | if X.is_some() {
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[deny(static_mut_refs)]` on by default
error: aborting due to 26 previous errors
error: aborting due to 36 previous errors

View file

@ -0,0 +1,64 @@
#![warn(clippy::cloned_ref_to_slice_refs)]
#[derive(Clone)]
struct Data;
fn main() {
{
let data = Data;
let data_ref = &data;
let _ = std::slice::from_ref(data_ref); //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`
}
{
let _ = std::slice::from_ref(&Data); //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`
}
{
#[derive(Clone)]
struct Point(i32, i32);
let _ = std::slice::from_ref(&Point(0, 0)); //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`
}
// the string was cloned with the intention to not mutate
{
struct BetterString(String);
let mut message = String::from("good");
let sender = BetterString(message.clone());
message.push_str("bye!");
println!("{} {}", message, sender.0)
}
// the string was cloned with the intention to not mutate
{
let mut x = String::from("Hello");
let r = &[x.clone()];
x.push('!');
println!("r = `{}', x = `{x}'", r[0]);
}
// mutable borrows may have the intention to clone
{
let data = Data;
let data_ref = &data;
let _ = &mut [data_ref.clone()];
}
// `T::clone` is used to denote a clone with side effects
{
use std::sync::Arc;
let data = Arc::new(Data);
let _ = &[Arc::clone(&data)];
}
// slices with multiple members can only be made from a singular reference
{
let data_1 = Data;
let data_2 = Data;
let _ = &[data_1.clone(), data_2.clone()];
}
}

View file

@ -0,0 +1,64 @@
#![warn(clippy::cloned_ref_to_slice_refs)]
#[derive(Clone)]
struct Data;
fn main() {
{
let data = Data;
let data_ref = &data;
let _ = &[data_ref.clone()]; //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`
}
{
let _ = &[Data.clone()]; //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`
}
{
#[derive(Clone)]
struct Point(i32, i32);
let _ = &[Point(0, 0).clone()]; //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`
}
// the string was cloned with the intention to not mutate
{
struct BetterString(String);
let mut message = String::from("good");
let sender = BetterString(message.clone());
message.push_str("bye!");
println!("{} {}", message, sender.0)
}
// the string was cloned with the intention to not mutate
{
let mut x = String::from("Hello");
let r = &[x.clone()];
x.push('!');
println!("r = `{}', x = `{x}'", r[0]);
}
// mutable borrows may have the intention to clone
{
let data = Data;
let data_ref = &data;
let _ = &mut [data_ref.clone()];
}
// `T::clone` is used to denote a clone with side effects
{
use std::sync::Arc;
let data = Arc::new(Data);
let _ = &[Arc::clone(&data)];
}
// slices with multiple members can only be made from a singular reference
{
let data_1 = Data;
let data_2 = Data;
let _ = &[data_1.clone(), data_2.clone()];
}
}

View file

@ -0,0 +1,23 @@
error: this call to `clone` can be replaced with `std::slice::from_ref`
--> tests/ui/cloned_ref_to_slice_refs.rs:10:17
|
LL | let _ = &[data_ref.clone()];
| ^^^^^^^^^^^^^^^^^^^ help: try: `std::slice::from_ref(data_ref)`
|
= note: `-D clippy::cloned-ref-to-slice-refs` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::cloned_ref_to_slice_refs)]`
error: this call to `clone` can be replaced with `std::slice::from_ref`
--> tests/ui/cloned_ref_to_slice_refs.rs:14:17
|
LL | let _ = &[Data.clone()];
| ^^^^^^^^^^^^^^^ help: try: `std::slice::from_ref(&Data)`
error: this call to `clone` can be replaced with `std::slice::from_ref`
--> tests/ui/cloned_ref_to_slice_refs.rs:21:17
|
LL | let _ = &[Point(0, 0).clone()];
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::slice::from_ref(&Point(0, 0))`
error: aborting due to 3 previous errors

View file

@ -101,27 +101,8 @@ fn main() {
}
}
// Test behavior wrt. `let_chains`.
// None of the cases below should be collapsed.
fn truth() -> bool { true }
// Prefix:
if let 0 = 1 {
if truth() {}
}
// Suffix:
if truth() {
if let 0 = 1 {}
}
// Midfix:
if truth() {
if let 0 = 1 {
if truth() {}
}
}
// Fix #5962
if matches!(true, true)
&& matches!(true, true) {}
@ -162,3 +143,14 @@ fn layout_check() -> u32 {
; 3
//~^^^^^ collapsible_if
}
fn issue14722() {
let x = if true {
Some(1)
} else {
if true {
println!("Some debug information");
};
None
};
}

View file

@ -108,27 +108,8 @@ fn main() {
}
}
// Test behavior wrt. `let_chains`.
// None of the cases below should be collapsed.
fn truth() -> bool { true }
// Prefix:
if let 0 = 1 {
if truth() {}
}
// Suffix:
if truth() {
if let 0 = 1 {}
}
// Midfix:
if truth() {
if let 0 = 1 {
if truth() {}
}
}
// Fix #5962
if matches!(true, true) {
if matches!(true, true) {}
@ -172,3 +153,14 @@ fn layout_check() -> u32 {
}; 3
//~^^^^^ collapsible_if
}
fn issue14722() {
let x = if true {
Some(1)
} else {
if true {
println!("Some debug information");
};
None
};
}

View file

@ -127,7 +127,7 @@ LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if.rs:133:5
--> tests/ui/collapsible_if.rs:114:5
|
LL | / if matches!(true, true) {
LL | | if matches!(true, true) {}
@ -141,7 +141,7 @@ LL ~ && matches!(true, true) {}
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if.rs:139:5
--> tests/ui/collapsible_if.rs:120:5
|
LL | / if matches!(true, true) && truth() {
LL | | if matches!(true, true) {}
@ -155,7 +155,7 @@ LL ~ && matches!(true, true) {}
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if.rs:151:5
--> tests/ui/collapsible_if.rs:132:5
|
LL | / if true {
LL | | if true {
@ -173,7 +173,7 @@ LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if.rs:168:5
--> tests/ui/collapsible_if.rs:149:5
|
LL | / if true {
LL | | if true {

View file

@ -0,0 +1,68 @@
//@revisions: edition2021 edition2024
//@[edition2021] edition:2021
//@[edition2024] edition:2024
//@[edition2021] check-pass
#![warn(clippy::collapsible_if)]
fn main() {
if let Some(a) = Some(3) {
// with comment, so do not lint
if let Some(b) = Some(4) {
let _ = a + b;
}
}
//~[edition2024]v collapsible_if
if let Some(a) = Some(3)
&& let Some(b) = Some(4) {
let _ = a + b;
}
//~[edition2024]v collapsible_if
if let Some(a) = Some(3)
&& a + 1 == 4 {
let _ = a;
}
//~[edition2024]v collapsible_if
if Some(3) == Some(4).map(|x| x - 1)
&& let Some(b) = Some(4) {
let _ = b;
}
fn truth() -> bool {
true
}
// Prefix:
//~[edition2024]v collapsible_if
if let 0 = 1
&& truth() {}
// Suffix:
//~[edition2024]v collapsible_if
if truth()
&& let 0 = 1 {}
// Midfix:
//~[edition2024]vvv collapsible_if
//~[edition2024]v collapsible_if
if truth()
&& let 0 = 1
&& truth() {}
}
#[clippy::msrv = "1.87.0"]
fn msrv_1_87() {
if let 0 = 1 {
if true {}
}
}
#[clippy::msrv = "1.88.0"]
fn msrv_1_88() {
//~[edition2024]v collapsible_if
if let 0 = 1
&& true {}
}

View file

@ -0,0 +1,132 @@
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:17:5
|
LL | / if let Some(a) = Some(3) {
LL | | if let Some(b) = Some(4) {
LL | | let _ = a + b;
LL | | }
LL | | }
| |_____^
|
= note: `-D clippy::collapsible-if` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::collapsible_if)]`
help: collapse nested if block
|
LL ~ if let Some(a) = Some(3)
LL ~ && let Some(b) = Some(4) {
LL | let _ = a + b;
LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:24:5
|
LL | / if let Some(a) = Some(3) {
LL | | if a + 1 == 4 {
LL | | let _ = a;
LL | | }
LL | | }
| |_____^
|
help: collapse nested if block
|
LL ~ if let Some(a) = Some(3)
LL ~ && a + 1 == 4 {
LL | let _ = a;
LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:31:5
|
LL | / if Some(3) == Some(4).map(|x| x - 1) {
LL | | if let Some(b) = Some(4) {
LL | | let _ = b;
LL | | }
LL | | }
| |_____^
|
help: collapse nested if block
|
LL ~ if Some(3) == Some(4).map(|x| x - 1)
LL ~ && let Some(b) = Some(4) {
LL | let _ = b;
LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:43:5
|
LL | / if let 0 = 1 {
LL | | if truth() {}
LL | | }
| |_____^
|
help: collapse nested if block
|
LL ~ if let 0 = 1
LL ~ && truth() {}
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:49:5
|
LL | / if truth() {
LL | | if let 0 = 1 {}
LL | | }
| |_____^
|
help: collapse nested if block
|
LL ~ if truth()
LL ~ && let 0 = 1 {}
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:56:5
|
LL | / if truth() {
LL | | if let 0 = 1 {
LL | | if truth() {}
LL | | }
LL | | }
| |_____^
|
help: collapse nested if block
|
LL ~ if truth()
LL ~ && let 0 = 1 {
LL | if truth() {}
LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:57:9
|
LL | / if let 0 = 1 {
LL | | if truth() {}
LL | | }
| |_________^
|
help: collapse nested if block
|
LL ~ if let 0 = 1
LL ~ && truth() {}
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:73:5
|
LL | / if let 0 = 1 {
LL | | if true {}
LL | | }
| |_____^
|
help: collapse nested if block
|
LL ~ if let 0 = 1
LL ~ && true {}
|
error: aborting due to 8 previous errors

View file

@ -1,29 +0,0 @@
#![feature(let_chains)]
#![warn(clippy::collapsible_if)]
fn main() {
if let Some(a) = Some(3) {
// with comment, so do not lint
if let Some(b) = Some(4) {
let _ = a + b;
}
}
if let Some(a) = Some(3)
&& let Some(b) = Some(4) {
let _ = a + b;
}
//~^^^^^ collapsible_if
if let Some(a) = Some(3)
&& a + 1 == 4 {
let _ = a;
}
//~^^^^^ collapsible_if
if Some(3) == Some(4).map(|x| x - 1)
&& let Some(b) = Some(4) {
let _ = b;
}
//~^^^^^ collapsible_if
}

View file

@ -1,4 +1,8 @@
#![feature(let_chains)]
//@revisions: edition2021 edition2024
//@[edition2021] edition:2021
//@[edition2024] edition:2024
//@[edition2021] check-pass
#![warn(clippy::collapsible_if)]
fn main() {
@ -9,24 +13,64 @@ fn main() {
}
}
//~[edition2024]v collapsible_if
if let Some(a) = Some(3) {
if let Some(b) = Some(4) {
let _ = a + b;
}
}
//~^^^^^ collapsible_if
//~[edition2024]v collapsible_if
if let Some(a) = Some(3) {
if a + 1 == 4 {
let _ = a;
}
}
//~^^^^^ collapsible_if
//~[edition2024]v collapsible_if
if Some(3) == Some(4).map(|x| x - 1) {
if let Some(b) = Some(4) {
let _ = b;
}
}
//~^^^^^ collapsible_if
fn truth() -> bool {
true
}
// Prefix:
//~[edition2024]v collapsible_if
if let 0 = 1 {
if truth() {}
}
// Suffix:
//~[edition2024]v collapsible_if
if truth() {
if let 0 = 1 {}
}
// Midfix:
//~[edition2024]vvv collapsible_if
//~[edition2024]v collapsible_if
if truth() {
if let 0 = 1 {
if truth() {}
}
}
}
#[clippy::msrv = "1.87.0"]
fn msrv_1_87() {
if let 0 = 1 {
if true {}
}
}
#[clippy::msrv = "1.88.0"]
fn msrv_1_88() {
//~[edition2024]v collapsible_if
if let 0 = 1 {
if true {}
}
}

View file

@ -1,58 +0,0 @@
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:12:5
|
LL | / if let Some(a) = Some(3) {
LL | | if let Some(b) = Some(4) {
LL | | let _ = a + b;
LL | | }
LL | | }
| |_____^
|
= note: `-D clippy::collapsible-if` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::collapsible_if)]`
help: collapse nested if block
|
LL ~ if let Some(a) = Some(3)
LL ~ && let Some(b) = Some(4) {
LL | let _ = a + b;
LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:19:5
|
LL | / if let Some(a) = Some(3) {
LL | | if a + 1 == 4 {
LL | | let _ = a;
LL | | }
LL | | }
| |_____^
|
help: collapse nested if block
|
LL ~ if let Some(a) = Some(3)
LL ~ && a + 1 == 4 {
LL | let _ = a;
LL ~ }
|
error: this `if` statement can be collapsed
--> tests/ui/collapsible_if_let_chains.rs:26:5
|
LL | / if Some(3) == Some(4).map(|x| x - 1) {
LL | | if let Some(b) = Some(4) {
LL | | let _ = b;
LL | | }
LL | | }
| |_____^
|
help: collapse nested if block
|
LL ~ if Some(3) == Some(4).map(|x| x - 1)
LL ~ && let Some(b) = Some(4) {
LL | let _ = b;
LL ~ }
|
error: aborting due to 3 previous errors

View file

@ -1,5 +1,6 @@
#![warn(clippy::collapsible_match)]
#![allow(
clippy::collapsible_if,
clippy::equatable_if_let,
clippy::needless_return,
clippy::no_effect,

View file

@ -1,5 +1,5 @@
error: this `match` can be collapsed into the outer `match`
--> tests/ui/collapsible_match.rs:14:20
--> tests/ui/collapsible_match.rs:15:20
|
LL | Ok(val) => match val {
| ____________________^
@ -10,7 +10,7 @@ LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:14:12
--> tests/ui/collapsible_match.rs:15:12
|
LL | Ok(val) => match val {
| ^^^ replace this binding
@ -21,7 +21,7 @@ LL | Some(n) => foo(n),
= help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]`
error: this `match` can be collapsed into the outer `match`
--> tests/ui/collapsible_match.rs:24:20
--> tests/ui/collapsible_match.rs:25:20
|
LL | Ok(val) => match val {
| ____________________^
@ -32,7 +32,7 @@ LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:24:12
--> tests/ui/collapsible_match.rs:25:12
|
LL | Ok(val) => match val {
| ^^^ replace this binding
@ -41,7 +41,7 @@ LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `if let`
--> tests/ui/collapsible_match.rs:34:9
--> tests/ui/collapsible_match.rs:35:9
|
LL | / if let Some(n) = val {
LL | |
@ -51,7 +51,7 @@ LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:33:15
--> tests/ui/collapsible_match.rs:34:15
|
LL | if let Ok(val) = res_opt {
| ^^^ replace this binding
@ -59,7 +59,7 @@ LL | if let Some(n) = val {
| ^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `if let`
--> tests/ui/collapsible_match.rs:43:9
--> tests/ui/collapsible_match.rs:44:9
|
LL | / if let Some(n) = val {
LL | |
@ -71,7 +71,7 @@ LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:42:15
--> tests/ui/collapsible_match.rs:43:15
|
LL | if let Ok(val) = res_opt {
| ^^^ replace this binding
@ -79,7 +79,7 @@ LL | if let Some(n) = val {
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `if let`
--> tests/ui/collapsible_match.rs:56:9
--> tests/ui/collapsible_match.rs:57:9
|
LL | / match val {
LL | |
@ -89,7 +89,7 @@ LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:55:15
--> tests/ui/collapsible_match.rs:56:15
|
LL | if let Ok(val) = res_opt {
| ^^^ replace this binding
@ -98,7 +98,7 @@ LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `match`
--> tests/ui/collapsible_match.rs:66:13
--> tests/ui/collapsible_match.rs:67:13
|
LL | / if let Some(n) = val {
LL | |
@ -108,7 +108,7 @@ LL | | }
| |_____________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:65:12
--> tests/ui/collapsible_match.rs:66:12
|
LL | Ok(val) => {
| ^^^ replace this binding
@ -116,7 +116,7 @@ LL | if let Some(n) = val {
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `if let`
--> tests/ui/collapsible_match.rs:77:9
--> tests/ui/collapsible_match.rs:78:9
|
LL | / match val {
LL | |
@ -126,7 +126,7 @@ LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:76:15
--> tests/ui/collapsible_match.rs:77:15
|
LL | if let Ok(val) = res_opt {
| ^^^ replace this binding
@ -135,7 +135,7 @@ LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `match`
--> tests/ui/collapsible_match.rs:89:13
--> tests/ui/collapsible_match.rs:90:13
|
LL | / if let Some(n) = val {
LL | |
@ -147,7 +147,7 @@ LL | | }
| |_____________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:88:12
--> tests/ui/collapsible_match.rs:89:12
|
LL | Ok(val) => {
| ^^^ replace this binding
@ -155,7 +155,7 @@ LL | if let Some(n) = val {
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `match`
--> tests/ui/collapsible_match.rs:102:20
--> tests/ui/collapsible_match.rs:103:20
|
LL | Ok(val) => match val {
| ____________________^
@ -166,7 +166,7 @@ LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:102:12
--> tests/ui/collapsible_match.rs:103:12
|
LL | Ok(val) => match val {
| ^^^ replace this binding
@ -175,7 +175,7 @@ LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `match`
--> tests/ui/collapsible_match.rs:112:22
--> tests/ui/collapsible_match.rs:113:22
|
LL | Some(val) => match val {
| ______________________^
@ -186,7 +186,7 @@ LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:112:14
--> tests/ui/collapsible_match.rs:113:14
|
LL | Some(val) => match val {
| ^^^ replace this binding
@ -195,7 +195,7 @@ LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `match`
--> tests/ui/collapsible_match.rs:256:22
--> tests/ui/collapsible_match.rs:257:22
|
LL | Some(val) => match val {
| ______________________^
@ -206,7 +206,7 @@ LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:256:14
--> tests/ui/collapsible_match.rs:257:14
|
LL | Some(val) => match val {
| ^^^ replace this binding
@ -215,7 +215,7 @@ LL | E::A(val) | E::B(val) => foo(val),
| ^^^^^^^^^^^^^^^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `if let`
--> tests/ui/collapsible_match.rs:288:9
--> tests/ui/collapsible_match.rs:289:9
|
LL | / if let Some(u) = a {
LL | |
@ -225,7 +225,7 @@ LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:287:27
--> tests/ui/collapsible_match.rs:288:27
|
LL | if let Issue9647::A { a, .. } = x {
| ^ replace this binding
@ -233,7 +233,7 @@ LL | if let Some(u) = a {
| ^^^^^^^ with this pattern, prefixed by `a`:
error: this `if let` can be collapsed into the outer `if let`
--> tests/ui/collapsible_match.rs:298:9
--> tests/ui/collapsible_match.rs:299:9
|
LL | / if let Some(u) = a {
LL | |
@ -243,7 +243,7 @@ LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
--> tests/ui/collapsible_match.rs:297:35
--> tests/ui/collapsible_match.rs:298:35
|
LL | if let Issue9647::A { a: Some(a), .. } = x {
| ^ replace this binding

View file

@ -1,6 +1,5 @@
#![warn(clippy::comparison_to_empty)]
#![allow(clippy::borrow_deref_ref, clippy::needless_if, clippy::useless_vec)]
#![feature(let_chains)]
fn main() {
// Disallow comparisons to empty

View file

@ -1,6 +1,5 @@
#![warn(clippy::comparison_to_empty)]
#![allow(clippy::borrow_deref_ref, clippy::needless_if, clippy::useless_vec)]
#![feature(let_chains)]
fn main() {
// Disallow comparisons to empty

View file

@ -1,5 +1,5 @@
error: comparison to empty slice
--> tests/ui/comparison_to_empty.rs:8:13
--> tests/ui/comparison_to_empty.rs:7:13
|
LL | let _ = s == "";
| ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
@ -8,73 +8,73 @@ LL | let _ = s == "";
= help: to override `-D warnings` add `#[allow(clippy::comparison_to_empty)]`
error: comparison to empty slice
--> tests/ui/comparison_to_empty.rs:10:13
--> tests/ui/comparison_to_empty.rs:9:13
|
LL | let _ = s != "";
| ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!s.is_empty()`
error: comparison to empty slice
--> tests/ui/comparison_to_empty.rs:14:13
--> tests/ui/comparison_to_empty.rs:13:13
|
LL | let _ = v == [];
| ^^^^^^^ help: using `is_empty` is clearer and more explicit: `v.is_empty()`
error: comparison to empty slice
--> tests/ui/comparison_to_empty.rs:16:13
--> tests/ui/comparison_to_empty.rs:15:13
|
LL | let _ = v != [];
| ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!v.is_empty()`
error: comparison to empty slice using `if let`
--> tests/ui/comparison_to_empty.rs:18:8
--> tests/ui/comparison_to_empty.rs:17:8
|
LL | if let [] = &*v {}
| ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(*v).is_empty()`
error: comparison to empty slice using `if let`
--> tests/ui/comparison_to_empty.rs:21:8
--> tests/ui/comparison_to_empty.rs:20:8
|
LL | if let [] = s {}
| ^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
error: comparison to empty slice using `if let`
--> tests/ui/comparison_to_empty.rs:23:8
--> tests/ui/comparison_to_empty.rs:22:8
|
LL | if let [] = &*s {}
| ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
error: comparison to empty slice using `if let`
--> tests/ui/comparison_to_empty.rs:25:8
--> tests/ui/comparison_to_empty.rs:24:8
|
LL | if let [] = &*s
| ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
error: comparison to empty slice
--> tests/ui/comparison_to_empty.rs:27:12
--> tests/ui/comparison_to_empty.rs:26:12
|
LL | && s == []
| ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
error: comparison to empty slice
--> tests/ui/comparison_to_empty.rs:48:13
--> tests/ui/comparison_to_empty.rs:47:13
|
LL | let _ = s.eq("");
| ^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
error: comparison to empty slice
--> tests/ui/comparison_to_empty.rs:50:13
--> tests/ui/comparison_to_empty.rs:49:13
|
LL | let _ = s.ne("");
| ^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!s.is_empty()`
error: comparison to empty slice
--> tests/ui/comparison_to_empty.rs:53:13
--> tests/ui/comparison_to_empty.rs:52:13
|
LL | let _ = v.eq(&[]);
| ^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `v.is_empty()`
error: comparison to empty slice
--> tests/ui/comparison_to_empty.rs:55:13
--> tests/ui/comparison_to_empty.rs:54:13
|
LL | let _ = v.ne(&[]);
| ^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!v.is_empty()`

View file

@ -0,0 +1,14 @@
#![feature(float_minimum_maximum)]
#![warn(clippy::confusing_method_to_numeric_cast)]
fn main() {
let _ = u16::MAX as usize; //~ confusing_method_to_numeric_cast
let _ = u16::MIN as usize; //~ confusing_method_to_numeric_cast
let _ = u16::MAX as usize; //~ confusing_method_to_numeric_cast
let _ = u16::MIN as usize; //~ confusing_method_to_numeric_cast
let _ = f32::MAX as usize; //~ confusing_method_to_numeric_cast
let _ = f32::MAX as usize; //~ confusing_method_to_numeric_cast
let _ = f32::MIN as usize; //~ confusing_method_to_numeric_cast
let _ = f32::MIN as usize; //~ confusing_method_to_numeric_cast
}

View file

@ -0,0 +1,14 @@
#![feature(float_minimum_maximum)]
#![warn(clippy::confusing_method_to_numeric_cast)]
fn main() {
let _ = u16::max as usize; //~ confusing_method_to_numeric_cast
let _ = u16::min as usize; //~ confusing_method_to_numeric_cast
let _ = u16::max_value as usize; //~ confusing_method_to_numeric_cast
let _ = u16::min_value as usize; //~ confusing_method_to_numeric_cast
let _ = f32::maximum as usize; //~ confusing_method_to_numeric_cast
let _ = f32::max as usize; //~ confusing_method_to_numeric_cast
let _ = f32::minimum as usize; //~ confusing_method_to_numeric_cast
let _ = f32::min as usize; //~ confusing_method_to_numeric_cast
}

View file

@ -0,0 +1,100 @@
error: casting function pointer `u16::max` to `usize`
--> tests/ui/confusing_method_to_numeric_cast.rs:5:13
|
LL | let _ = u16::max as usize;
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::confusing-method-to-numeric-cast` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::confusing_method_to_numeric_cast)]`
help: did you mean to use the associated constant?
|
LL - let _ = u16::max as usize;
LL + let _ = u16::MAX as usize;
|
error: casting function pointer `u16::min` to `usize`
--> tests/ui/confusing_method_to_numeric_cast.rs:6:13
|
LL | let _ = u16::min as usize;
| ^^^^^^^^^^^^^^^^^
|
help: did you mean to use the associated constant?
|
LL - let _ = u16::min as usize;
LL + let _ = u16::MIN as usize;
|
error: casting function pointer `u16::max_value` to `usize`
--> tests/ui/confusing_method_to_numeric_cast.rs:7:13
|
LL | let _ = u16::max_value as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: did you mean to use the associated constant?
|
LL - let _ = u16::max_value as usize;
LL + let _ = u16::MAX as usize;
|
error: casting function pointer `u16::min_value` to `usize`
--> tests/ui/confusing_method_to_numeric_cast.rs:8:13
|
LL | let _ = u16::min_value as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: did you mean to use the associated constant?
|
LL - let _ = u16::min_value as usize;
LL + let _ = u16::MIN as usize;
|
error: casting function pointer `f32::maximum` to `usize`
--> tests/ui/confusing_method_to_numeric_cast.rs:10:13
|
LL | let _ = f32::maximum as usize;
| ^^^^^^^^^^^^^^^^^^^^^
|
help: did you mean to use the associated constant?
|
LL - let _ = f32::maximum as usize;
LL + let _ = f32::MAX as usize;
|
error: casting function pointer `f32::max` to `usize`
--> tests/ui/confusing_method_to_numeric_cast.rs:11:13
|
LL | let _ = f32::max as usize;
| ^^^^^^^^^^^^^^^^^
|
help: did you mean to use the associated constant?
|
LL - let _ = f32::max as usize;
LL + let _ = f32::MAX as usize;
|
error: casting function pointer `f32::minimum` to `usize`
--> tests/ui/confusing_method_to_numeric_cast.rs:12:13
|
LL | let _ = f32::minimum as usize;
| ^^^^^^^^^^^^^^^^^^^^^
|
help: did you mean to use the associated constant?
|
LL - let _ = f32::minimum as usize;
LL + let _ = f32::MIN as usize;
|
error: casting function pointer `f32::min` to `usize`
--> tests/ui/confusing_method_to_numeric_cast.rs:13:13
|
LL | let _ = f32::min as usize;
| ^^^^^^^^^^^^^^^^^
|
help: did you mean to use the associated constant?
|
LL - let _ = f32::min as usize;
LL + let _ = f32::MIN as usize;
|
error: aborting due to 8 previous errors

View file

@ -0,0 +1,13 @@
//@compile-flags: -Z validate-mir
#![warn(clippy::missing_const_for_fn)]
static BLOCK_FN_DEF: fn(usize) -> usize = {
//~v missing_const_for_fn
const fn foo(a: usize) -> usize {
a + 10
}
foo
};
struct X;
fn main() {}

View file

@ -0,0 +1,13 @@
//@compile-flags: -Z validate-mir
#![warn(clippy::missing_const_for_fn)]
static BLOCK_FN_DEF: fn(usize) -> usize = {
//~v missing_const_for_fn
fn foo(a: usize) -> usize {
a + 10
}
foo
};
struct X;
fn main() {}

View file

@ -0,0 +1,17 @@
error: this could be a `const fn`
--> tests/ui/crashes/missing_const_for_fn_14774.rs:6:5
|
LL | / fn foo(a: usize) -> usize {
LL | | a + 10
LL | | }
| |_____^
|
= note: `-D clippy::missing-const-for-fn` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::missing_const_for_fn)]`
help: make the function `const`
|
LL | const fn foo(a: usize) -> usize {
| +++++
error: aborting due to 1 previous error

View file

@ -9,7 +9,6 @@
#![expect(incomplete_features)] // `unsafe_fields` is incomplete for the time being
#![feature(unsafe_fields)] // `clone()` cannot be derived automatically on unsafe fields
#[derive(Copy)]
struct Qux;

View file

@ -1,5 +1,5 @@
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:16:1
--> tests/ui/derive.rs:15:1
|
LL | / impl Clone for Qux {
LL | |
@ -10,7 +10,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:16:1
--> tests/ui/derive.rs:15:1
|
LL | / impl Clone for Qux {
LL | |
@ -23,7 +23,7 @@ LL | | }
= help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]`
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:42:1
--> tests/ui/derive.rs:41:1
|
LL | / impl<'a> Clone for Lt<'a> {
LL | |
@ -34,7 +34,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:42:1
--> tests/ui/derive.rs:41:1
|
LL | / impl<'a> Clone for Lt<'a> {
LL | |
@ -45,7 +45,7 @@ LL | | }
| |_^
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:55:1
--> tests/ui/derive.rs:54:1
|
LL | / impl Clone for BigArray {
LL | |
@ -56,7 +56,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:55:1
--> tests/ui/derive.rs:54:1
|
LL | / impl Clone for BigArray {
LL | |
@ -67,7 +67,7 @@ LL | | }
| |_^
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:68:1
--> tests/ui/derive.rs:67:1
|
LL | / impl Clone for FnPtr {
LL | |
@ -78,7 +78,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:68:1
--> tests/ui/derive.rs:67:1
|
LL | / impl Clone for FnPtr {
LL | |
@ -89,7 +89,7 @@ LL | | }
| |_^
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:90:1
--> tests/ui/derive.rs:89:1
|
LL | / impl<T: Clone> Clone for Generic2<T> {
LL | |
@ -100,7 +100,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:90:1
--> tests/ui/derive.rs:89:1
|
LL | / impl<T: Clone> Clone for Generic2<T> {
LL | |

View file

@ -220,4 +220,19 @@ mod issue11494 {
}
}
mod encapsulated {
mod types {
pub struct FooError;
pub struct BarError;
pub struct BazError;
}
enum Error {
FooError(types::FooError),
BarError(types::BarError),
BazError(types::BazError),
Other,
}
}
fn main() {}

View file

@ -1,5 +1,5 @@
#![deny(clippy::index_refutable_slice)]
#![allow(clippy::uninlined_format_args, clippy::needless_lifetimes)]
#![allow(clippy::uninlined_format_args, clippy::needless_lifetimes, clippy::collapsible_if)]
enum SomeEnum<T> {
One(T),

View file

@ -1,5 +1,5 @@
#![deny(clippy::index_refutable_slice)]
#![allow(clippy::uninlined_format_args, clippy::needless_lifetimes)]
#![allow(clippy::uninlined_format_args, clippy::needless_lifetimes, clippy::collapsible_if)]
enum SomeEnum<T> {
One(T),

View file

@ -1,5 +1,9 @@
#![warn(clippy::integer_division)]
use std::num::NonZeroU32;
const TWO: NonZeroU32 = NonZeroU32::new(2).unwrap();
fn main() {
let two = 2;
let n = 1 / 2;
@ -12,4 +16,8 @@ fn main() {
//~^ integer_division
let x = 1. / 2.0;
let a = 1;
let s = a / TWO;
//~^ integer_division
}

View file

@ -1,5 +1,5 @@
error: integer division
--> tests/ui/integer_division.rs:5:13
--> tests/ui/integer_division.rs:9:13
|
LL | let n = 1 / 2;
| ^^^^^
@ -9,7 +9,7 @@ LL | let n = 1 / 2;
= help: to override `-D warnings` add `#[allow(clippy::integer_division)]`
error: integer division
--> tests/ui/integer_division.rs:8:13
--> tests/ui/integer_division.rs:12:13
|
LL | let o = 1 / two;
| ^^^^^^^
@ -17,12 +17,20 @@ LL | let o = 1 / two;
= help: division of integers may cause loss of precision. consider using floats
error: integer division
--> tests/ui/integer_division.rs:11:13
--> tests/ui/integer_division.rs:15:13
|
LL | let p = two / 4;
| ^^^^^^^
|
= help: division of integers may cause loss of precision. consider using floats
error: aborting due to 3 previous errors
error: integer division
--> tests/ui/integer_division.rs:21:13
|
LL | let s = a / TWO;
| ^^^^^^^
|
= help: division of integers may cause loss of precision. consider using floats
error: aborting due to 4 previous errors

View file

@ -6,7 +6,6 @@
extern crate proc_macros;
use proc_macros::with_span;
use clippy_utils::is_from_proc_macro;
use std::boxed::Box;
use std::fmt::Display;
use std::future::Future;

View file

@ -1,11 +1,11 @@
error: non-binding `let` without a type annotation
--> tests/ui/let_underscore_untyped.rs:51:5
--> tests/ui/let_underscore_untyped.rs:50:5
|
LL | let _ = a();
| ^^^^^^^^^^^^
|
help: consider adding a type annotation
--> tests/ui/let_underscore_untyped.rs:51:10
--> tests/ui/let_underscore_untyped.rs:50:10
|
LL | let _ = a();
| ^
@ -13,49 +13,49 @@ LL | let _ = a();
= help: to override `-D warnings` add `#[allow(clippy::let_underscore_untyped)]`
error: non-binding `let` without a type annotation
--> tests/ui/let_underscore_untyped.rs:53:5
--> tests/ui/let_underscore_untyped.rs:52:5
|
LL | let _ = b(1);
| ^^^^^^^^^^^^^
|
help: consider adding a type annotation
--> tests/ui/let_underscore_untyped.rs:53:10
--> tests/ui/let_underscore_untyped.rs:52:10
|
LL | let _ = b(1);
| ^
error: non-binding `let` without a type annotation
--> tests/ui/let_underscore_untyped.rs:56:5
--> tests/ui/let_underscore_untyped.rs:55:5
|
LL | let _ = d(&1);
| ^^^^^^^^^^^^^^
|
help: consider adding a type annotation
--> tests/ui/let_underscore_untyped.rs:56:10
--> tests/ui/let_underscore_untyped.rs:55:10
|
LL | let _ = d(&1);
| ^
error: non-binding `let` without a type annotation
--> tests/ui/let_underscore_untyped.rs:58:5
--> tests/ui/let_underscore_untyped.rs:57:5
|
LL | let _ = e();
| ^^^^^^^^^^^^
|
help: consider adding a type annotation
--> tests/ui/let_underscore_untyped.rs:58:10
--> tests/ui/let_underscore_untyped.rs:57:10
|
LL | let _ = e();
| ^
error: non-binding `let` without a type annotation
--> tests/ui/let_underscore_untyped.rs:60:5
--> tests/ui/let_underscore_untyped.rs:59:5
|
LL | let _ = f();
| ^^^^^^^^^^^^
|
help: consider adding a type annotation
--> tests/ui/let_underscore_untyped.rs:60:10
--> tests/ui/let_underscore_untyped.rs:59:10
|
LL | let _ = f();
| ^

View file

@ -0,0 +1,47 @@
//@aux-build: proc_macros.rs
#![allow(unused)]
#![warn(clippy::let_with_type_underscore)]
#![allow(clippy::let_unit_value, clippy::needless_late_init)]
extern crate proc_macros;
fn func() -> &'static str {
""
}
#[rustfmt::skip]
fn main() {
// Will lint
let x = 1;
//~^ let_with_type_underscore
let _ = 2;
//~^ let_with_type_underscore
let x = func();
//~^ let_with_type_underscore
let x;
//~^ let_with_type_underscore
x = ();
let x = 1; // Will not lint, Rust infers this to an integer before Clippy
let x = func();
let x: Vec<_> = Vec::<u32>::new();
let x: [_; 1] = [1];
let x = 1;
//~^ let_with_type_underscore
// Do not lint from procedural macros
proc_macros::with_span! {
span
let x: _ = ();
// Late initialization
let x: _;
x = ();
// Ensure weird formatting will not break it (hopefully)
let x : _ = 1;
let x
: _ = 1;
let x :
_;
x = ();
};
}

View file

@ -4,13 +4,13 @@ error: variable declared with type underscore
LL | let x: _ = 1;
| ^^^^^^^^^^^^^
|
help: remove the explicit type `_` declaration
--> tests/ui/let_with_type_underscore.rs:15:10
|
LL | let x: _ = 1;
| ^^^
= note: `-D clippy::let-with-type-underscore` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::let_with_type_underscore)]`
help: remove the explicit type `_` declaration
|
LL - let x: _ = 1;
LL + let x = 1;
|
error: variable declared with type underscore
--> tests/ui/let_with_type_underscore.rs:17:5
@ -19,10 +19,10 @@ LL | let _: _ = 2;
| ^^^^^^^^^^^^^
|
help: remove the explicit type `_` declaration
--> tests/ui/let_with_type_underscore.rs:17:10
|
LL | let _: _ = 2;
| ^^^
LL - let _: _ = 2;
LL + let _ = 2;
|
error: variable declared with type underscore
--> tests/ui/let_with_type_underscore.rs:19:5
@ -31,10 +31,10 @@ LL | let x: _ = func();
| ^^^^^^^^^^^^^^^^^^
|
help: remove the explicit type `_` declaration
--> tests/ui/let_with_type_underscore.rs:19:10
|
LL | let x: _ = func();
| ^^^
LL - let x: _ = func();
LL + let x = func();
|
error: variable declared with type underscore
--> tests/ui/let_with_type_underscore.rs:21:5
@ -43,10 +43,10 @@ LL | let x: _;
| ^^^^^^^^^
|
help: remove the explicit type `_` declaration
--> tests/ui/let_with_type_underscore.rs:21:10
|
LL | let x: _;
| ^^^
LL - let x: _;
LL + let x;
|
error: variable declared with type underscore
--> tests/ui/let_with_type_underscore.rs:29:5
@ -55,10 +55,10 @@ LL | let x : _ = 1;
| ^^^^^^^^^^^^^^
|
help: remove the explicit type `_` declaration
--> tests/ui/let_with_type_underscore.rs:29:10
|
LL | let x : _ = 1;
| ^^^^
LL - let x : _ = 1;
LL + let x = 1;
|
error: aborting due to 5 previous errors

View file

@ -514,3 +514,35 @@ mod issue13768 {
};
}
}
mod issue14598 {
fn bar() -> Result<bool, &'static str> {
let value = match foo() {
//~^ manual_let_else
Err(_) => return Err("abc"),
Ok(value) => value,
};
let w = Some(0);
let v = match w {
//~^ manual_let_else
None => return Err("abc"),
Some(x) => x,
};
enum Foo<T> {
Foo(T),
}
let v = match Foo::Foo(Some(())) {
Foo::Foo(Some(_)) => return Err("abc"),
Foo::Foo(v) => v,
};
Ok(value == 42)
}
fn foo() -> Result<u32, &'static str> {
todo!()
}
}

View file

@ -529,5 +529,25 @@ LL + return;
LL + };
|
error: aborting due to 33 previous errors
error: this could be rewritten as `let...else`
--> tests/ui/manual_let_else.rs:520:9
|
LL | / let value = match foo() {
LL | |
LL | | Err(_) => return Err("abc"),
LL | | Ok(value) => value,
LL | | };
| |__________^ help: consider writing: `let Ok(value) = foo() else { return Err("abc") };`
error: this could be rewritten as `let...else`
--> tests/ui/manual_let_else.rs:527:9
|
LL | / let v = match w {
LL | |
LL | | None => return Err("abc"),
LL | | Some(x) => x,
LL | | };
| |__________^ help: consider writing: `let Some(v) = w else { return Err("abc") };`
error: aborting due to 35 previous errors

View file

@ -1,7 +1,5 @@
#![allow(clippy::legacy_numeric_constants, unused_imports)]
use std::{i32, i128, u32, u128};
fn main() {
let _ = 1u32.saturating_add(1);
//~^ manual_saturating_arithmetic

View file

@ -1,7 +1,5 @@
#![allow(clippy::legacy_numeric_constants, unused_imports)]
use std::{i32, i128, u32, u128};
fn main() {
let _ = 1u32.checked_add(1).unwrap_or(u32::max_value());
//~^ manual_saturating_arithmetic

View file

@ -1,5 +1,5 @@
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:6:13
--> tests/ui/manual_saturating_arithmetic.rs:4:13
|
LL | let _ = 1u32.checked_add(1).unwrap_or(u32::max_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u32.saturating_add(1)`
@ -8,19 +8,19 @@ LL | let _ = 1u32.checked_add(1).unwrap_or(u32::max_value());
= help: to override `-D warnings` add `#[allow(clippy::manual_saturating_arithmetic)]`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:8:13
--> tests/ui/manual_saturating_arithmetic.rs:6:13
|
LL | let _ = 1u32.checked_add(1).unwrap_or(u32::MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u32.saturating_add(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:10:13
--> tests/ui/manual_saturating_arithmetic.rs:8:13
|
LL | let _ = 1u8.checked_add(1).unwrap_or(255);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u8.saturating_add(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:12:13
--> tests/ui/manual_saturating_arithmetic.rs:10:13
|
LL | let _ = 1u128
| _____________^
@ -30,49 +30,49 @@ LL | | .unwrap_or(340_282_366_920_938_463_463_374_607_431_768_211_455);
| |_______________________________________________________________________^ help: consider using `saturating_add`: `1u128.saturating_add(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:18:13
--> tests/ui/manual_saturating_arithmetic.rs:16:13
|
LL | let _ = 1u32.checked_mul(1).unwrap_or(u32::MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_mul`: `1u32.saturating_mul(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:21:13
--> tests/ui/manual_saturating_arithmetic.rs:19:13
|
LL | let _ = 1u32.checked_sub(1).unwrap_or(u32::min_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:23:13
--> tests/ui/manual_saturating_arithmetic.rs:21:13
|
LL | let _ = 1u32.checked_sub(1).unwrap_or(u32::MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:25:13
--> tests/ui/manual_saturating_arithmetic.rs:23:13
|
LL | let _ = 1u8.checked_sub(1).unwrap_or(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u8.saturating_sub(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:30:13
--> tests/ui/manual_saturating_arithmetic.rs:28:13
|
LL | let _ = 1i32.checked_add(1).unwrap_or(i32::max_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:32:13
--> tests/ui/manual_saturating_arithmetic.rs:30:13
|
LL | let _ = 1i32.checked_add(1).unwrap_or(i32::MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:34:13
--> tests/ui/manual_saturating_arithmetic.rs:32:13
|
LL | let _ = 1i8.checked_add(1).unwrap_or(127);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:36:13
--> tests/ui/manual_saturating_arithmetic.rs:34:13
|
LL | let _ = 1i128
| _____________^
@ -82,25 +82,25 @@ LL | | .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);
| |_______________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:40:13
--> tests/ui/manual_saturating_arithmetic.rs:38:13
|
LL | let _ = 1i32.checked_add(-1).unwrap_or(i32::min_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:42:13
--> tests/ui/manual_saturating_arithmetic.rs:40:13
|
LL | let _ = 1i32.checked_add(-1).unwrap_or(i32::MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:44:13
--> tests/ui/manual_saturating_arithmetic.rs:42:13
|
LL | let _ = 1i8.checked_add(-1).unwrap_or(-128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(-1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:46:13
--> tests/ui/manual_saturating_arithmetic.rs:44:13
|
LL | let _ = 1i128
| _____________^
@ -110,25 +110,25 @@ LL | | .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);
| |________________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(-1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:54:13
--> tests/ui/manual_saturating_arithmetic.rs:52:13
|
LL | let _ = 1i32.checked_sub(1).unwrap_or(i32::min_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:56:13
--> tests/ui/manual_saturating_arithmetic.rs:54:13
|
LL | let _ = 1i32.checked_sub(1).unwrap_or(i32::MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:58:13
--> tests/ui/manual_saturating_arithmetic.rs:56:13
|
LL | let _ = 1i8.checked_sub(1).unwrap_or(-128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:60:13
--> tests/ui/manual_saturating_arithmetic.rs:58:13
|
LL | let _ = 1i128
| _____________^
@ -138,25 +138,25 @@ LL | | .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);
| |________________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:64:13
--> tests/ui/manual_saturating_arithmetic.rs:62:13
|
LL | let _ = 1i32.checked_sub(-1).unwrap_or(i32::max_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:66:13
--> tests/ui/manual_saturating_arithmetic.rs:64:13
|
LL | let _ = 1i32.checked_sub(-1).unwrap_or(i32::MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:68:13
--> tests/ui/manual_saturating_arithmetic.rs:66:13
|
LL | let _ = 1i8.checked_sub(-1).unwrap_or(127);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(-1)`
error: manual saturating arithmetic
--> tests/ui/manual_saturating_arithmetic.rs:70:13
--> tests/ui/manual_saturating_arithmetic.rs:68:13
|
LL | let _ = 1i128
| _____________^

Some files were not shown because too many files have changed in this diff Show more