Merge remote-tracking branch 'upstream/master' into rustup
This commit is contained in:
commit
89037ea18f
140 changed files with 1483 additions and 715 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 | |
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -240,3 +240,6 @@ extern {
|
|||
/// `foo()`
|
||||
fn in_extern();
|
||||
}
|
||||
|
||||
/// <https://github.com/rust-lang/rust-clippy/pull/12836>
|
||||
fn check_autofix_for_base_urls() {}
|
||||
|
|
|
|||
|
|
@ -240,3 +240,6 @@ extern {
|
|||
/// foo()
|
||||
fn in_extern();
|
||||
}
|
||||
|
||||
/// https://github.com/rust-lang/rust-clippy/pull/12836
|
||||
fn check_autofix_for_base_urls() {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
9
tests/ui/doc/issue_12795.fixed
Normal file
9
tests/ui/doc/issue_12795.fixed
Normal 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() {}
|
||||
9
tests/ui/doc/issue_12795.rs
Normal file
9
tests/ui/doc/issue_12795.rs
Normal 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() {}
|
||||
48
tests/ui/doc/issue_12795.stderr
Normal file
48
tests/ui/doc/issue_12795.stderr
Normal 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
|
||||
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
//@compile-flags: -Zdeduplicate-diagnostics=yes
|
||||
|
||||
#![allow(clippy::too_many_arguments, clippy::diverging_sub_expression)]
|
||||
#![warn(clippy::many_single_char_names)]
|
||||
|
||||
|
|
|
|||
|
|
@ -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!();
|
||||
| ^ ^ ^ ^ ^ ^ ^ ^
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -323,4 +323,8 @@ fn allow_works() -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
fn conjunctive_blocks() -> String {
|
||||
({ "a".to_string() } + "b" + { "c" })
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -333,4 +333,8 @@ fn allow_works() -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
fn conjunctive_blocks() -> String {
|
||||
return { "a".to_string() } + "b" + { "c" };
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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] };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![warn(clippy::temporary_assignment)]
|
||||
#![allow(const_item_mutation)]
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
|
|||
8
tests/ui/to_string_in_format_args_incremental.fixed
Normal file
8
tests/ui/to_string_in_format_args_incremental.fixed
Normal 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);
|
||||
}
|
||||
8
tests/ui/to_string_in_format_args_incremental.rs
Normal file
8
tests/ui/to_string_in_format_args_incremental.rs
Normal 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());
|
||||
}
|
||||
11
tests/ui/to_string_in_format_args_incremental.stderr
Normal file
11
tests/ui/to_string_in_format_args_incremental.stderr
Normal 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
|
||||
|
||||
|
|
@ -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`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
| ^^^^^^^^^^^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue