Auto merge of #13098 - oli-obk:bump_ui_test, r=Alexendoo

Bump ui_test version

r? `@alexendoo`

the rustfix diff is caused by https://github.com/oli-obk/ui_test/pull/244

This should solve the issues around missing summaries at the end

changelog: none
This commit is contained in:
bors 2024-07-15 12:29:11 +00:00
commit 22eeb1109b
43 changed files with 244 additions and 2549 deletions

View file

@ -30,7 +30,7 @@ color-print = "0.3.4"
anstream = "0.6.0"
[dev-dependencies]
ui_test = "0.23"
ui_test = "0.24"
regex = "1.5.5"
toml = "0.7.3"
walkdir = "2.3"

View file

@ -5,7 +5,7 @@
use ui_test::custom_flags::rustfix::RustfixMode;
use ui_test::spanned::Spanned;
use ui_test::{status_emitter, Args, CommandBuilder, Config, Match, Mode, OutputConflictHandling};
use ui_test::{status_emitter, Args, CommandBuilder, Config, Match, OutputConflictHandling};
use std::collections::BTreeMap;
use std::env::{self, set_var, var_os};
@ -122,7 +122,8 @@ fn base_config(test_dir: &str) -> (Config, Args) {
out_dir: target_dir.join("ui_test"),
..Config::rustc(Path::new("tests").join(test_dir))
};
config.comment_defaults.base().mode = Some(Spanned::dummy(Mode::Yolo)).into();
config.comment_defaults.base().exit_status = None.into();
config.comment_defaults.base().require_annotations = None.into();
config
.comment_defaults
.base()

View file

@ -1,24 +0,0 @@
#![deny(clippy::index_refutable_slice)]
fn below_limit() {
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {
//~^ ERROR: binding can be a slice pattern
// This would usually not be linted but is included now due to the
// index limit in the config file
println!("{}", slice_7);
}
}
fn above_limit() {
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some(slice) = slice {
// This will not be linted as 8 is above the limit
println!("{}", slice[8]);
}
}
fn main() {
below_limit();
above_limit();
}

View file

