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

This commit is contained in:
Philipp Krones 2023-11-02 17:01:56 +01:00
commit 95dc7be92f
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
358 changed files with 3171 additions and 2172 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
--> $DIR/derive.rs:8:1
--> $DIR/derive.rs:7:1
|
LL | / impl Clone for Qux {
LL | |
@ -10,7 +10,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> $DIR/derive.rs:8:1
--> $DIR/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
--> $DIR/derive.rs:33:1
--> $DIR/derive.rs:32:1
|
LL | / impl<'a> Clone for Lt<'a> {
LL | |
@ -34,7 +34,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> $DIR/derive.rs:33:1
--> $DIR/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
--> $DIR/derive.rs:45:1
--> $DIR/derive.rs:44:1
|
LL | / impl Clone for BigArray {
LL | |
@ -56,7 +56,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> $DIR/derive.rs:45:1
--> $DIR/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
--> $DIR/derive.rs:57:1
--> $DIR/derive.rs:56:1
|
LL | / impl Clone for FnPtr {
LL | |
@ -78,7 +78,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> $DIR/derive.rs:57:1
--> $DIR/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
--> $DIR/derive.rs:78:1
--> $DIR/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`
--> $DIR/derive.rs:78:1
--> $DIR/derive.rs:77:1
|
LL | / impl<T: Clone> Clone for Generic2<T> {
LL | |

View file

@ -224,3 +224,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: {
}
}
}
/// this checks if the lowerCamelCase issue is fixed
fn issue_11568() {}

View file

@ -224,3 +224,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: {
}
}
}
/// this checks if the lowerCamelCase issue is fixed
fn issue_11568() {}

View file

@ -204,4 +204,21 @@ mod allow_attributes_on_variants {
}
}
mod issue11494 {
// variant order should not affect lint
enum Data {
Valid,
Invalid,
DataDependent,
//~^ ERROR: variant name starts with the enum's name
}
enum Datas {
DatasDependent,
//~^ ERROR: variant name starts with the enum's name
Valid,
Invalid,
}
}
fn main() {}

View file

@ -158,5 +158,17 @@ LL | | }
|
= help: remove the postfixes and use full paths to the variants instead of glob imports
error: aborting due to 14 previous errors
error: variant name starts with the enum's name
--> $DIR/enum_variants.rs:212:9
|
LL | DataDependent,
| ^^^^^^^^^^^^^
error: variant name starts with the enum's name
--> $DIR/enum_variants.rs:217:9
|
LL | DatasDependent,
| ^^^^^^^^^^^^^^
error: aborting due to 16 previous errors

View file

@ -22,9 +22,9 @@ mod rustc_ok {
#[expect(illegal_floating_point_literal_pattern)]
match x {
5.0 => {}
6.0 => {}
_ => {}
5.0 => {},
6.0 => {},
_ => {},
}
}
}
@ -41,9 +41,9 @@ mod rustc_warn {
#[expect(illegal_floating_point_literal_pattern)]
//~^ ERROR: this lint expectation is unfulfilled
match x {
5 => {}
6 => {}
_ => {}
5 => {},
6 => {},
_ => {},
}
}
}

View file

@ -33,6 +33,9 @@ fn main() {
let _ = a.mul_add(a, b).sqrt();
let u = 1usize;
let _ = b.mul_add(-(u as f64), a);
// Cases where the lint shouldn't be applied
let _ = (a * a + b * b).sqrt();
}

View file

@ -33,6 +33,9 @@ fn main() {
let _ = (a * a + b).sqrt();
let u = 1usize;
let _ = a - (b * u as f64);
// Cases where the lint shouldn't be applied
let _ = (a * a + b * b).sqrt();
}

View file

@ -73,5 +73,11 @@ error: multiply and add expressions can be calculated more efficiently and accur
LL | let _ = (a * a + b).sqrt();
| ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)`
error: aborting due to 12 previous errors
error: multiply and add expressions can be calculated more efficiently and accurately
--> $DIR/floating_point_mul_add.rs:37:13
|
LL | let _ = a - (b * u as f64);
| ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)`
error: aborting due to 13 previous errors

View file

@ -32,9 +32,12 @@ fn main() {
let _ = z[0];
let vecdeque: VecDeque<_> = x.iter().cloned().collect();
let _ = vecdeque.front();
//~^ ERROR: accessing first element with `vecdeque.get(0)`
let _ = vecdeque.get(1);
let hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]);
let btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]);
let _ = vecdeque.get(0); // Do not lint, because VecDeque is not slice.
let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice.
let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice.

View file

@ -32,9 +32,12 @@ fn main() {
let _ = z[0];
let vecdeque: VecDeque<_> = x.iter().cloned().collect();
let _ = vecdeque.get(0);
//~^ ERROR: accessing first element with `vecdeque.get(0)`
let _ = vecdeque.get(1);
let hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]);
let btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]);
let _ = vecdeque.get(0); // Do not lint, because VecDeque is not slice.
let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice.
let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice.

View file

@ -19,11 +19,17 @@ error: accessing first element with `z.get(0)`
LL | let _ = z.get(0);
| ^^^^^^^^ help: try: `z.first()`
error: accessing first element with `vecdeque.get(0)`
--> $DIR/get_first.rs:35:13
|
LL | let _ = vecdeque.get(0);
| ^^^^^^^^^^^^^^^ help: try: `vecdeque.front()`
error: accessing first element with `non_primitives.get(0)`
--> $DIR/get_first.rs:45:13
--> $DIR/get_first.rs:48:13
|
LL | let _ = non_primitives.get(0);
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `non_primitives.first()`
error: aborting due to 4 previous errors
error: aborting due to 5 previous errors

View file

@ -0,0 +1,11 @@
#![deny(clippy::if_not_else)]
fn show_permissions(flags: u32) {
if flags & 0x0F00 != 0 {
println!("Has the 0x0F00 permission.");
} else {
println!("The 0x0F00 permission is missing.");
}
}
fn main() {}

View file

@ -38,3 +38,19 @@ pub fn moo(_: ()) {
let _: () = foo().unwrap();
let _: () = ();
}
fn test_unit_ref_1() {
let x: (usize, &&&&&()) = (1, &&&&&&());
match x {
(1, ()) => unimplemented!(),
//~^ ERROR: matching over `()` is more explicit
_ => unimplemented!(),
};
}
fn test_unit_ref_2(v: &[(usize, ())]) {
for (x, ()) in v {
//~^ ERROR: matching over `()` is more explicit
let _ = x;
}
}

View file

@ -38,3 +38,19 @@ pub fn moo(_: ()) {
let _: () = foo().unwrap();
let _: () = ();
}
fn test_unit_ref_1() {
let x: (usize, &&&&&()) = (1, &&&&&&());
match x {
(1, _) => unimplemented!(),
//~^ ERROR: matching over `()` is more explicit
_ => unimplemented!(),
};
}
fn test_unit_ref_2(v: &[(usize, ())]) {
for (x, _) in v {
//~^ ERROR: matching over `()` is more explicit
let _ = x;
}
}

View file

@ -43,5 +43,17 @@ error: matching over `()` is more explicit
LL | let _ = foo().unwrap();
| ^ help: use `()` instead of `_`: `()`
error: aborting due to 7 previous errors
error: matching over `()` is more explicit
--> $DIR/ignored_unit_patterns.rs:45:13
|
LL | (1, _) => unimplemented!(),
| ^ help: use `()` instead of `_`: `()`
error: matching over `()` is more explicit
--> $DIR/ignored_unit_patterns.rs:52:13
|
LL | for (x, _) in v {
| ^ help: use `()` instead of `_`: `()`
error: aborting due to 9 previous errors

View file

@ -3,127 +3,117 @@
use std::iter::IntoIterator;
fn main() {
{
struct S;
impl<'a> IntoIterator for &'a S {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method
type IntoIter = std::slice::Iter<'a, u8>;
type Item = &'a u8;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
impl<'a> IntoIterator for &'a mut S {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method
type IntoIter = std::slice::IterMut<'a, u8>;
type Item = &'a mut u8;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
pub struct S1;
impl<'a> IntoIterator for &'a S1 {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method
type IntoIter = std::slice::Iter<'a, u8>;
type Item = &'a u8;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
{
struct S<T>(T);
impl<'a, T> IntoIterator for &'a S<T> {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method
type IntoIter = std::slice::Iter<'a, T>;
type Item = &'a T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
impl<'a, T> IntoIterator for &'a mut S<T> {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method
type IntoIter = std::slice::IterMut<'a, T>;
type Item = &'a mut T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
}
{
// Both iter and iter_mut methods exist, don't lint
struct S<'a, T>(&'a T);
impl<'a, T> S<'a, T> {
fn iter(&self) -> std::slice::Iter<'a, T> {
todo!()
}
fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {
todo!()
}
}
impl<'a, T> IntoIterator for &S<'a, T> {
type IntoIter = std::slice::Iter<'a, T>;
type Item = &'a T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
impl<'a, T> IntoIterator for &mut S<'a, T> {
type IntoIter = std::slice::IterMut<'a, T>;
type Item = &'a mut T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
}
{
// Only `iter` exists, no `iter_mut`
struct S<'a, T>(&'a T);
impl<'a, T> S<'a, T> {
fn iter(&self) -> std::slice::Iter<'a, T> {
todo!()
}
}
impl<'a, T> IntoIterator for &S<'a, T> {
type IntoIter = std::slice::Iter<'a, T>;
type Item = &'a T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
impl<'a, T> IntoIterator for &mut S<'a, T> {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method
type IntoIter = std::slice::IterMut<'a, T>;
type Item = &'a mut T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
}
{
// `iter` exists, but `IntoIterator` is implemented for an alias. inherent_impls doesn't "normalize"
// aliases so that `inherent_impls(Alias)` where `type Alias = S` returns nothing, so this can lead
// to fun FPs. Make sure it doesn't happen here (we're using type_of, which should skip the alias).
struct S;
impl S {
fn iter(&self) -> std::slice::Iter<'static, u8> {
todo!()
}
}
type Alias = S;
impl IntoIterator for &Alias {
type IntoIter = std::slice::Iter<'static, u8>;
type Item = &'static u8;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
}
impl<'a> IntoIterator for &'a mut S1 {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method
type IntoIter = std::slice::IterMut<'a, u8>;
type Item = &'a mut u8;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
fn issue11635() {
pub struct S2<T>(T);
impl<'a, T> IntoIterator for &'a S2<T> {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method
type IntoIter = std::slice::Iter<'a, T>;
type Item = &'a T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
impl<'a, T> IntoIterator for &'a mut S2<T> {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method
type IntoIter = std::slice::IterMut<'a, T>;
type Item = &'a mut T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
// Both iter and iter_mut methods exist, don't lint
pub struct S3<'a, T>(&'a T);
impl<'a, T> S3<'a, T> {
fn iter(&self) -> std::slice::Iter<'a, T> {
todo!()
}
fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {
todo!()
}
}
impl<'a, T> IntoIterator for &S3<'a, T> {
type IntoIter = std::slice::Iter<'a, T>;
type Item = &'a T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
impl<'a, T> IntoIterator for &mut S3<'a, T> {
type IntoIter = std::slice::IterMut<'a, T>;
type Item = &'a mut T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
// Only `iter` exists, no `iter_mut`
pub struct S4<'a, T>(&'a T);
impl<'a, T> S4<'a, T> {
fn iter(&self) -> std::slice::Iter<'a, T> {
todo!()
}
}
impl<'a, T> IntoIterator for &S4<'a, T> {
type IntoIter = std::slice::Iter<'a, T>;
type Item = &'a T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
impl<'a, T> IntoIterator for &mut S4<'a, T> {
//~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method
type IntoIter = std::slice::IterMut<'a, T>;
type Item = &'a mut T;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
// `iter` exists, but `IntoIterator` is implemented for an alias. inherent_impls doesn't "normalize"
// aliases so that `inherent_impls(Alias)` where `type Alias = S` returns nothing, so this can lead
// to fun FPs. Make sure it doesn't happen here (we're using type_of, which should skip the alias).
pub struct S5;
impl S5 {
fn iter(&self) -> std::slice::Iter<'static, u8> {
todo!()
}
}
pub type Alias = S5;
impl IntoIterator for &Alias {
type IntoIter = std::slice::Iter<'static, u8>;
type Item = &'static u8;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
fn main() {}
pub mod issue11635 {
// A little more involved than the original repro in the issue, but this tests that it correctly
// works for more than one deref step

View file

@ -1,21 +1,21 @@
error: `IntoIterator` implemented for a reference type without an `iter` method
--> $DIR/into_iter_without_iter.rs:10:9
--> $DIR/into_iter_without_iter.rs:7:1
|
LL | / impl<'a> IntoIterator for &'a S {
LL | / impl<'a> IntoIterator for &'a S1 {
LL | |
LL | | type IntoIter = std::slice::Iter<'a, u8>;
LL | | type Item = &'a u8;
LL | | type IntoIter = std::slice::Iter<'a, u8>;
LL | | type Item = &'a u8;
... |
LL | | }
LL | | }
| |_________^
LL | | }
LL | | }
| |_^
|
= note: `-D clippy::into-iter-without-iter` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::into_iter_without_iter)]`
help: consider implementing `iter`
|
LL ~
LL + impl S {
LL +
LL + impl S1 {
LL + fn iter(&self) -> std::slice::Iter<'a, u8> {
LL + <&Self as IntoIterator>::into_iter(self)
LL + }
@ -23,21 +23,21 @@ LL + }
|
error: `IntoIterator` implemented for a reference type without an `iter_mut` method
--> $DIR/into_iter_without_iter.rs:18:9
--> $DIR/into_iter_without_iter.rs:15:1
|
LL | / impl<'a> IntoIterator for &'a mut S {
LL | / impl<'a> IntoIterator for &'a mut S1 {
LL | |
LL | | type IntoIter = std::slice::IterMut<'a, u8>;
LL | | type Item = &'a mut u8;
LL | | type IntoIter = std::slice::IterMut<'a, u8>;
LL | | type Item = &'a mut u8;
... |
LL | | }
LL | | }
| |_________^
LL | | }
LL | | }
| |_^
|
help: consider implementing `iter_mut`
|
LL ~
LL + impl S {
LL +
LL + impl S1 {
LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, u8> {
LL + <&mut Self as IntoIterator>::into_iter(self)
LL + }
@ -45,21 +45,21 @@ LL + }
|
error: `IntoIterator` implemented for a reference type without an `iter` method
--> $DIR/into_iter_without_iter.rs:29:9
--> $DIR/into_iter_without_iter.rs:25:1
|
LL | / impl<'a, T> IntoIterator for &'a S<T> {
LL | / impl<'a, T> IntoIterator for &'a S2<T> {
LL | |
LL | | type IntoIter = std::slice::Iter<'a, T>;
LL | | type Item = &'a T;
LL | | type IntoIter = std::slice::Iter<'a, T>;
LL | | type Item = &'a T;
... |
LL | | }
LL | | }
| |_________^
LL | | }
LL | | }
| |_^
|
help: consider implementing `iter`
|
LL ~
LL + impl S<T> {
LL +
LL + impl S2<T> {
LL + fn iter(&self) -> std::slice::Iter<'a, T> {
LL + <&Self as IntoIterator>::into_iter(self)
LL + }
@ -67,21 +67,21 @@ LL + }
|
error: `IntoIterator` implemented for a reference type without an `iter_mut` method
--> $DIR/into_iter_without_iter.rs:37:9
--> $DIR/into_iter_without_iter.rs:33:1
|
LL | / impl<'a, T> IntoIterator for &'a mut S<T> {
LL | / impl<'a, T> IntoIterator for &'a mut S2<T> {
LL | |
LL | | type IntoIter = std::slice::IterMut<'a, T>;
LL | | type Item = &'a mut T;
LL | | type IntoIter = std::slice::IterMut<'a, T>;
LL | | type Item = &'a mut T;
... |
LL | | }
LL | | }
| |_________^
LL | | }
LL | | }
| |_^
|
help: consider implementing `iter_mut`
|
LL ~
LL + impl S<T> {
LL +
LL + impl S2<T> {
LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {
LL + <&mut Self as IntoIterator>::into_iter(self)
LL + }
@ -89,21 +89,21 @@ LL + }
|
error: `IntoIterator` implemented for a reference type without an `iter_mut` method
--> $DIR/into_iter_without_iter.rs:93:9
--> $DIR/into_iter_without_iter.rs:84:1
|
LL | / impl<'a, T> IntoIterator for &mut S<'a, T> {
LL | / impl<'a, T> IntoIterator for &mut S4<'a, T> {
LL | |
LL | | type IntoIter = std::slice::IterMut<'a, T>;
LL | | type Item = &'a mut T;
LL | | type IntoIter = std::slice::IterMut<'a, T>;
LL | | type Item = &'a mut T;
... |
LL | | }
LL | | }
| |_________^
LL | | }
LL | | }
| |_^
|
help: consider implementing `iter_mut`
|
LL ~
LL + impl S<'a, T> {
LL +
LL + impl S4<'a, T> {
LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {
LL + <&mut Self as IntoIterator>::into_iter(self)
LL + }

