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

This commit is contained in:
Philipp Krones 2024-05-30 09:44:14 +02:00
commit 89037ea18f
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
140 changed files with 1483 additions and 715 deletions

View file

@ -1,7 +1,6 @@
#![allow(clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, dead_code)]
#![warn(clippy::expl_impl_clone_on_copy)]
#[derive(Copy)]
struct Qux;

View file

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

View file

@ -1,3 +1,4 @@
#![feature(lint_reasons)]
#![allow(unused)]
#![warn(clippy::derive_partial_eq_without_eq)]
@ -14,6 +15,22 @@ pub struct MissingEq {
bar: String,
}
// Check that we honor the `allow` attribute
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Debug, PartialEq)]
pub struct AllowedMissingEq {
foo: u32,
bar: String,
}
// Check that we honor the `expect` attribute
#[expect(clippy::derive_partial_eq_without_eq)]
#[derive(Debug, PartialEq)]
pub struct ExpectedMissingEq {
foo: u32,
bar: String,
}
// Eq is derived
#[derive(PartialEq, Eq)]
pub struct NotMissingEq {

View file

@ -1,3 +1,4 @@
#![feature(lint_reasons)]
#![allow(unused)]
#![warn(clippy::derive_partial_eq_without_eq)]
@ -14,6 +15,22 @@ pub struct MissingEq {
bar: String,
}
// Check that we honor the `allow` attribute
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Debug, PartialEq)]
pub struct AllowedMissingEq {
foo: u32,
bar: String,
}
// Check that we honor the `expect` attribute
#[expect(clippy::derive_partial_eq_without_eq)]
#[derive(Debug, PartialEq)]
pub struct ExpectedMissingEq {
foo: u32,
bar: String,
}
// Eq is derived
#[derive(PartialEq, Eq)]
pub struct NotMissingEq {

View file

@ -1,5 +1,5 @@
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:11:17
--> tests/ui/derive_partial_eq_without_eq.rs:12:17
|
LL | #[derive(Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
@ -8,73 +8,73 @@ LL | #[derive(Debug, PartialEq)]
= help: to override `-D warnings` add `#[allow(clippy::derive_partial_eq_without_eq)]`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:53:10
--> tests/ui/derive_partial_eq_without_eq.rs:70:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:59:10
--> tests/ui/derive_partial_eq_without_eq.rs:76:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:65:10
--> tests/ui/derive_partial_eq_without_eq.rs:82:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:68:10
--> tests/ui/derive_partial_eq_without_eq.rs:85:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:74:10
--> tests/ui/derive_partial_eq_without_eq.rs:91:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:80:10
--> tests/ui/derive_partial_eq_without_eq.rs:97:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:93:17
--> tests/ui/derive_partial_eq_without_eq.rs:110:17
|
LL | #[derive(Debug, PartialEq, Clone)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:96:10
--> tests/ui/derive_partial_eq_without_eq.rs:113:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:103:14
--> tests/ui/derive_partial_eq_without_eq.rs:120:14
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:106:14
--> tests/ui/derive_partial_eq_without_eq.rs:123:14
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:166:14
--> tests/ui/derive_partial_eq_without_eq.rs:183:14
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:174:14
--> tests/ui/derive_partial_eq_without_eq.rs:191:14
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`

View file

@ -240,3 +240,6 @@ extern {
/// `foo()`
fn in_extern();
}
/// <https://github.com/rust-lang/rust-clippy/pull/12836>
fn check_autofix_for_base_urls() {}

View file

@ -240,3 +240,6 @@ extern {
/// foo()
fn in_extern();
}
/// https://github.com/rust-lang/rust-clippy/pull/12836
fn check_autofix_for_base_urls() {}

View file

@ -363,5 +363,11 @@ help: try
LL | /// `foo()`
| ~~~~~~~
error: aborting due to 33 previous errors
error: you should put bare URLs between `<`/`>` or make a proper Markdown link
--> tests/ui/doc/doc-fixable.rs:244:5
|
LL | /// https://github.com/rust-lang/rust-clippy/pull/12836
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<https://github.com/rust-lang/rust-clippy/pull/12836>`
error: aborting due to 34 previous errors

View file

@ -0,0 +1,9 @@
#![warn(clippy::doc_markdown)]
//! A comment with `a_b(x)` and `a_c` in it and (`a_b((c))` ) too and (maybe `a_b((c))`)
//~^ ERROR: item in documentation is missing backticks
//~| ERROR: item in documentation is missing backticks
//~| ERROR: item in documentation is missing backticks
//~| ERROR: item in documentation is missing backticks
pub fn main() {}

View file

@ -0,0 +1,9 @@
#![warn(clippy::doc_markdown)]
//! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
//~^ ERROR: item in documentation is missing backticks
//~| ERROR: item in documentation is missing backticks
//~| ERROR: item in documentation is missing backticks
//~| ERROR: item in documentation is missing backticks
pub fn main() {}

View file

@ -0,0 +1,48 @@
error: item in documentation is missing backticks
--> tests/ui/doc/issue_12795.rs:3:20
|
LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
| ^^^^^^
|
= note: `-D clippy::doc-markdown` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
help: try
|
LL | //! A comment with `a_b(x)` and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
| ~~~~~~~~
error: item in documentation is missing backticks
--> tests/ui/doc/issue_12795.rs:3:31
|
LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
| ^^^
|
help: try
|
LL | //! A comment with a_b(x) and `a_c` in it and (a_b((c)) ) too and (maybe a_b((c)))
| ~~~~~
error: item in documentation is missing backticks
--> tests/ui/doc/issue_12795.rs:3:46
|
LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
| ^^^^^^^^
|
help: try
|
LL | //! A comment with a_b(x) and a_c in it and (`a_b((c))` ) too and (maybe a_b((c)))
| ~~~~~~~~~~
error: item in documentation is missing backticks
--> tests/ui/doc/issue_12795.rs:3:72
|
LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
| ^^^^^^^^
|
help: try
|
LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe `a_b((c))`)
| ~~~~~~~~~~
error: aborting due to 4 previous errors

View file

@ -20,6 +20,28 @@ fn array() {
};
let _ = if false { ["test"].iter() } else { [].iter() };
let smth = Some(vec![1, 2, 3]);
// Don't trigger when the empty collection iter is relied upon for its concrete type
// But do trigger if it is just an iterator, despite being an argument to a method
for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain(std::iter::empty()) {
println!("{i}");
}
// Same as above, but for empty collection iters with extra layers
for i in smth.as_ref().map_or({ [].iter() }, |s| s.iter()) {
println!("{y}", y = i + 1);
}
// Same as above, but for regular function calls
for i in Option::map_or(smth.as_ref(), [].iter(), |s| s.iter()) {
println!("{i}");
}
// Same as above, but when there are no predicates that mention the collection iter type.
let mut iter = [34, 228, 35].iter();
let _ = std::mem::replace(&mut iter, [].iter());
}
macro_rules! in_macros {

View file

@ -20,6 +20,28 @@ fn array() {
};
let _ = if false { ["test"].iter() } else { [].iter() };
let smth = Some(vec![1, 2, 3]);
// Don't trigger when the empty collection iter is relied upon for its concrete type
// But do trigger if it is just an iterator, despite being an argument to a method
for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain([].iter()) {
println!("{i}");
}
// Same as above, but for empty collection iters with extra layers
for i in smth.as_ref().map_or({ [].iter() }, |s| s.iter()) {
println!("{y}", y = i + 1);
}
// Same as above, but for regular function calls
for i in Option::map_or(smth.as_ref(), [].iter(), |s| s.iter()) {
println!("{i}");
}
// Same as above, but when there are no predicates that mention the collection iter type.
let mut iter = [34, 228, 35].iter();
let _ = std::mem::replace(&mut iter, [].iter());
}
macro_rules! in_macros {

View file

@ -37,5 +37,11 @@ error: `iter` call on an empty collection
LL | assert_eq!(None.iter().next(), Option::<&i32>::None);
| ^^^^^^^^^^^ help: try: `std::iter::empty()`
error: aborting due to 6 previous errors
error: `iter` call on an empty collection
--> tests/ui/iter_on_empty_collections.rs:28:66
|
LL | for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain([].iter()) {
| ^^^^^^^^^ help: try: `std::iter::empty()`
error: aborting due to 7 previous errors

View file

@ -210,4 +210,38 @@ fn issue9150() -> usize {
x
}
fn issue12801() {
fn left_is_if() -> String {
(if true { "a".to_string() } else { "b".to_string() } + "c")
//~^ ERROR: returning the result of a `let` binding from a block
}
fn no_par_needed() -> String {
"c".to_string() + if true { "a" } else { "b" }
//~^ ERROR: returning the result of a `let` binding from a block
}
fn conjunctive_blocks() -> String {
({ "a".to_string() } + "b" + { "c" } + "d")
//~^ ERROR: returning the result of a `let` binding from a block
}
#[allow(clippy::overly_complex_bool_expr)]
fn other_ops() {
let _ = || {
(if true { 2 } else { 3 } << 4)
//~^ ERROR: returning the result of a `let` binding from a block
};
let _ = || {
({ true } || { false } && { 2 <= 3 })
//~^ ERROR: returning the result of a `let` binding from a block
};
}
}
fn main() {}

View file

@ -210,4 +210,38 @@ fn issue9150() -> usize {
x
}
fn issue12801() {
fn left_is_if() -> String {
let s = if true { "a".to_string() } else { "b".to_string() } + "c";
s
//~^ ERROR: returning the result of a `let` binding from a block
}
fn no_par_needed() -> String {
let s = "c".to_string() + if true { "a" } else { "b" };
s
//~^ ERROR: returning the result of a `let` binding from a block
}
fn conjunctive_blocks() -> String {
let s = { "a".to_string() } + "b" + { "c" } + "d";
s
//~^ ERROR: returning the result of a `let` binding from a block
}
#[allow(clippy::overly_complex_bool_expr)]
fn other_ops() {
let _ = || {
let s = if true { 2 } else { 3 } << 4;
s
//~^ ERROR: returning the result of a `let` binding from a block
};
let _ = || {
let s = { true } || { false } && { 2 <= 3 };
s
//~^ ERROR: returning the result of a `let` binding from a block
};
}
}
fn main() {}

View file

@ -78,5 +78,75 @@ LL + E::B(x) => x,
LL + }) as _
|
error: aborting due to 5 previous errors
error: returning the result of a `let` binding from a block
--> tests/ui/let_and_return.rs:216:9
|
LL | let s = if true { "a".to_string() } else { "b".to_string() } + "c";
| ------------------------------------------------------------------- unnecessary `let` binding
LL | s
| ^
|
help: return the expression directly
|
LL ~
LL ~ (if true { "a".to_string() } else { "b".to_string() } + "c")
|
error: returning the result of a `let` binding from a block
--> tests/ui/let_and_return.rs:222:9
|
LL | let s = "c".to_string() + if true { "a" } else { "b" };
| ------------------------------------------------------- unnecessary `let` binding
LL | s
| ^
|
help: return the expression directly
|
LL ~
LL ~ "c".to_string() + if true { "a" } else { "b" }
|
error: returning the result of a `let` binding from a block
--> tests/ui/let_and_return.rs:228:9
|
LL | let s = { "a".to_string() } + "b" + { "c" } + "d";
| -------------------------------------------------- unnecessary `let` binding
LL | s
| ^
|
help: return the expression directly
|
LL ~
LL ~ ({ "a".to_string() } + "b" + { "c" } + "d")
|
error: returning the result of a `let` binding from a block
--> tests/ui/let_and_return.rs:236:13
|
LL | let s = if true { 2 } else { 3 } << 4;
| -------------------------------------- unnecessary `let` binding
LL | s
| ^
|
help: return the expression directly
|
LL ~
LL ~ (if true { 2 } else { 3 } << 4)
|
error: returning the result of a `let` binding from a block
--> tests/ui/let_and_return.rs:241:13
|
LL | let s = { true } || { false } && { 2 <= 3 };
| -------------------------------------------- unnecessary `let` binding
LL | s
| ^
|
help: return the expression directly
|
LL ~
LL ~ ({ true } || { false } && { 2 <= 3 })
|
error: aborting due to 10 previous errors

View file

@ -1,5 +1,3 @@
//@compile-flags: -Zdeduplicate-diagnostics=yes
#![allow(clippy::too_many_arguments, clippy::diverging_sub_expression)]
#![warn(clippy::many_single_char_names)]

View file

@ -1,5 +1,5 @@
error: 5 bindings with single-character names in scope
--> tests/ui/many_single_char_names.rs:7:9
--> tests/ui/many_single_char_names.rs:5:9
|
LL | let a: i32;
| ^
@ -14,7 +14,7 @@ LL | let e: i32;
= help: to override `-D warnings` add `#[allow(clippy::many_single_char_names)]`
error: 6 bindings with single-character names in scope
--> tests/ui/many_single_char_names.rs:7:9
--> tests/ui/many_single_char_names.rs:5:9
|
LL | let a: i32;
| ^
@ -28,7 +28,7 @@ LL | let f: i32;
| ^
error: 5 bindings with single-character names in scope
--> tests/ui/many_single_char_names.rs:7:9
--> tests/ui/many_single_char_names.rs:5:9
|
LL | let a: i32;
| ^
@ -40,13 +40,13 @@ LL | e => panic!(),
| ^
error: 8 bindings with single-character names in scope
--> tests/ui/many_single_char_names.rs:36:13
--> tests/ui/many_single_char_names.rs:34:13
|
LL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}
| ^ ^ ^ ^ ^ ^ ^ ^
error: 8 bindings with single-character names in scope
--> tests/ui/many_single_char_names.rs:40:10
--> tests/ui/many_single_char_names.rs:38:10
|
LL | let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!();
| ^ ^ ^ ^ ^ ^ ^ ^

View file

@ -10,7 +10,7 @@
/// unimplemented!();
/// }
/// ```
///
///
/// With an explicit return type it should lint too
/// ```edition2015
/// fn main() -> () {
@ -18,7 +18,7 @@
/// unimplemented!();
/// }
/// ```
///
///
/// This should, too.
/// ```rust
/// fn main() {
@ -26,7 +26,7 @@
/// unimplemented!();
/// }
/// ```
///
///
/// This one too.
/// ```no_run
/// // the fn is not always the first line

View file

@ -323,4 +323,8 @@ fn allow_works() -> i32 {
}
}
fn conjunctive_blocks() -> String {
({ "a".to_string() } + "b" + { "c" })
}
fn main() {}

View file

@ -333,4 +333,8 @@ fn allow_works() -> i32 {
}
}
fn conjunctive_blocks() -> String {
return { "a".to_string() } + "b" + { "c" };
}
fn main() {}

View file

@ -653,5 +653,17 @@ LL - return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4
LL + (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 })
|
error: aborting due to 52 previous errors
error: unneeded `return` statement
--> tests/ui/needless_return.rs:337:5
|
LL | return { "a".to_string() } + "b" + { "c" };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove `return` and wrap the sequence with parentheses
|
LL - return { "a".to_string() } + "b" + { "c" };
LL + ({ "a".to_string() } + "b" + { "c" })
|
error: aborting due to 53 previous errors

View file

@ -34,4 +34,9 @@ fn main() {
// Aliases can't be tuple constructed #8638
let _ = Alias { 0: 0, 1: 1, 2: 2 };
// Issue #12367
struct TupleStructVec(Vec<usize>);
let _ = TupleStructVec(vec![0, 1, 2, 3]);
}

View file

@ -42,4 +42,9 @@ fn main() {
// Aliases can't be tuple constructed #8638
let _ = Alias { 0: 0, 1: 1, 2: 2 };
// Issue #12367
struct TupleStructVec(Vec<usize>);
let _ = TupleStructVec { 0: vec![0, 1, 2, 3] };
}

View file

@ -23,5 +23,11 @@ LL | | 1: 3u32,
LL | | };
| |_____^ help: try: `TupleStruct(1u32, 3u32, 2u8)`
error: aborting due to 2 previous errors
error: used a field initializer for a tuple struct
--> tests/ui/numbered_fields.rs:49:13
|
LL | let _ = TupleStructVec { 0: vec![0, 1, 2, 3] };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `TupleStructVec(vec![0, 1, 2, 3])`
error: aborting due to 3 previous errors

View file