@ -1,5 +1,7 @@
#![deny(clippy::index_refutable_slice)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
fn below_limit() {
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some(slice) = slice {

View file

@ -1,5 +1,5 @@
error: this binding can be a slice pattern to avoid indexing
--> tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs:5:17
--> tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs:7:17
|
LL | if let Some(slice) = slice {
| ^^^^^

View file

@ -1,11 +0,0 @@
#![deny(clippy::implicit_hasher)]
use std::collections::HashSet;
fn main() {}
pub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) {
//~^ ERROR: parameter of type `HashSet` should be generalized over different hashers
let _ = [0u8; 0];
let _: HashSet<usize> = HashSet::default();
}

View file

@ -1,5 +1,7 @@
#![deny(clippy::implicit_hasher)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
use std::collections::HashSet;
fn main() {}

View file

@ -1,5 +1,5 @@
error: parameter of type `HashSet` should be generalized over different hashers
--> tests/ui/crashes/ice-3717.rs:7:21
--> tests/ui/crashes/ice-3717.rs:9:21
|
LL | pub fn ice_3717(_: &HashSet<usize>) {
| ^^^^^^^^^^^^^^

View file

@ -1,295 +0,0 @@
#![allow(dead_code)]
use std::collections::HashMap;
#[derive(Default)]
struct FooDefault<'a> {
a: bool,
b: i32,
c: u64,
d: Vec<i32>,
e: FooND1,
f: FooND2,
g: HashMap<i32, i32>,
h: (i32, Vec<i32>),
i: [Vec<i32>; 3],
j: [i32; 5],
k: Option<i32>,
l: &'a [i32],
}
#[derive(Default)]
struct TupleDefault(bool, i32, u64);
struct FooND1 {
a: bool,
}
impl std::default::Default for FooND1 {
fn default() -> Self {
Self { a: true }
}
}
struct FooND2 {
a: i32,
}
impl std::default::Default for FooND2 {
fn default() -> Self {
Self { a: 5 }
}
}
struct FooNDNew {
a: bool,
}
impl FooNDNew {
fn new() -> Self {
Self { a: true }
}
}
impl Default for FooNDNew {
fn default() -> Self {
Self::new()
}
}
struct FooNDVec(Vec<i32>);
impl Default for FooNDVec {
fn default() -> Self {
Self(vec![5, 12])
}
}
#[derive(Default)]
struct StrDefault<'a>(&'a str);
#[derive(Default)]
struct AlreadyDerived(i32, bool);
macro_rules! mac {
() => {
0
};
($e:expr) => {
struct X(u32);
impl Default for X {
fn default() -> Self {
Self($e)
}
}
};
}
mac!(0);
#[derive(Default)]
struct Y(u32);
struct RustIssue26925<T> {
a: Option<T>,
}
// We should watch out for cases where a manual impl is needed because a
// derive adds different type bounds (https://github.com/rust-lang/rust/issues/26925).
// For example, a struct with Option<T> does not require T: Default, but a derive adds
// that type bound anyways. So until #26925 get fixed we should disable lint
// for the following case
impl<T> Default for RustIssue26925<T> {
fn default() -> Self {
Self { a: None }
}
}
struct SpecializedImpl<A, B> {
a: A,
b: B,
}
impl<T: Default> Default for SpecializedImpl<T, T> {
fn default() -> Self {
Self {
a: T::default(),
b: T::default(),
}
}
}
#[derive(Default)]
struct WithoutSelfCurly {
a: bool,
}
#[derive(Default)]
struct WithoutSelfParan(bool);
// https://github.com/rust-lang/rust-clippy/issues/7655
pub struct SpecializedImpl2<T> {
v: Vec<T>,
}
impl Default for SpecializedImpl2<String> {
fn default() -> Self {
Self { v: Vec::new() }
}
}
// https://github.com/rust-lang/rust-clippy/issues/7654
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
}
/// `#000000`
impl Default for Color {
fn default() -> Self {
Color { r: 0, g: 0, b: 0 }
}
}
pub struct Color2 {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl Default for Color2 {
/// `#000000`
fn default() -> Self {
Self { r: 0, g: 0, b: 0 }
}
}
#[derive(Default)]
pub struct RepeatDefault1 {
a: [i8; 32],
}
pub struct RepeatDefault2 {
a: [i8; 33],
}
impl Default for RepeatDefault2 {
fn default() -> Self {
RepeatDefault2 { a: [0; 33] }
}
}
// https://github.com/rust-lang/rust-clippy/issues/7753
pub enum IntOrString {
Int(i32),
String(String),
}
impl Default for IntOrString {
fn default() -> Self {
IntOrString::Int(0)
}
}
#[derive(Default)]
pub enum SimpleEnum {
Foo,
#[default]
Bar,
}
pub enum NonExhaustiveEnum {
Foo,
#[non_exhaustive]
Bar,
}
impl Default for NonExhaustiveEnum {
fn default() -> Self {
NonExhaustiveEnum::Bar
}
}
// https://github.com/rust-lang/rust-clippy/issues/10396
#[derive(Default)]
struct DefaultType;
struct GenericType<T = DefaultType> {
t: T,
}
impl Default for GenericType {
fn default() -> Self {
Self { t: Default::default() }
}
}
struct InnerGenericType<T> {
t: T,
}
impl Default for InnerGenericType<DefaultType> {
fn default() -> Self {
Self { t: Default::default() }
}
}
struct OtherGenericType<T = DefaultType> {
inner: InnerGenericType<T>,
}
impl Default for OtherGenericType {
fn default() -> Self {
Self {
inner: Default::default(),
}
}
}
mod issue10158 {
pub trait T {}
#[derive(Default)]
pub struct S {}
impl T for S {}
pub struct Outer {
pub inner: Box<dyn T>,
}
impl Default for Outer {
fn default() -> Self {
Outer {
// Box::<S>::default() adjusts to Box<dyn T>
inner: Box::<S>::default(),
}
}
}
}
mod issue11368 {
pub struct A {
a: u32,
}
impl Default for A {
#[track_caller]
fn default() -> Self {
Self { a: 0 }
}
}
}
fn main() {}

View file

@ -1,5 +1,7 @@
#![allow(dead_code)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
use std::collections::HashMap;
struct FooDefault<'a> {

View file

@ -1,5 +1,5 @@
error: this `impl` can be derived
--> tests/ui/derivable_impls.rs:20:1
--> tests/ui/derivable_impls.rs:22:1
|
LL | / impl std::default::Default for FooDefault<'_> {
LL | | fn default() -> Self {
@ -20,7 +20,7 @@ LL | struct FooDefault<'a> {
|
error: this `impl` can be derived
--> tests/ui/derivable_impls.rs:41:1
--> tests/ui/derivable_impls.rs:43:1
|
LL | / impl std::default::Default for TupleDefault {
LL | | fn default() -> Self {
@ -37,7 +37,7 @@ LL | struct TupleDefault(bool, i32, u64);
|
error: this `impl` can be derived
--> tests/ui/derivable_impls.rs:93:1
--> tests/ui/derivable_impls.rs:95:1
|
LL | / impl Default for StrDefault<'_> {
LL | | fn default() -> Self {
@ -54,7 +54,7 @@ LL | struct StrDefault<'a>(&'a str);
|
error: this `impl` can be derived
--> tests/ui/derivable_impls.rs:119:1
--> tests/ui/derivable_impls.rs:121:1
|
LL | / impl Default for Y {
LL | | fn default() -> Self {
@ -71,7 +71,7 @@ LL | struct Y(u32);
|
error: this `impl` can be derived
--> tests/ui/derivable_impls.rs:158:1
--> tests/ui/derivable_impls.rs:160:1
|
LL | / impl Default for WithoutSelfCurly {
LL | | fn default() -> Self {
@ -88,7 +88,7 @@ LL | struct WithoutSelfCurly {
|
error: this `impl` can be derived
--> tests/ui/derivable_impls.rs:166:1
--> tests/ui/derivable_impls.rs:168:1
|
LL | / impl Default for WithoutSelfParan {
LL | | fn default() -> Self {
@ -105,7 +105,7 @@ LL | struct WithoutSelfParan(bool);
|
error: this `impl` can be derived
--> tests/ui/derivable_impls.rs:216:1
--> tests/ui/derivable_impls.rs:218:1
|
LL | / impl Default for RepeatDefault1 {
LL | | fn default() -> Self {
@ -122,7 +122,7 @@ LL | pub struct RepeatDefault1 {
|
error: this `impl` can be derived
--> tests/ui/derivable_impls.rs:250:1
--> tests/ui/derivable_impls.rs:252:1
|
LL | / impl Default for SimpleEnum {
LL | | fn default() -> Self {

View file

@ -1,177 +0,0 @@
#![deny(clippy::index_refutable_slice)]
#![allow(clippy::uninlined_format_args)]
enum SomeEnum<T> {
One(T),
Two(T),
Three(T),
Four(T),
}
fn lintable_examples() {
// Try with reference
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some([slice_0, ..]) = slice {
//~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{}", slice_0);
}
// Try with copy
let slice: Option<[u32; 3]> = Some([1, 2, 3]);
if let Some([slice_0, ..]) = slice {
//~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{}", slice_0);
}
// Try with long slice and small indices
let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]);
if let Some([slice_0, _, slice_2, ..]) = slice {
//~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{}", slice_2);
println!("{}", slice_0);
}
// Multiple bindings
let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]);
if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {
//~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{}", slice_0);
}
// Two lintable slices in one if let
let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]);
let b_wrapped: Option<[u32; 2]> = Some([4, 6]);
if let (SomeEnum::Three([_, _, a_2, ..]), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {
//~^ ERROR: this binding can be a slice pattern to avoid indexing
//~| ERROR: this binding can be a slice pattern to avoid indexing
println!("{} -> {}", a_2, b_1);
}
// This requires the slice values to be borrowed as the slice values can only be
// borrowed and `String` doesn't implement copy
let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
if let Some([_, ref slice_1, ..]) = slice {
//~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{:?}", slice_1);
}
println!("{:?}", slice);
// This should not suggest using the `ref` keyword as the scrutinee is already
// a reference
let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
if let Some([slice_0, ..]) = &slice {
//~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{:?}", slice_0);
}
println!("{:?}", slice);
}
fn slice_index_above_limit() {
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some(slice) = slice {
// Would cause a panic, IDK
println!("{}", slice[7]);
}
}
fn slice_is_used() {
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some(slice) = slice {
println!("{:?}", slice.len());
}
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some(slice) = slice {
println!("{:?}", slice.to_vec());
}
let opt: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
if let Some(slice) = opt {
if !slice.is_empty() {
println!("first: {}", slice[0]);
}
}
}
/// The slice is used by an external function and should therefore not be linted
fn check_slice_as_arg() {
fn is_interesting<T>(slice: &[T; 2]) -> bool {
!slice.is_empty()
}
let slice_wrapped: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
if let Some(slice) = &slice_wrapped {
if is_interesting(slice) {
println!("This is interesting {}", slice[0]);
}
}
println!("{:?}", slice_wrapped);
}
fn check_slice_in_struct() {
#[derive(Debug)]
struct Wrapper<'a> {
inner: Option<&'a [String]>,
is_awesome: bool,
}
impl<'a> Wrapper<'a> {
fn is_super_awesome(&self) -> bool {
self.is_awesome
}
}
let inner = &[String::from("New"), String::from("World")];
let wrap = Wrapper {
inner: Some(inner),
is_awesome: true,
};
// Test 1: Field access
if let Some([slice_0, ..]) = wrap.inner {
//~^ ERROR: this binding can be a slice pattern to avoid indexing
if wrap.is_awesome {
println!("This is awesome! {}", slice_0);
}
}
// Test 2: function access
if let Some([slice_0, ..]) = wrap.inner {
//~^ ERROR: this binding can be a slice pattern to avoid indexing
if wrap.is_super_awesome() {
println!("This is super awesome! {}", slice_0);
}
}
println!("Complete wrap: {:?}", wrap);
}
/// This would be a nice additional feature to have in the future, but adding it
/// now would make the PR too large. This is therefore only a test that we don't
/// lint cases we can't make a reasonable suggestion for
fn mutable_slice_index() {
// Mut access
let mut slice: Option<[String; 1]> = Some([String::from("Penguin")]);
if let Some(ref mut slice) = slice {
slice[0] = String::from("Mr. Penguin");
}
println!("Use after modification: {:?}", slice);
// Mut access on reference
let mut slice: Option<[String; 1]> = Some([String::from("Cat")]);
if let Some(slice) = &mut slice {
slice[0] = String::from("Lord Meow Meow");
}
println!("Use after modification: {:?}", slice);
}
/// The lint will ignore bindings with sub patterns as it would be hard
/// to build correct suggestions for these instances :)
fn binding_with_sub_pattern() {
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some(slice @ [_, _, _]) = slice {
println!("{:?}", slice[2]);
}
}
fn main() {}

View file

@ -1,6 +1,8 @@
#![deny(clippy::index_refutable_slice)]
#![allow(clippy::uninlined_format_args)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
enum SomeEnum<T> {
One(T),
Two(T),

View file

@ -1,5 +1,5 @@
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:14:17
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:16:17
|
LL | if let Some(slice) = slice {
| ^^^^^
@ -19,7 +19,7 @@ LL | println!("{}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:21:17
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:23:17
|
LL | if let Some(slice) = slice {
| ^^^^^
@ -34,7 +34,7 @@ LL | println!("{}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:28:17
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:30:17
|
LL | if let Some(slice) = slice {
| ^^^^^
@ -50,7 +50,7 @@ LL ~ println!("{}", slice_0);
|
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:36:26
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:38:26
|
LL | if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped {
| ^^^^^
@ -65,7 +65,7 @@ LL | println!("{}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:44:29
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:46:29
|
LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
| ^
@ -80,7 +80,7 @@ LL | println!("{} -> {}", a_2, b[1]);
| ~~~
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:44:38
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:46:38
|
LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
| ^
@ -95,7 +95,7 @@ LL | println!("{} -> {}", a[2], b_1);
| ~~~
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:53:21
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:55:21
|
LL | if let Some(ref slice) = slice {
| ^^^^^
@ -110,7 +110,7 @@ LL | println!("{:?}", slice_1);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:62:17
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:64:17
|
LL | if let Some(slice) = &slice {
| ^^^^^
@ -125,7 +125,7 @@ LL | println!("{:?}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:132:17
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:134:17
|
LL | if let Some(slice) = wrap.inner {
| ^^^^^
@ -140,7 +140,7 @@ LL | println!("This is awesome! {}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:140:17
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:142:17
|
LL | if let Some(slice) = wrap.inner {
| ^^^^^

View file

@ -1,29 +0,0 @@
#![deny(clippy::index_refutable_slice)]
extern crate if_chain;
use if_chain::if_chain;
macro_rules! if_let_slice_macro {
() => {
// This would normally be linted
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some(slice) = slice {
println!("{}", slice[0]);
}
};
}
fn main() {
// Don't lint this
if_let_slice_macro!();
// Do lint this
if_chain! {
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some([slice_0, ..]) = slice;
//~^ ERROR: this binding can be a slice pattern to avoid indexing
then {
println!("{}", slice_0);
}
}
}

View file

@ -1,5 +1,7 @@
#![deny(clippy::index_refutable_slice)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
extern crate if_chain;
use if_chain::if_chain;

View file

@ -1,5 +1,5 @@
error: this binding can be a slice pattern to avoid indexing
--> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:23:21
--> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:25:21
|
LL | if let Some(slice) = slice;
| ^^^^^

View file

@ -1,196 +0,0 @@
#![warn(clippy::let_unit_value)]
#![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)]
macro_rules! let_and_return {
($n:expr) => {{
let ret = $n;
}};
}
fn main() {
println!("x");
let _y = 1; // this is fine
let _z = ((), 1); // this as well
if true {
// do not lint this, since () is explicit
let _a = ();
let () = dummy();
let () = ();
() = dummy();
() = ();
let _a: () = ();
let _a: () = dummy();
}
consume_units_with_for_loop(); // should be fine as well
multiline_sugg();
let_and_return!(()) // should be fine
}
fn dummy() {}
// Related to issue #1964
fn consume_units_with_for_loop() {
// `for_let_unit` lint should not be triggered by consuming them using for loop.
let v = vec![(), (), ()];
let mut count = 0;
for _ in v {
count += 1;
}
assert_eq!(count, 3);
// Same for consuming from some other Iterator<Item = ()>.
let (tx, rx) = ::std::sync::mpsc::channel();
tx.send(()).unwrap();
drop(tx);
count = 0;
for _ in rx.iter() {
count += 1;
}
assert_eq!(count, 1);
}
fn multiline_sugg() {
let v: Vec<u8> = vec![2];
v
.into_iter()
.map(|i| i * 2)
.filter(|i| i % 2 == 0)
.map(|_| ())
.next()
.unwrap();
}
#[derive(Copy, Clone)]
pub struct ContainsUnit(()); // should be fine
fn _returns_generic() {
fn f<T>() -> T {
unimplemented!()
}
fn f2<T, U>(_: T) -> U {
unimplemented!()
}
fn f3<T>(x: T) -> T {
x
}
fn f5<T: Default>(x: bool) -> Option<T> {
x.then(|| T::default())
}
let _: () = f();
let x: () = f();
let _: () = f2(0i32);
let x: () = f2(0i32);
let _: () = f3(());
let x: () = f3(());
fn f4<T>(mut x: Vec<T>) -> T {
x.pop().unwrap()
}
let _: () = f4(vec![()]);
let x: () = f4(vec![()]);
let _: () = {
let x = 5;
f2(x)
};
let _: () = if true { f() } else { f2(0) };
let x: () = if true { f() } else { f2(0) };
match Some(0) {
None => f2(1),
Some(0) => f(),
Some(1) => f2(3),
Some(_) => (),
};
let _: () = f5(true).unwrap();
#[allow(clippy::let_unit_value)]
{
let x = f();
let y;
let z;
match 0 {
0 => {
y = f();
z = f();
},
1 => {
println!("test");
y = f();
z = f3(());
},
_ => panic!(),
}
let x1;
let x2;
if true {
x1 = f();
x2 = x1;
} else {
x2 = f();
x1 = x2;
}
let opt;
match f5(true) {
Some(x) => opt = x,
None => panic!(),
};
#[warn(clippy::let_unit_value)]
{
let _: () = x;
let _: () = y;
let _: () = z;
let _: () = x1;
let _: () = x2;
let _: () = opt;
}
}
let () = f();
}
fn attributes() {
fn f() {}
#[allow(clippy::let_unit_value)]
let _ = f();
#[expect(clippy::let_unit_value)]
let _ = f();
}
async fn issue10433() {
let _pending: () = std::future::pending().await;
}
pub async fn issue11502(a: ()) {}
pub fn issue12594() {
fn returns_unit() {}
fn returns_result<T>(res: T) -> Result<T, ()> {
Ok(res)
}
fn actual_test() {
// create first a unit value'd value
returns_unit();
returns_result(()).unwrap();
returns_result(()).unwrap();
// make sure we replace only the first variable
let res = 1;
returns_result(res).unwrap();
}
}

View file

@ -1,6 +1,8 @@
#![warn(clippy::let_unit_value)]
#![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
macro_rules! let_and_return {
($n:expr) => {{
let ret = $n;

View file

@ -1,5 +1,5 @@
error: this let-binding has unit value
--> tests/ui/let_unit.rs:11:5
--> tests/ui/let_unit.rs:13:5
|
LL | let _x = println!("x");
| ^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `println!("x");`
@ -8,7 +8,7 @@ LL | let _x = println!("x");
= help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]`
error: this let-binding has unit value
--> tests/ui/let_unit.rs:59:5
--> tests/ui/let_unit.rs:61:5
|
LL | / let _ = v
LL | | .into_iter()
@ -31,7 +31,7 @@ LL + .unwrap();
|
error: this let-binding has unit value
--> tests/ui/let_unit.rs:108:5
--> tests/ui/let_unit.rs:110:5
|
LL | / let x = match Some(0) {
LL | | None => f2(1),
@ -52,7 +52,7 @@ LL + };
|
error: this let-binding has unit value
--> tests/ui/let_unit.rs:189:9
--> tests/ui/let_unit.rs:191:9
|
LL | let res = returns_unit();
| ^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,76 +0,0 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
#![warn(clippy::manual_assert)]
#![allow(dead_code, unused_doc_comments)]
#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)]
macro_rules! one {
() => {
1
};
}
fn main() {
let a = vec![1, 2, 3];
let c = Some(2);
if !a.is_empty()
&& a.len() == 3
&& c.is_some()
&& !a.is_empty()
&& a.len() == 3
&& !a.is_empty()
&& a.len() == 3
&& !a.is_empty()
&& a.len() == 3
{
panic!("qaqaq{:?}", a);
}
assert!(a.is_empty(), "qaqaq{:?}", a);
assert!(a.is_empty(), "qwqwq");
if a.len() == 3 {
println!("qwq");
println!("qwq");
println!("qwq");
}
if let Some(b) = c {
panic!("orz {}", b);
}
if a.len() == 3 {
panic!("qaqaq");
} else {
println!("qwq");
}
let b = vec![1, 2, 3];
assert!(!b.is_empty(), "panic1");
assert!(!(b.is_empty() && a.is_empty()), "panic2");
assert!(!(a.is_empty() && !b.is_empty()), "panic3");
assert!(!(b.is_empty() || a.is_empty()), "panic4");
assert!(!(a.is_empty() || !b.is_empty()), "panic5");
assert!(!a.is_empty(), "with expansion {}", one!());
if a.is_empty() {
let _ = 0;
} else if a.len() == 1 {
panic!("panic6");
}
}
fn issue7730(a: u8) {
// Suggestion should preserve comment
// comment
/* this is a
multiline
comment */
/// Doc comment
// comment after `panic!`
assert!(!(a > 2), "panic with comment");
}
fn issue12505() {
struct Foo<T, const N: usize>(T);
impl<T, const N: usize> Foo<T, N> {
const BAR: () = assert!(!(N == 0), );
}
}

View file

@ -1,5 +1,5 @@
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:30:5
--> tests/ui/manual_assert.rs:32:5
|
LL | / if !a.is_empty() {
LL | | panic!("qaqaq{:?}", a);
@ -10,7 +10,7 @@ LL | | }
= help: to override `-D warnings` add `#[allow(clippy::manual_assert)]`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:33:5
--> tests/ui/manual_assert.rs:35:5
|
LL | / if !a.is_empty() {
LL | | panic!("qwqwq");
@ -18,7 +18,7 @@ LL | | }
| |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:50:5
--> tests/ui/manual_assert.rs:52:5
|
LL | / if b.is_empty() {
LL | | panic!("panic1");
@ -26,7 +26,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:53:5
--> tests/ui/manual_assert.rs:55:5
|
LL | / if b.is_empty() && a.is_empty() {
LL | | panic!("panic2");
@ -34,7 +34,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:56:5
--> tests/ui/manual_assert.rs:58:5
|
LL | / if a.is_empty() && !b.is_empty() {
LL | | panic!("panic3");
@ -42,7 +42,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:59:5
--> tests/ui/manual_assert.rs:61:5
|
LL | / if b.is_empty() || a.is_empty() {
LL | | panic!("panic4");
@ -50,7 +50,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:62:5
--> tests/ui/manual_assert.rs:64:5
|
LL | / if a.is_empty() || !b.is_empty() {
LL | | panic!("panic5");
@ -58,7 +58,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:65:5
--> tests/ui/manual_assert.rs:67:5
|
LL | / if a.is_empty() {
LL | | panic!("with expansion {}", one!())
@ -66,7 +66,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:77:5
--> tests/ui/manual_assert.rs:79:5
|
LL | / if a > 2 {
LL | | // comment
@ -83,7 +83,7 @@ LL | assert!(!(a > 2), "panic with comment");
|
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:91:25
--> tests/ui/manual_assert.rs:93:25
|
LL | const BAR: () = if N == 0 {
| _________________________^

View file

@ -1,76 +0,0 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
#![warn(clippy::manual_assert)]
#![allow(dead_code, unused_doc_comments)]
#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)]
macro_rules! one {
() => {
1
};
}
fn main() {
let a = vec![1, 2, 3];
let c = Some(2);
if !a.is_empty()
&& a.len() == 3
&& c.is_some()
&& !a.is_empty()
&& a.len() == 3
&& !a.is_empty()
&& a.len() == 3
&& !a.is_empty()
&& a.len() == 3
{
panic!("qaqaq{:?}", a);
}
assert!(a.is_empty(), "qaqaq{:?}", a);
assert!(a.is_empty(), "qwqwq");
if a.len() == 3 {
println!("qwq");
println!("qwq");
println!("qwq");
}
if let Some(b) = c {
panic!("orz {}", b);
}
if a.len() == 3 {
panic!("qaqaq");
} else {
println!("qwq");
}
let b = vec![1, 2, 3];
assert!(!b.is_empty(), "panic1");
assert!(!(b.is_empty() && a.is_empty()), "panic2");
assert!(!(a.is_empty() && !b.is_empty()), "panic3");
assert!(!(b.is_empty() || a.is_empty()), "panic4");
assert!(!(a.is_empty() || !b.is_empty()), "panic5");
assert!(!a.is_empty(), "with expansion {}", one!());
if a.is_empty() {
let _ = 0;
} else if a.len() == 1 {
panic!("panic6");
}
}
fn issue7730(a: u8) {
// Suggestion should preserve comment
// comment
/* this is a
multiline
comment */
/// Doc comment
// comment after `panic!`
assert!(!(a > 2), "panic with comment");
}
fn issue12505() {
struct Foo<T, const N: usize>(T);
impl<T, const N: usize> Foo<T, N> {
const BAR: () = assert!(!(N == 0), );
}
}

View file

@ -1,5 +1,5 @@
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:30:5
--> tests/ui/manual_assert.rs:32:5
|
LL | / if !a.is_empty() {
LL | | panic!("qaqaq{:?}", a);
@ -10,7 +10,7 @@ LL | | }
= help: to override `-D warnings` add `#[allow(clippy::manual_assert)]`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:33:5
--> tests/ui/manual_assert.rs:35:5
|
LL | / if !a.is_empty() {
LL | | panic!("qwqwq");
@ -18,7 +18,7 @@ LL | | }
| |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:50:5
--> tests/ui/manual_assert.rs:52:5
|
LL | / if b.is_empty() {
LL | | panic!("panic1");
@ -26,7 +26,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:53:5
--> tests/ui/manual_assert.rs:55:5
|
LL | / if b.is_empty() && a.is_empty() {
LL | | panic!("panic2");
@ -34,7 +34,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:56:5
--> tests/ui/manual_assert.rs:58:5
|
LL | / if a.is_empty() && !b.is_empty() {
LL | | panic!("panic3");
@ -42,7 +42,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:59:5
--> tests/ui/manual_assert.rs:61:5
|
LL | / if b.is_empty() || a.is_empty() {
LL | | panic!("panic4");
@ -50,7 +50,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:62:5
--> tests/ui/manual_assert.rs:64:5
|
LL | / if a.is_empty() || !b.is_empty() {
LL | | panic!("panic5");
@ -58,7 +58,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:65:5
--> tests/ui/manual_assert.rs:67:5
|
LL | / if a.is_empty() {
LL | | panic!("with expansion {}", one!())
@ -66,7 +66,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());`
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:77:5
--> tests/ui/manual_assert.rs:79:5
|
LL | / if a > 2 {
LL | | // comment
@ -83,7 +83,7 @@ LL | assert!(!(a > 2), "panic with comment");
|
error: only a `panic!` in `if`-then statement
--> tests/ui/manual_assert.rs:91:25
--> tests/ui/manual_assert.rs:93:25
|
LL | const BAR: () = if N == 0 {
| _________________________^

View file

@ -2,6 +2,8 @@
//@[edition2018] edition:2018
//@[edition2021] edition:2021
//@no-rustfix: need to change the suggestion to a multipart suggestion
#![warn(clippy::manual_assert)]
#![allow(dead_code, unused_doc_comments)]
#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)]

View file

@ -1,115 +0,0 @@
#![warn(clippy::manual_async_fn)]
#![allow(clippy::needless_pub_self, unused)]
use std::future::Future;
async fn fut() -> i32 { 42 }
#[rustfmt::skip]
async fn fut2() -> i32 { 42 }
#[rustfmt::skip]
async fn fut3() -> i32 { 42 }
async fn empty_fut() {}
#[rustfmt::skip]
async fn empty_fut2() {}
#[rustfmt::skip]
async fn empty_fut3() {}
async fn core_fut() -> i32 { 42 }
// should be ignored
fn has_other_stmts() -> impl core::future::Future<Output = i32> {
let _ = 42;
async move { 42 }
}
// should be ignored
fn not_fut() -> i32 {
42
}
// should be ignored
async fn already_async() -> impl Future<Output = i32> {
async { 42 }
}
struct S;
impl S {
async fn inh_fut() -> i32 {
// NOTE: this code is here just to check that the indentation is correct in the suggested fix
let a = 42;
let b = 21;
if a < b {
let c = 21;
let d = 42;
if c < d {
let _ = 42;
}
}
42
}
// should be ignored
fn not_fut(&self) -> i32 {
42
}
// should be ignored
fn has_other_stmts() -> impl core::future::Future<Output = i32> {
let _ = 42;
async move { 42 }
}
// should be ignored
async fn already_async(&self) -> impl Future<Output = i32> {
async { 42 }
}
}
// Tests related to lifetime capture
async fn elided(_: &i32) -> i32 { 42 }
// should be ignored
fn elided_not_bound(_: &i32) -> impl Future<Output = i32> {
async { 42 }
}
async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }
// should be ignored
#[allow(clippy::needless_lifetimes)]
fn explicit_not_bound<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> {
async { 42 }
}
// should be ignored
mod issue_5765 {
use std::future::Future;
struct A;
impl A {
fn f(&self) -> impl Future<Output = ()> {
async {}
}
}
fn test() {
let _future = {
let a = A;
a.f()
};
}
}
pub async fn issue_10450() -> i32 { 42 }
pub(crate) async fn issue_10450_2() -> i32 { 42 }
pub(self) async fn issue_10450_3() -> i32 { 42 }
fn main() {}

View file

@ -1,6 +1,8 @@
#![warn(clippy::manual_async_fn)]
#![allow(clippy::needless_pub_self, unused)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
use std::future::Future;
fn fut() -> impl Future<Output = i32> {

View file

@ -1,5 +1,5 @@
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:6:1
--> tests/ui/manual_async_fn.rs:8:1
|
LL | fn fut() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -16,7 +16,7 @@ LL | fn fut() -> impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:11:1
--> tests/ui/manual_async_fn.rs:13:1
|
LL | fn fut2() ->impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -31,7 +31,7 @@ LL | fn fut2() ->impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:16:1
--> tests/ui/manual_async_fn.rs:18:1
|
LL | fn fut3()-> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -46,7 +46,7 @@ LL | fn fut3()-> impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:20:1
--> tests/ui/manual_async_fn.rs:22:1
|
LL | fn empty_fut() -> impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -61,7 +61,7 @@ LL | fn empty_fut() -> impl Future<Output = ()> {}
| ~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:25:1
--> tests/ui/manual_async_fn.rs:27:1
|
LL | fn empty_fut2() ->impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -76,7 +76,7 @@ LL | fn empty_fut2() ->impl Future<Output = ()> {}
| ~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:30:1
--> tests/ui/manual_async_fn.rs:32:1
|
LL | fn empty_fut3()-> impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -91,7 +91,7 @@ LL | fn empty_fut3()-> impl Future<Output = ()> {}
| ~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:34:1
--> tests/ui/manual_async_fn.rs:36:1
|
LL | fn core_fut() -> impl core::future::Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -106,7 +106,7 @@ LL | fn core_fut() -> impl core::future::Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:56:5
--> tests/ui/manual_async_fn.rs:58:5
|
LL | fn inh_fut() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -133,7 +133,7 @@ LL + }
|
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:91:1
--> tests/ui/manual_async_fn.rs:93:1
|
LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -148,7 +148,7 @@ LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:100:1
--> tests/ui/manual_async_fn.rs:102:1
|
LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -163,7 +163,7 @@ LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> +
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:129:1
--> tests/ui/manual_async_fn.rs:131:1
|
LL | pub fn issue_10450() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -178,7 +178,7 @@ LL | pub fn issue_10450() -> impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:133:1
--> tests/ui/manual_async_fn.rs:135:1
|
LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -193,7 +193,7 @@ LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
--> tests/ui/manual_async_fn.rs:137:1
--> tests/ui/manual_async_fn.rs:139:1
|
LL | pub(self) fn issue_10450_3() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,144 +0,0 @@
#![warn(clippy::manual_split_once)]
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
extern crate itertools;
#[allow(unused_imports)]
use itertools::Itertools;
fn main() {
let _ = "key=value".splitn(2, '=').nth(2);
let _ = "key=value".split_once('=').unwrap().1;
let _ = "key=value".split_once('=').unwrap().1;
let (_, _) = "key=value".split_once('=').unwrap();
let s = String::from("key=value");
let _ = s.split_once('=').unwrap().1;
let s = Box::<str>::from("key=value");
let _ = s.split_once('=').unwrap().1;
let s = &"key=value";
let _ = s.split_once('=').unwrap().1;
fn _f(s: &str) -> Option<&str> {
let _ = s.split_once('=')?.1;
let _ = s.split_once('=')?.1;
let _ = s.rsplit_once('=')?.0;
let _ = s.rsplit_once('=')?.0;
None
}
// Don't lint, slices don't have `split_once`
let _ = [0, 1, 2].splitn(2, |&x| x == 1).nth(1).unwrap();
// `rsplitn` gives the results in the reverse order of `rsplit_once`
let _ = "key=value".rsplit_once('=').unwrap().0;
let (_, _) = "key=value".rsplit_once('=').map(|(x, y)| (y, x)).unwrap();
let _ = s.rsplit_once('=').map(|x| x.0);
}
fn indirect() -> Option<()> {
let (l, r) = "a.b.c".split_once('.').unwrap();
let (l, r) = "a.b.c".split_once('.')?;
let (l, r) = "a.b.c".rsplit_once('.').unwrap();
let (l, r) = "a.b.c".rsplit_once('.')?;
// could lint, currently doesn't
let mut iter = "a.b.c".splitn(2, '.');
let other = 1;
let l = iter.next()?;
let r = iter.next()?;
let mut iter = "a.b.c".splitn(2, '.');
let mut mut_binding = iter.next()?;
let r = iter.next()?;
let mut iter = "a.b.c".splitn(2, '.');
let tuple = (iter.next()?, iter.next()?);
// should not lint
let mut missing_unwrap = "a.b.c".splitn(2, '.');
let l = missing_unwrap.next();
let r = missing_unwrap.next();
let mut mixed_unrap = "a.b.c".splitn(2, '.');
let unwrap = mixed_unrap.next().unwrap();
let question_mark = mixed_unrap.next()?;
let mut iter = "a.b.c".splitn(2, '.');
let same_name = iter.next()?;
let same_name = iter.next()?;
let mut iter = "a.b.c".splitn(2, '.');
let shadows_existing = "d";
let shadows_existing = iter.next()?;
let r = iter.next()?;
let mut iter = "a.b.c".splitn(2, '.');
let becomes_shadowed = iter.next()?;
let becomes_shadowed = "d";
let r = iter.next()?;
let mut iter = "a.b.c".splitn(2, '.');
let l = iter.next()?;
let r = iter.next()?;
let third_usage = iter.next()?;
let mut n_three = "a.b.c".splitn(3, '.');
let l = n_three.next()?;
let r = n_three.next()?;
let mut iter = "a.b.c".splitn(2, '.');
{
let in_block = iter.next()?;
}
let r = iter.next()?;
let mut lacks_binding = "a.b.c".splitn(2, '.');
let _ = lacks_binding.next()?;
let r = lacks_binding.next()?;
let mut mapped = "a.b.c".splitn(2, '.').map(|_| "~");
let l = iter.next()?;
let r = iter.next()?;
let mut assigned = "";
let mut iter = "a.b.c".splitn(2, '.');
let l = iter.next()?;
assigned = iter.next()?;
None
}
#[clippy::msrv = "1.51"]
fn _msrv_1_51() {
// `str::split_once` was stabilized in 1.52. Do not lint this
let _ = "key=value".splitn(2, '=').nth(1).unwrap();
let mut iter = "a.b.c".splitn(2, '.');
let a = iter.next().unwrap();
let b = iter.next().unwrap();
}
#[clippy::msrv = "1.52"]
fn _msrv_1_52() {
let _ = "key=value".split_once('=').unwrap().1;
let (a, b) = "a.b.c".split_once('.').unwrap();
}

View file

@ -1,6 +1,8 @@
#![warn(clippy::manual_split_once)]
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
extern crate itertools;
#[allow(unused_imports)]

View file

@ -1,5 +1,5 @@
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:11:13
--> tests/ui/manual_split_once.rs:13:13
|
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
@ -8,79 +8,79 @@ LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
= help: to override `-D warnings` add `#[allow(clippy::manual_split_once)]`
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:12:13
--> tests/ui/manual_split_once.rs:14:13
|
LL | let _ = "key=value".splitn(2, '=').skip(1).next().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:13:18
--> tests/ui/manual_split_once.rs:15:18
|
LL | let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=')`
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:16:13
--> tests/ui/manual_split_once.rs:18:13
|
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:19:13
--> tests/ui/manual_split_once.rs:21:13
|
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:22:13
--> tests/ui/manual_split_once.rs:24:13
|
LL | let _ = s.splitn(2, '=').skip(1).next().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:25:17
--> tests/ui/manual_split_once.rs:27:17
|
LL | let _ = s.splitn(2, '=').nth(1)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:26:17
--> tests/ui/manual_split_once.rs:28:17
|
LL | let _ = s.splitn(2, '=').skip(1).next()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
error: manual implementation of `rsplit_once`
--> tests/ui/manual_split_once.rs:27:17
--> tests/ui/manual_split_once.rs:29:17
|
LL | let _ = s.rsplitn(2, '=').nth(1)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
error: manual implementation of `rsplit_once`
--> tests/ui/manual_split_once.rs:28:17
--> tests/ui/manual_split_once.rs:30:17
|
LL | let _ = s.rsplitn(2, '=').skip(1).next()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
error: manual implementation of `rsplit_once`
--> tests/ui/manual_split_once.rs:36:13
--> tests/ui/manual_split_once.rs:38:13
|
LL | let _ = "key=value".rsplitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').unwrap().0`
error: manual implementation of `rsplit_once`
--> tests/ui/manual_split_once.rs:37:18
--> tests/ui/manual_split_once.rs:39:18
|
LL | let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))`
error: manual implementation of `rsplit_once`
--> tests/ui/manual_split_once.rs:38:13
--> tests/ui/manual_split_once.rs:40:13
|
LL | let _ = s.rsplitn(2, '=').nth(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=').map(|x| x.0)`
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:42:5
--> tests/ui/manual_split_once.rs:44:5
|
LL | let mut iter = "a.b.c".splitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -103,7 +103,7 @@ LL - let r = iter.next().unwrap();
|
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:46:5
--> tests/ui/manual_split_once.rs:48:5
|
LL | let mut iter = "a.b.c".splitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -126,7 +126,7 @@ LL - let r = iter.next()?;
|
error: manual implementation of `rsplit_once`
--> tests/ui/manual_split_once.rs:50:5
--> tests/ui/manual_split_once.rs:52:5
|
LL | let mut iter = "a.b.c".rsplitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -149,7 +149,7 @@ LL - let l = iter.next().unwrap();
|
error: manual implementation of `rsplit_once`
--> tests/ui/manual_split_once.rs:54:5
--> tests/ui/manual_split_once.rs:56:5
|
LL | let mut iter = "a.b.c".rsplitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -172,13 +172,13 @@ LL - let l = iter.next()?;
|
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:139:13
--> tests/ui/manual_split_once.rs:141:13
|
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
error: manual implementation of `split_once`
--> tests/ui/manual_split_once.rs:141:5
--> tests/ui/manual_split_once.rs:143:5
|
LL | let mut iter = "a.b.c".splitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,258 +0,0 @@
#![warn(clippy::match_same_arms)]
#![allow(
clippy::disallowed_names,
clippy::diverging_sub_expression,
clippy::uninlined_format_args,
clippy::match_single_binding,
clippy::match_like_matches_macro
)]
fn bar<T>(_: T) {}
fn foo() -> bool {
unimplemented!()
}
fn match_same_arms() {
let _ = match 42 {
_ => {
foo();
let mut a = 42 + [23].len() as i32;
if true {
a += 7;
}
a = -31 - a;
a
},
};
//~^^^^^^^^^^^^^^^^^^^ ERROR: this match arm has an identical body to the `_` wildcard arm
let _ = match 42 {
51 | 42 => foo(), //~ ERROR: this match arm has an identical body to another arm
_ => true,
};
let _ = match Some(42) {
None | Some(_) => 24, //~ ERROR: this match arm has an identical body to another arm
};
let _ = match Some(42) {
Some(foo) => 24,
None => 24,
};
let _ = match Some(42) {
Some(42) => 24,
Some(a) => 24, // bindings are different
None => 0,
};
let _ = match Some(42) {
Some(a) if a > 0 => 24,
Some(a) => 24, // one arm has a guard
None => 0,
};
match (Some(42), Some(42)) {
(None, Some(a)) | (Some(a), None) => bar(a), //~ ERROR: this match arm has an identical body to another arm
_ => (),
}
// No warning because guards are different
let _ = match Some(42) {
Some(a) if a == 42 => a,
Some(a) if a == 24 => a,
Some(_) => 24,
None => 0,
};
let _ = match (Some(42), Some(42)) {
(None, Some(a)) | (Some(a), None) if a == 42 => a, //~ ERROR: this match arm has an identical body to another arm
_ => 0,
};
match (Some(42), Some(42)) {
(Some(a), ..) | (.., Some(a)) => bar(a), //~ ERROR: this match arm has an identical body to another arm
_ => (),
}
let _ = match Some(()) {
Some(()) => 0.0,
None => -0.0,
};
match (Some(42), Some("")) {
(Some(a), None) => bar(a),
(None, Some(a)) => bar(a), // bindings have different types
_ => (),
}
let x: Result<i32, &str> = Ok(3);
// No warning because of the guard.
match x {
Ok(x) if x * x == 64 => println!("ok"),
Ok(_) => println!("ok"),
Err(_) => println!("err"),
}
// This used to be a false positive; see issue #1996.
match x {
Ok(3) => println!("ok"),
Ok(x) if x * x == 64 => println!("ok 64"),
Ok(_) => println!("ok"),
Err(_) => println!("err"),
}
match (x, Some(1i32)) {
(Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), //~ ERROR: this match arm has an identical body to another arm
_ => println!("err"),
}
// No warning; different types for `x`.
match (x, Some(1.0f64)) {
(Ok(x), Some(_)) => println!("ok {}", x),
(Ok(_), Some(x)) => println!("ok {}", x),
_ => println!("err"),
}
// False negative #2251.
match x {
Ok(_tmp) => println!("ok"),
Ok(_) | Ok(3) => println!("ok"), //~ ERROR: this match arm has an identical body to another arm
Err(_) => {
unreachable!();
},
}
// False positive #1390
macro_rules! empty {
($e:expr) => {};
}
match 0 {
0 => {
empty!(0);
},
1 => {
empty!(1);
},
x => {
empty!(x);
},
};
// still lint if the tokens are the same
match 0 {
1 | 0 => {
empty!(0);
},
x => {
empty!(x);
},
}
//~^^^^^^^ ERROR: this match arm has an identical body to another arm
match_expr_like_matches_macro_priority();
}
fn match_expr_like_matches_macro_priority() {
enum E {
A,
B,
C,
}
let x = E::A;
let _ans = match x {
E::A => false,
E::B => false,
_ => true,
};
}
fn main() {
let _ = match Some(0) {
Some(0) => 0,
Some(1) => 1,
#[cfg(feature = "foo")]
Some(2) => 2,
_ => 1,
};
enum Foo {
X(u32),
Y(u32),
Z(u32),
}
// Don't lint. `Foo::X(0)` and `Foo::Z(_)` overlap with the arm in between.
let _ = match Foo::X(0) {
Foo::X(0) => 1,
Foo::X(_) | Foo::Y(_) | Foo::Z(0) => 2,
Foo::Z(_) => 1,
_ => 0,
};
// Suggest moving `Foo::Z(_)` up.
let _ = match Foo::X(0) {
Foo::X(0) | Foo::Z(_) => 1, //~ ERROR: this match arm has an identical body to another arm
Foo::X(_) | Foo::Y(_) => 2,
_ => 0,
};
// Suggest moving `Foo::X(0)` down.
let _ = match Foo::X(0) {
Foo::Y(_) | Foo::Z(0) => 2,
Foo::Z(_) | Foo::X(0) => 1, //~ ERROR: this match arm has an identical body to another arm
_ => 0,
};
// Don't lint.
let _ = match 0 {
-2 => 1,
-5..=50 => 2,
-150..=88 => 1,
_ => 3,
};
struct Bar {
x: u32,
y: u32,
z: u32,
}
// Lint.
let _ = match None {
Some(Bar { y: 10, z: 0, .. }) => 2,
None => 50,
Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, //~ ERROR: this match arm has an identical body to another arm
_ => 200,
};
let _ = match 0 {
0 => todo!(),
1 => todo!(),
2 => core::convert::identity::<u32>(todo!()),
3 => core::convert::identity::<u32>(todo!()),
_ => 5,
};
let _ = match 0 {
1 | 0 => cfg!(not_enable),
_ => false,
};
}
// issue #8919, fixed on https://github.com/rust-lang/rust/pull/97312
mod with_lifetime {
enum MaybeStaticStr<'a> {
Static(&'static str),
Borrowed(&'a str),
}
impl<'a> MaybeStaticStr<'a> {
fn get(&self) -> &'a str {
match *self {
MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s,
//~^ ERROR: this match arm has an identical body to another arm
}
}
}
}

View file

@ -6,6 +6,9 @@
clippy::match_single_binding,
clippy::match_like_matches_macro
)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
fn bar<T>(_: T) {}
fn foo() -> bool {
unimplemented!()

View file

@ -1,5 +1,5 @@
error: this match arm has an identical body to the `_` wildcard arm
--> tests/ui/match_same_arms2.rs:16:9
--> tests/ui/match_same_arms2.rs:19:9
|
LL | / 42 => {
LL | | foo();
@ -12,7 +12,7 @@ LL | | _ => {
|
= help: or try changing either arm body
note: `_` wildcard arm here
--> tests/ui/match_same_arms2.rs:25:9
--> tests/ui/match_same_arms2.rs:28:9
|
LL | / _ => {
LL | | foo();
@ -26,7 +26,7 @@ LL | | },
= help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:39:9
--> tests/ui/match_same_arms2.rs:42:9
|
LL | 51 => foo(),
| ^^^^^^^^^^^
@ -42,7 +42,7 @@ LL - 42 => foo(),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:45:9
--> tests/ui/match_same_arms2.rs:48:9
|
LL | None => 24,
| ^^^^^^^^^^
@ -58,7 +58,7 @@ LL - Some(_) => 24,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:67:9
--> tests/ui/match_same_arms2.rs:70:9
|
LL | (None, Some(a)) => bar(a),
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@ -74,7 +74,7 @@ LL - (Some(a), None) => bar(a),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:81:9
--> tests/ui/match_same_arms2.rs:84:9
|
LL | (None, Some(a)) if a == 42 => a,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -90,7 +90,7 @@ LL - (Some(a), None) if a == 42 => a,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:86:9
--> tests/ui/match_same_arms2.rs:89:9
|
LL | (Some(a), ..) => bar(a),
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -106,7 +106,7 @@ LL - (.., Some(a)) => bar(a),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:120:9
--> tests/ui/match_same_arms2.rs:123:9
|
LL | (Ok(x), Some(_)) => println!("ok {}", x),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -122,7 +122,7 @@ LL - (Ok(_), Some(x)) => println!("ok {}", x),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:136:9
--> tests/ui/match_same_arms2.rs:139:9
|
LL | Ok(_) => println!("ok"),
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -138,7 +138,7 @@ LL - Ok(3) => println!("ok"),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:163:9
--> tests/ui/match_same_arms2.rs:166:9
|
LL | / 1 => {
LL | | empty!(0);
@ -158,7 +158,7 @@ LL - },
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:214:9
--> tests/ui/match_same_arms2.rs:217:9
|
LL | Foo::X(0) => 1,
| ^^^^^^^^^^^^^^
@ -174,7 +174,7 @@ LL - Foo::Z(_) => 1,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:224:9
--> tests/ui/match_same_arms2.rs:227:9
|
LL | Foo::Z(_) => 1,
| ^^^^^^^^^^^^^^
@ -190,7 +190,7 @@ LL - Foo::X(0) => 1,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:247:9
--> tests/ui/match_same_arms2.rs:250:9
|
LL | Some(Bar { y: 0, x: 5, .. }) => 1,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -206,7 +206,7 @@ LL - Some(Bar { x: 0, y: 5, .. }) => 1,
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:261:9
--> tests/ui/match_same_arms2.rs:264:9
|
LL | 1 => cfg!(not_enable),
| ^^^^^^^^^^^^^^^^^^^^^
@ -222,7 +222,7 @@ LL - 0 => cfg!(not_enable),
|
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:277:17
--> tests/ui/match_same_arms2.rs:280:17
|
LL | MaybeStaticStr::Borrowed(s) => s,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,144 +0,0 @@
#![warn(clippy::significant_drop_tightening)]
use std::sync::Mutex;
pub fn complex_return_triggers_the_lint() -> i32 {
fn foo() -> i32 {
1
}
let mutex = Mutex::new(1);
let lock = mutex.lock().unwrap();
let _ = *lock;
let _ = *lock;
drop(lock);
foo()
}
pub fn issue_10413() {
let mutex = Mutex::new(Some(1));
let opt = Some(1);
if opt.is_some() {
let lock = mutex.lock().unwrap();
let _ = *lock;
if opt.is_some() {
let _ = *lock;
}
}
}
pub fn issue_11128() {
use std::mem::drop as unlock;
struct Foo {
droppable: Option<Vec<i32>>,
mutex: Mutex<Vec<i32>>,
}
impl Drop for Foo {
fn drop(&mut self) {
if let Some(droppable) = self.droppable.take() {
let lock = self.mutex.lock().unwrap();
let idx_opt = lock.iter().copied().find(|el| Some(el) == droppable.first());
if let Some(idx) = idx_opt {
let local_droppable = vec![lock.first().copied().unwrap_or_default()];
unlock(lock);
drop(local_droppable);
}
}
}
}
}
pub fn issue_11160() -> bool {
let mutex = Mutex::new(1i32);
let lock = mutex.lock().unwrap();
let _ = lock.abs();
true
}
pub fn issue_11189() {
struct Number {
pub value: u32,
}
fn do_something() -> Result<(), ()> {
let number = Mutex::new(Number { value: 1 });
let number2 = Mutex::new(Number { value: 2 });
let number3 = Mutex::new(Number { value: 3 });
let mut lock = number.lock().unwrap();
let mut lock2 = number2.lock().unwrap();
let mut lock3 = number3.lock().unwrap();
lock.value += 1;
lock2.value += 1;
lock3.value += 1;
drop((lock, lock2, lock3));
Ok(())
}
}
pub fn path_return_can_be_ignored() -> i32 {
let mutex = Mutex::new(1);
let lock = mutex.lock().unwrap();
let rslt = *lock;
let _ = *lock;
rslt
}
pub fn post_bindings_can_be_ignored() {
let mutex = Mutex::new(1);
let lock = mutex.lock().unwrap();
let rslt = *lock;
let another = rslt;
let _ = another;
}
pub fn unnecessary_contention_with_multiple_owned_results() {
{
let mutex = Mutex::new(1i32);
let lock = mutex.lock().unwrap();
let _ = lock.abs();
let _ = lock.is_positive();
}
{
let mutex = Mutex::new(1i32);
let lock = mutex.lock().unwrap();
let rslt0 = lock.abs();
let rslt1 = lock.is_positive();
drop(lock);
do_heavy_computation_that_takes_time((rslt0, rslt1));
}
}
pub fn unnecessary_contention_with_single_owned_results() {
{
let mutex = Mutex::new(1i32);
let lock = mutex.lock().unwrap();
let _ = lock.abs();
}
{
let mutex = Mutex::new(vec![1i32]);
let mut lock = mutex.lock().unwrap();
lock.clear();
}
{
let mutex = Mutex::new(1i32);
let rslt0 = mutex.lock().unwrap().abs();
do_heavy_computation_that_takes_time(rslt0);
}
{
let mutex = Mutex::new(vec![1i32]);
mutex.lock().unwrap().clear();
do_heavy_computation_that_takes_time(());
}
}
// Marker used for illustration purposes.
pub fn do_heavy_computation_that_takes_time<T>(_: T) {}
fn main() {}

View file

@ -1,5 +1,7 @@
#![warn(clippy::significant_drop_tightening)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
use std::sync::Mutex;
pub fn complex_return_triggers_the_lint() -> i32 {

View file

@ -1,5 +1,5 @@
error: temporary with significant `Drop` can be early dropped
--> tests/ui/significant_drop_tightening.rs:10:9
--> tests/ui/significant_drop_tightening.rs:12:9
|
LL | pub fn complex_return_triggers_the_lint() -> i32 {
| __________________________________________________-
@ -24,7 +24,7 @@ LL + drop(lock);
|
error: temporary with significant `Drop` can be early dropped
--> tests/ui/significant_drop_tightening.rs:104:13
--> tests/ui/significant_drop_tightening.rs:106:13
|
LL | / {
LL | | let mutex = Mutex::new(1i32);
@ -44,7 +44,7 @@ LL + drop(lock);
|
error: temporary with significant `Drop` can be early dropped
--> tests/ui/significant_drop_tightening.rs:125:13
--> tests/ui/significant_drop_tightening.rs:127:13
|
LL | / {
LL | | let mutex = Mutex::new(1i32);
@ -67,7 +67,7 @@ LL - let rslt0 = lock.abs();
|
error: temporary with significant `Drop` can be early dropped
--> tests/ui/significant_drop_tightening.rs:131:17
--> tests/ui/significant_drop_tightening.rs:133:17
|
LL | / {
LL | | let mutex = Mutex::new(vec![1i32]);

View file

@ -1,201 +0,0 @@
#![allow(unused_assignments)]
#![warn(clippy::unnecessary_to_owned)]
#[allow(dead_code)]
#[derive(Clone, Copy)]
enum FileType {
Account,
PrivateKey,
Certificate,
}
fn main() {
let path = std::path::Path::new("x");
let _ = check_files(&[(FileType::Account, path)]);
let _ = check_files_vec(vec![(FileType::Account, path)]);
// negative tests
let _ = check_files_ref(&[(FileType::Account, path)]);
let _ = check_files_mut(&[(FileType::Account, path)]);
let _ = check_files_ref_mut(&[(FileType::Account, path)]);
let _ = check_files_self_and_arg(&[(FileType::Account, path)]);
let _ = check_files_mut_path_buf(&[(FileType::Account, std::path::PathBuf::new())]);
check_mut_iteratee_and_modify_inner_variable();
}
// `check_files` and its variants are based on:
// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262
fn check_files(files: &[(FileType, &std::path::Path)]) -> bool {
for (t, path) in files {
let other = match get_file_path(t) {
Ok(p) => p,
Err(_) => {
return false;
},
};
if !path.is_file() || !other.is_file() {
return false;
}
}
true
}
fn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool {
for (t, path) in files.iter() {
let other = match get_file_path(t) {
Ok(p) => p,
Err(_) => {
return false;
},
};
if !path.is_file() || !other.is_file() {
return false;
}
}
true
}
fn check_files_ref(files: &[(FileType, &std::path::Path)]) -> bool {
for (ref t, path) in files.iter().copied() {
let other = match get_file_path(t) {
Ok(p) => p,
Err(_) => {
return false;
},
};
if !path.is_file() || !other.is_file() {
return false;
}
}
true
}
#[allow(unused_assignments)]
fn check_files_mut(files: &[(FileType, &std::path::Path)]) -> bool {
for (mut t, path) in files.iter().copied() {
t = FileType::PrivateKey;
let other = match get_file_path(&t) {
Ok(p) => p,
Err(_) => {
return false;
},
};
if !path.is_file() || !other.is_file() {
return false;
}
}
true
}
fn check_files_ref_mut(files: &[(FileType, &std::path::Path)]) -> bool {
for (ref mut t, path) in files.iter().copied() {
*t = FileType::PrivateKey;
let other = match get_file_path(t) {
Ok(p) => p,
Err(_) => {
return false;
},
};
if !path.is_file() || !other.is_file() {
return false;
}
}
true
}
fn check_files_self_and_arg(files: &[(FileType, &std::path::Path)]) -> bool {
for (t, path) in files.iter().copied() {
let other = match get_file_path(&t) {
Ok(p) => p,
Err(_) => {
return false;
},
};
if !path.join(path).is_file() || !other.is_file() {
return false;
}
}
true
}
#[allow(unused_assignments)]
fn check_files_mut_path_buf(files: &[(FileType, std::path::PathBuf)]) -> bool {
for (mut t, path) in files.iter().cloned() {
t = FileType::PrivateKey;
let other = match get_file_path(&t) {
Ok(p) => p,
Err(_) => {
return false;
},
};
if !path.is_file() || !other.is_file() {
return false;
}
}
true
}
fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {
Ok(std::path::PathBuf::new())
}
// Issue 12098
// https://github.com/rust-lang/rust-clippy/issues/12098
// no message emits
fn check_mut_iteratee_and_modify_inner_variable() {
struct Test {
list: Vec<String>,
mut_this: bool,
}
impl Test {
fn list(&self) -> &[String] {
&self.list
}
}
let mut test = Test {
list: vec![String::from("foo"), String::from("bar")],
mut_this: false,
};
for _item in test.list().to_vec() {
println!("{}", _item);
test.mut_this = true;
{
test.mut_this = true;
}
}
}
mod issue_12821 {
fn foo() {
let v: Vec<_> = "hello".chars().collect();
for c in v.iter() {
//~^ ERROR: unnecessary use of `cloned`
println!("{c}"); // should not suggest to remove `&`
}
}
fn bar() {
let v: Vec<_> = "hello".chars().collect();
for c in v.iter() {
//~^ ERROR: unnecessary use of `cloned`
let ref_c = c; //~ HELP: remove any references to the binding
println!("{ref_c}");
}
}
fn baz() {
let v: Vec<_> = "hello".chars().enumerate().collect();
for (i, c) in v.iter() {
//~^ ERROR: unnecessary use of `cloned`
let ref_c = c; //~ HELP: remove any references to the binding
let ref_i = i;
println!("{i} {ref_c}"); // should not suggest to remove `&` from `i`
}
}
}

View file

@ -1,6 +1,8 @@
#![allow(unused_assignments)]
#![warn(clippy::unnecessary_to_owned)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
#[allow(dead_code)]
#[derive(Clone, Copy)]
enum FileType {

View file

@ -1,5 +1,5 @@
error: unnecessary use of `copied`
--> tests/ui/unnecessary_iter_cloned.rs:31:22
--> tests/ui/unnecessary_iter_cloned.rs:33:22
|
LL | for (t, path) in files.iter().copied() {
| ^^^^^^^^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ LL + let other = match get_file_path(t) {
|
error: unnecessary use of `copied`
--> tests/ui/unnecessary_iter_cloned.rs:46:22
--> tests/ui/unnecessary_iter_cloned.rs:48:22
|
LL | for (t, path) in files.iter().copied() {
| ^^^^^^^^^^^^^^^^^^^^^
@ -33,13 +33,13 @@ LL + let other = match get_file_path(t) {
|
error: unnecessary use of `cloned`
--> tests/ui/unnecessary_iter_cloned.rs:177:18
--> tests/ui/unnecessary_iter_cloned.rs:179:18
|
LL | for c in v.iter().cloned() {
| ^^^^^^^^^^^^^^^^^ help: use: `v.iter()`
error: unnecessary use of `cloned`
--> tests/ui/unnecessary_iter_cloned.rs:185:18
--> tests/ui/unnecessary_iter_cloned.rs:187:18
|
LL | for c in v.iter().cloned() {
| ^^^^^^^^^^^^^^^^^
@ -55,7 +55,7 @@ LL + let ref_c = c;
|
error: unnecessary use of `cloned`
--> tests/ui/unnecessary_iter_cloned.rs:194:23
--> tests/ui/unnecessary_iter_cloned.rs:196:23
|
LL | for (i, c) in v.iter().cloned() {
| ^^^^^^^^^^^^^^^^^

View file

@ -1,587 +0,0 @@
#![allow(
clippy::needless_borrow,
clippy::needless_borrows_for_generic_args,
clippy::ptr_arg,
clippy::manual_async_fn,
clippy::needless_lifetimes
)]
#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
use std::borrow::Cow;
use std::ffi::{CStr, CString, OsStr, OsString};
use std::ops::Deref;
#[derive(Clone)]
struct X(String);
impl Deref for X {
type Target = [u8];
fn deref(&self) -> &[u8] {
self.0.as_bytes()
}
}
impl AsRef<str> for X {
fn as_ref(&self) -> &str {
self.0.as_str()
}
}
#[allow(clippy::to_string_trait_impl)]
impl ToString for X {
fn to_string(&self) -> String {
self.0.to_string()
}
}
impl X {
fn join(&self, other: impl AsRef<str>) -> Self {
let mut s = self.0.clone();
s.push_str(other.as_ref());
Self(s)
}
}
#[allow(dead_code)]
#[derive(Clone)]
enum FileType {
Account,
PrivateKey,
Certificate,
}
fn main() {
let c_str = CStr::from_bytes_with_nul(&[0]).unwrap();
let os_str = OsStr::new("x");
let path = std::path::Path::new("x");
let s = "x";
let array = ["x"];
let array_ref = &["x"];
let slice = &["x"][..];
let x = X(String::from("x"));
let x_ref = &x;
require_c_str(&Cow::from(c_str));
require_c_str(c_str);
require_os_str(os_str);
require_os_str(&Cow::from(os_str));
require_os_str(os_str);
require_path(path);
require_path(&Cow::from(path));
require_path(path);
require_str(s);
require_str(&Cow::from(s));
require_str(s);
require_str(x_ref.as_ref());
require_slice(slice);
require_slice(&Cow::from(slice));
require_slice(array.as_ref());
require_slice(array_ref.as_ref());
require_slice(slice);
require_slice(&x_ref.to_owned()); // No longer flagged because of #8759.
require_x(&Cow::<X>::Owned(x.clone()));
require_x(&x_ref.to_owned()); // No longer flagged because of #8759.
require_deref_c_str(c_str);
require_deref_os_str(os_str);
require_deref_path(path);
require_deref_str(s);
require_deref_slice(slice);
require_impl_deref_c_str(c_str);
require_impl_deref_os_str(os_str);
require_impl_deref_path(path);
require_impl_deref_str(s);
require_impl_deref_slice(slice);
require_deref_str_slice(s, slice);
require_deref_slice_str(slice, s);
require_as_ref_c_str(c_str);
require_as_ref_os_str(os_str);
require_as_ref_path(path);
require_as_ref_str(s);
require_as_ref_str(&x);
require_as_ref_slice(array);
require_as_ref_slice(array_ref);
require_as_ref_slice(slice);
require_impl_as_ref_c_str(c_str);
require_impl_as_ref_os_str(os_str);
require_impl_as_ref_path(path);
require_impl_as_ref_str(s);
require_impl_as_ref_str(&x);
require_impl_as_ref_slice(array);
require_impl_as_ref_slice(array_ref);
require_impl_as_ref_slice(slice);
require_as_ref_str_slice(s, array);
require_as_ref_str_slice(s, array_ref);
require_as_ref_str_slice(s, slice);
require_as_ref_slice_str(array, s);
require_as_ref_slice_str(array_ref, s);
require_as_ref_slice_str(slice, s);
let _ = x.join(x_ref);
let _ = slice.iter().copied();
let _ = slice.iter().copied();
let _ = [std::path::PathBuf::new()][..].iter().cloned();
let _ = [std::path::PathBuf::new()][..].iter().cloned();
let _ = slice.iter().copied();
let _ = slice.iter().copied();
let _ = [std::path::PathBuf::new()][..].iter().cloned();
let _ = [std::path::PathBuf::new()][..].iter().cloned();
let _ = check_files(&[FileType::Account]);
// negative tests
require_string(&s.to_string());
require_string(&Cow::from(s).into_owned());
require_string(&s.to_owned());
require_string(&x_ref.to_string());
// `X` isn't copy.
require_slice(&x.to_owned());
require_deref_slice(x.to_owned());
// The following should be flagged by `redundant_clone`, but not by this lint.
require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap());
require_os_str(&OsString::from("x"));
require_path(&std::path::PathBuf::from("x"));
require_str(&String::from("x"));
require_slice(&[String::from("x")]);
let slice = [0u8; 1024];
let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8");
let _ref_str: &str = core::str::from_utf8(b"foo").unwrap();
let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap();
// Expression is of type `&String`, can't suggest `str::from_utf8` here
let _ref_string = &String::from_utf8(b"foo".to_vec()).unwrap();
macro_rules! arg_from_macro {
() => {
b"foo".to_vec()
};
}
macro_rules! string_from_utf8_from_macro {
() => {
&String::from_utf8(b"foo".to_vec()).unwrap()
};
}
let _ref_str: &str = &String::from_utf8(arg_from_macro!()).unwrap();
let _ref_str: &str = string_from_utf8_from_macro!();
}
fn require_c_str(_: &CStr) {}
fn require_os_str(_: &OsStr) {}
fn require_path(_: &std::path::Path) {}
fn require_str(_: &str) {}
fn require_slice<T>(_: &[T]) {}
fn require_x(_: &X) {}
fn require_deref_c_str<T: Deref<Target = CStr>>(_: T) {}
fn require_deref_os_str<T: Deref<Target = OsStr>>(_: T) {}
fn require_deref_path<T: Deref<Target = std::path::Path>>(_: T) {}
fn require_deref_str<T: Deref<Target = str>>(_: T) {}
fn require_deref_slice<T, U: Deref<Target = [T]>>(_: U) {}
fn require_impl_deref_c_str(_: impl Deref<Target = CStr>) {}
fn require_impl_deref_os_str(_: impl Deref<Target = OsStr>) {}
fn require_impl_deref_path(_: impl Deref<Target = std::path::Path>) {}
fn require_impl_deref_str(_: impl Deref<Target = str>) {}
fn require_impl_deref_slice<T>(_: impl Deref<Target = [T]>) {}
fn require_deref_str_slice<T: Deref<Target = str>, U, V: Deref<Target = [U]>>(_: T, _: V) {}
fn require_deref_slice_str<T, U: Deref<Target = [T]>, V: Deref<Target = str>>(_: U, _: V) {}
fn require_as_ref_c_str<T: AsRef<CStr>>(_: T) {}
fn require_as_ref_os_str<T: AsRef<OsStr>>(_: T) {}
fn require_as_ref_path<T: AsRef<std::path::Path>>(_: T) {}
fn require_as_ref_str<T: AsRef<str>>(_: T) {}
fn require_as_ref_slice<T, U: AsRef<[T]>>(_: U) {}
fn require_impl_as_ref_c_str(_: impl AsRef<CStr>) {}
fn require_impl_as_ref_os_str(_: impl AsRef<OsStr>) {}
fn require_impl_as_ref_path(_: impl AsRef<std::path::Path>) {}
fn require_impl_as_ref_str(_: impl AsRef<str>) {}
fn require_impl_as_ref_slice<T>(_: impl AsRef<[T]>) {}
fn require_as_ref_str_slice<T: AsRef<str>, U, V: AsRef<[U]>>(_: T, _: V) {}
fn require_as_ref_slice_str<T, U: AsRef<[T]>, V: AsRef<str>>(_: U, _: V) {}
// `check_files` is based on:
// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262
fn check_files(file_types: &[FileType]) -> bool {
for t in file_types {
let path = match get_file_path(t) {
Ok(p) => p,
Err(_) => {
return false;
},
};
if !path.is_file() {
return false;
}
}
true
}
fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {
Ok(std::path::PathBuf::new())
}
fn require_string(_: &String) {}
#[clippy::msrv = "1.35"]
fn _msrv_1_35() {
// `copied` was stabilized in 1.36, so clippy should use `cloned`.
let _ = &["x"][..].iter().cloned();
}
#[clippy::msrv = "1.36"]
fn _msrv_1_36() {
let _ = &["x"][..].iter().copied();
}
// https://github.com/rust-lang/rust-clippy/issues/8507
mod issue_8507 {
#![allow(dead_code)]
struct Opaque<P>(P);
pub trait Abstracted {}
impl<P> Abstracted for Opaque<P> {}
fn build<P>(p: P) -> Opaque<P>
where
P: AsRef<str>,
{
Opaque(p)
}
// Should not lint.
fn test_str(s: &str) -> Box<dyn Abstracted> {
Box::new(build(s.to_string()))
}
// Should not lint.
fn test_x(x: super::X) -> Box<dyn Abstracted> {
Box::new(build(x))
}
#[derive(Clone, Copy)]
struct Y(&'static str);
impl AsRef<str> for Y {
fn as_ref(&self) -> &str {
self.0
}
}
#[allow(clippy::to_string_trait_impl)]
impl ToString for Y {
fn to_string(&self) -> String {
self.0.to_string()
}
}
// Should lint because Y is copy.
fn test_y(y: Y) -> Box<dyn Abstracted> {
Box::new(build(y))
}
}
// https://github.com/rust-lang/rust-clippy/issues/8759
mod issue_8759 {
#![allow(dead_code)]
#[derive(Default)]
struct View {}
impl std::borrow::ToOwned for View {
type Owned = View;
fn to_owned(&self) -> Self::Owned {
View {}
}
}
#[derive(Default)]
struct RenderWindow {
default_view: View,
}
impl RenderWindow {
fn default_view(&self) -> &View {
&self.default_view
}
fn set_view(&mut self, _view: &View) {}
}
fn main() {
let mut rw = RenderWindow::default();
rw.set_view(&rw.default_view().to_owned());
}
}
mod issue_8759_variant {
#![allow(dead_code)]
#[derive(Clone, Default)]
struct View {}
#[derive(Default)]
struct RenderWindow {
default_view: View,
}
impl RenderWindow {
fn default_view(&self) -> &View {
&self.default_view
}
fn set_view(&mut self, _view: &View) {}
}
fn main() {
let mut rw = RenderWindow::default();
rw.set_view(&rw.default_view().to_owned());
}
}
mod issue_9317 {
#![allow(dead_code)]
struct Bytes {}
#[allow(clippy::to_string_trait_impl)]
impl ToString for Bytes {
fn to_string(&self) -> String {
"123".to_string()
}
}
impl AsRef<[u8]> for Bytes {
fn as_ref(&self) -> &[u8] {
&[1, 2, 3]
}
}
fn consume<C: AsRef<[u8]>>(c: C) {
let _ = c;
}
pub fn main() {
let b = Bytes {};
// Should not lint.
consume(b.to_string());
}
}
mod issue_9351 {
#![allow(dead_code)]
use std::ops::Deref;
use std::path::{Path, PathBuf};
fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {
x
}
fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}
fn id<T: AsRef<str>>(x: T) -> T {
x
}
fn predicates_are_satisfied(_x: impl std::fmt::Write) {}
// Should lint
fn single_return() -> impl AsRef<str> {
id("abc")
}
// Should not lint
fn multiple_returns(b: bool) -> impl AsRef<str> {
if b {
return String::new();
}
id("abc".to_string())
}
struct S1(String);
// Should not lint
fn fields1() -> S1 {
S1(id("abc".to_string()))
}
struct S2 {
s: String,
}
// Should not lint
fn fields2() {
let mut s = S2 { s: "abc".into() };
s.s = id("abc".to_string());
}
pub fn main() {
let path = std::path::Path::new("x");
let path_buf = path.to_owned();
// Should not lint.
let _x: PathBuf = require_deref_path(path.to_owned());
generic_arg_used_elsewhere(path.to_owned(), path_buf);
predicates_are_satisfied(id("abc".to_string()));
}
}
mod issue_9504 {
#![allow(dead_code)]
async fn foo<S: AsRef<str>>(_: S) {}
async fn bar() {
foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;
}
}
mod issue_9771a {
#![allow(dead_code)]
use std::marker::PhantomData;
pub struct Key<K: AsRef<[u8]>, V: ?Sized>(K, PhantomData<V>);
impl<K: AsRef<[u8]>, V: ?Sized> Key<K, V> {
pub fn new(key: K) -> Key<K, V> {
Key(key, PhantomData)
}
}
pub fn pkh(pkh: &[u8]) -> Key<Vec<u8>, String> {
Key::new([b"pkh-", pkh].concat().to_vec())
}
}
mod issue_9771b {
#![allow(dead_code)]
pub struct Key<K: AsRef<[u8]>>(K);
pub fn from(c: &[u8]) -> Key<Vec<u8>> {
let v = [c].concat();
Key(v.to_vec())
}
}
// This is a watered down version of the code in: https://github.com/oxigraph/rio
// The ICE is triggered by the call to `to_owned` on this line:
// https://github.com/oxigraph/rio/blob/66635b9ff8e5423e58932353fa40d6e64e4820f7/testsuite/src/parser_evaluator.rs#L116
mod issue_10021 {
#![allow(unused)]
pub struct Iri<T>(T);
impl<T: AsRef<str>> Iri<T> {
pub fn parse(iri: T) -> Result<Self, ()> {
unimplemented!()
}
}
pub fn parse_w3c_rdf_test_file(url: &str) -> Result<(), ()> {
let base_iri = Iri::parse(url.to_owned())?;
Ok(())
}
}
mod issue_10033 {
#![allow(dead_code)]
use std::fmt::Display;
use std::ops::Deref;
fn _main() {
let f = Foo;
// Not actually unnecessary - this calls `Foo`'s `Display` impl, not `str`'s (even though `Foo` does
// deref to `str`)
foo(&f.to_string());
}
fn foo(s: &str) {
println!("{}", s);
}
struct Foo;
impl Deref for Foo {
type Target = str;
fn deref(&self) -> &Self::Target {
"str"
}
}
impl Display for Foo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Foo")
}
}
}
mod issue_11952 {
use core::future::{Future, IntoFuture};
fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> {
async move {
let _y = y;
Ok(())
}
}
fn bar() {
IntoFuture::into_future(foo([], &0));
}
}
fn borrow_checks() {
use std::borrow::Borrow;
use std::collections::HashSet;
fn inner(a: &[&str]) {
let mut s = HashSet::from([vec!["a"]]);
s.remove(a); //~ ERROR: unnecessary use of `to_vec`
}
let mut s = HashSet::from(["a".to_string()]);
s.remove("b"); //~ ERROR: unnecessary use of `to_owned`
s.remove("b"); //~ ERROR: unnecessary use of `to_string`
// Should not warn.
s.remove("b");
let mut s = HashSet::from([vec!["a"]]);
s.remove(["b"].as_slice()); //~ ERROR: unnecessary use of `to_vec`
s.remove((&["b"]).as_slice()); //~ ERROR: unnecessary use of `to_vec`
// Should not warn.
s.remove(&["b"].to_vec().clone());
s.remove(["a"].as_slice());
trait SetExt {
fn foo<Q: Borrow<str>>(&self, _: &String);
}
impl<K> SetExt for HashSet<K> {
fn foo<Q: Borrow<str>>(&self, _: &String) {}
}
// Should not lint!
HashSet::<i32>::new().foo::<&str>(&"".to_owned());
HashSet::<String>::new().get(&1.to_string());
}

View file

@ -7,6 +7,8 @@
)]
#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
//@no-rustfix: need to change the suggestion to a multipart suggestion
use std::borrow::Cow;
use std::ffi::{CStr, CString, OsStr, OsString};
use std::ops::Deref;

View file

@ -1,11 +1,11 @@
error: redundant clone
--> tests/ui/unnecessary_to_owned.rs:155:64
--> tests/ui/unnecessary_to_owned.rs:157:64
|
LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> tests/ui/unnecessary_to_owned.rs:155:20
--> tests/ui/unnecessary_to_owned.rs:157:20
|
LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -13,55 +13,55 @@ LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned())
= help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
error: redundant clone
--> tests/ui/unnecessary_to_owned.rs:156:40
--> tests/ui/unnecessary_to_owned.rs:158:40
|
LL | require_os_str(&OsString::from("x").to_os_string());
| ^^^^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> tests/ui/unnecessary_to_owned.rs:156:21
--> tests/ui/unnecessary_to_owned.rs:158:21
|
LL | require_os_str(&OsString::from("x").to_os_string());
| ^^^^^^^^^^^^^^^^^^^
error: redundant clone
--> tests/ui/unnecessary_to_owned.rs:157:48
--> tests/ui/unnecessary_to_owned.rs:159:48
|
LL | require_path(&std::path::PathBuf::from("x").to_path_buf());
| ^^^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> tests/ui/unnecessary_to_owned.rs:157:19
--> tests/ui/unnecessary_to_owned.rs:159:19
|
LL | require_path(&std::path::PathBuf::from("x").to_path_buf());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant clone
--> tests/ui/unnecessary_to_owned.rs:158:35
--> tests/ui/unnecessary_to_owned.rs:160:35
|
LL | require_str(&String::from("x").to_string());
| ^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> tests/ui/unnecessary_to_owned.rs:158:18
--> tests/ui/unnecessary_to_owned.rs:160:18
|
LL | require_str(&String::from("x").to_string());
| ^^^^^^^^^^^^^^^^^
error: redundant clone
--> tests/ui/unnecessary_to_owned.rs:159:39
--> tests/ui/unnecessary_to_owned.rs:161:39
|
LL | require_slice(&[String::from("x")].to_owned());
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
--> tests/ui/unnecessary_to_owned.rs:159:20
--> tests/ui/unnecessary_to_owned.rs:161:20
|
LL | require_slice(&[String::from("x")].to_owned());
| ^^^^^^^^^^^^^^^^^^^
error: unnecessary use of `into_owned`
--> tests/ui/unnecessary_to_owned.rs:64:36
--> tests/ui/unnecessary_to_owned.rs:66:36
|
LL | require_c_str(&Cow::from(c_str).into_owned());
| ^^^^^^^^^^^^^ help: remove this
@ -70,415 +70,415 @@ LL | require_c_str(&Cow::from(c_str).into_owned());
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:65:19
--> tests/ui/unnecessary_to_owned.rs:67:19
|
LL | require_c_str(&c_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_os_string`
--> tests/ui/unnecessary_to_owned.rs:67:20
--> tests/ui/unnecessary_to_owned.rs:69:20
|
LL | require_os_str(&os_str.to_os_string());
| ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `into_owned`
--> tests/ui/unnecessary_to_owned.rs:68:38
--> tests/ui/unnecessary_to_owned.rs:70:38
|
LL | require_os_str(&Cow::from(os_str).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:69:20
--> tests/ui/unnecessary_to_owned.rs:71:20
|
LL | require_os_str(&os_str.to_owned());
| ^^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_path_buf`
--> tests/ui/unnecessary_to_owned.rs:71:18
--> tests/ui/unnecessary_to_owned.rs:73:18
|
LL | require_path(&path.to_path_buf());
| ^^^^^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `into_owned`
--> tests/ui/unnecessary_to_owned.rs:72:34
--> tests/ui/unnecessary_to_owned.rs:74:34
|
LL | require_path(&Cow::from(path).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:73:18
--> tests/ui/unnecessary_to_owned.rs:75:18
|
LL | require_path(&path.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_string`
--> tests/ui/unnecessary_to_owned.rs:75:17
--> tests/ui/unnecessary_to_owned.rs:77:17
|
LL | require_str(&s.to_string());
| ^^^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `into_owned`
--> tests/ui/unnecessary_to_owned.rs:76:30
--> tests/ui/unnecessary_to_owned.rs:78:30
|
LL | require_str(&Cow::from(s).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:77:17
--> tests/ui/unnecessary_to_owned.rs:79:17
|
LL | require_str(&s.to_owned());
| ^^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_string`
--> tests/ui/unnecessary_to_owned.rs:78:17
--> tests/ui/unnecessary_to_owned.rs:80:17
|
LL | require_str(&x_ref.to_string());
| ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:80:19
--> tests/ui/unnecessary_to_owned.rs:82:19
|
LL | require_slice(&slice.to_vec());
| ^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `into_owned`
--> tests/ui/unnecessary_to_owned.rs:81:36
--> tests/ui/unnecessary_to_owned.rs:83:36
|
LL | require_slice(&Cow::from(slice).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:82:19
--> tests/ui/unnecessary_to_owned.rs:84:19
|
LL | require_slice(&array.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:83:19
--> tests/ui/unnecessary_to_owned.rs:85:19
|
LL | require_slice(&array_ref.to_owned());
| ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:84:19
--> tests/ui/unnecessary_to_owned.rs:86:19
|
LL | require_slice(&slice.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `into_owned`
--> tests/ui/unnecessary_to_owned.rs:87:42
--> tests/ui/unnecessary_to_owned.rs:89:42
|
LL | require_x(&Cow::<X>::Owned(x.clone()).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:90:25
--> tests/ui/unnecessary_to_owned.rs:92:25
|
LL | require_deref_c_str(c_str.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:91:26
--> tests/ui/unnecessary_to_owned.rs:93:26
|
LL | require_deref_os_str(os_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:92:24
--> tests/ui/unnecessary_to_owned.rs:94:24
|
LL | require_deref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:93:23
--> tests/ui/unnecessary_to_owned.rs:95:23
|
LL | require_deref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:94:25
--> tests/ui/unnecessary_to_owned.rs:96:25
|
LL | require_deref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:96:30
--> tests/ui/unnecessary_to_owned.rs:98:30
|
LL | require_impl_deref_c_str(c_str.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:97:31
--> tests/ui/unnecessary_to_owned.rs:99:31
|
LL | require_impl_deref_os_str(os_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:98:29
--> tests/ui/unnecessary_to_owned.rs:100:29
|
LL | require_impl_deref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:99:28
--> tests/ui/unnecessary_to_owned.rs:101:28
|
LL | require_impl_deref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:100:30
--> tests/ui/unnecessary_to_owned.rs:102:30
|
LL | require_impl_deref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:102:29
--> tests/ui/unnecessary_to_owned.rs:104:29
|
LL | require_deref_str_slice(s.to_owned(), slice.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:102:43
--> tests/ui/unnecessary_to_owned.rs:104:43
|
LL | require_deref_str_slice(s.to_owned(), slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:103:29
--> tests/ui/unnecessary_to_owned.rs:105:29
|
LL | require_deref_slice_str(slice.to_owned(), s.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:103:47
--> tests/ui/unnecessary_to_owned.rs:105:47
|
LL | require_deref_slice_str(slice.to_owned(), s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:105:26
--> tests/ui/unnecessary_to_owned.rs:107:26
|
LL | require_as_ref_c_str(c_str.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:106:27
--> tests/ui/unnecessary_to_owned.rs:108:27
|
LL | require_as_ref_os_str(os_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:107:25
--> tests/ui/unnecessary_to_owned.rs:109:25
|
LL | require_as_ref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:108:24
--> tests/ui/unnecessary_to_owned.rs:110:24
|
LL | require_as_ref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:109:24
--> tests/ui/unnecessary_to_owned.rs:111:24
|
LL | require_as_ref_str(x.to_owned());
| ^^^^^^^^^^^^ help: use: `&x`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:110:26
--> tests/ui/unnecessary_to_owned.rs:112:26
|
LL | require_as_ref_slice(array.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:111:26
--> tests/ui/unnecessary_to_owned.rs:113:26
|
LL | require_as_ref_slice(array_ref.to_owned());
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:112:26
--> tests/ui/unnecessary_to_owned.rs:114:26
|
LL | require_as_ref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:114:31
--> tests/ui/unnecessary_to_owned.rs:116:31
|
LL | require_impl_as_ref_c_str(c_str.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:115:32
--> tests/ui/unnecessary_to_owned.rs:117:32
|
LL | require_impl_as_ref_os_str(os_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:116:30
--> tests/ui/unnecessary_to_owned.rs:118:30
|
LL | require_impl_as_ref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:117:29
--> tests/ui/unnecessary_to_owned.rs:119:29
|
LL | require_impl_as_ref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:118:29
--> tests/ui/unnecessary_to_owned.rs:120:29
|
LL | require_impl_as_ref_str(x.to_owned());
| ^^^^^^^^^^^^ help: use: `&x`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:119:31
--> tests/ui/unnecessary_to_owned.rs:121:31
|
LL | require_impl_as_ref_slice(array.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:120:31
--> tests/ui/unnecessary_to_owned.rs:122:31
|
LL | require_impl_as_ref_slice(array_ref.to_owned());
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:121:31
--> tests/ui/unnecessary_to_owned.rs:123:31
|
LL | require_impl_as_ref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:123:30
|
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:123:44
|
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:124:30
|
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:124:44
|
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:125:30
|
LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned());
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:125:44
|
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:126:30
|
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:126:44
|
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:127:30
|
LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:127:44
|
LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:126:30
--> tests/ui/unnecessary_to_owned.rs:128:30
|
LL | require_as_ref_slice_str(array.to_owned(), s.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:126:48
--> tests/ui/unnecessary_to_owned.rs:128:48
|
LL | require_as_ref_slice_str(array.to_owned(), s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:127:30
--> tests/ui/unnecessary_to_owned.rs:129:30
|
LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:127:52
--> tests/ui/unnecessary_to_owned.rs:129:52
|
LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:128:30
--> tests/ui/unnecessary_to_owned.rs:130:30
|
LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:128:48
--> tests/ui/unnecessary_to_owned.rs:130:48
|
LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_string`
--> tests/ui/unnecessary_to_owned.rs:130:20
--> tests/ui/unnecessary_to_owned.rs:132:20
|
LL | let _ = x.join(&x_ref.to_string());
| ^^^^^^^^^^^^^^^^^^ help: use: `x_ref`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:132:13
--> tests/ui/unnecessary_to_owned.rs:134:13
|
LL | let _ = slice.to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:133:13
--> tests/ui/unnecessary_to_owned.rs:135:13
|
LL | let _ = slice.to_owned().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:134:13
--> tests/ui/unnecessary_to_owned.rs:136:13
|
LL | let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:135:13
--> tests/ui/unnecessary_to_owned.rs:137:13
|
LL | let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:137:13
--> tests/ui/unnecessary_to_owned.rs:139:13
|
LL | let _ = IntoIterator::into_iter(slice.to_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:138:13
--> tests/ui/unnecessary_to_owned.rs:140:13
|
LL | let _ = IntoIterator::into_iter(slice.to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:139:13
--> tests/ui/unnecessary_to_owned.rs:141:13
|
LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:140:13
--> tests/ui/unnecessary_to_owned.rs:142:13
|
LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
error: allocating a new `String` only to create a temporary `&str` from it
--> tests/ui/unnecessary_to_owned.rs:162:26
--> tests/ui/unnecessary_to_owned.rs:164:26
|
LL | let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -490,7 +490,7 @@ LL + let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8");
|
error: allocating a new `String` only to create a temporary `&str` from it
--> tests/ui/unnecessary_to_owned.rs:163:26
--> tests/ui/unnecessary_to_owned.rs:165:26
|
LL | let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -502,7 +502,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo").unwrap();
|
error: allocating a new `String` only to create a temporary `&str` from it
--> tests/ui/unnecessary_to_owned.rs:164:26
--> tests/ui/unnecessary_to_owned.rs:166:26
|
LL | let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -514,7 +514,7 @@ LL + let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap();
|
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:221:14
--> tests/ui/unnecessary_to_owned.rs:223:14
|
LL | for t in file_types.to_vec() {
| ^^^^^^^^^^^^^^^^^^^
@ -530,61 +530,61 @@ LL + let path = match get_file_path(t) {
|
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:244:14
--> tests/ui/unnecessary_to_owned.rs:246:14
|
LL | let _ = &["x"][..].to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:249:14
--> tests/ui/unnecessary_to_owned.rs:251:14
|
LL | let _ = &["x"][..].to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
error: unnecessary use of `to_string`
--> tests/ui/unnecessary_to_owned.rs:297:24
--> tests/ui/unnecessary_to_owned.rs:299:24
|
LL | Box::new(build(y.to_string()))
| ^^^^^^^^^^^^^ help: use: `y`
error: unnecessary use of `to_string`
--> tests/ui/unnecessary_to_owned.rs:406:12
--> tests/ui/unnecessary_to_owned.rs:408:12
|
LL | id("abc".to_string())
| ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:549:37
--> tests/ui/unnecessary_to_owned.rs:551:37
|
LL | IntoFuture::into_future(foo([].to_vec(), &0));
| ^^^^^^^^^^^ help: use: `[]`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:559:18
--> tests/ui/unnecessary_to_owned.rs:561:18
|
LL | s.remove(&a.to_vec());
| ^^^^^^^^^^^ help: replace it with: `a`
error: unnecessary use of `to_owned`
--> tests/ui/unnecessary_to_owned.rs:563:14
--> tests/ui/unnecessary_to_owned.rs:565:14
|
LL | s.remove(&"b".to_owned());
| ^^^^^^^^^^^^^^^ help: replace it with: `"b"`
error: unnecessary use of `to_string`
--> tests/ui/unnecessary_to_owned.rs:564:14
--> tests/ui/unnecessary_to_owned.rs:566:14
|
LL | s.remove(&"b".to_string());
| ^^^^^^^^^^^^^^^^ help: replace it with: `"b"`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:569:14
--> tests/ui/unnecessary_to_owned.rs:571:14
|
LL | s.remove(&["b"].to_vec());
| ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()`
error: unnecessary use of `to_vec`
--> tests/ui/unnecessary_to_owned.rs:570:14
--> tests/ui/unnecessary_to_owned.rs:572:14
|
LL | s.remove(&(&["b"]).to_vec());
| ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()`