View file

@ -1,120 +1,124 @@
//@no-rustfix
#![warn(clippy::iter_without_into_iter)]
fn main() {
{
struct S;
impl S {
pub fn iter(&self) -> std::slice::Iter<'_, u8> {
//~^ ERROR: `iter` method without an `IntoIterator` impl
[].iter()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
//~^ ERROR: `iter_mut` method without an `IntoIterator` impl
[].iter_mut()
}
}
pub struct S1;
impl S1 {
pub fn iter(&self) -> std::slice::Iter<'_, u8> {
//~^ ERROR: `iter` method without an `IntoIterator` impl
[].iter()
}
{
struct S;
impl S {
pub fn iter(&self) -> impl Iterator<Item = &u8> {
// RPITIT is not stable, so we can't generally suggest it here yet
[].iter()
}
}
}
{
struct S<'a>(&'a mut [u8]);
impl<'a> S<'a> {
pub fn iter(&self) -> std::slice::Iter<'_, u8> {
//~^ ERROR: `iter` method without an `IntoIterator` impl
self.0.iter()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
//~^ ERROR: `iter_mut` method without an `IntoIterator` impl
self.0.iter_mut()
}
}
}
{
// Incompatible signatures
struct S;
impl S {
pub fn iter(self) -> std::slice::Iter<'static, u8> {
todo!()
}
}
struct S2;
impl S2 {
pub async fn iter(&self) -> std::slice::Iter<'static, u8> {
todo!()
}
}
struct S3;
impl S3 {
pub fn iter(&self, _additional_param: ()) -> std::slice::Iter<'static, u8> {
todo!()
}
}
struct S4<T>(T);
impl<T> S4<T> {
pub fn iter<U>(&self) -> std::slice::Iter<'static, (T, U)> {
todo!()
}
}
struct S5<T>(T);
impl<T> S5<T> {
pub fn iter(&self) -> std::slice::Iter<'static, T> {
todo!()
}
}
}
{
struct S<T>(T);
impl<T> S<T> {
pub fn iter(&self) -> std::slice::Iter<'_, T> {
//~^ ERROR: `iter` method without an `IntoIterator` impl
todo!()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
//~^ ERROR: `iter_mut` method without an `IntoIterator` impl
todo!()
}
}
}
{
struct S<T>(T);
impl<T> S<T> {
pub fn iter(&self) -> std::slice::Iter<'_, T> {
// Don't lint, there's an existing (wrong) IntoIterator impl
todo!()
}
}
impl<'a, T> IntoIterator for &'a S<T> {
type Item = &'a String;
type IntoIter = std::slice::Iter<'a, String>;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
}
{
struct S<T>(T);
impl<T> S<T> {
pub fn iter_mut(&self) -> std::slice::IterMut<'_, T> {
// Don't lint, there's an existing (wrong) IntoIterator impl
todo!()
}
}
impl<'a, T> IntoIterator for &'a mut S<T> {
type Item = &'a mut String;
type IntoIter = std::slice::IterMut<'a, String>;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
//~^ ERROR: `iter_mut` method without an `IntoIterator` impl
[].iter_mut()
}
}
pub struct S2;
impl S2 {
pub fn iter(&self) -> impl Iterator<Item = &u8> {
// RPITIT is not stable, so we can't generally suggest it here yet
[].iter()
}
}
pub struct S3<'a>(&'a mut [u8]);
impl<'a> S3<'a> {
pub fn iter(&self) -> std::slice::Iter<'_, u8> {
//~^ ERROR: `iter` method without an `IntoIterator` impl
self.0.iter()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
//~^ ERROR: `iter_mut` method without an `IntoIterator` impl
self.0.iter_mut()
}
}
// Incompatible signatures
pub struct S4;
impl S4 {
pub fn iter(self) -> std::slice::Iter<'static, u8> {
todo!()
}
}
pub struct S5;
impl S5 {
pub async fn iter(&self) -> std::slice::Iter<'static, u8> {
todo!()
}
}
pub struct S6;
impl S6 {
pub fn iter(&self, _additional_param: ()) -> std::slice::Iter<'static, u8> {
todo!()
}
}
pub struct S7<T>(T);
impl<T> S7<T> {
pub fn iter<U>(&self) -> std::slice::Iter<'static, (T, U)> {
todo!()
}
}
pub struct S8<T>(T);
impl<T> S8<T> {
pub fn iter(&self) -> std::slice::Iter<'static, T> {
todo!()
}
}
// ===========================
pub struct S9<T>(T);
impl<T> S9<T> {
pub fn iter(&self) -> std::slice::Iter<'_, T> {
//~^ ERROR: `iter` method without an `IntoIterator` impl
todo!()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
//~^ ERROR: `iter_mut` method without an `IntoIterator` impl
todo!()
}
}
pub struct S10<T>(T);
impl<T> S10<T> {
pub fn iter(&self) -> std::slice::Iter<'_, T> {
// Don't lint, there's an existing (wrong) IntoIterator impl
todo!()
}
}
impl<'a, T> IntoIterator for &'a S10<T> {
type Item = &'a String;
type IntoIter = std::slice::Iter<'a, String>;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
pub struct S11<T>(T);
impl<T> S11<T> {
pub fn iter_mut(&self) -> std::slice::IterMut<'_, T> {
// Don't lint, there's an existing (wrong) IntoIterator impl
todo!()
}
}
impl<'a, T> IntoIterator for &'a mut S11<T> {
type Item = &'a mut String;
type IntoIter = std::slice::IterMut<'a, String>;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
// Private type not exported: don't lint
struct S12;
impl S12 {
fn iter(&self) -> std::slice::Iter<'_, u8> {
todo!()
}
}
fn main() {}