@ -274,11 +274,20 @@ fn should_trigger_lint_for_tuple_in_scrutinee() {
},
(_, _, _) => {},
};
}
}
// Should not trigger lint since `String::as_str` returns a reference (i.e., `&str`)
// to the locked data (i.e., the `String`) and it is not surprising that matching such
// a reference needs to keep the data locked until the end of the match block.
fn should_not_trigger_lint_for_string_as_str() {
let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() });
{
let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() });
let mutex3 = Mutex::new(StateWithField { s: "three".to_owned() });
match mutex3.lock().unwrap().s.as_str() {
//~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until
//~| NOTE: this might lead to deadlocks or other unexpected behavior
"three" => {
println!("started");
mutex1.lock().unwrap().s.len();
@ -289,8 +298,6 @@ fn should_trigger_lint_for_tuple_in_scrutinee() {
};
match (true, mutex3.lock().unwrap().s.as_str()) {
//~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until
//~| NOTE: this might lead to deadlocks or other unexpected behavior
(_, "three") => {
println!("started");
mutex1.lock().unwrap().s.len();
@ -514,16 +521,15 @@ impl StateStringWithBoxedMutexGuard {
}
}
fn should_trigger_lint_for_boxed_mutex_guard_holding_string() {
fn should_not_trigger_lint_for_string_ref() {
let s = StateStringWithBoxedMutexGuard::new();
let matcher = String::from("A String");
// Should trigger lint because a temporary Box holding a type with a significant drop in a match
// scrutinee may have a potentially surprising lifetime.
// Should not trigger lint because the second `deref` returns a string reference (`&String`).
// So it is not surprising that matching the reference implies that the lock needs to be held
// until the end of the block.
match s.lock().deref().deref() {
//~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
//~| NOTE: this might lead to deadlocks or other unexpected behavior
matcher => println!("Value is {}", s.lock().deref()),
_ => println!("Value was not a match"),
};
@ -639,13 +645,12 @@ fn should_trigger_lint_for_non_ref_move_and_clone_suggestion() {
};
}
fn should_trigger_lint_for_read_write_lock_for_loop() {
// For-in loops desugar to match expressions and are prone to the type of deadlock this lint is
// designed to look for.
fn should_not_trigger_lint_for_read_write_lock_for_loop() {
let rwlock = RwLock::<Vec<String>>::new(vec!["1".to_string()]);
// Should not trigger lint. Since we're iterating over the data, it's obvious that the lock
// has to be held until the iteration finishes.
// https://github.com/rust-lang/rust-clippy/issues/8987
for s in rwlock.read().unwrap().iter() {
//~^ ERROR: temporary with significant `Drop` in `for` loop condition will live until
//~| NOTE: this might lead to deadlocks or other unexpected behavior
println!("{}", s);
}
}
@ -731,4 +736,69 @@ fn should_not_trigger_for_significant_drop_ref() {
};
}
struct Foo<'a>(&'a Vec<u32>);
impl<'a> Foo<'a> {
fn copy_old_lifetime(&self) -> &'a Vec<u32> {
self.0
}
fn reborrow_new_lifetime(&self) -> &Vec<u32> {
self.0
}
}
fn should_trigger_lint_if_and_only_if_lifetime_is_irrelevant() {
let vec = Vec::new();
let mutex = Mutex::new(Foo(&vec));
// Should trigger lint even if `copy_old_lifetime()` has a lifetime, as the lifetime of
// `&vec` is unrelated to the temporary with significant drop (i.e., the `MutexGuard`).
for val in mutex.lock().unwrap().copy_old_lifetime() {
//~^ ERROR: temporary with significant `Drop` in `for` loop condition will live until the
//~| NOTE: this might lead to deadlocks or other unexpected behavior
println!("{}", val);
}
// Should not trigger lint because `reborrow_new_lifetime()` has a lifetime and the
// lifetime is related to the temporary with significant drop (i.e., the `MutexGuard`).
for val in mutex.lock().unwrap().reborrow_new_lifetime() {
println!("{}", val);
}
}
fn should_not_trigger_lint_for_complex_lifetime() {
let mutex = Mutex::new(vec!["hello".to_owned()]);
let string = "world".to_owned();
// Should not trigger lint due to the relevant lifetime.
for c in mutex.lock().unwrap().first().unwrap().chars() {
println!("{}", c);
}
// Should trigger lint due to the irrelevant lifetime.
//
// FIXME: The lifetime is too complex to analyze. In order to avoid false positives, we do not
// trigger lint.
for c in mutex.lock().unwrap().first().map(|_| &string).unwrap().chars() {
println!("{}", c);
}
}
fn should_not_trigger_lint_with_explicit_drop() {
let mutex = Mutex::new(vec![1]);
// Should not trigger lint since the drop explicitly happens.
for val in [drop(mutex.lock().unwrap()), ()] {
println!("{:?}", val);
}
// Should trigger lint if there is no explicit drop.
for val in [mutex.lock().unwrap()[0], 2] {
//~^ ERROR: temporary with significant `Drop` in `for` loop condition will live until the
//~| NOTE: this might lead to deadlocks or other unexpected behavior
println!("{:?}", val);
}
}
fn main() {}

View file

@ -160,42 +160,10 @@ LL ~ match (mutex1.lock().unwrap().s.len(), true, value) {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:279:15
|
LL | match mutex3.lock().unwrap().s.as_str() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | mutex1.lock().unwrap().s.len();
| ---------------------- another value with significant `Drop` created here
LL | mutex2.lock().unwrap().s.len();
| ---------------------- another value with significant `Drop` created here
...
LL | };
| - temporary lives until here
|
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:291:22
|
LL | match (true, mutex3.lock().unwrap().s.as_str()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | mutex1.lock().unwrap().s.len();
| ---------------------- another value with significant `Drop` created here
LL | mutex2.lock().unwrap().s.len();
| ---------------------- another value with significant `Drop` created here
...
LL | };
| - temporary lives until here
|
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:312:11
--> tests/ui/significant_drop_in_scrutinee.rs:319:11
|
LL | match mutex.lock().unwrap().s.len() > 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | mutex.lock().unwrap().s.len();
| --------------------- another value with significant `Drop` created here
@ -206,15 +174,15 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ let value = mutex.lock().unwrap().s.len() > 1;
LL ~ match value {
LL ~ let value = mutex.lock().unwrap().s.len();
LL ~ match value > 1 {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:321:11
--> tests/ui/significant_drop_in_scrutinee.rs:328:15
|
LL | match 1 < mutex.lock().unwrap().s.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | mutex.lock().unwrap().s.len();
| --------------------- another value with significant `Drop` created here
@ -225,15 +193,15 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ let value = 1 < mutex.lock().unwrap().s.len();
LL ~ match value {
LL ~ let value = mutex.lock().unwrap().s.len();
LL ~ match 1 < value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:341:11
--> tests/ui/significant_drop_in_scrutinee.rs:348:11
|
LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | mutex1.lock().unwrap().s.len(),
| ---------------------- another value with significant `Drop` created here
@ -246,15 +214,36 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ let value = mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len();
LL ~ match value {
LL ~ let value = mutex1.lock().unwrap().s.len();
LL ~ match value < mutex2.lock().unwrap().s.len() {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:354:11
--> tests/ui/significant_drop_in_scrutinee.rs:348:44
|
LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | mutex1.lock().unwrap().s.len(),
| ---------------------- another value with significant `Drop` created here
LL | mutex2.lock().unwrap().s.len()
| ---------------------- another value with significant `Drop` created here
...
LL | };
| - temporary lives until here
|
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ let value = mutex2.lock().unwrap().s.len();
LL ~ match mutex1.lock().unwrap().s.len() < value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:361:11
|
LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | mutex1.lock().unwrap().s.len(),
| ---------------------- another value with significant `Drop` created here
@ -267,15 +256,36 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ let value = mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len();
LL ~ match value {
LL ~ let value = mutex1.lock().unwrap().s.len();
LL ~ match value >= mutex2.lock().unwrap().s.len() {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:391:11
--> tests/ui/significant_drop_in_scrutinee.rs:361:45
|
LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | mutex1.lock().unwrap().s.len(),
| ---------------------- another value with significant `Drop` created here
LL | mutex2.lock().unwrap().s.len()
| ---------------------- another value with significant `Drop` created here
...
LL | };
| - temporary lives until here
|
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ let value = mutex2.lock().unwrap().s.len();
LL ~ match mutex1.lock().unwrap().s.len() >= value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:398:11
|
LL | match get_mutex_guard().s.len() > 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | mutex1.lock().unwrap().s.len();
| ---------------------- another value with significant `Drop` created here
@ -286,12 +296,12 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ let value = get_mutex_guard().s.len() > 1;
LL ~ match value {
LL ~ let value = get_mutex_guard().s.len();
LL ~ match value > 1 {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:410:11
--> tests/ui/significant_drop_in_scrutinee.rs:417:11
|
LL | match match i {
| ___________^
@ -299,9 +309,9 @@ LL | |
LL | |
LL | | 100 => mutex1.lock().unwrap(),
... |
LL | | .s
LL | | .len()
LL | | > 1
| |___________^
| |__________^
...
LL | mutex1.lock().unwrap().s.len();
| ---------------------- another value with significant `Drop` created here
@ -319,13 +329,12 @@ LL + 100 => mutex1.lock().unwrap(),
LL + _ => mutex2.lock().unwrap(),
LL + }
LL + .s
LL + .len()
LL + > 1;
LL + .len();
LL ~ match value
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:438:11
--> tests/ui/significant_drop_in_scrutinee.rs:445:11
|
LL | match if i > 1 {
| ___________^
@ -333,9 +342,9 @@ LL | |
LL | |
LL | | mutex1.lock().unwrap()
... |
LL | | .s
LL | | .len()
LL | | > 1
| |___________^
| |__________^
...
LL | mutex1.lock().unwrap().s.len();
| ---------------------- another value with significant `Drop` created here
@ -354,13 +363,12 @@ LL + } else {
LL + mutex2.lock().unwrap()
LL + }
LL + .s
LL + .len()
LL + > 1;
LL + .len();
LL ~ match value
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:494:11
--> tests/ui/significant_drop_in_scrutinee.rs:501:11
|
LL | match s.lock().deref().deref() {
| ^^^^^^^^^^^^^^^^^^^^^^^^
@ -374,25 +382,11 @@ LL | };
help: try moving the temporary above the match and create a copy
|
LL ~ let value = *s.lock().deref().deref();
LL ~ match value {
LL ~ match (&value) {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:524:11
|
LL | match s.lock().deref().deref() {
| ^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | matcher => println!("Value is {}", s.lock().deref()),
| -------- another value with significant `Drop` created here
LL | _ => println!("Value was not a match"),
LL | };
| - temporary lives until here
|
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:545:11
--> tests/ui/significant_drop_in_scrutinee.rs:551:11
|
LL | match mutex.lock().unwrap().i = i {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -411,10 +405,10 @@ LL ~ match () {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:553:11
--> tests/ui/significant_drop_in_scrutinee.rs:559:15
|
LL | match i = mutex.lock().unwrap().i {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^
...
LL | println!("{}", mutex.lock().unwrap().i);
| --------------------- another value with significant `Drop` created here
@ -425,12 +419,12 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ i = mutex.lock().unwrap().i;
LL ~ match () {
LL ~ let value = mutex.lock().unwrap().i;
LL ~ match i = value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:561:11
--> tests/ui/significant_drop_in_scrutinee.rs:567:11
|
LL | match mutex.lock().unwrap().i += 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -449,10 +443,10 @@ LL ~ match () {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:569:11
--> tests/ui/significant_drop_in_scrutinee.rs:575:16
|
LL | match i += mutex.lock().unwrap().i {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^
...
LL | println!("{}", mutex.lock().unwrap().i);
| --------------------- another value with significant `Drop` created here
@ -463,12 +457,12 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ i += mutex.lock().unwrap().i;
LL ~ match () {
LL ~ let value = mutex.lock().unwrap().i;
LL ~ match i += value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:634:11
--> tests/ui/significant_drop_in_scrutinee.rs:640:11
|
LL | match rwlock.read().unwrap().to_number() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -477,20 +471,14 @@ LL | };
| - temporary lives until here
|
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression
--> tests/ui/significant_drop_in_scrutinee.rs:646:14
help: try moving the temporary above the match
|
LL | for s in rwlock.read().unwrap().iter() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | }
| - temporary lives until here
LL ~ let value = rwlock.read().unwrap().to_number();
LL ~ match value {
|
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:663:11
--> tests/ui/significant_drop_in_scrutinee.rs:668:11
|
LL | match mutex.lock().unwrap().foo() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -506,7 +494,7 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
--> tests/ui/significant_drop_in_scrutinee.rs:726:11
--> tests/ui/significant_drop_in_scrutinee.rs:731:11
|
LL | match guard.take().len() {
| ^^^^^^^^^^^^^^^^^^
@ -521,5 +509,37 @@ LL ~ let value = guard.take().len();
LL ~ match value {
|
error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression
--> tests/ui/significant_drop_in_scrutinee.rs:757:16
|
LL | for val in mutex.lock().unwrap().copy_old_lifetime() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | }
| - temporary lives until here
|
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ let value = mutex.lock().unwrap().copy_old_lifetime();
LL ~ for val in value {
|
error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression
--> tests/ui/significant_drop_in_scrutinee.rs:797:17
|
LL | for val in [mutex.lock().unwrap()[0], 2] {
| ^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | }
| - temporary lives until here
|
= note: this might lead to deadlocks or other unexpected behavior
help: try moving the temporary above the match
|
LL ~ let value = mutex.lock().unwrap()[0];
LL ~ for val in [value, 2] {
|
error: aborting due to 27 previous errors

View file

@ -1,5 +1,4 @@
#![warn(clippy::temporary_assignment)]
#![allow(const_item_mutation)]
use std::ops::{Deref, DerefMut};

View file

@ -1,5 +1,5 @@
error: assignment to temporary
--> tests/ui/temporary_assignment.rs:48:5
--> tests/ui/temporary_assignment.rs:47:5
|
LL | Struct { field: 0 }.field = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | Struct { field: 0 }.field = 1;
= help: to override `-D warnings` add `#[allow(clippy::temporary_assignment)]`
error: assignment to temporary
--> tests/ui/temporary_assignment.rs:51:5
--> tests/ui/temporary_assignment.rs:50:5
|
LL | / MultiStruct {
LL | |
@ -19,13 +19,13 @@ LL | | .field = 1;
| |______________^
error: assignment to temporary
--> tests/ui/temporary_assignment.rs:57:5
--> tests/ui/temporary_assignment.rs:56:5
|
LL | ArrayStruct { array: [0] }.array[0] = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: assignment to temporary
--> tests/ui/temporary_assignment.rs:59:5
--> tests/ui/temporary_assignment.rs:58:5
|
LL | (0, 0).0 = 1;
| ^^^^^^^^^^^^

View file

@ -0,0 +1,8 @@
//@compile-flags: -C incremental=target/debug/test/incr
// see https://github.com/rust-lang/rust-clippy/issues/10969
fn main() {
let s = "Hello, world!";
println!("{}", s);
}

View file

@ -0,0 +1,8 @@
//@compile-flags: -C incremental=target/debug/test/incr
// see https://github.com/rust-lang/rust-clippy/issues/10969
fn main() {
let s = "Hello, world!";
println!("{}", s.to_string());
}

View file

@ -0,0 +1,11 @@
error: `to_string` applied to a type that implements `Display` in `println!` args
--> tests/ui/to_string_in_format_args_incremental.rs:7:21
|
LL | println!("{}", s.to_string());
| ^^^^^^^^^^^^ help: remove this
|
= note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::to_string_in_format_args)]`
error: aborting due to 1 previous error

View file

@ -170,3 +170,32 @@ fn check_mut_iteratee_and_modify_inner_variable() {
}
}
}
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

@ -170,3 +170,32 @@ fn check_mut_iteratee_and_modify_inner_variable() {
}
}
}
mod issue_12821 {
fn foo() {
let v: Vec<_> = "hello".chars().collect();
for c in v.iter().cloned() {
//~^ 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().cloned() {
//~^ 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().cloned() {
//~^ 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

@ -10,7 +10,7 @@ help: use
|
LL | for (t, path) in files {
| ~~~~~
help: remove this `&`
help: remove any references to the binding
|
LL - let other = match get_file_path(&t) {
LL + let other = match get_file_path(t) {
@ -26,11 +26,49 @@ help: use
|
LL | for (t, path) in files.iter() {
| ~~~~~~~~~~~~
help: remove this `&`
help: remove any references to the binding
|
LL - let other = match get_file_path(&t) {
LL + let other = match get_file_path(t) {
|
error: aborting due to 2 previous errors
error: unnecessary use of `cloned`
--> tests/ui/unnecessary_iter_cloned.rs:177: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
|
LL | for c in v.iter().cloned() {
| ^^^^^^^^^^^^^^^^^
|
help: use
|
LL | for c in v.iter() {
| ~~~~~~~~
help: remove any references to the binding
|
LL - let ref_c = &c;
LL + let ref_c = c;
|
error: unnecessary use of `cloned`
--> tests/ui/unnecessary_iter_cloned.rs:194:23
|
LL | for (i, c) in v.iter().cloned() {
| ^^^^^^^^^^^^^^^^^
|
help: use
|
LL | for (i, c) in v.iter() {
| ~~~~~~~~
help: remove any references to the binding
|
LL ~ let ref_c = c;
LL ~ let ref_i = i;
|
error: aborting due to 5 previous errors

View file

@ -487,7 +487,7 @@ help: use
|
LL | for t in file_types {
| ~~~~~~~~~~
help: remove this `&`
help: remove any references to the binding
|
LL - let path = match get_file_path(&t) {
LL + let path = match get_file_path(t) {

View file

@ -1,3 +1,4 @@
#![feature(lint_reasons)]
#![warn(clippy::unsafe_derive_deserialize)]
#![allow(unused, clippy::missing_safety_doc)]
@ -71,4 +72,14 @@ impl G {
}
}
// Check that we honor the `expect` attribute on the ADT
#[expect(clippy::unsafe_derive_deserialize)]
#[derive(Deserialize)]
pub struct H;
impl H {
pub fn unsafe_block(&self) {
unsafe {}
}
}
fn main() {}

View file

@ -1,5 +1,5 @@
error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
--> tests/ui/unsafe_derive_deserialize.rs:8:10
--> tests/ui/unsafe_derive_deserialize.rs:9:10
|
LL | #[derive(Deserialize)]
| ^^^^^^^^^^^
@ -10,7 +10,7 @@ LL | #[derive(Deserialize)]
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
--> tests/ui/unsafe_derive_deserialize.rs:17:10
--> tests/ui/unsafe_derive_deserialize.rs:18:10
|
LL | #[derive(Deserialize)]
| ^^^^^^^^^^^
@ -19,7 +19,7 @@ LL | #[derive(Deserialize)]
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
--> tests/ui/unsafe_derive_deserialize.rs:24:10
--> tests/ui/unsafe_derive_deserialize.rs:25:10
|
LL | #[derive(Deserialize)]
| ^^^^^^^^^^^
@ -28,7 +28,7 @@ LL | #[derive(Deserialize)]
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
--> tests/ui/unsafe_derive_deserialize.rs:33:10
--> tests/ui/unsafe_derive_deserialize.rs:34:10
|
LL | #[derive(Deserialize)]
| ^^^^^^^^^^^