View file

@ -1,146 +1,146 @@
error: `iter` method without an `IntoIterator` impl for `&S`
--> $DIR/iter_without_into_iter.rs:8:13
error: `iter` method without an `IntoIterator` impl for `&S1`
--> $DIR/iter_without_into_iter.rs:6:5
|
LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> {
LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> {
LL | |
LL | | [].iter()
LL | | }
| |_____________^
LL | | [].iter()
LL | | }
| |_____^
|
= note: `-D clippy::iter-without-into-iter` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::iter_without_into_iter)]`
help: consider implementing `IntoIterator` for `&S`
help: consider implementing `IntoIterator` for `&S1`
|
LL ~
LL + impl IntoIterator for &S {
LL +
LL + impl IntoIterator for &S1 {
LL + type IntoIter = std::slice::Iter<'_, u8>;
LL + type Iter = &u8;
LL + fn into_iter() -> Self::IntoIter {
LL + type Item = &u8;
LL + fn into_iter(self) -> Self::IntoIter {
LL + self.iter()
LL + }
LL + }
|
error: `iter_mut` method without an `IntoIterator` impl for `&mut S`
--> $DIR/iter_without_into_iter.rs:12:13
error: `iter_mut` method without an `IntoIterator` impl for `&mut S1`
--> $DIR/iter_without_into_iter.rs:10:5
|
LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
LL | |
LL | | [].iter_mut()
LL | | }
| |_____________^
LL | | [].iter_mut()
LL | | }
| |_____^
|
help: consider implementing `IntoIterator` for `&mut S`
help: consider implementing `IntoIterator` for `&mut S1`
|
LL ~
LL + impl IntoIterator for &mut S {
LL +
LL + impl IntoIterator for &mut S1 {
LL + type IntoIter = std::slice::IterMut<'_, u8>;
LL + type Iter = &mut u8;
LL + fn into_iter() -> Self::IntoIter {
LL + type Item = &mut u8;
LL + fn into_iter(self) -> Self::IntoIter {
LL + self.iter()
LL + }
LL + }
|
error: `iter` method without an `IntoIterator` impl for `&S<'a>`
--> $DIR/iter_without_into_iter.rs:30:13
error: `iter` method without an `IntoIterator` impl for `&S3<'a>`
--> $DIR/iter_without_into_iter.rs:26:5
|
LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> {
LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> {
LL | |
LL | | self.0.iter()
LL | | }
| |_____________^
LL | | self.0.iter()
LL | | }
| |_____^
|
help: consider implementing `IntoIterator` for `&S<'a>`
help: consider implementing `IntoIterator` for `&S3<'a>`
|
LL ~
LL + impl IntoIterator for &S<'a> {
LL +
LL + impl IntoIterator for &S3<'a> {
LL + type IntoIter = std::slice::Iter<'_, u8>;
LL + type Iter = &u8;
LL + fn into_iter() -> Self::IntoIter {
LL + type Item = &u8;
LL + fn into_iter(self) -> Self::IntoIter {
LL + self.iter()
LL + }
LL + }
|
error: `iter_mut` method without an `IntoIterator` impl for `&mut S<'a>`
--> $DIR/iter_without_into_iter.rs:34:13
error: `iter_mut` method without an `IntoIterator` impl for `&mut S3<'a>`
--> $DIR/iter_without_into_iter.rs:30:5
|
LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
LL | |
LL | | self.0.iter_mut()
LL | | }
| |_____________^
LL | | self.0.iter_mut()
LL | | }
| |_____^
|
help: consider implementing `IntoIterator` for `&mut S<'a>`
help: consider implementing `IntoIterator` for `&mut S3<'a>`
|
LL ~
LL + impl IntoIterator for &mut S<'a> {
LL +
LL + impl IntoIterator for &mut S3<'a> {
LL + type IntoIter = std::slice::IterMut<'_, u8>;
LL + type Iter = &mut u8;
LL + fn into_iter() -> Self::IntoIter {
LL + type Item = &mut u8;
LL + fn into_iter(self) -> Self::IntoIter {
LL + self.iter()
LL + }
LL + }
|
error: `iter` method without an `IntoIterator` impl for `&S5<T>`
--> $DIR/iter_without_into_iter.rs:68:13
error: `iter` method without an `IntoIterator` impl for `&S8<T>`
--> $DIR/iter_without_into_iter.rs:67:5
|
LL | / pub fn iter(&self) -> std::slice::Iter<'static, T> {
LL | | todo!()
LL | | }
| |_____________^
LL | / pub fn iter(&self) -> std::slice::Iter<'static, T> {
LL | | todo!()
LL | | }
| |_____^
|
help: consider implementing `IntoIterator` for `&S5<T>`
help: consider implementing `IntoIterator` for `&S8<T>`
|
LL ~
LL + impl IntoIterator for &S5<T> {
LL +
LL + impl IntoIterator for &S8<T> {
LL + type IntoIter = std::slice::Iter<'static, T>;
LL + type Iter = &T;
LL + fn into_iter() -> Self::IntoIter {
LL + type Item = &T;
LL + fn into_iter(self) -> Self::IntoIter {
LL + self.iter()
LL + }
LL + }
|
error: `iter` method without an `IntoIterator` impl for `&S<T>`
--> $DIR/iter_without_into_iter.rs:76:13
error: `iter` method without an `IntoIterator` impl for `&S9<T>`
--> $DIR/iter_without_into_iter.rs:75:5
|
LL | / pub fn iter(&self) -> std::slice::Iter<'_, T> {
LL | / pub fn iter(&self) -> std::slice::Iter<'_, T> {
LL | |
LL | | todo!()
LL | | }
| |_____________^
LL | | todo!()
LL | | }
| |_____^
|
help: consider implementing `IntoIterator` for `&S<T>`
help: consider implementing `IntoIterator` for `&S9<T>`
|
LL ~
LL + impl IntoIterator for &S<T> {
LL +
LL + impl IntoIterator for &S9<T> {
LL + type IntoIter = std::slice::Iter<'_, T>;
LL + type Iter = &T;
LL + fn into_iter() -> Self::IntoIter {
LL + type Item = &T;
LL + fn into_iter(self) -> Self::IntoIter {
LL + self.iter()
LL + }
LL + }
|
error: `iter_mut` method without an `IntoIterator` impl for `&mut S<T>`
--> $DIR/iter_without_into_iter.rs:80:13
error: `iter_mut` method without an `IntoIterator` impl for `&mut S9<T>`
--> $DIR/iter_without_into_iter.rs:79:5
|
LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
LL | |
LL | | todo!()
LL | | }
| |_____________^
LL | | todo!()
LL | | }
| |_____^
|
help: consider implementing `IntoIterator` for `&mut S<T>`
help: consider implementing `IntoIterator` for `&mut S9<T>`
|
LL ~
LL + impl IntoIterator for &mut S<T> {
LL +
LL + impl IntoIterator for &mut S9<T> {
LL + type IntoIter = std::slice::IterMut<'_, T>;
LL + type Iter = &mut T;
LL + fn into_iter() -> Self::IntoIter {
LL + type Item = &mut T;
LL + fn into_iter(self) -> Self::IntoIter {
LL + self.iter()
LL + }
LL + }

View file

@ -168,7 +168,26 @@ mod issue_5729 {
impl<T: Foo + 'static> FooStorage for FooStorageImpl<T> {
fn foo_cloned(&self) -> Arc<dyn Foo> {
Arc::clone(&self.foo) as _
(Arc::clone(&self.foo)) as _
//~^ ERROR: returning the result of a `let` binding from a block
}
}
}
mod issue_11335 {
pub enum E<T> {
A(T),
B(T),
}
impl<T> E<T> {
pub fn inner(&self) -> &T {
(match self {
E::A(x) => x,
E::B(x) => x,
}) as _
//~^ ERROR: returning the result of a `let` binding from a block
}
}

View file

@ -174,6 +174,25 @@ mod issue_5729 {
}
}
mod issue_11335 {
pub enum E<T> {
A(T),
B(T),
}
impl<T> E<T> {
pub fn inner(&self) -> &T {
let result = match self {
E::A(x) => x,
E::B(x) => x,
};
result
//~^ ERROR: returning the result of a `let` binding from a block
}
}
}
// https://github.com/rust-lang/rust-clippy/issues/11167
macro_rules! fn_in_macro {
($b:block) => {

View file

@ -53,8 +53,30 @@ LL | clone
help: return the expression directly
|
LL ~
LL ~ Arc::clone(&self.foo) as _
LL ~ (Arc::clone(&self.foo)) as _
|
error: aborting due to 4 previous errors
error: returning the result of a `let` binding from a block
--> $DIR/let_and_return.rs:190:13
|
LL | / let result = match self {
LL | | E::A(x) => x,
LL | | E::B(x) => x,
LL | | };
| |______________- unnecessary `let` binding
LL |
LL | result
| ^^^^^^
|
help: return the expression directly
|
LL ~
LL |
LL ~ (match self {
LL + E::A(x) => x,
LL + E::B(x) => x,
LL + }) as _
|
error: aborting due to 5 previous errors

View file

@ -1,4 +1,5 @@
#![warn(clippy::manual_string_new)]
#![allow(clippy::unnecessary_fallible_conversions)]
macro_rules! create_strings_from_macro {
// When inside a macro, nothing should warn to prevent false positives.

View file

@ -1,4 +1,5 @@
#![warn(clippy::manual_string_new)]
#![allow(clippy::unnecessary_fallible_conversions)]
macro_rules! create_strings_from_macro {
// When inside a macro, nothing should warn to prevent false positives.

View file

@ -1,5 +1,5 @@
error: empty String is being created manually
--> $DIR/manual_string_new.rs:13:13
--> $DIR/manual_string_new.rs:14:13
|
LL | let _ = "".to_string();
| ^^^^^^^^^^^^^^ help: consider using: `String::new()`
@ -8,49 +8,49 @@ LL | let _ = "".to_string();
= help: to override `-D warnings` add `#[allow(clippy::manual_string_new)]`
error: empty String is being created manually
--> $DIR/manual_string_new.rs:16:13
--> $DIR/manual_string_new.rs:17:13
|
LL | let _ = "".to_owned();
| ^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
--> $DIR/manual_string_new.rs:19:21
--> $DIR/manual_string_new.rs:20:21
|
LL | let _: String = "".into();
| ^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
--> $DIR/manual_string_new.rs:26:13
--> $DIR/manual_string_new.rs:27:13
|
LL | let _ = String::from("");
| ^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
--> $DIR/manual_string_new.rs:27:13
--> $DIR/manual_string_new.rs:28:13
|
LL | let _ = <String>::from("");
| ^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
--> $DIR/manual_string_new.rs:32:13
--> $DIR/manual_string_new.rs:33:13
|
LL | let _ = String::try_from("").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
--> $DIR/manual_string_new.rs:38:21
--> $DIR/manual_string_new.rs:39:21
|
LL | let _: String = From::from("");
| ^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
--> $DIR/manual_string_new.rs:43:21
--> $DIR/manual_string_new.rs:44:21
|
LL | let _: String = TryFrom::try_from("").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
--> $DIR/manual_string_new.rs:46:21
--> $DIR/manual_string_new.rs:47:21
|
LL | let _: String = TryFrom::try_from("").expect("this should warn");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`

View file

@ -22,6 +22,30 @@ fn main() {
let _ = Ok(1).map_err(std::convert::identity::<u32>);
}
fn issue7189() {
// should lint
let x = [(1, 2), (3, 4)];
let _ = x.iter();
let _ = x.iter();
let _ = x.iter();
let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))];
let _ = y.iter();
// should not lint
let _ = x.iter().map(|(x, y)| (x, y, y));
let _ = x.iter().map(|(x, _y)| (x,));
let _ = x.iter().map(|(x, _)| (x,));
let _ = x.iter().map(|(x, ..)| (x,));
let _ = y.iter().map(|(x, y, (z, _))| (x, y, (z, z)));
let _ = y
.iter()
.map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z)));
let _ = y
.iter()
.map(|(x, y, (z, (w,))): &(i32, i32, (i32, (i32,)))| (x, y, (z, (w,))));
}
fn not_identity(x: &u16) -> u16 {
*x
}

View file

@ -24,6 +24,32 @@ fn main() {
let _ = Ok(1).map_err(std::convert::identity::<u32>);
}
fn issue7189() {
// should lint
let x = [(1, 2), (3, 4)];
let _ = x.iter().map(|(x, y)| (x, y));
let _ = x.iter().map(|(x, y)| {
return (x, y);
});
let _ = x.iter().map(|(x, y)| return (x, y));
let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))];
let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));
// should not lint
let _ = x.iter().map(|(x, y)| (x, y, y));
let _ = x.iter().map(|(x, _y)| (x,));
let _ = x.iter().map(|(x, _)| (x,));
let _ = x.iter().map(|(x, ..)| (x,));
let _ = y.iter().map(|(x, y, (z, _))| (x, y, (z, z)));
let _ = y
.iter()
.map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z)));
let _ = y
.iter()
.map(|(x, y, (z, (w,))): &(i32, i32, (i32, (i32,)))| (x, y, (z, (w,))));
}
fn not_identity(x: &u16) -> u16 {
*x
}

View file

@ -40,5 +40,32 @@ error: unnecessary map of the identity function
LL | let _: Result<u32, u32> = Ok(1).map_err(|a| a);
| ^^^^^^^^^^^^^^^ help: remove the call to `map_err`
error: aborting due to 6 previous errors
error: unnecessary map of the identity function
--> $DIR/map_identity.rs:30:21
|
LL | let _ = x.iter().map(|(x, y)| (x, y));
| ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
error: unnecessary map of the identity function
--> $DIR/map_identity.rs:31:21
|
LL | let _ = x.iter().map(|(x, y)| {
| _____________________^
LL | | return (x, y);
LL | | });
| |______^ help: remove the call to `map`
error: unnecessary map of the identity function
--> $DIR/map_identity.rs:34:21
|
LL | let _ = x.iter().map(|(x, y)| return (x, y));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
error: unnecessary map of the identity function
--> $DIR/map_identity.rs:37:21
|
LL | let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
error: aborting due to 10 previous errors

View file

@ -11,13 +11,12 @@ fn outer_attr() {}
mod multiple {
#![clippy::msrv = "1.40"]
#![clippy::msrv = "=1.35.0"]
//~^ ERROR: `msrv` is defined multiple times
#![clippy::msrv = "1.10.1"]
//~^ ERROR: `msrv` is defined multiple times
//~^ ERROR: `clippy::msrv` is defined multiple times
mod foo {
#![clippy::msrv = "1"]
#![clippy::msrv = "1.0.0"]
//~^ ERROR: `msrv` is defined multiple times
//~^ ERROR: `clippy::msrv` is defined multiple times
}
}

View file

@ -10,20 +10,8 @@ error: `invalid.version` is not a valid Rust version
LL | #[clippy::msrv = "invalid.version"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:13:5
|
LL | #![clippy::msrv = "=1.35.0"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first definition found here
--> $DIR/min_rust_version_invalid_attr.rs:12:5
|
LL | #![clippy::msrv = "1.40"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:15:5
error: `clippy::msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:14:5
|
LL | #![clippy::msrv = "1.10.1"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -34,17 +22,17 @@ note: first definition found here
LL | #![clippy::msrv = "1.40"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:20:9
error: `clippy::msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:19:9
|
LL | #![clippy::msrv = "1.0.0"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first definition found here
--> $DIR/min_rust_version_invalid_attr.rs:19:9
--> $DIR/min_rust_version_invalid_attr.rs:18:9
|
LL | #![clippy::msrv = "1"]
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

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

@ -1,7 +1,6 @@
#![warn(clippy::option_if_let_else)]
#![allow(
unused_tuple_struct_fields,
clippy::redundant_closure,
clippy::ref_option_ref,
clippy::equatable_if_let,
clippy::let_unit_value,
@ -52,7 +51,7 @@ fn impure_else(arg: Option<i32>) {
println!("return 1");
1
};
let _ = arg.map_or_else(|| side_effect(), |x| x);
let _ = arg.map_or_else(side_effect, |x| x);
}
fn test_map_or_else(arg: Option<u32>) {
@ -224,3 +223,17 @@ mod issue10729 {
fn do_something(_value: &str) {}
fn do_something2(_value: &mut str) {}
}
fn issue11429() {
use std::collections::HashMap;
macro_rules! new_map {
() => {{ HashMap::new() }};
}
let opt: Option<HashMap<u8, u8>> = None;
let mut _hashmap = opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone());
let mut _hm = opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone());
}

View file

@ -1,7 +1,6 @@
#![warn(clippy::option_if_let_else)]
#![allow(
unused_tuple_struct_fields,
clippy::redundant_closure,
clippy::ref_option_ref,
clippy::equatable_if_let,
clippy::let_unit_value,
@ -271,3 +270,21 @@ mod issue10729 {
fn do_something(_value: &str) {}
fn do_something2(_value: &mut str) {}
}
fn issue11429() {
use std::collections::HashMap;
macro_rules! new_map {
() => {{ HashMap::new() }};
}
let opt: Option<HashMap<u8, u8>> = None;
let mut _hashmap = if let Some(hm) = &opt {
hm.clone()
} else {
HashMap::new()
};
let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() };
}

View file

@ -1,5 +1,5 @@
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:12:5
--> $DIR/option_if_let_else.rs:11:5
|
LL | / if let Some(x) = string {
LL | | (true, x)
@ -12,19 +12,19 @@ LL | | }
= help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:30:13
--> $DIR/option_if_let_else.rs:29:13
|
LL | let _ = if let Some(s) = *string { s.len() } else { 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:31:13
--> $DIR/option_if_let_else.rs:30:13
|
LL | let _ = if let Some(s) = &num { s } else { &0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:32:13
--> $DIR/option_if_let_else.rs:31:13
|
LL | let _ = if let Some(s) = &mut num {
| _____________^
@ -44,13 +44,13 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:38:13
--> $DIR/option_if_let_else.rs:37:13
|
LL | let _ = if let Some(ref s) = num { s } else { &0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:39:13
--> $DIR/option_if_let_else.rs:38:13
|
LL | let _ = if let Some(mut s) = num {
| _____________^
@ -70,7 +70,7 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:45:13
--> $DIR/option_if_let_else.rs:44:13
|
LL | let _ = if let Some(ref mut s) = num {
| _____________^
@ -90,7 +90,7 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:54:5
--> $DIR/option_if_let_else.rs:53:5
|
LL | / if let Some(x) = arg {
LL | | let y = x * x;
@ -109,7 +109,7 @@ LL + })
|
error: use Option::map_or_else instead of an if let/else
--> $DIR/option_if_let_else.rs:67:13
--> $DIR/option_if_let_else.rs:66:13
|
LL | let _ = if let Some(x) = arg {
| _____________^
@ -118,10 +118,10 @@ LL | | } else {
LL | | // map_or_else must be suggested
LL | | side_effect()
LL | | };
| |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)`
| |_____^ help: try: `arg.map_or_else(side_effect, |x| x)`
error: use Option::map_or_else instead of an if let/else
--> $DIR/option_if_let_else.rs:76:13
--> $DIR/option_if_let_else.rs:75:13
|
LL | let _ = if let Some(x) = arg {
| _____________^
@ -144,7 +144,7 @@ LL ~ }, |x| x * x * x * x);
|
error: use Option::map_or_else instead of an if let/else
--> $DIR/option_if_let_else.rs:109:13
--> $DIR/option_if_let_else.rs:108:13
|
LL | / if let Some(idx) = s.find('.') {
LL | | vec![s[..idx].to_string(), s[idx..].to_string()]
@ -154,7 +154,7 @@ LL | | }
| |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])`
error: use Option::map_or_else instead of an if let/else
--> $DIR/option_if_let_else.rs:120:5
--> $DIR/option_if_let_else.rs:119:5
|
LL | / if let Ok(binding) = variable {
LL | | println!("Ok {binding}");
@ -173,13 +173,13 @@ LL + })
|
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:142:13
--> $DIR/option_if_let_else.rs:141:13
|
LL | let _ = if let Some(x) = optional { x + 2 } else { 5 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:152:13
--> $DIR/option_if_let_else.rs:151:13
|
LL | let _ = if let Some(x) = Some(0) {
| _____________^
@ -201,13 +201,13 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:180:13
--> $DIR/option_if_let_else.rs:179:13
|
LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:184:13
--> $DIR/option_if_let_else.rs:183:13
|
LL | let _ = if let Some(x) = Some(0) {
| _____________^
@ -227,7 +227,7 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:223:13
--> $DIR/option_if_let_else.rs:222:13
|
LL | let _ = match s {
| _____________^
@ -237,7 +237,7 @@ LL | | };
| |_____^ help: try: `s.map_or(1, |string| string.len())`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:227:13
--> $DIR/option_if_let_else.rs:226:13
|
LL | let _ = match Some(10) {
| _____________^
@ -247,7 +247,7 @@ LL | | };
| |_____^ help: try: `Some(10).map_or(5, |a| a + 1)`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:233:13
--> $DIR/option_if_let_else.rs:232:13
|
LL | let _ = match res {
| _____________^
@ -257,7 +257,7 @@ LL | | };
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:237:13
--> $DIR/option_if_let_else.rs:236:13
|
LL | let _ = match res {
| _____________^
@ -267,13 +267,13 @@ LL | | };
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:241:13
--> $DIR/option_if_let_else.rs:240:13
|
LL | let _ = if let Ok(a) = res { a + 1 } else { 5 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:258:9
--> $DIR/option_if_let_else.rs:257:9
|
LL | / match initial {
LL | | Some(value) => do_something(value),
@ -282,7 +282,7 @@ LL | | }
| |_________^ help: try: `initial.as_ref().map_or({}, |value| do_something(value))`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:265:9
--> $DIR/option_if_let_else.rs:264:9
|
LL | / match initial {
LL | | Some(value) => do_something2(value),
@ -290,5 +290,22 @@ LL | | None => {},
LL | | }
| |_________^ help: try: `initial.as_mut().map_or({}, |value| do_something2(value))`
error: aborting due to 23 previous errors
error: use Option::map_or_else instead of an if let/else
--> $DIR/option_if_let_else.rs:283:24
|
LL | let mut _hashmap = if let Some(hm) = &opt {
| ________________________^
LL | | hm.clone()
LL | | } else {
LL | | HashMap::new()
LL | | };
| |_____^ help: try: `opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone())`
error: use Option::map_or_else instead of an if let/else
--> $DIR/option_if_let_else.rs:289:19
|
LL | let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())`
error: aborting due to 25 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
--> $DIR/temporary_assignment.rs:48:5
--> $DIR/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
--> $DIR/temporary_assignment.rs:51:5
--> $DIR/temporary_assignment.rs:50:5
|
LL | / MultiStruct {
LL | |
@ -19,13 +19,13 @@ LL | | .field = 1;
| |______________^
error: assignment to temporary
--> $DIR/temporary_assignment.rs:57:5
--> $DIR/temporary_assignment.rs:56:5
|
LL | ArrayStruct { array: [0] }.array[0] = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: assignment to temporary
--> $DIR/temporary_assignment.rs:59:5
--> $DIR/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.to_string());
}

View file

@ -0,0 +1,11 @@
error: `to_string` applied to a type that implements `Display` in `println!` args
--> $DIR/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 previous error

View file

@ -0,0 +1,6 @@
#![warn(clippy::unnecessary_fallible_conversions)]
fn main() {
let _: i64 = 0i32.into();
let _: i64 = 0i32.into();
}

View file

@ -0,0 +1,6 @@
#![warn(clippy::unnecessary_fallible_conversions)]
fn main() {
let _: i64 = 0i32.try_into().unwrap();
let _: i64 = 0i32.try_into().expect("can't happen");
}

View file

@ -0,0 +1,17 @@
error: use of a fallible conversion when an infallible one could be used
--> $DIR/unnecessary_fallible_conversions.rs:4:23
|
LL | let _: i64 = 0i32.try_into().unwrap();
| ^^^^^^^^^^^^^^^^^^^ help: use: `into()`
|
= note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]`
error: use of a fallible conversion when an infallible one could be used
--> $DIR/unnecessary_fallible_conversions.rs:5:23
|
LL | let _: i64 = 0i32.try_into().expect("can't happen");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `into()`
error: aborting due to 2 previous errors

View file

@ -0,0 +1,43 @@
//@aux-build:proc_macros.rs
//@no-rustfix
#![warn(clippy::unnecessary_fallible_conversions)]
extern crate proc_macros;
struct Foo;
impl TryFrom<i32> for Foo {
type Error = ();
fn try_from(_: i32) -> Result<Self, Self::Error> {
Ok(Foo)
}
}
impl From<i64> for Foo {
fn from(_: i64) -> Self {
Foo
}
}
fn main() {
// `Foo` only implements `TryFrom<i32>` and not `From<i32>`, so don't lint
let _: Result<Foo, _> = 0i32.try_into();
let _: Result<Foo, _> = i32::try_into(0i32);
let _: Result<Foo, _> = Foo::try_from(0i32);
// ... it does impl From<i64> however
let _: Result<Foo, _> = 0i64.try_into();
//~^ ERROR: use of a fallible conversion when an infallible one could be used
let _: Result<Foo, _> = i64::try_into(0i64);
//~^ ERROR: use of a fallible conversion when an infallible one could be used
let _: Result<Foo, _> = Foo::try_from(0i64);
//~^ ERROR: use of a fallible conversion when an infallible one could be used
let _: Result<i64, _> = 0i32.try_into();
//~^ ERROR: use of a fallible conversion when an infallible one could be used
let _: Result<i64, _> = i32::try_into(0i32);
//~^ ERROR: use of a fallible conversion when an infallible one could be used
let _: Result<i64, _> = <_>::try_from(0i32);
//~^ ERROR: use of a fallible conversion when an infallible one could be used
// From a macro
let _: Result<i64, _> = proc_macros::external!(0i32).try_into();
}

View file

@ -0,0 +1,41 @@
error: use of a fallible conversion when an infallible one could be used
--> $DIR/unnecessary_fallible_conversions_unfixable.rs:27:34
|
LL | let _: Result<Foo, _> = 0i64.try_into();
| ^^^^^^^^ help: use: `into`
|
= note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]`
error: use of a fallible conversion when an infallible one could be used
--> $DIR/unnecessary_fallible_conversions_unfixable.rs:29:29
|
LL | let _: Result<Foo, _> = i64::try_into(0i64);
| ^^^^^^^^^^^^^ help: use: `Into::into`
error: use of a fallible conversion when an infallible one could be used
--> $DIR/unnecessary_fallible_conversions_unfixable.rs:31:29
|
LL | let _: Result<Foo, _> = Foo::try_from(0i64);
| ^^^^^^^^^^^^^ help: use: `From::from`
error: use of a fallible conversion when an infallible one could be used
--> $DIR/unnecessary_fallible_conversions_unfixable.rs:34:34
|
LL | let _: Result<i64, _> = 0i32.try_into();
| ^^^^^^^^ help: use: `into`
error: use of a fallible conversion when an infallible one could be used
--> $DIR/unnecessary_fallible_conversions_unfixable.rs:36:29
|
LL | let _: Result<i64, _> = i32::try_into(0i32);
| ^^^^^^^^^^^^^ help: use: `Into::into`
error: use of a fallible conversion when an infallible one could be used
--> $DIR/unnecessary_fallible_conversions_unfixable.rs:38:29
|
LL | let _: Result<i64, _> = <_>::try_from(0i32);
| ^^^^^^^^^^^^^ help: use: `From::from`
error: aborting due to 6 previous errors

View file

@ -0,0 +1,58 @@
#![allow(unused)]
#![warn(clippy::unused_enumerate_index)]
use std::iter::Enumerate;
fn main() {
let v = [1, 2, 3];
for x in v.iter() {
println!("{x}");
}
struct Dummy1;
impl Dummy1 {
fn enumerate(self) -> Vec<usize> {
vec![]
}
}
let dummy = Dummy1;
for x in dummy.enumerate() {
println!("{x}");
}
struct Dummy2;
impl Dummy2 {
fn enumerate(self) -> Enumerate<std::vec::IntoIter<usize>> {
vec![1, 2].into_iter().enumerate()
}
}
let dummy = Dummy2;
for (_, x) in dummy.enumerate() {
println!("{x}");
}
let mut with_used_iterator = [1, 2, 3].into_iter().enumerate();
with_used_iterator.next();
for (_, x) in with_used_iterator {
println!("{x}");
}
struct Dummy3(std::vec::IntoIter<usize>);
impl Iterator for Dummy3 {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
let dummy = Dummy3(vec![1, 2, 3].into_iter());
for x in dummy {
println!("{x}");
}
}

View file

@ -0,0 +1,58 @@
#![allow(unused)]
#![warn(clippy::unused_enumerate_index)]
use std::iter::Enumerate;
fn main() {
let v = [1, 2, 3];
for (_, x) in v.iter().enumerate() {
println!("{x}");
}
struct Dummy1;
impl Dummy1 {
fn enumerate(self) -> Vec<usize> {
vec![]
}
}
let dummy = Dummy1;
for x in dummy.enumerate() {
println!("{x}");
}
struct Dummy2;
impl Dummy2 {
fn enumerate(self) -> Enumerate<std::vec::IntoIter<usize>> {
vec![1, 2].into_iter().enumerate()
}
}
let dummy = Dummy2;
for (_, x) in dummy.enumerate() {
println!("{x}");
}
let mut with_used_iterator = [1, 2, 3].into_iter().enumerate();
with_used_iterator.next();
for (_, x) in with_used_iterator {
println!("{x}");
}
struct Dummy3(std::vec::IntoIter<usize>);
impl Iterator for Dummy3 {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
let dummy = Dummy3(vec![1, 2, 3].into_iter());
for (_, x) in dummy.enumerate() {
println!("{x}");
}
}

View file

@ -0,0 +1,26 @@
error: you seem to use `.enumerate()` and immediately discard the index
--> $DIR/unused_enumerate_index.rs:8:19
|
LL | for (_, x) in v.iter().enumerate() {
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unused-enumerate-index` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::unused_enumerate_index)]`
help: remove the `.enumerate()` call
|
LL | for x in v.iter() {
| ~ ~~~~~~~~
error: you seem to use `.enumerate()` and immediately discard the index
--> $DIR/unused_enumerate_index.rs:55:19
|
LL | for (_, x) in dummy.enumerate() {
| ^^^^^^^^^^^^^^^^^
|
help: remove the `.enumerate()` call
|
LL | for x in dummy {
| ~ ~~~~~
error: aborting due to 2 previous errors

View file

@ -1,5 +1,5 @@
#![deny(clippy::useless_conversion)]
#![allow(clippy::needless_if)]
#![allow(clippy::needless_if, clippy::unnecessary_fallible_conversions)]
fn test_generic<T: Copy>(val: T) -> T {
let _ = T::try_from(val).unwrap();

View file

@ -0,0 +1,29 @@
#[derive(Clone)]
pub struct Custom;
impl Custom {
pub fn wake(self) {}
}
macro_rules! mac {
($cx:ident) => {
$cx.waker()
};
}
pub fn wake(cx: &mut std::task::Context) {
cx.waker().wake_by_ref();
mac!(cx).wake_by_ref();
}
pub fn no_lint(cx: &mut std::task::Context, c: &Custom) {
c.clone().wake();
let w = cx.waker().clone();
w.wake();
cx.waker().clone().wake_by_ref();
}
fn main() {}

View file

@ -0,0 +1,29 @@
#[derive(Clone)]
pub struct Custom;
impl Custom {
pub fn wake(self) {}
}
macro_rules! mac {
($cx:ident) => {
$cx.waker()
};
}
pub fn wake(cx: &mut std::task::Context) {
cx.waker().clone().wake();
mac!(cx).clone().wake();
}
pub fn no_lint(cx: &mut std::task::Context, c: &Custom) {
c.clone().wake();
let w = cx.waker().clone();
w.wake();
cx.waker().clone().wake_by_ref();
}
fn main() {}

View file

@ -0,0 +1,17 @@
error: cloning a `Waker` only to wake it
--> $DIR/waker_clone_wake.rs:15:5
|
LL | cx.waker().clone().wake();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `cx.waker().wake_by_ref()`
|
= note: `-D clippy::waker-clone-wake` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::waker_clone_wake)]`
error: cloning a `Waker` only to wake it
--> $DIR/waker_clone_wake.rs:17:5
|
LL | mac!(cx).clone().wake();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `mac!(cx).wake_by_ref()`
error: aborting due to 2 previous errors