diff options
Diffstat (limited to 'src/tools/clippy/tests/ui')
228 files changed, 4696 insertions, 866 deletions
diff --git a/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs b/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs index d03a577c4..349e81912 100644 --- a/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs +++ b/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs @@ -33,16 +33,16 @@ fn main() { let _ = Arc::new(42); let _ = Arc::new(RefCell::new(42)); - //~^ ERROR: usage of an `Arc` that is not `Send` or `Sync` + //~^ ERROR: usage of an `Arc` that is not `Send` and `Sync` //~| NOTE: the trait `Sync` is not implemented for `RefCell<i32>` let mutex = Mutex::new(1); let _ = Arc::new(mutex.lock().unwrap()); - //~^ ERROR: usage of an `Arc` that is not `Send` or `Sync` + //~^ ERROR: usage of an `Arc` that is not `Send` and `Sync` //~| NOTE: the trait `Send` is not implemented for `MutexGuard<'_, i32>` let _ = Arc::new(&42 as *const i32); - //~^ ERROR: usage of an `Arc` that is not `Send` or `Sync` + //~^ ERROR: usage of an `Arc` that is not `Send` and `Sync` //~| NOTE: the trait `Send` is not implemented for `*const i32` //~| NOTE: the trait `Sync` is not implemented for `*const i32` } diff --git a/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr b/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr index fd239580d..a7f91abda 100644 --- a/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr +++ b/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr @@ -1,35 +1,41 @@ -error: usage of an `Arc` that is not `Send` or `Sync` +error: usage of an `Arc` that is not `Send` and `Sync` --> $DIR/arc_with_non_send_sync.rs:35:13 | LL | let _ = Arc::new(RefCell::new(42)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: the trait `Sync` is not implemented for `RefCell<i32>` - = note: required for `Arc<RefCell<i32>>` to implement `Send` and `Sync` - = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex` + = note: `Arc<RefCell<i32>>` is not `Send` and `Sync` as: + = note: - the trait `Sync` is not implemented for `RefCell<i32>` + = help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types + = note: if you intend to use `Arc` with `Send` and `Sync` traits + = note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `RefCell<i32>` = note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::arc_with_non_send_sync)]` -error: usage of an `Arc` that is not `Send` or `Sync` +error: usage of an `Arc` that is not `Send` and `Sync` --> $DIR/arc_with_non_send_sync.rs:40:13 | LL | let _ = Arc::new(mutex.lock().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: the trait `Send` is not implemented for `MutexGuard<'_, i32>` - = note: required for `Arc<MutexGuard<'_, i32>>` to implement `Send` and `Sync` - = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex` + = note: `Arc<MutexGuard<'_, i32>>` is not `Send` and `Sync` as: + = note: - the trait `Send` is not implemented for `MutexGuard<'_, i32>` + = help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types + = note: if you intend to use `Arc` with `Send` and `Sync` traits + = note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `MutexGuard<'_, i32>` -error: usage of an `Arc` that is not `Send` or `Sync` +error: usage of an `Arc` that is not `Send` and `Sync` --> $DIR/arc_with_non_send_sync.rs:44:13 | LL | let _ = Arc::new(&42 as *const i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: the trait `Send` is not implemented for `*const i32` - = note: the trait `Sync` is not implemented for `*const i32` - = note: required for `Arc<*const i32>` to implement `Send` and `Sync` - = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex` + = note: `Arc<*const i32>` is not `Send` and `Sync` as: + = note: - the trait `Send` is not implemented for `*const i32` + = note: - the trait `Sync` is not implemented for `*const i32` + = help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types + = note: if you intend to use `Arc` with `Send` and `Sync` traits + = note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `*const i32` error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/attrs.rs b/src/tools/clippy/tests/ui/attrs.rs index 05ee48d17..da96eabed 100644 --- a/src/tools/clippy/tests/ui/attrs.rs +++ b/src/tools/clippy/tests/ui/attrs.rs @@ -36,6 +36,9 @@ pub const ANOTHER_CONST: u8 = 23; #[deprecated(since = "0.1.1")] pub const YET_ANOTHER_CONST: u8 = 0; +#[deprecated(since = "TBD")] +pub const GONNA_DEPRECATE_THIS_LATER: u8 = 0; + fn main() { test_attr_lint(); if false { diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed index 8cbadc67d..8c77039b3 100644 --- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed +++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed @@ -1,5 +1,5 @@ #![deny(clippy::bind_instead_of_map)] -#![allow(clippy::blocks_in_if_conditions)] +#![allow(clippy::blocks_in_conditions)] pub fn main() { let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs index 91d9d11e3..44257f3a4 100644 --- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs +++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs @@ -1,5 +1,5 @@ #![deny(clippy::bind_instead_of_map)] -#![allow(clippy::blocks_in_if_conditions)] +#![allow(clippy::blocks_in_conditions)] pub fn main() { let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) }); diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed index f89c46504..2ab441bbd 100644 --- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed +++ b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed @@ -1,4 +1,4 @@ -#![warn(clippy::blocks_in_if_conditions)] +#![warn(clippy::blocks_in_conditions)] #![allow(unused, clippy::let_and_return, clippy::needless_if)] #![warn(clippy::nonminimal_bool)] @@ -21,6 +21,7 @@ fn macro_if() { fn condition_has_block() -> i32 { let res = { + //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` let x = 3; x == 3 }; if res { @@ -32,6 +33,7 @@ fn condition_has_block() -> i32 { fn condition_has_block_with_single_expression() -> i32 { if true { 6 } else { 10 } + //~^ ERROR: omit braces around single expression condition } fn condition_is_normal() -> i32 { @@ -61,4 +63,26 @@ fn block_in_assert() { ); } +// issue #11814 +fn block_in_match_expr(num: i32) -> i32 { + let res = { + //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` + let opt = Some(2); + opt + }; match res { + Some(0) => 1, + Some(n) => num * 2, + None => 0, + }; + + match unsafe { + let hearty_hearty_hearty = vec![240, 159, 146, 150]; + String::from_utf8_unchecked(hearty_hearty_hearty).as_str() + } { + "💖" => 1, + "what" => 2, + _ => 3, + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs b/src/tools/clippy/tests/ui/blocks_in_conditions.rs index 34febc5fa..dd5ae4fb4 100644 --- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs +++ b/src/tools/clippy/tests/ui/blocks_in_conditions.rs @@ -1,4 +1,4 @@ -#![warn(clippy::blocks_in_if_conditions)] +#![warn(clippy::blocks_in_conditions)] #![allow(unused, clippy::let_and_return, clippy::needless_if)] #![warn(clippy::nonminimal_bool)] @@ -21,6 +21,7 @@ fn macro_if() { fn condition_has_block() -> i32 { if { + //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` let x = 3; x == 3 } { @@ -32,6 +33,7 @@ fn condition_has_block() -> i32 { fn condition_has_block_with_single_expression() -> i32 { if { true } { 6 } else { 10 } + //~^ ERROR: omit braces around single expression condition } fn condition_is_normal() -> i32 { @@ -61,4 +63,26 @@ fn block_in_assert() { ); } +// issue #11814 +fn block_in_match_expr(num: i32) -> i32 { + match { + //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` + let opt = Some(2); + opt + } { + Some(0) => 1, + Some(n) => num * 2, + None => 0, + }; + + match unsafe { + let hearty_hearty_hearty = vec![240, 159, 146, 150]; + String::from_utf8_unchecked(hearty_hearty_hearty).as_str() + } { + "💖" => 1, + "what" => 2, + _ => 3, + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr index d80ef9c0f..b00fe2f63 100644 --- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr +++ b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr @@ -1,30 +1,32 @@ error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> $DIR/blocks_in_if_conditions.rs:23:5 + --> $DIR/blocks_in_conditions.rs:23:5 | LL | / if { +LL | | LL | | let x = 3; LL | | x == 3 LL | | } { | |_____^ | - = note: `-D clippy::blocks-in-if-conditions` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::blocks_in_if_conditions)]` + = note: `-D clippy::blocks-in-conditions` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]` help: try | LL ~ let res = { +LL + LL + let x = 3; LL + x == 3 LL ~ }; if res { | error: omit braces around single expression condition - --> $DIR/blocks_in_if_conditions.rs:34:8 + --> $DIR/blocks_in_conditions.rs:35:8 | LL | if { true } { 6 } else { 10 } | ^^^^^^^^ help: try: `true` error: this boolean expression can be simplified - --> $DIR/blocks_in_if_conditions.rs:39:8 + --> $DIR/blocks_in_conditions.rs:41:8 | LL | if true && x == 3 { 6 } else { 10 } | ^^^^^^^^^^^^^^ help: try: `x == 3` @@ -32,5 +34,24 @@ LL | if true && x == 3 { 6 } else { 10 } = note: `-D clippy::nonminimal-bool` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` -error: aborting due to 3 previous errors +error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` + --> $DIR/blocks_in_conditions.rs:68:5 + | +LL | / match { +LL | | +LL | | let opt = Some(2); +LL | | opt +LL | | } { + | |_____^ + | +help: try + | +LL ~ let res = { +LL + +LL + let opt = Some(2); +LL + opt +LL ~ }; match res { + | + +error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs b/src/tools/clippy/tests/ui/blocks_in_conditions_closure.rs index 539f2df15..db31e4ae1 100644 --- a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs +++ b/src/tools/clippy/tests/ui/blocks_in_conditions_closure.rs @@ -1,4 +1,4 @@ -#![warn(clippy::blocks_in_if_conditions)] +#![warn(clippy::blocks_in_conditions)] #![allow( unused, clippy::let_and_return, @@ -22,7 +22,7 @@ fn pred_test() { && predicate( |x| { //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks - //~| NOTE: `-D clippy::blocks-in-if-conditions` implied by `-D warnings` + //~| NOTE: `-D clippy::blocks-in-conditions` implied by `-D warnings` let target = 3; x == target }, @@ -60,6 +60,23 @@ fn function_with_empty_closure() { if closure(|| {}) {} } +// issue #11814 +fn match_with_pred() { + let v = 3; + match Some(predicate( + |x| { + //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks + let target = 3; + x == target + }, + v, + )) { + Some(true) => 1, + Some(false) => 2, + None => 3, + }; +} + #[rustfmt::skip] fn main() { let mut range = 0..10; diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr b/src/tools/clippy/tests/ui/blocks_in_conditions_closure.stderr index ab68997d4..08b98f1b4 100644 --- a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr +++ b/src/tools/clippy/tests/ui/blocks_in_conditions_closure.stderr @@ -1,5 +1,5 @@ error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> $DIR/blocks_in_if_conditions_closure.rs:23:17 + --> $DIR/blocks_in_conditions_closure.rs:23:17 | LL | |x| { | _________________^ @@ -10,11 +10,11 @@ LL | | x == target LL | | }, | |_____________^ | - = note: `-D clippy::blocks-in-if-conditions` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::blocks_in_if_conditions)]` + = note: `-D clippy::blocks-in-conditions` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]` error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> $DIR/blocks_in_if_conditions_closure.rs:34:13 + --> $DIR/blocks_in_conditions_closure.rs:34:13 | LL | |x| { | _____________^ @@ -24,5 +24,16 @@ LL | | x == target LL | | }, | |_________^ -error: aborting due to 2 previous errors +error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` + --> $DIR/blocks_in_conditions_closure.rs:67:13 + | +LL | |x| { + | _____________^ +LL | | +LL | | let target = 3; +LL | | x == target +LL | | }, + | |_________^ + +error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr index 2a21f5ca2..296af6436 100644 --- a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr +++ b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr @@ -15,5 +15,5 @@ help: if you would like to deref, try using `&**` LL | let x: &str = &**s; | ~~~~ -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/box_default.fixed b/src/tools/clippy/tests/ui/box_default.fixed index 69cabcb32..48408e191 100644 --- a/src/tools/clippy/tests/ui/box_default.fixed +++ b/src/tools/clippy/tests/ui/box_default.fixed @@ -90,3 +90,17 @@ fn issue_10381() { assert!(maybe_get_bar(2).is_some()); } + +#[allow(unused)] +fn issue_11868() { + fn foo(_: &mut Vec<usize>) {} + + macro_rules! bar { + ($baz:expr) => { + Box::leak(Box::new($baz)) + }; + } + + foo(bar!(vec![])); + foo(bar!(vec![1])); +} diff --git a/src/tools/clippy/tests/ui/box_default.rs b/src/tools/clippy/tests/ui/box_default.rs index 48fa8bc33..58b912707 100644 --- a/src/tools/clippy/tests/ui/box_default.rs +++ b/src/tools/clippy/tests/ui/box_default.rs @@ -90,3 +90,17 @@ fn issue_10381() { assert!(maybe_get_bar(2).is_some()); } + +#[allow(unused)] +fn issue_11868() { + fn foo(_: &mut Vec<usize>) {} + + macro_rules! bar { + ($baz:expr) => { + Box::leak(Box::new($baz)) + }; + } + + foo(bar!(vec![])); + foo(bar!(vec![1])); +} diff --git a/src/tools/clippy/tests/ui/cfg_features.fixed b/src/tools/clippy/tests/ui/cfg_features.fixed index 3d52f2382..0fe38f169 100644 --- a/src/tools/clippy/tests/ui/cfg_features.fixed +++ b/src/tools/clippy/tests/ui/cfg_features.fixed @@ -2,16 +2,28 @@ fn main() { #[cfg(feature = "not-really-a-feature")] - //~^ ERROR: feature may misspelled as features + //~^ ERROR: 'feature' may be misspelled as 'features' //~| NOTE: `-D clippy::maybe-misused-cfg` implied by `-D warnings` let _ = 1 + 2; #[cfg(all(feature = "right", feature = "wrong"))] - //~^ ERROR: feature may misspelled as features + //~^ ERROR: 'feature' may be misspelled as 'features' let _ = 1 + 2; #[cfg(all(feature = "wrong1", any(feature = "right", feature = "wrong2", feature, features)))] - //~^ ERROR: feature may misspelled as features - //~| ERROR: feature may misspelled as features + //~^ ERROR: 'feature' may be misspelled as 'features' + //~| ERROR: 'feature' may be misspelled as 'features' let _ = 1 + 2; + + #[cfg(test)] + //~^ ERROR: 'test' may be misspelled as 'tests' + let _ = 2; + #[cfg(test)] + //~^ ERROR: 'test' may be misspelled as 'Test' + let _ = 2; + + #[cfg(all(test, test))] + //~^ ERROR: 'test' may be misspelled as 'tests' + //~| ERROR: 'test' may be misspelled as 'Test' + let _ = 2; } diff --git a/src/tools/clippy/tests/ui/cfg_features.rs b/src/tools/clippy/tests/ui/cfg_features.rs index a0344a004..9c0db035e 100644 --- a/src/tools/clippy/tests/ui/cfg_features.rs +++ b/src/tools/clippy/tests/ui/cfg_features.rs @@ -2,16 +2,28 @@ fn main() { #[cfg(features = "not-really-a-feature")] - //~^ ERROR: feature may misspelled as features + //~^ ERROR: 'feature' may be misspelled as 'features' //~| NOTE: `-D clippy::maybe-misused-cfg` implied by `-D warnings` let _ = 1 + 2; #[cfg(all(feature = "right", features = "wrong"))] - //~^ ERROR: feature may misspelled as features + //~^ ERROR: 'feature' may be misspelled as 'features' let _ = 1 + 2; #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))] - //~^ ERROR: feature may misspelled as features - //~| ERROR: feature may misspelled as features + //~^ ERROR: 'feature' may be misspelled as 'features' + //~| ERROR: 'feature' may be misspelled as 'features' let _ = 1 + 2; + + #[cfg(tests)] + //~^ ERROR: 'test' may be misspelled as 'tests' + let _ = 2; + #[cfg(Test)] + //~^ ERROR: 'test' may be misspelled as 'Test' + let _ = 2; + + #[cfg(all(tests, Test))] + //~^ ERROR: 'test' may be misspelled as 'tests' + //~| ERROR: 'test' may be misspelled as 'Test' + let _ = 2; } diff --git a/src/tools/clippy/tests/ui/cfg_features.stderr b/src/tools/clippy/tests/ui/cfg_features.stderr index 401c3e92e..e1593e207 100644 --- a/src/tools/clippy/tests/ui/cfg_features.stderr +++ b/src/tools/clippy/tests/ui/cfg_features.stderr @@ -1,29 +1,53 @@ -error: feature may misspelled as features +error: 'feature' may be misspelled as 'features' --> $DIR/cfg_features.rs:4:11 | LL | #[cfg(features = "not-really-a-feature")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `feature = "not-really-a-feature"` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "not-really-a-feature"` | = note: `-D clippy::maybe-misused-cfg` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::maybe_misused_cfg)]` -error: feature may misspelled as features +error: 'feature' may be misspelled as 'features' --> $DIR/cfg_features.rs:9:34 | LL | #[cfg(all(feature = "right", features = "wrong"))] - | ^^^^^^^^^^^^^^^^^^ help: use: `feature = "wrong"` + | ^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "wrong"` -error: feature may misspelled as features +error: 'feature' may be misspelled as 'features' --> $DIR/cfg_features.rs:13:15 | LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))] - | ^^^^^^^^^^^^^^^^^^^ help: use: `feature = "wrong1"` + | ^^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "wrong1"` -error: feature may misspelled as features +error: 'feature' may be misspelled as 'features' --> $DIR/cfg_features.rs:13:59 | LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))] - | ^^^^^^^^^^^^^^^^^^^ help: use: `feature = "wrong2"` + | ^^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "wrong2"` -error: aborting due to 4 previous errors +error: 'test' may be misspelled as 'tests' + --> $DIR/cfg_features.rs:18:11 + | +LL | #[cfg(tests)] + | ^^^^^ help: did you mean: `test` + +error: 'test' may be misspelled as 'Test' + --> $DIR/cfg_features.rs:21:11 + | +LL | #[cfg(Test)] + | ^^^^ help: did you mean: `test` + +error: 'test' may be misspelled as 'tests' + --> $DIR/cfg_features.rs:25:15 + | +LL | #[cfg(all(tests, Test))] + | ^^^^^ help: did you mean: `test` + +error: 'test' may be misspelled as 'Test' + --> $DIR/cfg_features.rs:25:22 + | +LL | #[cfg(all(tests, Test))] + | ^^^^ help: did you mean: `test` + +error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8.stderr b/src/tools/clippy/tests/ui/char_lit_as_u8.stderr index ce1f2f829..22774d2f9 100644 --- a/src/tools/clippy/tests/ui/char_lit_as_u8.stderr +++ b/src/tools/clippy/tests/ui/char_lit_as_u8.stderr @@ -8,5 +8,5 @@ LL | let _ = '❤' as u8; = note: `-D clippy::char-lit-as-u8` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::char_lit_as_u8)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr index 9cd25f6fd..b9af72371 100644 --- a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr +++ b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr @@ -8,5 +8,5 @@ LL | fn kaboom() { = note: `-D clippy::cognitive-complexity` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cognitive_complexity)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/copy_iterator.stderr b/src/tools/clippy/tests/ui/copy_iterator.stderr index 48c3385b6..30535db50 100644 --- a/src/tools/clippy/tests/ui/copy_iterator.stderr +++ b/src/tools/clippy/tests/ui/copy_iterator.stderr @@ -14,5 +14,5 @@ LL | | } = note: `-D clippy::copy-iterator` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::copy_iterator)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-10148.stderr b/src/tools/clippy/tests/ui/crashes/ice-10148.stderr index 4d436e3aa..ece3e1c39 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-10148.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-10148.stderr @@ -9,5 +9,5 @@ LL | println!(with_span!(""something "")); = note: `-D clippy::println-empty-string` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::println_empty_string)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-11422.stderr b/src/tools/clippy/tests/ui/crashes/ice-11422.stderr index fb80b5b14..b3dcc00f3 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-11422.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-11422.stderr @@ -12,5 +12,5 @@ LL - fn gen() -> impl PartialOrd + PartialEq + Debug {} LL + fn gen() -> impl PartialOrd + Debug {} | -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-11803.rs b/src/tools/clippy/tests/ui/crashes/ice-11803.rs new file mode 100644 index 000000000..1bb8bf0c7 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-11803.rs @@ -0,0 +1,9 @@ +//@no-rustfix + +#![warn(clippy::impl_trait_in_params)] + +pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>>() { + extern "C" fn implementation_detail() {} +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/crashes/ice-11803.stderr b/src/tools/clippy/tests/ui/crashes/ice-11803.stderr new file mode 100644 index 000000000..b8289048a --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-11803.stderr @@ -0,0 +1,26 @@ +error: `impl Trait` used as a function parameter + --> $DIR/ice-11803.rs:5:54 + | +LL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>>() { + | ^^^^^^^^^^ + | + = note: `-D clippy::impl-trait-in-params` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::impl_trait_in_params)]` +help: add a type parameter + | +LL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>, { /* Generic name */ }: Clone>() { + | +++++++++++++++++++++++++++++++ + +error: `impl Trait` used as a function parameter + --> $DIR/ice-11803.rs:5:33 + | +LL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: add a type parameter + | +LL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>, { /* Generic name */ }: Iterator<Item = impl Clone>>() { + | +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/crashes/ice-2774.stderr b/src/tools/clippy/tests/ui/crashes/ice-2774.stderr index ae9610c9a..188a59850 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-2774.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-2774.stderr @@ -12,5 +12,5 @@ LL - pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) { LL + pub fn add_barfoos_to_foos(bars: &HashSet<&Bar>) { | -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.stderr b/src/tools/clippy/tests/ui/crashes/ice-3717.stderr index 4d3d617b6..863608fca 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-3717.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-3717.stderr @@ -18,5 +18,5 @@ help: ...and use generic constructor LL | let _: HashSet<usize> = HashSet::default(); | ~~~~~~~~~~~~~~~~~~ -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-3891.stderr b/src/tools/clippy/tests/ui/crashes/ice-3891.stderr index 59469ec58..5358734fe 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-3891.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-3891.stderr @@ -6,5 +6,5 @@ LL | 1x; | = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-5497.stderr b/src/tools/clippy/tests/ui/crashes/ice-5497.stderr index e75e7dc91..ee69f3379 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-5497.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-5497.stderr @@ -6,5 +6,5 @@ LL | const OOB: i32 = [1][1] + T::OOB; | = note: `#[deny(unconditional_panic)]` on by default -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-5835.stderr b/src/tools/clippy/tests/ui/crashes/ice-5835.stderr index 74d99a348..1f930e1f6 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-5835.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-5835.stderr @@ -7,5 +7,5 @@ LL | /// 位 = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-5872.stderr b/src/tools/clippy/tests/ui/crashes/ice-5872.stderr index 75a26ee31..d0067a223 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-5872.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-5872.stderr @@ -7,5 +7,5 @@ LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>().is_empty(); = note: `-D clippy::needless-collect` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr index 6ace7dae8..7a34e6cce 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr @@ -11,5 +11,5 @@ LL | FOO_REF_REF => {}, = note: `-D indirect-structural-match` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(indirect_structural_match)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-6255.stderr b/src/tools/clippy/tests/ui/crashes/ice-6255.stderr index db0cb25e3..bc13319be 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6255.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6255.stderr @@ -9,5 +9,5 @@ LL | define_other_core!(); | = note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-6256.stderr b/src/tools/clippy/tests/ui/crashes/ice-6256.stderr index 671933157..cba6df194 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6256.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6256.stderr @@ -9,6 +9,6 @@ LL | let f = |x: &dyn TT| x.func(); | | let's call the lifetime of this reference `'1` | `x` is a reference that is only valid in the closure body -error: aborting due to previous error +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0521`. diff --git a/src/tools/clippy/tests/ui/crashes/ice-7169.stderr b/src/tools/clippy/tests/ui/crashes/ice-7169.stderr index 47947f89b..3126de93d 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-7169.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-7169.stderr @@ -7,5 +7,5 @@ LL | if let Ok(_) = Ok::<_, ()>(A::<String>::default()) {} = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr index e5f14f221..3315a8d90 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr @@ -8,5 +8,5 @@ LL | unsafe { 0 }; = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-7869.stderr b/src/tools/clippy/tests/ui/crashes/ice-7869.stderr index 7acace78a..22f2c7e46 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-7869.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-7869.stderr @@ -13,5 +13,5 @@ LL | | } = note: `-D clippy::enum-variant-names` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-8250.stderr b/src/tools/clippy/tests/ui/crashes/ice-8250.stderr index 9c57f3345..397e978af 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-8250.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-8250.stderr @@ -7,5 +7,5 @@ LL | let _ = s[1..].splitn(2, '.').next()?; = note: `-D clippy::needless-splitn` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_splitn)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-8821.stderr b/src/tools/clippy/tests/ui/crashes/ice-8821.stderr index c8bd01fb1..94ebb2091 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-8821.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-8821.stderr @@ -7,5 +7,5 @@ LL | let _: () = FN(); = note: `-D clippy::let-unit-value` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-9041.stderr b/src/tools/clippy/tests/ui/crashes/ice-9041.stderr index 49c9bdc30..00b65f00d 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-9041.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-9041.stderr @@ -7,5 +7,5 @@ LL | things.iter().find(|p| is_thing_ready(p)).is_some() = note: `-D clippy::search-is-some` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-9445.stderr b/src/tools/clippy/tests/ui/crashes/ice-9445.stderr index 9307409ba..f97b4536e 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-9445.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-9445.stderr @@ -9,5 +9,5 @@ LL | const UNINIT: core::mem::MaybeUninit<core::cell::Cell<&'static ()>> = core: = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-96721.stderr b/src/tools/clippy/tests/ui/crashes/ice-96721.stderr index 712bd14c6..1741c7c6a 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-96721.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-96721.stderr @@ -4,5 +4,5 @@ error: malformed `path` attribute input LL | #[path = foo!()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[path = "file"]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr index 37484f5eb..2ebb9d5cd 100644 --- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr +++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr @@ -15,5 +15,5 @@ LL - fn baz<'a>(&'a self) -> impl Foo + 'a { LL + fn baz(&self) -> impl Foo + '_ { | -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr index 6d4539399..b318f8d3f 100644 --- a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr +++ b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr @@ -12,5 +12,5 @@ LL | struct Foo<'a>(&'a [(); 100]); = note: `-D clippy::needless-pass-by-value` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.stderr b/src/tools/clippy/tests/ui/crate_in_macro_def.stderr index 3e6246182..1a21d4e92 100644 --- a/src/tools/clippy/tests/ui/crate_in_macro_def.stderr +++ b/src/tools/clippy/tests/ui/crate_in_macro_def.stderr @@ -7,5 +7,5 @@ LL | println!("{}", crate::unhygienic::MESSAGE); = note: `-D clippy::crate-in-macro-def` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::crate_in_macro_def)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr index 01033246d..7ef8d08d5 100644 --- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr +++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr @@ -11,5 +11,5 @@ LL | | b = a; = note: `-D clippy::almost-swapped` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::almost_swapped)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr index f3ffd6a10..3bc406206 100644 --- a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr +++ b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr @@ -8,5 +8,5 @@ LL | main(); = note: `-D clippy::main-recursion` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::main_recursion)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/dbg_macro/auxiliary/submodule.rs b/src/tools/clippy/tests/ui/dbg_macro/auxiliary/submodule.rs new file mode 100644 index 000000000..b1df24737 --- /dev/null +++ b/src/tools/clippy/tests/ui/dbg_macro/auxiliary/submodule.rs @@ -0,0 +1,3 @@ +fn f() { + dbg!(); +} diff --git a/src/tools/clippy/tests/ui/dbg_macro.rs b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.rs index 149b08476..3f4770c63 100644 --- a/src/tools/clippy/tests/ui/dbg_macro.rs +++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.rs @@ -2,10 +2,12 @@ #![warn(clippy::dbg_macro)] +#[path = "auxiliary/submodule.rs"] +mod submodule; + fn foo(n: u32) -> u32 { if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } //~^ ERROR: the `dbg!` macro is intended as a debugging tool - //~| NOTE: `-D clippy::dbg-macro` implied by `-D warnings` } fn bar(_: ()) {} diff --git a/src/tools/clippy/tests/ui/dbg_macro.stderr b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr index f45a7ba1f..4d00421c7 100644 --- a/src/tools/clippy/tests/ui/dbg_macro.stderr +++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr @@ -1,18 +1,30 @@ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:6:22 + --> $DIR/auxiliary/submodule.rs:2:5 | -LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | dbg!(); + | ^^^^^^^ | = note: `-D clippy::dbg-macro` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]` help: remove the invocation before committing it to a version control system | +LL - dbg!(); +LL + + | + +error: the `dbg!` macro is intended as a debugging tool + --> $DIR/dbg_macro.rs:9:22 + | +LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the invocation before committing it to a version control system + | LL | if let Some(n) = n.checked_sub(4) { n } else { n } | ~~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:13:8 + --> $DIR/dbg_macro.rs:15:8 | LL | if dbg!(n <= 1) { | ^^^^^^^^^^^^ @@ -23,7 +35,7 @@ LL | if n <= 1 { | ~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:15:9 + --> $DIR/dbg_macro.rs:17:9 | LL | dbg!(1) | ^^^^^^^ @@ -34,7 +46,7 @@ LL | 1 | error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:18:9 + --> $DIR/dbg_macro.rs:20:9 | LL | dbg!(n * factorial(n - 1)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +57,7 @@ LL | n * factorial(n - 1) | error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:24:5 + --> $DIR/dbg_macro.rs:26:5 | LL | dbg!(42); | ^^^^^^^^ @@ -56,7 +68,7 @@ LL | 42; | ~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:26:5 + --> $DIR/dbg_macro.rs:28:5 | LL | dbg!(dbg!(dbg!(42))); | ^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +79,7 @@ LL | dbg!(dbg!(42)); | ~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:28:14 + --> $DIR/dbg_macro.rs:30:14 | LL | foo(3) + dbg!(factorial(4)); | ^^^^^^^^^^^^^^^^^^ @@ -78,7 +90,7 @@ LL | foo(3) + factorial(4); | ~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:30:5 + --> $DIR/dbg_macro.rs:32:5 | LL | dbg!(1, 2, dbg!(3, 4)); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +101,7 @@ LL | (1, 2, dbg!(3, 4)); | ~~~~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:32:5 + --> $DIR/dbg_macro.rs:34:5 | LL | dbg!(1, 2, 3, 4, 5); | ^^^^^^^^^^^^^^^^^^^ @@ -100,7 +112,7 @@ LL | (1, 2, 3, 4, 5); | ~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:53:5 + --> $DIR/dbg_macro.rs:55:5 | LL | dbg!(); | ^^^^^^^ @@ -112,7 +124,7 @@ LL + | error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:56:13 + --> $DIR/dbg_macro.rs:58:13 | LL | let _ = dbg!(); | ^^^^^^ @@ -123,7 +135,7 @@ LL | let _ = (); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:58:9 + --> $DIR/dbg_macro.rs:60:9 | LL | bar(dbg!()); | ^^^^^^ @@ -134,7 +146,7 @@ LL | bar(()); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:60:10 + --> $DIR/dbg_macro.rs:62:10 | LL | foo!(dbg!()); | ^^^^^^ @@ -145,7 +157,7 @@ LL | foo!(()); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:62:16 + --> $DIR/dbg_macro.rs:64:16 | LL | foo2!(foo!(dbg!())); | ^^^^^^ @@ -156,7 +168,7 @@ LL | foo2!(foo!(())); | ~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:84:9 + --> $DIR/dbg_macro.rs:86:9 | LL | dbg!(2); | ^^^^^^^ @@ -167,7 +179,7 @@ LL | 2; | ~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:91:5 + --> $DIR/dbg_macro.rs:93:5 | LL | dbg!(1); | ^^^^^^^ @@ -178,7 +190,7 @@ LL | 1; | ~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:97:5 + --> $DIR/dbg_macro.rs:99:5 | LL | dbg!(1); | ^^^^^^^ @@ -189,7 +201,7 @@ LL | 1; | ~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:104:9 + --> $DIR/dbg_macro.rs:106:9 | LL | dbg!(1); | ^^^^^^^ @@ -199,5 +211,5 @@ help: remove the invocation before committing it to a version control system LL | 1; | ~ -error: aborting due to 18 previous errors +error: aborting due to 19 previous errors diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr index bfd0de4e1..6a00331ec 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.stderr +++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr @@ -8,5 +8,5 @@ LL | pub fn as_ref(self) -> &'static str { = note: `-D clippy::wrong-self-convention` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed index aee897197..708ac6666 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed @@ -227,3 +227,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: { /// this checks if the lowerCamelCase issue is fixed fn issue_11568() {} + +/// There is no try (`do()` or `do_not()`). +fn parenthesized_word() {} diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs index b6346b881..040d6352c 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs @@ -227,3 +227,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: { /// this checks if the lowerCamelCase issue is fixed fn issue_11568() {} + +/// There is no try (do() or do_not()). +fn parenthesized_word() {} diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr index 4c9ff41d9..033604e03 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr @@ -319,5 +319,27 @@ help: try LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint` | ~~~~~~~~~~~~~~~~~ -error: aborting due to 29 previous errors +error: item in documentation is missing backticks + --> $DIR/doc-fixable.rs:231:22 + | +LL | /// There is no try (do() or do_not()). + | ^^^^ + | +help: try + | +LL | /// There is no try (`do()` or do_not()). + | ~~~~~~ + +error: item in documentation is missing backticks + --> $DIR/doc-fixable.rs:231:30 + | +LL | /// There is no try (do() or do_not()). + | ^^^^^^^^ + | +help: try + | +LL | /// There is no try (do() or `do_not()`). + | ~~~~~~~~~~ + +error: aborting due to 31 previous errors diff --git a/src/tools/clippy/tests/ui/doc_link_with_quotes.rs b/src/tools/clippy/tests/ui/doc_link_with_quotes.rs index 37d0d1359..48e1b1819 100644 --- a/src/tools/clippy/tests/ui/doc_link_with_quotes.rs +++ b/src/tools/clippy/tests/ui/doc_link_with_quotes.rs @@ -11,6 +11,12 @@ pub fn foo() { bar() } +/// Calls ["bar"] uselessly +//~^ ERROR: possible intra-doc link using quotes instead of backticks +pub fn foo2() { + bar() +} + /// # Examples /// This demonstrates issue \#8961 /// ``` diff --git a/src/tools/clippy/tests/ui/doc_link_with_quotes.stderr b/src/tools/clippy/tests/ui/doc_link_with_quotes.stderr index 2db1bc092..cd4f87c56 100644 --- a/src/tools/clippy/tests/ui/doc_link_with_quotes.stderr +++ b/src/tools/clippy/tests/ui/doc_link_with_quotes.stderr @@ -7,5 +7,11 @@ LL | /// Calls ['bar'] uselessly = note: `-D clippy::doc-link-with-quotes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::doc_link_with_quotes)]` -error: aborting due to previous error +error: possible intra-doc link using quotes instead of backticks + --> $DIR/doc_link_with_quotes.rs:14:12 + | +LL | /// Calls ["bar"] uselessly + | ^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/double_neg.stderr b/src/tools/clippy/tests/ui/double_neg.stderr index a6241c786..a4fa1688d 100644 --- a/src/tools/clippy/tests/ui/double_neg.stderr +++ b/src/tools/clippy/tests/ui/double_neg.stderr @@ -7,5 +7,5 @@ LL | --x; = note: `-D clippy::double-neg` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::double_neg)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr b/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr index f47f6c896..53ee0c4e8 100644 --- a/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr +++ b/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr @@ -7,5 +7,5 @@ LL | fn join_the_dark_side(darth: i32, _darth: i32) {} = note: `-D clippy::duplicate-underscore-argument` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::duplicate_underscore_argument)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/empty_enum.stderr b/src/tools/clippy/tests/ui/empty_enum.stderr index 92d81c726..c9bd88764 100644 --- a/src/tools/clippy/tests/ui/empty_enum.stderr +++ b/src/tools/clippy/tests/ui/empty_enum.stderr @@ -8,5 +8,5 @@ LL | enum Empty {} = note: `-D clippy::empty-enum` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::empty_enum)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/entry_btree.stderr b/src/tools/clippy/tests/ui/entry_btree.stderr index cc0e951d9..63e9a0af8 100644 --- a/src/tools/clippy/tests/ui/entry_btree.stderr +++ b/src/tools/clippy/tests/ui/entry_btree.stderr @@ -17,5 +17,5 @@ LL + foo(); LL + } | -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/exit1.stderr b/src/tools/clippy/tests/ui/exit1.stderr index 94d8f1e32..bbe0762c8 100644 --- a/src/tools/clippy/tests/ui/exit1.stderr +++ b/src/tools/clippy/tests/ui/exit1.stderr @@ -7,5 +7,5 @@ LL | std::process::exit(4); = note: `-D clippy::exit` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::exit)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/exit2.stderr b/src/tools/clippy/tests/ui/exit2.stderr index cd324f182..19abbc606 100644 --- a/src/tools/clippy/tests/ui/exit2.stderr +++ b/src/tools/clippy/tests/ui/exit2.stderr @@ -7,5 +7,5 @@ LL | std::process::exit(3); = note: `-D clippy::exit` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::exit)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed index 12158d0d1..e6ca4bb66 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed @@ -301,24 +301,47 @@ fn main() { }; // Issue #11474 - pub struct Variant { - pub anonymous: Variant0, + #[derive(Clone, Copy)] + struct Wrap<T>(T); + impl<T> core::ops::Deref for Wrap<T> { + type Target = T; + fn deref(&self) -> &T { + &self.0 + } } - - pub union Variant0 { - pub anonymous: std::mem::ManuallyDrop<Variant00>, + impl<T> core::ops::DerefMut for Wrap<T> { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } } - pub struct Variant00 { - pub anonymous: Variant000, + union U<T: Copy> { + u: T, } - pub union Variant000 { - pub val: i32, + #[derive(Clone, Copy)] + struct S8 { + x: &'static str, } unsafe { - let mut p = core::mem::zeroed::<Variant>(); - (*p.anonymous.anonymous).anonymous.val = 1; + let mut x = U { + u: core::mem::ManuallyDrop::new(S8 { x: "" }), + }; + let _ = &mut (*x.u).x; + let _ = &mut { x.u }.x; + let _ = &mut ({ *x.u }).x; + + let mut x = U { + u: Wrap(core::mem::ManuallyDrop::new(S8 { x: "" })), + }; + let _ = &mut (*x.u).x; + let _ = &mut { x.u }.x; + let _ = &mut ({ **x.u }).x; + + let mut x = U { u: Wrap(S8 { x: "" }) }; + let _ = &mut x.u.x; + let _ = &mut { x.u }.x; + let _ = &mut ({ *x.u }).x; } } diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.rs b/src/tools/clippy/tests/ui/explicit_auto_deref.rs index dec021c18..7531e1f87 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.rs +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.rs @@ -301,24 +301,47 @@ fn main() { }; // Issue #11474 - pub struct Variant { - pub anonymous: Variant0, + #[derive(Clone, Copy)] + struct Wrap<T>(T); + impl<T> core::ops::Deref for Wrap<T> { + type Target = T; + fn deref(&self) -> &T { + &self.0 + } } - - pub union Variant0 { - pub anonymous: std::mem::ManuallyDrop<Variant00>, + impl<T> core::ops::DerefMut for Wrap<T> { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } } - pub struct Variant00 { - pub anonymous: Variant000, + union U<T: Copy> { + u: T, } - pub union Variant000 { - pub val: i32, + #[derive(Clone, Copy)] + struct S8 { + x: &'static str, } unsafe { - let mut p = core::mem::zeroed::<Variant>(); - (*p.anonymous.anonymous).anonymous.val = 1; + let mut x = U { + u: core::mem::ManuallyDrop::new(S8 { x: "" }), + }; + let _ = &mut (*x.u).x; + let _ = &mut (*{ x.u }).x; + let _ = &mut ({ *x.u }).x; + + let mut x = U { + u: Wrap(core::mem::ManuallyDrop::new(S8 { x: "" })), + }; + let _ = &mut (**x.u).x; + let _ = &mut (**{ x.u }).x; + let _ = &mut ({ **x.u }).x; + + let mut x = U { u: Wrap(S8 { x: "" }) }; + let _ = &mut (*x.u).x; + let _ = &mut (*{ x.u }).x; + let _ = &mut ({ *x.u }).x; } } diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr index 3d2a7b0d9..cc9eeeb50 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr @@ -241,5 +241,35 @@ error: deref which would be done by auto-deref LL | Some(x) => &mut *x, | ^^^^^^^ help: try: `x` -error: aborting due to 40 previous errors +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:332:22 + | +LL | let _ = &mut (*{ x.u }).x; + | ^^^^^^^^^^ help: try: `{ x.u }` + +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:338:22 + | +LL | let _ = &mut (**x.u).x; + | ^^^^^^^ help: try: `(*x.u)` + +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:339:22 + | +LL | let _ = &mut (**{ x.u }).x; + | ^^^^^^^^^^^ help: try: `{ x.u }` + +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:343:22 + | +LL | let _ = &mut (*x.u).x; + | ^^^^^^ help: try: `x.u` + +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:344:22 + | +LL | let _ = &mut (*{ x.u }).x; + | ^^^^^^^^^^ help: try: `{ x.u }` + +error: aborting due to 45 previous errors diff --git a/src/tools/clippy/tests/ui/filter_map_next.stderr b/src/tools/clippy/tests/ui/filter_map_next.stderr index 184155391..07760d883 100644 --- a/src/tools/clippy/tests/ui/filter_map_next.stderr +++ b/src/tools/clippy/tests/ui/filter_map_next.stderr @@ -14,5 +14,5 @@ LL | | .next(); = note: `-D clippy::filter-map-next` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::filter_map_next)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed index a4d6d49e5..3ce2edf2c 100644 --- a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed +++ b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed @@ -39,3 +39,21 @@ fn main() { // Cases where the lint shouldn't be applied let _ = (a * a + b * b).sqrt(); } + +fn _issue11831() { + struct NotAFloat; + + impl std::ops::Add<f64> for NotAFloat { + type Output = Self; + + fn add(self, _: f64) -> Self { + NotAFloat + } + } + + let a = NotAFloat; + let b = 1.0_f64; + let c = 1.0; + + let _ = a + b * c; +} diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.rs b/src/tools/clippy/tests/ui/floating_point_mul_add.rs index 262a20f0f..b5e4a8db4 100644 --- a/src/tools/clippy/tests/ui/floating_point_mul_add.rs +++ b/src/tools/clippy/tests/ui/floating_point_mul_add.rs @@ -39,3 +39,21 @@ fn main() { // Cases where the lint shouldn't be applied let _ = (a * a + b * b).sqrt(); } + +fn _issue11831() { + struct NotAFloat; + + impl std::ops::Add<f64> for NotAFloat { + type Output = Self; + + fn add(self, _: f64) -> Self { + NotAFloat + } + } + + let a = NotAFloat; + let b = 1.0_f64; + let c = 1.0; + + let _ = a + b * c; +} diff --git a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr index afb7c6b4d..f49b7a097 100644 --- a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr +++ b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr @@ -12,5 +12,5 @@ help: make this a doc comment by removing one `/` LL + /// borked doc comment on the first line. doesn't combust! | -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/functions_maxlines.stderr b/src/tools/clippy/tests/ui/functions_maxlines.stderr index 1d6ddad79..497acc0a6 100644 --- a/src/tools/clippy/tests/ui/functions_maxlines.stderr +++ b/src/tools/clippy/tests/ui/functions_maxlines.stderr @@ -13,5 +13,5 @@ LL | | } = note: `-D clippy::too-many-lines` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::too_many_lines)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/impl_hash_with_borrow_str_and_bytes.rs b/src/tools/clippy/tests/ui/impl_hash_with_borrow_str_and_bytes.rs new file mode 100644 index 000000000..f6ce6153e --- /dev/null +++ b/src/tools/clippy/tests/ui/impl_hash_with_borrow_str_and_bytes.rs @@ -0,0 +1,136 @@ +#![warn(clippy::impl_hash_borrow_with_str_and_bytes)] + +use std::borrow::Borrow; +use std::hash::{Hash, Hasher}; + +struct ExampleType { + data: String, +} + +impl Hash for ExampleType { + //~^ ERROR: can't + fn hash<H: Hasher>(&self, state: &mut H) { + self.data.hash(state); + } +} + +impl Borrow<str> for ExampleType { + fn borrow(&self) -> &str { + &self.data + } +} + +impl Borrow<[u8]> for ExampleType { + fn borrow(&self) -> &[u8] { + self.data.as_bytes() + } +} + +struct ShouldNotRaiseForHash {} +impl Hash for ShouldNotRaiseForHash { + fn hash<H: Hasher>(&self, state: &mut H) { + todo!(); + } +} + +struct ShouldNotRaiseForBorrow {} +impl Borrow<str> for ShouldNotRaiseForBorrow { + fn borrow(&self) -> &str { + todo!(); + } +} +impl Borrow<[u8]> for ShouldNotRaiseForBorrow { + fn borrow(&self) -> &[u8] { + todo!(); + } +} + +struct ShouldNotRaiseForHashBorrowStr {} +impl Hash for ShouldNotRaiseForHashBorrowStr { + fn hash<H: Hasher>(&self, state: &mut H) { + todo!(); + } +} +impl Borrow<str> for ShouldNotRaiseForHashBorrowStr { + fn borrow(&self) -> &str { + todo!(); + } +} + +struct ShouldNotRaiseForHashBorrowSlice {} +impl Hash for ShouldNotRaiseForHashBorrowSlice { + fn hash<H: Hasher>(&self, state: &mut H) { + todo!(); + } +} + +impl Borrow<[u8]> for ShouldNotRaiseForHashBorrowSlice { + fn borrow(&self) -> &[u8] { + todo!(); + } +} + +#[derive(Hash)] +//~^ ERROR: can't +struct Derived { + data: String, +} + +impl Borrow<str> for Derived { + fn borrow(&self) -> &str { + self.data.as_str() + } +} + +impl Borrow<[u8]> for Derived { + fn borrow(&self) -> &[u8] { + self.data.as_bytes() + } +} + +struct GenericExampleType<T> { + data: T, +} + +impl<T: Hash> Hash for GenericExampleType<T> { + fn hash<H: Hasher>(&self, state: &mut H) { + self.data.hash(state); + } +} + +impl Borrow<str> for GenericExampleType<String> { + fn borrow(&self) -> &str { + &self.data + } +} + +impl Borrow<[u8]> for GenericExampleType<&'static [u8]> { + fn borrow(&self) -> &[u8] { + self.data + } +} + +struct GenericExampleType2<T> { + data: T, +} + +impl Hash for GenericExampleType2<String> { + //~^ ERROR: can't + // this is correctly throwing an error for generic with concrete impl + // for all 3 types + fn hash<H: Hasher>(&self, state: &mut H) { + self.data.hash(state); + } +} + +impl Borrow<str> for GenericExampleType2<String> { + fn borrow(&self) -> &str { + &self.data + } +} + +impl Borrow<[u8]> for GenericExampleType2<String> { + fn borrow(&self) -> &[u8] { + self.data.as_bytes() + } +} diff --git a/src/tools/clippy/tests/ui/impl_hash_with_borrow_str_and_bytes.stderr b/src/tools/clippy/tests/ui/impl_hash_with_borrow_str_and_bytes.stderr new file mode 100644 index 000000000..afc35ef98 --- /dev/null +++ b/src/tools/clippy/tests/ui/impl_hash_with_borrow_str_and_bytes.stderr @@ -0,0 +1,41 @@ +error: the semantics of `Borrow<T>` around `Hash` can't be satisfied when both `Borrow<str>` and `Borrow<[u8]>` are implemented + --> $DIR/impl_hash_with_borrow_str_and_bytes.rs:10:6 + | +LL | impl Hash for ExampleType { + | ^^^^ + | + = note: the `Borrow` semantics require that `Hash` must behave the same for all implementations of Borrow<T> + = note: however, the hash implementations of a string (`str`) and the bytes of a string `[u8]` do not behave the same ... + = note: ... as (`hash("abc") != hash("abc".as_bytes())` + = help: consider either removing one of the `Borrow` implementations (`Borrow<str>` or `Borrow<[u8]>`) ... + = help: ... or not implementing `Hash` for this type + = note: `-D clippy::impl-hash-borrow-with-str-and-bytes` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::impl_hash_borrow_with_str_and_bytes)]` + +error: the semantics of `Borrow<T>` around `Hash` can't be satisfied when both `Borrow<str>` and `Borrow<[u8]>` are implemented + --> $DIR/impl_hash_with_borrow_str_and_bytes.rs:73:10 + | +LL | #[derive(Hash)] + | ^^^^ + | + = note: the `Borrow` semantics require that `Hash` must behave the same for all implementations of Borrow<T> + = note: however, the hash implementations of a string (`str`) and the bytes of a string `[u8]` do not behave the same ... + = note: ... as (`hash("abc") != hash("abc".as_bytes())` + = help: consider either removing one of the `Borrow` implementations (`Borrow<str>` or `Borrow<[u8]>`) ... + = help: ... or not implementing `Hash` for this type + = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: the semantics of `Borrow<T>` around `Hash` can't be satisfied when both `Borrow<str>` and `Borrow<[u8]>` are implemented + --> $DIR/impl_hash_with_borrow_str_and_bytes.rs:117:6 + | +LL | impl Hash for GenericExampleType2<String> { + | ^^^^ + | + = note: the `Borrow` semantics require that `Hash` must behave the same for all implementations of Borrow<T> + = note: however, the hash implementations of a string (`str`) and the bytes of a string `[u8]` do not behave the same ... + = note: ... as (`hash("abc") != hash("abc".as_bytes())` + = help: consider either removing one of the `Borrow` implementations (`Borrow<str>` or `Borrow<[u8]>`) ... + = help: ... or not implementing `Hash` for this type + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr index 11b19428b..429861e99 100644 --- a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr +++ b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr @@ -18,5 +18,5 @@ help: and replace the index expressions here LL | println!("{}", slice_0); | ~~~~~~~ -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/ineffective_open_options.fixed b/src/tools/clippy/tests/ui/ineffective_open_options.fixed new file mode 100644 index 000000000..3af8f3c5a --- /dev/null +++ b/src/tools/clippy/tests/ui/ineffective_open_options.fixed @@ -0,0 +1,41 @@ +#![warn(clippy::ineffective_open_options)] + +use std::fs::OpenOptions; + +fn main() { + let file = OpenOptions::new() + .create(true) + //~ ERROR: unnecessary use of `.write(true)` + .append(true) + .open("dump.json") + .unwrap(); + + let file = OpenOptions::new() + .create(true) + .append(true) + //~ ERROR: unnecessary use of `.write(true)` + .open("dump.json") + .unwrap(); + + // All the next calls are ok. + let file = OpenOptions::new() + .create(true) + .write(false) + .append(true) + .open("dump.json") + .unwrap(); + let file = OpenOptions::new() + .create(true) + .write(true) + .append(false) + .open("dump.json") + .unwrap(); + let file = OpenOptions::new() + .create(true) + .write(false) + .append(false) + .open("dump.json") + .unwrap(); + let file = OpenOptions::new().create(true).append(true).open("dump.json").unwrap(); + let file = OpenOptions::new().create(true).write(true).open("dump.json").unwrap(); +} diff --git a/src/tools/clippy/tests/ui/ineffective_open_options.rs b/src/tools/clippy/tests/ui/ineffective_open_options.rs new file mode 100644 index 000000000..4eaf6293c --- /dev/null +++ b/src/tools/clippy/tests/ui/ineffective_open_options.rs @@ -0,0 +1,41 @@ +#![warn(clippy::ineffective_open_options)] + +use std::fs::OpenOptions; + +fn main() { + let file = OpenOptions::new() + .create(true) + .write(true) //~ ERROR: unnecessary use of `.write(true)` + .append(true) + .open("dump.json") + .unwrap(); + + let file = OpenOptions::new() + .create(true) + .append(true) + .write(true) //~ ERROR: unnecessary use of `.write(true)` + .open("dump.json") + .unwrap(); + + // All the next calls are ok. + let file = OpenOptions::new() + .create(true) + .write(false) + .append(true) + .open("dump.json") + .unwrap(); + let file = OpenOptions::new() + .create(true) + .write(true) + .append(false) + .open("dump.json") + .unwrap(); + let file = OpenOptions::new() + .create(true) + .write(false) + .append(false) + .open("dump.json") + .unwrap(); + let file = OpenOptions::new().create(true).append(true).open("dump.json").unwrap(); + let file = OpenOptions::new().create(true).write(true).open("dump.json").unwrap(); +} diff --git a/src/tools/clippy/tests/ui/ineffective_open_options.stderr b/src/tools/clippy/tests/ui/ineffective_open_options.stderr new file mode 100644 index 000000000..7dc532223 --- /dev/null +++ b/src/tools/clippy/tests/ui/ineffective_open_options.stderr @@ -0,0 +1,17 @@ +error: unnecessary use of `.write(true)` because there is `.append(true)` + --> $DIR/ineffective_open_options.rs:8:9 + | +LL | .write(true) + | ^^^^^^^^^^^^ help: remove `.write(true)` + | + = note: `-D clippy::ineffective-open-options` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::ineffective_open_options)]` + +error: unnecessary use of `.write(true)` because there is `.append(true)` + --> $DIR/ineffective_open_options.rs:16:9 + | +LL | .write(true) + | ^^^^^^^^^^^^ help: remove `.write(true)` + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed index 60304177b..ecf1b14e5 100644 --- a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed +++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed @@ -1,6 +1,6 @@ #![feature(exhaustive_patterns, never_type)] #![allow(dead_code, unreachable_code, unused_variables)] -#![allow(clippy::let_and_return)] +#![allow(clippy::let_and_return, clippy::uninhabited_references)] enum SingleVariantEnum { Variant(i32), diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs index b77aac4a1..7cc7cb9d6 100644 --- a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs +++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs @@ -1,6 +1,6 @@ #![feature(exhaustive_patterns, never_type)] #![allow(dead_code, unreachable_code, unused_variables)] -#![allow(clippy::let_and_return)] +#![allow(clippy::let_and_return, clippy::uninhabited_references)] enum SingleVariantEnum { Variant(i32), diff --git a/src/tools/clippy/tests/ui/infinite_loops.rs b/src/tools/clippy/tests/ui/infinite_loops.rs new file mode 100644 index 000000000..646f1eca5 --- /dev/null +++ b/src/tools/clippy/tests/ui/infinite_loops.rs @@ -0,0 +1,366 @@ +//@no-rustfix +#![allow(clippy::never_loop)] +#![warn(clippy::infinite_loop)] + +fn do_something() {} + +fn no_break() { + loop { + //~^ ERROR: infinite loop detected + do_something(); + } +} + +fn all_inf() { + loop { + //~^ ERROR: infinite loop detected + loop { + //~^ ERROR: infinite loop detected + loop { + //~^ ERROR: infinite loop detected + do_something(); + } + } + do_something(); + } +} + +fn no_break_return_some_ty() -> Option<u8> { + loop { + do_something(); + return None; + } + loop { + //~^ ERROR: infinite loop detected + do_something(); + } +} + +fn no_break_never_ret() -> ! { + loop { + do_something(); + } +} + +fn no_break_never_ret_noise() { + loop { + fn inner_fn() -> ! { + std::process::exit(0); + } + do_something(); + } +} + +fn has_direct_break_1() { + loop { + do_something(); + break; + } +} + +fn has_direct_break_2() { + 'outer: loop { + do_something(); + break 'outer; + } +} + +fn has_indirect_break_1(cond: bool) { + 'outer: loop { + loop { + if cond { + break 'outer; + } + } + } +} + +fn has_indirect_break_2(stop_num: i32) { + 'outer: loop { + for x in 0..5 { + if x == stop_num { + break 'outer; + } + } + } +} + +fn break_inner_but_not_outer_1(cond: bool) { + loop { + //~^ ERROR: infinite loop detected + loop { + if cond { + break; + } + } + } +} + +fn break_inner_but_not_outer_2(cond: bool) { + loop { + //~^ ERROR: infinite loop detected + 'inner: loop { + loop { + if cond { + break 'inner; + } + } + } + } +} + +fn break_outer_but_not_inner() { + loop { + loop { + //~^ ERROR: infinite loop detected + do_something(); + } + break; + } +} + +fn can_break_both_inner_and_outer(cond: bool) { + 'outer: loop { + loop { + if cond { + break 'outer; + } else { + break; + } + } + } +} + +fn break_wrong_loop(cond: bool) { + // 'inner has statement to break 'outer loop, but it was breaked early by a labeled child loop + 'outer: loop { + loop { + //~^ ERROR: infinite loop detected + 'inner: loop { + loop { + loop { + break 'inner; + } + break 'outer; + } + } + } + } +} + +fn has_direct_return(cond: bool) { + loop { + if cond { + return; + } + } +} + +fn ret_in_inner(cond: bool) { + loop { + loop { + if cond { + return; + } + } + } +} + +enum Foo { + A, + B, + C, +} + +fn match_like() { + let opt: Option<u8> = Some(1); + loop { + //~^ ERROR: infinite loop detected + match opt { + Some(v) => { + println!("{v}"); + }, + None => { + do_something(); + }, + } + } + + loop { + match opt { + Some(v) => { + println!("{v}"); + }, + None => { + do_something(); + break; + }, + } + } + + let result: Result<u8, u16> = Ok(1); + loop { + let _val = match result { + Ok(1) => 1 + 1, + Ok(v) => v / 2, + Err(_) => return, + }; + } + + loop { + let Ok(_val) = result else { return }; + } + + loop { + let Ok(_val) = result.map(|v| 10) else { break }; + } + + loop { + //~^ ERROR: infinite loop detected + let _x = matches!(result, Ok(v) if v != 0).then_some(0); + } + + loop { + //~^ ERROR: infinite loop detected + // This `return` does not return the function, so it doesn't count + let _x = matches!(result, Ok(v) if v != 0).then(|| { + if true { + return; + } + do_something(); + }); + } + + let mut val = 0; + let mut fooc = Foo::C; + + loop { + val = match fooc { + Foo::A => 0, + Foo::B => { + fooc = Foo::C; + 1 + }, + Foo::C => break, + }; + } + + loop { + val = match fooc { + Foo::A => 0, + Foo::B => 1, + Foo::C => { + break; + }, + }; + } +} + +macro_rules! set_or_ret { + ($opt:expr, $a:expr) => {{ + match $opt { + Some(val) => $a = val, + None => return, + } + }}; +} + +fn ret_in_macro(opt: Option<u8>) { + let opt: Option<u8> = Some(1); + let mut a: u8 = 0; + loop { + set_or_ret!(opt, a); + } + + let res: Result<bool, u8> = Ok(true); + loop { + match res { + Ok(true) => set_or_ret!(opt, a), + _ => do_something(), + } + } +} + +fn panic_like_macros_1() { + loop { + do_something(); + panic!(); + } +} + +fn panic_like_macros_2() { + let mut x = 0; + + loop { + do_something(); + if true { + todo!(); + } + } + loop { + do_something(); + x += 1; + assert_eq!(x, 0); + } + loop { + do_something(); + assert!(x % 2 == 0); + } + loop { + do_something(); + match Some(1) { + Some(n) => println!("{n}"), + None => unreachable!("It won't happen"), + } + } +} + +fn exit_directly(cond: bool) { + loop { + if cond { + std::process::exit(0); + } + } +} + +trait MyTrait { + fn problematic_trait_method() { + loop { + //~^ ERROR: infinite loop detected + do_something(); + } + } + fn could_be_problematic(); +} + +impl MyTrait for String { + fn could_be_problematic() { + loop { + //~^ ERROR: infinite loop detected + do_something(); + } + } +} + +fn inf_loop_in_closure() { + let _loop_forever = || { + loop { + //~^ ERROR: infinite loop detected + do_something(); + } + }; + + let _somehow_ok = || -> ! { + loop { + do_something(); + } + }; +} + +fn inf_loop_in_res() -> Result<(), i32> { + Ok(loop { + do_something() + }) +} + +fn main() {} diff --git a/src/tools/clippy/tests/ui/infinite_loops.stderr b/src/tools/clippy/tests/ui/infinite_loops.stderr new file mode 100644 index 000000000..f58b3cebb --- /dev/null +++ b/src/tools/clippy/tests/ui/infinite_loops.stderr @@ -0,0 +1,259 @@ +error: infinite loop detected + --> $DIR/infinite_loops.rs:8:5 + | +LL | / loop { +LL | | +LL | | do_something(); +LL | | } + | |_____^ + | + = note: `-D clippy::infinite-loop` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::infinite_loop)]` +help: if this is intentional, consider specifing `!` as function return + | +LL | fn no_break() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:15:5 + | +LL | / loop { +LL | | +LL | | loop { +LL | | +... | +LL | | do_something(); +LL | | } + | |_____^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn all_inf() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:17:9 + | +LL | / loop { +LL | | +LL | | loop { +LL | | +LL | | do_something(); +LL | | } +LL | | } + | |_________^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn all_inf() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:19:13 + | +LL | / loop { +LL | | +LL | | do_something(); +LL | | } + | |_____________^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn all_inf() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:33:5 + | +LL | / loop { +LL | | +LL | | do_something(); +LL | | } + | |_____^ + | + = help: if this is not intended, try adding a `break` or `return` condition in the loop + +error: infinite loop detected + --> $DIR/infinite_loops.rs:46:5 + | +LL | / loop { +LL | | fn inner_fn() -> ! { +LL | | std::process::exit(0); +LL | | } +LL | | do_something(); +LL | | } + | |_____^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn no_break_never_ret_noise() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:89:5 + | +LL | / loop { +LL | | +LL | | loop { +LL | | if cond { +... | +LL | | } +LL | | } + | |_____^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn break_inner_but_not_outer_1(cond: bool) -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:100:5 + | +LL | / loop { +LL | | +LL | | 'inner: loop { +LL | | loop { +... | +LL | | } +LL | | } + | |_____^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn break_inner_but_not_outer_2(cond: bool) -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:114:9 + | +LL | / loop { +LL | | +LL | | do_something(); +LL | | } + | |_________^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn break_outer_but_not_inner() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:137:9 + | +LL | / loop { +LL | | +LL | | 'inner: loop { +LL | | loop { +... | +LL | | } +LL | | } + | |_________^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn break_wrong_loop(cond: bool) -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:177:5 + | +LL | / loop { +LL | | +LL | | match opt { +LL | | Some(v) => { +... | +LL | | } +LL | | } + | |_____^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn match_like() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:218:5 + | +LL | / loop { +LL | | +LL | | let _x = matches!(result, Ok(v) if v != 0).then_some(0); +LL | | } + | |_____^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn match_like() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:223:5 + | +LL | / loop { +LL | | +LL | | // This `return` does not return the function, so it doesn't count +LL | | let _x = matches!(result, Ok(v) if v != 0).then(|| { +... | +LL | | }); +LL | | } + | |_____^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn match_like() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:328:9 + | +LL | / loop { +LL | | +LL | | do_something(); +LL | | } + | |_________^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn problematic_trait_method() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:338:9 + | +LL | / loop { +LL | | +LL | | do_something(); +LL | | } + | |_________^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | fn could_be_problematic() -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:347:9 + | +LL | / loop { +LL | | +LL | | do_something(); +LL | | } + | |_________^ + | +help: if this is intentional, consider specifing `!` as function return + | +LL | let _loop_forever = || -> ! { + | ++++ + +error: infinite loop detected + --> $DIR/infinite_loops.rs:361:8 + | +LL | Ok(loop { + | ________^ +LL | | do_something() +LL | | }) + | |_____^ + | + = help: if this is not intended, try adding a `break` or `return` condition in the loop + +error: aborting due to 17 previous errors + diff --git a/src/tools/clippy/tests/ui/inspect_for_each.stderr b/src/tools/clippy/tests/ui/inspect_for_each.stderr index 80df86ad6..8bd4fe398 100644 --- a/src/tools/clippy/tests/ui/inspect_for_each.stderr +++ b/src/tools/clippy/tests/ui/inspect_for_each.stderr @@ -14,5 +14,5 @@ LL | | }); = note: `-D clippy::inspect-for-each` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::inspect_for_each)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/issue-3145.stderr b/src/tools/clippy/tests/ui/issue-3145.stderr index d7c2c88a2..51debc9b7 100644 --- a/src/tools/clippy/tests/ui/issue-3145.stderr +++ b/src/tools/clippy/tests/ui/issue-3145.stderr @@ -4,5 +4,5 @@ error: expected `,`, found `a` LL | println!("{}" a); | ^ expected `,` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/issue_2356.stderr b/src/tools/clippy/tests/ui/issue_2356.stderr index d04b49e52..860c545c7 100644 --- a/src/tools/clippy/tests/ui/issue_2356.stderr +++ b/src/tools/clippy/tests/ui/issue_2356.stderr @@ -10,5 +10,5 @@ note: the lint level is defined here LL | #![deny(clippy::while_let_on_iterator)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr index 4e9987636..30aa90d29 100644 --- a/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr +++ b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr @@ -10,5 +10,5 @@ LL | fn in_submodule() {} = note: `-D clippy::items-after-test-module` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::items_after_test_module)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr b/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr index 67bc82ebf..17b07cc32 100644 --- a/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr +++ b/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr @@ -16,5 +16,5 @@ LL | macro_rules! should_lint { = help: to override `-D warnings` add `#[allow(clippy::items_after_test_module)]` = help: move the items to before the test module was defined -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/iter_kv_map.fixed b/src/tools/clippy/tests/ui/iter_kv_map.fixed index 566a5b690..2cbf972fc 100644 --- a/src/tools/clippy/tests/ui/iter_kv_map.fixed +++ b/src/tools/clippy/tests/ui/iter_kv_map.fixed @@ -89,3 +89,46 @@ fn main() { // Don't let a mut interfere. let _ = map.clone().into_values().count(); } + +#[clippy::msrv = "1.53"] +fn msrv_1_53() { + let map: HashMap<u32, u32> = HashMap::new(); + + // Don't lint because into_iter is not supported + let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>(); + let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>(); + + let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>(); + let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>(); + + // Lint + let _ = map.keys().collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's keys + let _ = map.values().collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values + let _ = map.values().map(|v| v + 2).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values +} + +#[clippy::msrv = "1.54"] +fn msrv_1_54() { + // Lint all + let map: HashMap<u32, u32> = HashMap::new(); + + let _ = map.clone().into_keys().collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's keys + let _ = map.clone().into_keys().map(|key| key + 2).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's keys + + let _ = map.clone().into_values().collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values + let _ = map.clone().into_values().map(|val| val + 2).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values + + let _ = map.keys().collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's keys + let _ = map.values().collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values + let _ = map.values().map(|v| v + 2).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values +} diff --git a/src/tools/clippy/tests/ui/iter_kv_map.rs b/src/tools/clippy/tests/ui/iter_kv_map.rs index d85e501da..6a9a4267a 100644 --- a/src/tools/clippy/tests/ui/iter_kv_map.rs +++ b/src/tools/clippy/tests/ui/iter_kv_map.rs @@ -93,3 +93,46 @@ fn main() { // Don't let a mut interfere. let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); } + +#[clippy::msrv = "1.53"] +fn msrv_1_53() { + let map: HashMap<u32, u32> = HashMap::new(); + + // Don't lint because into_iter is not supported + let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>(); + let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>(); + + let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>(); + let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>(); + + // Lint + let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's keys + let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values + let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values +} + +#[clippy::msrv = "1.54"] +fn msrv_1_54() { + // Lint all + let map: HashMap<u32, u32> = HashMap::new(); + + let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's keys + let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's keys + + let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values + let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values + + let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's keys + let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values + let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>(); + //~^ ERROR: iterating on a map's values +} diff --git a/src/tools/clippy/tests/ui/iter_kv_map.stderr b/src/tools/clippy/tests/ui/iter_kv_map.stderr index 62155b7f8..471615978 100644 --- a/src/tools/clippy/tests/ui/iter_kv_map.stderr +++ b/src/tools/clippy/tests/ui/iter_kv_map.stderr @@ -201,5 +201,65 @@ error: iterating on a map's values LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` -error: aborting due to 28 previous errors +error: iterating on a map's keys + --> $DIR/iter_kv_map.rs:109:13 + | +LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:111:13 + | +LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:113:13 + | +LL | let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` + +error: iterating on a map's keys + --> $DIR/iter_kv_map.rs:122:13 + | +LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()` + +error: iterating on a map's keys + --> $DIR/iter_kv_map.rs:124:13 + | +LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:127:13 + | +LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:129:13 + | +LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)` + +error: iterating on a map's keys + --> $DIR/iter_kv_map.rs:132:13 + | +LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:134:13 + | +LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:136:13 + | +LL | let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` + +error: aborting due to 38 previous errors diff --git a/src/tools/clippy/tests/ui/iter_next_loop.stderr b/src/tools/clippy/tests/ui/iter_next_loop.stderr index 5bba0e635..5871d21e4 100644 --- a/src/tools/clippy/tests/ui/iter_next_loop.stderr +++ b/src/tools/clippy/tests/ui/iter_next_loop.stderr @@ -4,6 +4,6 @@ error[E0423]: expected value, found macro `vec` LL | for _ in vec.iter().next() {} | ^^^ not a value -error: aborting due to previous error +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0423`. diff --git a/src/tools/clippy/tests/ui/iter_over_hash_type.rs b/src/tools/clippy/tests/ui/iter_over_hash_type.rs new file mode 100644 index 000000000..7000c8bf9 --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_over_hash_type.rs @@ -0,0 +1,74 @@ +//@aux-build:proc_macros.rs +#![feature(rustc_private)] +#![warn(clippy::iter_over_hash_type)] +use std::collections::{HashMap, HashSet}; + +extern crate rustc_data_structures; + +extern crate proc_macros; + +fn main() { + let mut hash_set = HashSet::<i32>::new(); + let mut hash_map = HashMap::<i32, i32>::new(); + let mut fx_hash_map = rustc_data_structures::fx::FxHashMap::<i32, i32>::default(); + let mut fx_hash_set = rustc_data_structures::fx::FxHashMap::<i32, i32>::default(); + let vec = Vec::<i32>::new(); + + // test hashset + for x in &hash_set { + let _ = x; + } + for x in hash_set.iter() { + let _ = x; + } + for x in hash_set.clone() { + let _ = x; + } + for x in hash_set.drain() { + let _ = x; + } + + // test hashmap + for (x, y) in &hash_map { + let _ = (x, y); + } + for x in hash_map.keys() { + let _ = x; + } + for x in hash_map.values() { + let _ = x; + } + for x in hash_map.values_mut() { + *x += 1; + } + for x in hash_map.iter() { + let _ = x; + } + for x in hash_map.clone() { + let _ = x; + } + for x in hash_map.drain() { + let _ = x; + } + + // test type-aliased hashers + for x in fx_hash_set { + let _ = x; + } + for x in fx_hash_map { + let _ = x; + } + + // shouldnt fire + for x in &vec { + let _ = x; + } + for x in vec { + let _ = x; + } + + // should not lint, this comes from an external crate + proc_macros::external! { + for _ in HashMap::<i32, i32>::new() {} + } +} diff --git a/src/tools/clippy/tests/ui/iter_over_hash_type.stderr b/src/tools/clippy/tests/ui/iter_over_hash_type.stderr new file mode 100644 index 000000000..cf420fb8e --- /dev/null +++ b/src/tools/clippy/tests/ui/iter_over_hash_type.stderr @@ -0,0 +1,109 @@ +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:18:5 + | +LL | / for x in &hash_set { +LL | | let _ = x; +LL | | } + | |_____^ + | + = note: `-D clippy::iter-over-hash-type` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]` + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:21:5 + | +LL | / for x in hash_set.iter() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:24:5 + | +LL | / for x in hash_set.clone() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:27:5 + | +LL | / for x in hash_set.drain() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:32:5 + | +LL | / for (x, y) in &hash_map { +LL | | let _ = (x, y); +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:35:5 + | +LL | / for x in hash_map.keys() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:38:5 + | +LL | / for x in hash_map.values() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:41:5 + | +LL | / for x in hash_map.values_mut() { +LL | | *x += 1; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:44:5 + | +LL | / for x in hash_map.iter() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:47:5 + | +LL | / for x in hash_map.clone() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:50:5 + | +LL | / for x in hash_map.drain() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:55:5 + | +LL | / for x in fx_hash_set { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:58:5 + | +LL | / for x in fx_hash_map { +LL | | let _ = x; +LL | | } + | |_____^ + +error: aborting due to 13 previous errors + diff --git a/src/tools/clippy/tests/ui/join_absolute_paths.rs b/src/tools/clippy/tests/ui/join_absolute_paths.rs new file mode 100644 index 000000000..efa77a049 --- /dev/null +++ b/src/tools/clippy/tests/ui/join_absolute_paths.rs @@ -0,0 +1,30 @@ +//@no-rustfix + +#![allow(clippy::needless_raw_string_hashes)] +#![warn(clippy::join_absolute_paths)] + +use std::path::{Path, PathBuf}; + +fn main() { + let path = Path::new("/bin"); + path.join("/sh"); + //~^ ERROR: argument to `Path::join` starts with a path separator + + let path = Path::new("C:\\Users"); + path.join("\\user"); + //~^ ERROR: argument to `Path::join` starts with a path separator + + let path = PathBuf::from("/bin"); + path.join("/sh"); + //~^ ERROR: argument to `Path::join` starts with a path separator + + let path = PathBuf::from("/bin"); + path.join(r#"/sh"#); + //~^ ERROR: argument to `Path::join` starts with a path separator + + let path: &[&str] = &["/bin"]; + path.join("/sh"); + + let path = Path::new("/bin"); + path.join("sh"); +} diff --git a/src/tools/clippy/tests/ui/join_absolute_paths.stderr b/src/tools/clippy/tests/ui/join_absolute_paths.stderr new file mode 100644 index 000000000..0c2f89d99 --- /dev/null +++ b/src/tools/clippy/tests/ui/join_absolute_paths.stderr @@ -0,0 +1,68 @@ +error: argument to `Path::join` starts with a path separator + --> $DIR/join_absolute_paths.rs:10:15 + | +LL | path.join("/sh"); + | ^^^^^ + | + = note: joining a path starting with separator will replace the path instead + = note: `-D clippy::join-absolute-paths` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::join_absolute_paths)]` +help: if this is unintentional, try removing the starting separator + | +LL | path.join("sh"); + | ~~~~ +help: if this is intentional, try using `Path::new` instead + | +LL | PathBuf::from("/sh"); + | ~~~~~~~~~~~~~~~~~~~~ + +error: argument to `Path::join` starts with a path separator + --> $DIR/join_absolute_paths.rs:14:15 + | +LL | path.join("\\user"); + | ^^^^^^^^ + | + = note: joining a path starting with separator will replace the path instead +help: if this is unintentional, try removing the starting separator + | +LL | path.join("\user"); + | ~~~~~~~ +help: if this is intentional, try using `Path::new` instead + | +LL | PathBuf::from("\\user"); + | ~~~~~~~~~~~~~~~~~~~~~~~ + +error: argument to `Path::join` starts with a path separator + --> $DIR/join_absolute_paths.rs:18:15 + | +LL | path.join("/sh"); + | ^^^^^ + | + = note: joining a path starting with separator will replace the path instead +help: if this is unintentional, try removing the starting separator + | +LL | path.join("sh"); + | ~~~~ +help: if this is intentional, try using `Path::new` instead + | +LL | PathBuf::from("/sh"); + | ~~~~~~~~~~~~~~~~~~~~ + +error: argument to `Path::join` starts with a path separator + --> $DIR/join_absolute_paths.rs:22:15 + | +LL | path.join(r#"/sh"#); + | ^^^^^^^^ + | + = note: joining a path starting with separator will replace the path instead +help: if this is unintentional, try removing the starting separator + | +LL | path.join(r#"sh"#); + | ~~~~~~~ +help: if this is intentional, try using `Path::new` instead + | +LL | PathBuf::from(r#"/sh"#); + | ~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed b/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed index 74ef6f729..621115cc1 100644 --- a/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed +++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed @@ -10,11 +10,17 @@ fn main() -> io::Result<()> { // Lint let f = std::fs::File::open("/")?; BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ()); + // Lint + let f = std::fs::File::open("/")?; + BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ()); + let s = "foo\nbar\nbaz\n"; // Lint io::stdin().lines().map_while(Result::ok).for_each(|_| ()); // Lint io::stdin().lines().map_while(Result::ok).for_each(|_| ()); + // Lint + io::stdin().lines().map_while(Result::ok).for_each(|_| ()); // Do not lint (not a `Lines` iterator) io::stdin() .lines() diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.rs b/src/tools/clippy/tests/ui/lines_filter_map_ok.rs index 345f4dc5f..a86efbd66 100644 --- a/src/tools/clippy/tests/ui/lines_filter_map_ok.rs +++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.rs @@ -10,11 +10,17 @@ fn main() -> io::Result<()> { // Lint let f = std::fs::File::open("/")?; BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ()); + // Lint + let f = std::fs::File::open("/")?; + BufReader::new(f).lines().flatten().for_each(|_| ()); + let s = "foo\nbar\nbaz\n"; // Lint io::stdin().lines().filter_map(Result::ok).for_each(|_| ()); // Lint io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ()); + // Lint + io::stdin().lines().flatten().for_each(|_| ()); // Do not lint (not a `Lines` iterator) io::stdin() .lines() diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr b/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr index fa2ba0a9a..9833ab164 100644 --- a/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr +++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr @@ -24,29 +24,53 @@ note: this expression returning a `std::io::Lines` may produce an infinite numbe LL | BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: `flatten()` will run forever if the iterator repeatedly produces an `Err` + --> $DIR/lines_filter_map_ok.rs:15:31 + | +LL | BufReader::new(f).lines().flatten().for_each(|_| ()); + | ^^^^^^^^^ help: replace with: `map_while(Result::ok)` + | +note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error + --> $DIR/lines_filter_map_ok.rs:15:5 + | +LL | BufReader::new(f).lines().flatten().for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + error: `filter_map()` will run forever if the iterator repeatedly produces an `Err` - --> $DIR/lines_filter_map_ok.rs:15:25 + --> $DIR/lines_filter_map_ok.rs:19:25 | LL | io::stdin().lines().filter_map(Result::ok).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)` | note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error - --> $DIR/lines_filter_map_ok.rs:15:5 + --> $DIR/lines_filter_map_ok.rs:19:5 | LL | io::stdin().lines().filter_map(Result::ok).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^ error: `filter_map()` will run forever if the iterator repeatedly produces an `Err` - --> $DIR/lines_filter_map_ok.rs:17:25 + --> $DIR/lines_filter_map_ok.rs:21:25 | LL | io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)` | note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error - --> $DIR/lines_filter_map_ok.rs:17:5 + --> $DIR/lines_filter_map_ok.rs:21:5 | LL | io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ()); | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: `flatten()` will run forever if the iterator repeatedly produces an `Err` + --> $DIR/lines_filter_map_ok.rs:23:25 + | +LL | io::stdin().lines().flatten().for_each(|_| ()); + | ^^^^^^^^^ help: replace with: `map_while(Result::ok)` + | +note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error + --> $DIR/lines_filter_map_ok.rs:23:5 + | +LL | io::stdin().lines().flatten().for_each(|_| ()); + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/macro_use_imports.stderr b/src/tools/clippy/tests/ui/macro_use_imports.stderr index 6de869699..5524e7e56 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports.stderr +++ b/src/tools/clippy/tests/ui/macro_use_imports.stderr @@ -1,8 +1,8 @@ error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> $DIR/macro_use_imports.rs:25:5 + --> $DIR/macro_use_imports.rs:19:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;` + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};` | = note: `-D clippy::macro-use-imports` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::macro_use_imports)]` @@ -14,16 +14,16 @@ LL | #[macro_use] | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> $DIR/macro_use_imports.rs:21:5 + --> $DIR/macro_use_imports.rs:25:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;` + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> $DIR/macro_use_imports.rs:19:5 + --> $DIR/macro_use_imports.rs:21:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};` + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;` error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/manual_filter.fixed b/src/tools/clippy/tests/ui/manual_filter.fixed index c1bc4aae9..a0fb0e32d 100644 --- a/src/tools/clippy/tests/ui/manual_filter.fixed +++ b/src/tools/clippy/tests/ui/manual_filter.fixed @@ -40,7 +40,7 @@ fn main() { }; } - #[allow(clippy::blocks_in_if_conditions)] + #[allow(clippy::blocks_in_conditions)] Some(11).filter(|&x| { println!("foo"); x > 10 && x < 100 diff --git a/src/tools/clippy/tests/ui/manual_filter.rs b/src/tools/clippy/tests/ui/manual_filter.rs index ee44909f3..0ac6cbefc 100644 --- a/src/tools/clippy/tests/ui/manual_filter.rs +++ b/src/tools/clippy/tests/ui/manual_filter.rs @@ -135,7 +135,7 @@ fn main() { }; } - #[allow(clippy::blocks_in_if_conditions)] + #[allow(clippy::blocks_in_conditions)] match Some(11) { // Lint, statement is preserved by `.filter` Some(x) => { diff --git a/src/tools/clippy/tests/ui/manual_let_else.rs b/src/tools/clippy/tests/ui/manual_let_else.rs index 27717ab3a..5d94660ec 100644 --- a/src/tools/clippy/tests/ui/manual_let_else.rs +++ b/src/tools/clippy/tests/ui/manual_let_else.rs @@ -5,7 +5,9 @@ clippy::let_unit_value, clippy::match_single_binding, clippy::never_loop, - clippy::needless_if + clippy::needless_if, + clippy::diverging_sub_expression, + clippy::single_match )] #![warn(clippy::manual_let_else)] //@no-rustfix @@ -24,7 +26,7 @@ fn main() {} fn fire() { let v = if let Some(v_some) = g() { v_some } else { return }; //~^ ERROR: this could be rewritten as `let...else` - //~| NOTE: `-D clippy::manual-let-else` implied by `-D warnings` + let v = if let Some(v_some) = g() { //~^ ERROR: this could be rewritten as `let...else` v_some @@ -79,22 +81,76 @@ fn fire() { panic!(); }; + // The final expression will need to be turned into a statement. + let v = if let Some(v_some) = g() { + //~^ ERROR: this could be rewritten as `let...else` + v_some + } else { + panic!(); + () + }; + + // Even if the result is buried multiple expressions deep. + let v = if let Some(v_some) = g() { + //~^ ERROR: this could be rewritten as `let...else` + v_some + } else { + panic!(); + if true { + match 0 { + 0 => (), + _ => (), + } + } else { + panic!() + } + }; + + // Or if a break gives the value. + let v = if let Some(v_some) = g() { + //~^ ERROR: this could be rewritten as `let...else` + v_some + } else { + loop { + panic!(); + break (); + } + }; + + // Even if the break is in a weird position. + let v = if let Some(v_some) = g() { + //~^ ERROR: this could be rewritten as `let...else` + v_some + } else { + 'a: loop { + panic!(); + loop { + match 0 { + 0 if (return break 'a ()) => {}, + _ => {}, + } + } + } + }; + // A match diverges if all branches diverge: - // Note: the corresponding let-else requires a ; at the end of the match - // as otherwise the type checker does not turn it into a ! type. let v = if let Some(v_some) = g() { //~^ ERROR: this could be rewritten as `let...else` v_some } else { - match () { - _ if panic!() => {}, + match 0 { + 0 if true => panic!(), _ => panic!(), - } + }; }; // An if's expression can cause divergence: - let v = if let Some(v_some) = g() { v_some } else { if panic!() {} }; - //~^ ERROR: this could be rewritten as `let...else` + let v = if let Some(v_some) = g() { + //~^ ERROR: this could be rewritten as `let...else` + v_some + } else { + if panic!() {}; + }; // An expression of a match can cause divergence: let v = if let Some(v_some) = g() { @@ -103,7 +159,7 @@ fn fire() { } else { match panic!() { _ => {}, - } + }; }; // Top level else if @@ -342,6 +398,43 @@ fn not_fire() { } else { return; }; + + // A break that skips the divergent statement will cause the expression to be non-divergent. + let _x = if let Some(x) = Some(0) { + x + } else { + 'foo: loop { + break 'foo 0; + panic!(); + } + }; + + // Even in inner loops. + let _x = if let Some(x) = Some(0) { + x + } else { + 'foo: { + loop { + break 'foo 0; + } + panic!(); + } + }; + + // But a break that can't ever be reached still affects divergence checking. + let _x = if let Some(x) = g() { + x + } else { + 'foo: { + 'bar: loop { + loop { + break 'bar (); + } + break 'foo (); + } + panic!(); + }; + }; } struct S<T> { diff --git a/src/tools/clippy/tests/ui/manual_let_else.stderr b/src/tools/clippy/tests/ui/manual_let_else.stderr index 2b6504a18..3beaf766e 100644 --- a/src/tools/clippy/tests/ui/manual_let_else.stderr +++ b/src/tools/clippy/tests/ui/manual_let_else.stderr @@ -1,5 +1,5 @@ error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:25:5 + --> $DIR/manual_let_else.rs:27:5 | LL | let v = if let Some(v_some) = g() { v_some } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };` @@ -8,7 +8,7 @@ LL | let v = if let Some(v_some) = g() { v_some } else { return }; = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:28:5 + --> $DIR/manual_let_else.rs:30:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -26,7 +26,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:35:5 + --> $DIR/manual_let_else.rs:37:5 | LL | / let v = if let Some(v) = g() { LL | | @@ -47,25 +47,25 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:47:9 + --> $DIR/manual_let_else.rs:49:9 | LL | let v = if let Some(v_some) = g() { v_some } else { continue }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:49:9 + --> $DIR/manual_let_else.rs:51:9 | LL | let v = if let Some(v_some) = g() { v_some } else { break }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:54:5 + --> $DIR/manual_let_else.rs:56:5 | LL | let v = if let Some(v_some) = g() { v_some } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:58:5 + --> $DIR/manual_let_else.rs:60:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -83,7 +83,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:66:5 + --> $DIR/manual_let_else.rs:68:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -101,7 +101,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:74:5 + --> $DIR/manual_let_else.rs:76:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -127,6 +127,26 @@ LL | / let v = if let Some(v_some) = g() { LL | | LL | | v_some LL | | } else { +LL | | panic!(); +LL | | () +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(v) = g() else { +LL + panic!(); +LL + () +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:94:5 + | +LL | / let v = if let Some(v_some) = g() { +LL | | +LL | | v_some +LL | | } else { ... | LL | | } LL | | }; @@ -135,21 +155,42 @@ LL | | }; help: consider writing | LL ~ let Some(v) = g() else { -LL + match () { -LL + _ if panic!() => {}, -LL + _ => panic!(), +LL + panic!(); +LL + if true { +LL + match 0 { +LL + 0 => (), +LL + _ => (), +LL + } +LL + } else { +LL + panic!() LL + } LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:96:5 + --> $DIR/manual_let_else.rs:110:5 + | +LL | / let v = if let Some(v_some) = g() { +LL | | +LL | | v_some +LL | | } else { +... | +LL | | } +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(v) = g() else { +LL + loop { +LL + panic!(); +LL + break (); +LL + } +LL + }; | -LL | let v = if let Some(v_some) = g() { v_some } else { if panic!() {} }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { if panic!() {} };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:100:5 + --> $DIR/manual_let_else.rs:121:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -163,14 +204,81 @@ LL | | }; help: consider writing | LL ~ let Some(v) = g() else { +LL + 'a: loop { +LL + panic!(); +LL + loop { +LL + match 0 { +LL + 0 if (return break 'a ()) => {}, +LL + _ => {}, +LL + } +LL + } +LL + } +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:137:5 + | +LL | / let v = if let Some(v_some) = g() { +LL | | +LL | | v_some +LL | | } else { +... | +LL | | }; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(v) = g() else { +LL + match 0 { +LL + 0 if true => panic!(), +LL + _ => panic!(), +LL + }; +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:148:5 + | +LL | / let v = if let Some(v_some) = g() { +LL | | +LL | | v_some +LL | | } else { +LL | | if panic!() {}; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(v) = g() else { +LL + if panic!() {}; +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:156:5 + | +LL | / let v = if let Some(v_some) = g() { +LL | | +LL | | v_some +LL | | } else { +... | +LL | | }; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(v) = g() else { LL + match panic!() { LL + _ => {}, -LL + } +LL + }; LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:110:5 + --> $DIR/manual_let_else.rs:166:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -191,7 +299,7 @@ LL + } }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:120:5 + --> $DIR/manual_let_else.rs:176:5 | LL | / let v = if let Some(v_some) = g() { LL | | @@ -220,7 +328,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:138:5 + --> $DIR/manual_let_else.rs:194:5 | LL | / let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) { LL | | @@ -238,7 +346,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:146:5 + --> $DIR/manual_let_else.rs:202:5 | LL | / let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) { LL | | @@ -256,7 +364,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:156:13 + --> $DIR/manual_let_else.rs:212:13 | LL | let $n = if let Some(v) = $e { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };` @@ -267,19 +375,19 @@ LL | create_binding_if_some!(w, g()); = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info) error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:165:5 + --> $DIR/manual_let_else.rs:221:5 | LL | let v = if let Variant::A(a, 0) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:169:5 + --> $DIR/manual_let_else.rs:225:5 | LL | let mut v = if let Variant::B(b) = e() { b } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:174:5 + --> $DIR/manual_let_else.rs:230:5 | LL | / let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { LL | | @@ -297,19 +405,19 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:181:5 + --> $DIR/manual_let_else.rs:237:5 | LL | let v = if let Variant::A(.., a) = e() { a } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:185:5 + --> $DIR/manual_let_else.rs:241:5 | LL | let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:189:5 + --> $DIR/manual_let_else.rs:245:5 | LL | / let w = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | @@ -327,7 +435,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:197:5 + --> $DIR/manual_let_else.rs:253:5 | LL | / let v = if let Some(S { v: x }) = Some(S { v: 0 }) { LL | | @@ -345,7 +453,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:205:5 + --> $DIR/manual_let_else.rs:261:5 | LL | / let (x, S { v }, w) = if let Some(U { v, w, x }) = None::<U<S<()>>> { LL | | @@ -363,7 +471,7 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:322:5 + --> $DIR/manual_let_else.rs:378:5 | LL | / let _ = match ff { LL | | @@ -372,5 +480,5 @@ LL | | _ => macro_call!(), LL | | }; | |______^ help: consider writing: `let Some(_) = ff else { macro_call!() };` -error: aborting due to 26 previous errors +error: aborting due to 30 previous errors diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs index a224001a3..8146091a2 100644 --- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs +++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs @@ -138,6 +138,26 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { for i in 0..dst.len() { dst[i] = src[i]; } + + // Range is equal to array length + let src = [0, 1, 2, 3, 4]; + let mut dst = [0; 4]; + for i in 0..4 { + //~^ ERROR: it looks like you're manually copying between slices + dst[i] = src[i]; + } + + let mut dst = [0; 6]; + for i in 0..5 { + //~^ ERROR: it looks like you're manually copying between slices + dst[i] = src[i]; + } + + let mut dst = [0; 5]; + for i in 0..5 { + //~^ ERROR: it looks like you're manually copying between slices + dst[i] = src[i]; + } } #[warn(clippy::needless_range_loop, clippy::manual_memcpy)] diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr index b9dbda6ed..4b5cd274d 100644 --- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr +++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr @@ -106,7 +106,7 @@ LL | / for i in 0..5 { LL | | LL | | dst[i - 0] = src[i]; LL | | } - | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src[..5]);` + | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);` error: it looks like you're manually copying between slices --> $DIR/without_loop_counters.rs:121:5 @@ -120,11 +120,38 @@ LL | | } error: it looks like you're manually copying between slices --> $DIR/without_loop_counters.rs:145:5 | +LL | / for i in 0..4 { +LL | | +LL | | dst[i] = src[i]; +LL | | } + | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..4]);` + +error: it looks like you're manually copying between slices + --> $DIR/without_loop_counters.rs:151:5 + | +LL | / for i in 0..5 { +LL | | +LL | | dst[i] = src[i]; +LL | | } + | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);` + +error: it looks like you're manually copying between slices + --> $DIR/without_loop_counters.rs:157:5 + | +LL | / for i in 0..5 { +LL | | +LL | | dst[i] = src[i]; +LL | | } + | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src);` + +error: it looks like you're manually copying between slices + --> $DIR/without_loop_counters.rs:165:5 + | LL | / for i in 0..src.len() { LL | | LL | | dst[i] = src[i].clone(); LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..]);` -error: aborting due to 13 previous errors +error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs index e32ba8631..eb3875320 100644 --- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs +++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs @@ -26,7 +26,7 @@ enum NoDocHidden { _C, } -// name of variant with doc hidden does not start with underscore, should be ignored +// name of variant with doc hidden does not start with underscore enum NoUnderscore { A, B, diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr index 7361a4a2c..c4b13a577 100644 --- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr +++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr @@ -22,5 +22,26 @@ LL | _C, = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]` -error: aborting due to previous error +error: this seems like a manual implementation of the non-exhaustive pattern + --> $DIR/manual_non_exhaustive_enum.rs:30:1 + | +LL | enum NoUnderscore { + | ^---------------- + | | + | _help: add the attribute: `#[non_exhaustive] enum NoUnderscore` + | | +LL | | A, +LL | | B, +LL | | #[doc(hidden)] +LL | | C, +LL | | } + | |_^ + | +help: remove this variant + --> $DIR/manual_non_exhaustive_enum.rs:34:5 + | +LL | C, + | ^ + +error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr index 028b8ff76..0b88b1969 100644 --- a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr +++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr @@ -39,6 +39,26 @@ LL | _c: (), | ^^^^^^ error: this seems like a manual implementation of the non-exhaustive pattern + --> $DIR/manual_non_exhaustive_struct.rs:29:5 + | +LL | struct NoUnderscore { + | ^------------------ + | | + | _____help: add the attribute: `#[non_exhaustive] struct NoUnderscore` + | | +LL | | pub a: i32, +LL | | pub b: i32, +LL | | c: (), +LL | | } + | |_____^ + | +help: remove this field + --> $DIR/manual_non_exhaustive_struct.rs:32:9 + | +LL | c: (), + | ^^^^^ + +error: this seems like a manual implementation of the non-exhaustive pattern --> $DIR/manual_non_exhaustive_struct.rs:56:5 | LL | struct T(pub i32, pub i32, ()); @@ -64,5 +84,5 @@ help: remove this field LL | struct Tp(pub i32, pub i32, ()); | ^^ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/manual_ok_or.stderr b/src/tools/clippy/tests/ui/manual_ok_or.stderr index ddb2cf261..b277d22e5 100644 --- a/src/tools/clippy/tests/ui/manual_ok_or.stderr +++ b/src/tools/clippy/tests/ui/manual_ok_or.stderr @@ -13,6 +13,15 @@ error: this pattern reimplements `Option::ok_or` LL | foo.map_or(Err("error"), Ok); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or("error")` +error: called `map_or(Err(_), Ok)` on an `Option` value + --> $DIR/manual_ok_or.rs:14:5 + | +LL | foo.map_or(Err("error"), Ok); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok_or` instead: `foo.ok_or("error")` + | + = note: `-D clippy::option-map-or-err-ok` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]` + error: this pattern reimplements `Option::ok_or` --> $DIR/manual_ok_or.rs:17:5 | @@ -38,5 +47,5 @@ LL + "{}{}{}{}{}{}{}", LL ~ "Alice", "Bob", "Sarah", "Marc", "Sandra", "Eric", "Jenifer")); | -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/manual_try_fold.rs b/src/tools/clippy/tests/ui/manual_try_fold.rs index bddf03ac3..7299d7cf9 100644 --- a/src/tools/clippy/tests/ui/manual_try_fold.rs +++ b/src/tools/clippy/tests/ui/manual_try_fold.rs @@ -96,3 +96,33 @@ fn msrv_juust_right() { .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) .unwrap(); } + +mod issue11876 { + struct Foo; + + impl Bar for Foo { + type Output = u32; + } + + trait Bar: Sized { + type Output; + fn fold<A, F>(self, init: A, func: F) -> Fold<Self, A, F> + where + A: Clone, + F: Fn(A, Self::Output) -> A, + { + Fold { this: self, init, func } + } + } + + #[allow(dead_code)] + struct Fold<S, A, F> { + this: S, + init: A, + func: F, + } + + fn main() { + Foo.fold(Some(0), |acc, entry| Some(acc? + entry)); + } +} diff --git a/src/tools/clippy/tests/ui/map_err.stderr b/src/tools/clippy/tests/ui/map_err.stderr index 6a845c84a..eb6742ff2 100644 --- a/src/tools/clippy/tests/ui/map_err.stderr +++ b/src/tools/clippy/tests/ui/map_err.stderr @@ -8,5 +8,5 @@ LL | println!("{:?}", x.map_err(|_| Errors::Ignored)); = note: `-D clippy::map-err-ignore` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::map_err_ignore)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/map_identity.fixed b/src/tools/clippy/tests/ui/map_identity.fixed index 62b0ba018..53ebfb40b 100644 --- a/src/tools/clippy/tests/ui/map_identity.fixed +++ b/src/tools/clippy/tests/ui/map_identity.fixed @@ -24,28 +24,40 @@ fn main() { fn issue7189() { // should lint - let x = [(1, 2), (3, 4)]; - let _ = x.iter(); - let _ = x.iter(); - let _ = x.iter(); + let x = [(1, 2), (3, 4)].iter().copied(); + let _ = x.clone(); + let _ = x.clone(); + let _ = x.clone(); - let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))]; - let _ = y.iter(); + let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))].iter().copied(); + let _ = y.clone(); // 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 _ = x.clone().map(|(x, y)| (x, y, y)); + let _ = x.clone().map(|(x, _y)| (x,)); + let _ = x.clone().map(|(x, _)| (x,)); + let _ = x.clone().map(|(x, ..)| (x,)); + let _ = y.clone().map(|(x, y, (z, _))| (x, y, (z, z))); let _ = y - .iter() - .map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z))); + .clone() + .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,)))); + .clone() + .map(|(x, y, (z, (w,))): (i32, i32, (i32, (i32,)))| (x, y, (z, (w,)))); } fn not_identity(x: &u16) -> u16 { *x } + +fn issue11764() { + let x = [(1, 2), (3, 4)]; + // don't lint: this is an `Iterator<Item = &(i32, i32)>` + // match ergonomics makes the binding patterns into references + // so that its type changes to `Iterator<Item = (&i32, &i32)>` + let _ = x.iter().map(|(x, y)| (x, y)); + let _ = x.iter().map(|x| (x.0,)).map(|(x,)| x); + + // no match ergonomics for `(i32, i32)` + let _ = x.iter().copied(); +} diff --git a/src/tools/clippy/tests/ui/map_identity.rs b/src/tools/clippy/tests/ui/map_identity.rs index b7f4c99f2..c646c0568 100644 --- a/src/tools/clippy/tests/ui/map_identity.rs +++ b/src/tools/clippy/tests/ui/map_identity.rs @@ -26,30 +26,42 @@ fn main() { fn issue7189() { // should lint - let x = [(1, 2), (3, 4)]; - let _ = x.iter().map(|(x, y)| (x, y)); - let _ = x.iter().map(|(x, y)| { + let x = [(1, 2), (3, 4)].iter().copied(); + let _ = x.clone().map(|(x, y)| (x, y)); + let _ = x.clone().map(|(x, y)| { return (x, y); }); - let _ = x.iter().map(|(x, y)| return (x, y)); + let _ = x.clone().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,)))); + let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))].iter().copied(); + let _ = y.clone().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 _ = x.clone().map(|(x, y)| (x, y, y)); + let _ = x.clone().map(|(x, _y)| (x,)); + let _ = x.clone().map(|(x, _)| (x,)); + let _ = x.clone().map(|(x, ..)| (x,)); + let _ = y.clone().map(|(x, y, (z, _))| (x, y, (z, z))); let _ = y - .iter() - .map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z))); + .clone() + .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,)))); + .clone() + .map(|(x, y, (z, (w,))): (i32, i32, (i32, (i32,)))| (x, y, (z, (w,)))); } fn not_identity(x: &u16) -> u16 { *x } + +fn issue11764() { + let x = [(1, 2), (3, 4)]; + // don't lint: this is an `Iterator<Item = &(i32, i32)>` + // match ergonomics makes the binding patterns into references + // so that its type changes to `Iterator<Item = (&i32, &i32)>` + let _ = x.iter().map(|(x, y)| (x, y)); + let _ = x.iter().map(|x| (x.0,)).map(|(x,)| x); + + // no match ergonomics for `(i32, i32)` + let _ = x.iter().copied().map(|(x, y)| (x, y)); +} diff --git a/src/tools/clippy/tests/ui/map_identity.stderr b/src/tools/clippy/tests/ui/map_identity.stderr index 4ca24b0b0..ea077d66d 100644 --- a/src/tools/clippy/tests/ui/map_identity.stderr +++ b/src/tools/clippy/tests/ui/map_identity.stderr @@ -41,31 +41,37 @@ LL | let _: Result<u32, u32> = Ok(1).map_err(|a| a); | ^^^^^^^^^^^^^^^ help: remove the call to `map_err` error: unnecessary map of the identity function - --> $DIR/map_identity.rs:30:21 + --> $DIR/map_identity.rs:30:22 | -LL | let _ = x.iter().map(|(x, y)| (x, y)); - | ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` +LL | let _ = x.clone().map(|(x, y)| (x, y)); + | ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` error: unnecessary map of the identity function - --> $DIR/map_identity.rs:31:21 + --> $DIR/map_identity.rs:31:22 | -LL | let _ = x.iter().map(|(x, y)| { - | _____________________^ +LL | let _ = x.clone().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 + --> $DIR/map_identity.rs:34:22 | -LL | let _ = x.iter().map(|(x, y)| return (x, y)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` +LL | let _ = x.clone().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 + --> $DIR/map_identity.rs:37:22 | -LL | let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,)))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` +LL | let _ = y.clone().map(|(x, y, (z, (w,)))| (x, y, (z, (w,)))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` -error: aborting due to 10 previous errors +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:66:30 + | +LL | let _ = x.iter().copied().map(|(x, y)| (x, y)); + | ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` + +error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/map_unwrap_or.stderr b/src/tools/clippy/tests/ui/map_unwrap_or.stderr index 7b7eeb322..54ddd1402 100644 --- a/src/tools/clippy/tests/ui/map_unwrap_or.stderr +++ b/src/tools/clippy/tests/ui/map_unwrap_or.stderr @@ -1,4 +1,4 @@ -error: called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead +error: called `map(<f>).unwrap_or(<a>)` on an `Option` value --> $DIR/map_unwrap_or.rs:17:13 | LL | let _ = opt.map(|x| x + 1) @@ -15,7 +15,7 @@ LL - let _ = opt.map(|x| x + 1) LL + let _ = opt.map_or(0, |x| x + 1); | -error: called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead +error: called `map(<f>).unwrap_or(<a>)` on an `Option` value --> $DIR/map_unwrap_or.rs:21:13 | LL | let _ = opt.map(|x| { @@ -33,7 +33,7 @@ LL | } LL ~ ); | -error: called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead +error: called `map(<f>).unwrap_or(<a>)` on an `Option` value --> $DIR/map_unwrap_or.rs:25:13 | LL | let _ = opt.map(|x| x + 1) @@ -50,7 +50,7 @@ LL + 0 LL ~ }, |x| x + 1); | -error: called `map(<f>).unwrap_or(None)` on an `Option` value. This can be done more directly by calling `and_then(<f>)` instead +error: called `map(<f>).unwrap_or(None)` on an `Option` value --> $DIR/map_unwrap_or.rs:30:13 | LL | let _ = opt.map(|x| Some(x + 1)).unwrap_or(None); @@ -62,7 +62,7 @@ LL - let _ = opt.map(|x| Some(x + 1)).unwrap_or(None); LL + let _ = opt.and_then(|x| Some(x + 1)); | -error: called `map(<f>).unwrap_or(None)` on an `Option` value. This can be done more directly by calling `and_then(<f>)` instead +error: called `map(<f>).unwrap_or(None)` on an `Option` value --> $DIR/map_unwrap_or.rs:32:13 | LL | let _ = opt.map(|x| { @@ -80,7 +80,7 @@ LL | } LL ~ ); | -error: called `map(<f>).unwrap_or(None)` on an `Option` value. This can be done more directly by calling `and_then(<f>)` instead +error: called `map(<f>).unwrap_or(None)` on an `Option` value --> $DIR/map_unwrap_or.rs:36:13 | LL | let _ = opt @@ -95,7 +95,7 @@ LL - .map(|x| Some(x + 1)) LL + .and_then(|x| Some(x + 1)); | -error: called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead +error: called `map(<f>).unwrap_or(<a>)` on an `Option` value --> $DIR/map_unwrap_or.rs:47:13 | LL | let _ = Some("prefix").map(|p| format!("{}.", p)).unwrap_or(id); @@ -107,7 +107,7 @@ LL - let _ = Some("prefix").map(|p| format!("{}.", p)).unwrap_or(id); LL + let _ = Some("prefix").map_or(id, |p| format!("{}.", p)); | -error: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value. This can be done more directly by calling `map_or_else(<g>, <f>)` instead +error: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value --> $DIR/map_unwrap_or.rs:51:13 | LL | let _ = opt.map(|x| { @@ -117,7 +117,7 @@ LL | | } LL | | ).unwrap_or_else(|| 0); | |__________________________^ -error: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value. This can be done more directly by calling `map_or_else(<g>, <f>)` instead +error: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value --> $DIR/map_unwrap_or.rs:55:13 | LL | let _ = opt.map(|x| x + 1) @@ -127,7 +127,7 @@ LL | | 0 LL | | ); | |_________^ -error: called `map(<f>).unwrap_or(false)` on an `Option` value. This can be done more directly by calling `is_some_and(<f>)` instead +error: called `map(<f>).unwrap_or(false)` on an `Option` value --> $DIR/map_unwrap_or.rs:61:13 | LL | let _ = opt.map(|x| x > 5).unwrap_or(false); @@ -139,7 +139,7 @@ LL - let _ = opt.map(|x| x > 5).unwrap_or(false); LL + let _ = opt.is_some_and(|x| x > 5); | -error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value. This can be done more directly by calling `.map_or_else(<g>, <f>)` instead +error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value --> $DIR/map_unwrap_or.rs:71:13 | LL | let _ = res.map(|x| { @@ -149,7 +149,7 @@ LL | | } LL | | ).unwrap_or_else(|_e| 0); | |____________________________^ -error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value. This can be done more directly by calling `.map_or_else(<g>, <f>)` instead +error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value --> $DIR/map_unwrap_or.rs:75:13 | LL | let _ = res.map(|x| x + 1) @@ -159,13 +159,13 @@ LL | | 0 LL | | }); | |__________^ -error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value. This can be done more directly by calling `.map_or_else(<g>, <f>)` instead +error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value --> $DIR/map_unwrap_or.rs:99:13 | LL | let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)` -error: called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead +error: called `map(<f>).unwrap_or(<a>)` on an `Option` value --> $DIR/map_unwrap_or.rs:106:13 | LL | let _ = opt.map(|x| x > 5).unwrap_or(false); @@ -177,7 +177,7 @@ LL - let _ = opt.map(|x| x > 5).unwrap_or(false); LL + let _ = opt.map_or(false, |x| x > 5); | -error: called `map(<f>).unwrap_or(false)` on an `Option` value. This can be done more directly by calling `is_some_and(<f>)` instead +error: called `map(<f>).unwrap_or(false)` on an `Option` value --> $DIR/map_unwrap_or.rs:113:13 | LL | let _ = opt.map(|x| x > 5).unwrap_or(false); diff --git a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.stderr b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.stderr index ca611ac9d..d1a9fdd6e 100644 --- a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.stderr +++ b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.stderr @@ -1,4 +1,4 @@ -error: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value. This can be done more directly by calling `map_or_else(<g>, <f>)` instead +error: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value --> $DIR/map_unwrap_or_fixable.rs:16:13 | LL | let _ = opt.map(|x| x + 1) @@ -10,7 +10,7 @@ LL | | .unwrap_or_else(|| 0); = note: `-D clippy::map-unwrap-or` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::map_unwrap_or)]` -error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value. This can be done more directly by calling `.map_or_else(<g>, <f>)` instead +error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value --> $DIR/map_unwrap_or_fixable.rs:46:13 | LL | let _ = res.map(|x| x + 1) diff --git a/src/tools/clippy/tests/ui/mem_replace_macro.stderr b/src/tools/clippy/tests/ui/mem_replace_macro.stderr index 842ad3a85..c6435e94e 100644 --- a/src/tools/clippy/tests/ui/mem_replace_macro.stderr +++ b/src/tools/clippy/tests/ui/mem_replace_macro.stderr @@ -8,5 +8,5 @@ LL | inline!(std::mem::replace($s, Default::default())); = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]` = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/methods_fixable.stderr b/src/tools/clippy/tests/ui/methods_fixable.stderr index 1bfe56d91..f290c20e5 100644 --- a/src/tools/clippy/tests/ui/methods_fixable.stderr +++ b/src/tools/clippy/tests/ui/methods_fixable.stderr @@ -7,5 +7,5 @@ LL | let _ = v.iter().filter(|&x| *x < 0).next(); = note: `-D clippy::filter-next` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::filter_next)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/methods_unfixable.stderr b/src/tools/clippy/tests/ui/methods_unfixable.stderr index 581a985e0..771e10cbe 100644 --- a/src/tools/clippy/tests/ui/methods_unfixable.stderr +++ b/src/tools/clippy/tests/ui/methods_unfixable.stderr @@ -12,5 +12,5 @@ LL | let iter = (0..10); = note: `-D clippy::filter-next` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::filter_next)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed index a96827259..ac44a6f3f 100644 --- a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed +++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed @@ -118,4 +118,19 @@ fn index_different_slice_in_same_expr(v1: &[u8], v2: &[u8]) { let _ = v1[0] + v2[1]; } +fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) { + assert!(v1.len() == 3); + assert!(v2.len() == 4); + assert!(v3.len() == 3); + assert!(4 == v4.len()); + + let _ = v1[0] + v1[1] + v1[2]; + //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + let _ = v2[0] + v2[1] + v2[2]; + + let _ = v3[0] + v3[1] + v3[2]; + //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + let _ = v4[0] + v4[1] + v4[2]; +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs index 0b4b883ac..f05d5fea5 100644 --- a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs +++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs @@ -118,4 +118,19 @@ fn index_different_slice_in_same_expr(v1: &[u8], v2: &[u8]) { let _ = v1[0] + v2[1]; } +fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) { + assert!(v1.len() == 2); + assert!(v2.len() == 4); + assert!(2 == v3.len()); + assert!(4 == v4.len()); + + let _ = v1[0] + v1[1] + v1[2]; + //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + let _ = v2[0] + v2[1] + v2[2]; + + let _ = v3[0] + v3[1] + v3[2]; + //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the + let _ = v4[0] + v4[1] + v4[2]; +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr index a3e66d795..61dce6ccc 100644 --- a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr +++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr @@ -249,5 +249,57 @@ LL | let _ = v1[0] + v1[12]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks -error: aborting due to 9 previous errors +error: indexing into a slice multiple times with an `assert` that does not cover the highest index + --> $DIR/missing_asserts_for_indexing.rs:127:13 + | +LL | assert!(v1.len() == 2); + | ---------------------- help: provide the highest index that is indexed with: `assert!(v1.len() == 3)` +... +LL | let _ = v1[0] + v1[1] + v1[2]; + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: slice indexed here + --> $DIR/missing_asserts_for_indexing.rs:127:13 + | +LL | let _ = v1[0] + v1[1] + v1[2]; + | ^^^^^ +note: slice indexed here + --> $DIR/missing_asserts_for_indexing.rs:127:21 + | +LL | let _ = v1[0] + v1[1] + v1[2]; + | ^^^^^ +note: slice indexed here + --> $DIR/missing_asserts_for_indexing.rs:127:29 + | +LL | let _ = v1[0] + v1[1] + v1[2]; + | ^^^^^ + = note: asserting the length before indexing will elide bounds checks + +error: indexing into a slice multiple times with an `assert` that does not cover the highest index + --> $DIR/missing_asserts_for_indexing.rs:131:13 + | +LL | assert!(2 == v3.len()); + | ---------------------- help: provide the highest index that is indexed with: `assert!(v3.len() == 3)` +... +LL | let _ = v3[0] + v3[1] + v3[2]; + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: slice indexed here + --> $DIR/missing_asserts_for_indexing.rs:131:13 + | +LL | let _ = v3[0] + v3[1] + v3[2]; + | ^^^^^ +note: slice indexed here + --> $DIR/missing_asserts_for_indexing.rs:131:21 + | +LL | let _ = v3[0] + v3[1] + v3[2]; + | ^^^^^ +note: slice indexed here + --> $DIR/missing_asserts_for_indexing.rs:131:29 + | +LL | let _ = v3[0] + v3[1] + v3[2]; + | ^^^^^ + = note: asserting the length before indexing will elide bounds checks + +error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.rs b/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.rs index 4346ed892..de53079a4 100644 --- a/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.rs +++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.rs @@ -46,4 +46,26 @@ fn index_struct_different_fields(f: &Foo<'_>) { let _ = f.v[0] + f.v2[1]; } +fn shadowing() { + let x: &[i32] = &[1]; + assert!(x.len() > 1); + + let x: &[i32] = &[1]; + let _ = x[0] + x[1]; + //~^ ERROR: indexing into a slice multiple times without an `assert` +} + +pub fn issue11856(values: &[i32]) -> usize { + let mut ascending = Vec::new(); + for w in values.windows(2) { + assert!(w.len() > 1); + if w[0] < w[1] { + ascending.push((w[0], w[1])); + } else { + ascending.push((w[1], w[0])); + } + } + ascending.len() +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.stderr b/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.stderr index 12c9eed5d..12e054227 100644 --- a/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.stderr +++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.stderr @@ -160,5 +160,24 @@ LL | let _ = f.v[0] + f.v[1]; | ^^^^^^ = note: asserting the length before indexing will elide bounds checks -error: aborting due to 7 previous errors +error: indexing into a slice multiple times without an `assert` + --> $DIR/missing_asserts_for_indexing_unfixable.rs:54:13 + | +LL | let _ = x[0] + x[1]; + | ^^^^^^^^^^^ + | + = help: consider asserting the length before indexing: `assert!(x.len() > 1);` +note: slice indexed here + --> $DIR/missing_asserts_for_indexing_unfixable.rs:54:13 + | +LL | let _ = x[0] + x[1]; + | ^^^^ +note: slice indexed here + --> $DIR/missing_asserts_for_indexing_unfixable.rs:54:20 + | +LL | let _ = x[0] + x[1]; + | ^^^^ + = note: asserting the length before indexing will elide bounds checks + +error: aborting due to 8 previous errors diff --git a/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr index c684bc8e7..3aa9781c2 100644 --- a/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr +++ b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr @@ -11,5 +11,5 @@ LL | | fn main() {} = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.stderr b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.stderr index 0b7be4616..d84d06088 100644 --- a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.stderr +++ b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.stderr @@ -7,5 +7,5 @@ LL | while b.load(Ordering::Acquire) {} = note: `-D clippy::missing-spin-loop` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_spin_loop)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.stderr b/src/tools/clippy/tests/ui/mut_mutex_lock.stderr index 9b20016be..819602882 100644 --- a/src/tools/clippy/tests/ui/mut_mutex_lock.stderr +++ b/src/tools/clippy/tests/ui/mut_mutex_lock.stderr @@ -7,5 +7,5 @@ LL | let mut value = value_mutex.lock().unwrap(); = note: `-D clippy::mut-mutex-lock` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::mut_mutex_lock)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr index 183e2dbc8..e91359a3c 100644 --- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr +++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr @@ -7,5 +7,5 @@ LL | fn call_with_mut_self(self: &mut Self) {} = note: `-D clippy::needless-arbitrary-self-type` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_arbitrary_self_type)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr b/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr index 2ed9208e6..b1fc1a7a9 100644 --- a/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr +++ b/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr @@ -7,5 +7,5 @@ LL | if y & !x { = note: `-D clippy::needless-bitwise-bool` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_bitwise_bool)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.stderr b/src/tools/clippy/tests/ui/needless_bool_assign.stderr index 7866c89bd..244a88e66 100644 --- a/src/tools/clippy/tests/ui/needless_bool_assign.stderr +++ b/src/tools/clippy/tests/ui/needless_bool_assign.stderr @@ -48,7 +48,8 @@ LL | } else { LL | | a.field = true; LL | | } | |_____^ - = note: `#[deny(clippy::if_same_then_else)]` on by default + = note: `-D clippy::if-same-then-else` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]` error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed index c2c5f765a..ff1e2dc88 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.fixed +++ b/src/tools/clippy/tests/ui/needless_borrow.fixed @@ -190,27 +190,48 @@ fn issue9383() { // Should not lint because unions need explicit deref when accessing field use std::mem::ManuallyDrop; - union Coral { - crab: ManuallyDrop<Vec<i32>>, + #[derive(Clone, Copy)] + struct Wrap<T>(T); + impl<T> core::ops::Deref for Wrap<T> { + type Target = T; + fn deref(&self) -> &T { + &self.0 + } + } + impl<T> core::ops::DerefMut for Wrap<T> { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } } - union Ocean { - coral: ManuallyDrop<Coral>, + union U<T: Copy> { + u: T, } - let mut ocean = Ocean { - coral: ManuallyDrop::new(Coral { - crab: ManuallyDrop::new(vec![1, 2, 3]), - }), - }; + #[derive(Clone, Copy)] + struct Foo { + x: u32, + } unsafe { - ManuallyDrop::drop(&mut (&mut ocean.coral).crab); - - (*ocean.coral).crab = ManuallyDrop::new(vec![4, 5, 6]); - ManuallyDrop::drop(&mut (*ocean.coral).crab); - - ManuallyDrop::drop(&mut ocean.coral); + let mut x = U { + u: ManuallyDrop::new(Foo { x: 0 }), + }; + let _ = &mut (&mut x.u).x; + let _ = &mut { x.u }.x; + let _ = &mut ({ &mut x.u }).x; + + let mut x = U { + u: Wrap(ManuallyDrop::new(Foo { x: 0 })), + }; + let _ = &mut (&mut x.u).x; + let _ = &mut { x.u }.x; + let _ = &mut ({ &mut x.u }).x; + + let mut x = U { u: Wrap(Foo { x: 0 }) }; + let _ = &mut x.u.x; + let _ = &mut { x.u }.x; + let _ = &mut ({ &mut x.u }).x; } } diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs index 0cd6e41b8..597021539 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.rs +++ b/src/tools/clippy/tests/ui/needless_borrow.rs @@ -190,27 +190,48 @@ fn issue9383() { // Should not lint because unions need explicit deref when accessing field use std::mem::ManuallyDrop; - union Coral { - crab: ManuallyDrop<Vec<i32>>, + #[derive(Clone, Copy)] + struct Wrap<T>(T); + impl<T> core::ops::Deref for Wrap<T> { + type Target = T; + fn deref(&self) -> &T { + &self.0 + } + } + impl<T> core::ops::DerefMut for Wrap<T> { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } } - union Ocean { - coral: ManuallyDrop<Coral>, + union U<T: Copy> { + u: T, } - let mut ocean = Ocean { - coral: ManuallyDrop::new(Coral { - crab: ManuallyDrop::new(vec![1, 2, 3]), - }), - }; + #[derive(Clone, Copy)] + struct Foo { + x: u32, + } unsafe { - ManuallyDrop::drop(&mut (&mut ocean.coral).crab); - - (*ocean.coral).crab = ManuallyDrop::new(vec![4, 5, 6]); - ManuallyDrop::drop(&mut (*ocean.coral).crab); - - ManuallyDrop::drop(&mut ocean.coral); + let mut x = U { + u: ManuallyDrop::new(Foo { x: 0 }), + }; + let _ = &mut (&mut x.u).x; + let _ = &mut (&mut { x.u }).x; + let _ = &mut ({ &mut x.u }).x; + + let mut x = U { + u: Wrap(ManuallyDrop::new(Foo { x: 0 })), + }; + let _ = &mut (&mut x.u).x; + let _ = &mut (&mut { x.u }).x; + let _ = &mut ({ &mut x.u }).x; + + let mut x = U { u: Wrap(Foo { x: 0 }) }; + let _ = &mut (&mut x.u).x; + let _ = &mut (&mut { x.u }).x; + let _ = &mut ({ &mut x.u }).x; } } diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr index e91b78b0a..44552ee6a 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.stderr +++ b/src/tools/clippy/tests/ui/needless_borrow.stderr @@ -133,5 +133,29 @@ error: this expression borrows a value the compiler would automatically borrow LL | (&mut self.f)() | ^^^^^^^^^^^^^ help: change this to: `(self.f)` -error: aborting due to 22 previous errors +error: this expression borrows a value the compiler would automatically borrow + --> $DIR/needless_borrow.rs:221:22 + | +LL | let _ = &mut (&mut { x.u }).x; + | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` + +error: this expression borrows a value the compiler would automatically borrow + --> $DIR/needless_borrow.rs:228:22 + | +LL | let _ = &mut (&mut { x.u }).x; + | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` + +error: this expression borrows a value the compiler would automatically borrow + --> $DIR/needless_borrow.rs:232:22 + | +LL | let _ = &mut (&mut x.u).x; + | ^^^^^^^^^^ help: change this to: `x.u` + +error: this expression borrows a value the compiler would automatically borrow + --> $DIR/needless_borrow.rs:233:22 + | +LL | let _ = &mut (&mut { x.u }).x; + | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` + +error: aborting due to 26 previous errors diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed index 2a335516f..bd7a9a0b9 100644 --- a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed +++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed @@ -284,4 +284,19 @@ fn main() { { } } + // address of field when operand impl Drop + { + struct CustomDrop(String); + + impl Drop for CustomDrop { + fn drop(&mut self) {} + } + + fn check_str<P: AsRef<str>>(_to: P) {} + + fn test() { + let owner = CustomDrop(String::default()); + check_str(&owner.0); // Don't lint. `owner` can't be partially moved because it impl Drop + } + } } diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs index f0567f486..5cfd4ce30 100644 --- a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs @@ -284,4 +284,19 @@ fn main() { { } } + // address of field when operand impl Drop + { + struct CustomDrop(String); + + impl Drop for CustomDrop { + fn drop(&mut self) {} + } + + fn check_str<P: AsRef<str>>(_to: P) {} + + fn test() { + let owner = CustomDrop(String::default()); + check_str(&owner.0); // Don't lint. `owner` can't be partially moved because it impl Drop + } + } } diff --git a/src/tools/clippy/tests/ui/needless_else.stderr b/src/tools/clippy/tests/ui/needless_else.stderr index e6f7138e9..66552109c 100644 --- a/src/tools/clippy/tests/ui/needless_else.stderr +++ b/src/tools/clippy/tests/ui/needless_else.stderr @@ -9,5 +9,5 @@ LL | | } = note: `-D clippy::needless-else` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_else)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr index 73f249ae6..24a22e232 100644 --- a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr +++ b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr @@ -29,5 +29,5 @@ help: ...and replace `return` with `continue` LL | continue; | ~~~~~~~~ -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/needless_if.fixed b/src/tools/clippy/tests/ui/needless_if.fixed index be35dcddb..1086ae2c9 100644 --- a/src/tools/clippy/tests/ui/needless_if.fixed +++ b/src/tools/clippy/tests/ui/needless_if.fixed @@ -1,7 +1,7 @@ //@aux-build:proc_macros.rs #![feature(let_chains)] #![allow( - clippy::blocks_in_if_conditions, + clippy::blocks_in_conditions, clippy::if_same_then_else, clippy::ifs_same_cond, clippy::let_unit_value, diff --git a/src/tools/clippy/tests/ui/needless_if.rs b/src/tools/clippy/tests/ui/needless_if.rs index e2ad17e69..131cceaf7 100644 --- a/src/tools/clippy/tests/ui/needless_if.rs +++ b/src/tools/clippy/tests/ui/needless_if.rs @@ -1,7 +1,7 @@ //@aux-build:proc_macros.rs #![feature(let_chains)] #![allow( - clippy::blocks_in_if_conditions, + clippy::blocks_in_conditions, clippy::if_same_then_else, clippy::ifs_same_cond, clippy::let_unit_value, diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed index 891b2b014..6db870490 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.fixed +++ b/src/tools/clippy/tests/ui/needless_late_init.fixed @@ -3,7 +3,7 @@ #![allow(unused)] #![allow( clippy::assign_op_pattern, - clippy::blocks_in_if_conditions, + clippy::blocks_in_conditions, clippy::let_and_return, clippy::let_unit_value, clippy::nonminimal_bool, diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs index 553995116..c1e86212a 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.rs +++ b/src/tools/clippy/tests/ui/needless_late_init.rs @@ -3,7 +3,7 @@ #![allow(unused)] #![allow( clippy::assign_op_pattern, - clippy::blocks_in_if_conditions, + clippy::blocks_in_conditions, clippy::let_and_return, clippy::let_unit_value, clippy::nonminimal_bool, diff --git a/src/tools/clippy/tests/ui/needless_option_take.stderr b/src/tools/clippy/tests/ui/needless_option_take.stderr index d3c22441d..bf43a18e7 100644 --- a/src/tools/clippy/tests/ui/needless_option_take.stderr +++ b/src/tools/clippy/tests/ui/needless_option_take.stderr @@ -7,5 +7,5 @@ LL | x.as_ref().take(); = note: `-D clippy::needless-option-take` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_option_take)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs index bdb6d40d9..a92197fb0 100644 --- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs @@ -1,4 +1,9 @@ -#![allow(clippy::if_same_then_else, clippy::no_effect, clippy::redundant_closure_call)] +#![allow( + clippy::if_same_then_else, + clippy::no_effect, + clippy::redundant_closure_call, + clippy::ptr_arg +)] #![warn(clippy::needless_pass_by_ref_mut)] #![feature(lint_reasons)] //@no-rustfix diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr index 3e1415be0..5d1e9515d 100644 --- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr +++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr @@ -1,5 +1,5 @@ error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:7:11 + --> $DIR/needless_pass_by_ref_mut.rs:12:11 | LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>` @@ -8,79 +8,79 @@ LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) { = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:32:12 + --> $DIR/needless_pass_by_ref_mut.rs:37:12 | LL | fn foo6(s: &mut Vec<u32>) { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:45:29 + --> $DIR/needless_pass_by_ref_mut.rs:50:29 | LL | fn mushroom(&self, vec: &mut Vec<i32>) -> usize { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:50:31 + --> $DIR/needless_pass_by_ref_mut.rs:55:31 | LL | fn badger(&mut self, vec: &mut Vec<i32>) -> usize { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:127:16 + --> $DIR/needless_pass_by_ref_mut.rs:132:16 | LL | async fn a1(x: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:131:16 + --> $DIR/needless_pass_by_ref_mut.rs:136:16 | LL | async fn a2(x: &mut i32, y: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:135:16 + --> $DIR/needless_pass_by_ref_mut.rs:140:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:139:16 + --> $DIR/needless_pass_by_ref_mut.rs:144:16 | LL | async fn a4(x: &mut i32, y: i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:143:24 + --> $DIR/needless_pass_by_ref_mut.rs:148:24 | LL | async fn a5(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:147:24 + --> $DIR/needless_pass_by_ref_mut.rs:152:24 | LL | async fn a6(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:151:32 + --> $DIR/needless_pass_by_ref_mut.rs:156:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:155:24 + --> $DIR/needless_pass_by_ref_mut.rs:160:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:155:45 + --> $DIR/needless_pass_by_ref_mut.rs:160:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:189:16 + --> $DIR/needless_pass_by_ref_mut.rs:194:16 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -88,7 +88,7 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:195:20 + --> $DIR/needless_pass_by_ref_mut.rs:200:20 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -96,19 +96,19 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:209:39 + --> $DIR/needless_pass_by_ref_mut.rs:214:39 | LL | async fn inner_async2(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:217:26 + --> $DIR/needless_pass_by_ref_mut.rs:222:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:236:34 + --> $DIR/needless_pass_by_ref_mut.rs:241:34 | LL | pub async fn call_in_closure1(n: &mut str) { | ^^^^^^^^ help: consider changing to: `&str` @@ -116,7 +116,7 @@ LL | pub async fn call_in_closure1(n: &mut str) { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:248:25 + --> $DIR/needless_pass_by_ref_mut.rs:253:25 | LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() { | ^^^^^^^^^^ help: consider changing to: `&usize` @@ -124,7 +124,7 @@ LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:255:20 + --> $DIR/needless_pass_by_ref_mut.rs:260:20 | LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { | ^^^^^^^^^^ help: consider changing to: `&usize` @@ -132,7 +132,7 @@ LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:266:26 + --> $DIR/needless_pass_by_ref_mut.rs:271:26 | LL | pub async fn closure4(n: &mut usize) { | ^^^^^^^^^^ help: consider changing to: `&usize` @@ -140,61 +140,61 @@ LL | pub async fn closure4(n: &mut usize) { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:306:18 + --> $DIR/needless_pass_by_ref_mut.rs:311:18 | LL | fn _empty_tup(x: &mut (())) {} | ^^^^^^^^^ help: consider changing to: `&()` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:307:19 + --> $DIR/needless_pass_by_ref_mut.rs:312:19 | LL | fn _single_tup(x: &mut ((i32,))) {} | ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:308:18 + --> $DIR/needless_pass_by_ref_mut.rs:313:18 | LL | fn _multi_tup(x: &mut ((i32, u32))) {} | ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:309:11 + --> $DIR/needless_pass_by_ref_mut.rs:314:11 | LL | fn _fn(x: &mut (fn())) {} | ^^^^^^^^^^^ help: consider changing to: `&fn()` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:311:23 + --> $DIR/needless_pass_by_ref_mut.rs:316:23 | LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:312:20 + --> $DIR/needless_pass_by_ref_mut.rs:317:20 | LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:313:18 + --> $DIR/needless_pass_by_ref_mut.rs:318:18 | LL | fn _unsafe_fn(x: &mut unsafe fn()) {} | ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:314:25 + --> $DIR/needless_pass_by_ref_mut.rs:319:25 | LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:315:20 + --> $DIR/needless_pass_by_ref_mut.rs:320:20 | LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:316:20 + --> $DIR/needless_pass_by_ref_mut.rs:321:20 | LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)` diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed index 52d541809..0147c73a9 100644 --- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed +++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed @@ -4,6 +4,8 @@ clippy::no_effect, clippy::unit_arg, clippy::useless_conversion, + clippy::diverging_sub_expression, + clippy::let_unit_value, unused )] @@ -35,5 +37,43 @@ fn main() -> Result<(), ()> { with_span! { return Err(())?; } + + // Issue #11765 + // Should not lint + let Some(s) = Some("") else { + return Err(())?; + }; + + let Some(s) = Some("") else { + let Some(s) = Some("") else { + return Err(())?; + }; + + return Err(())?; + }; + + let Some(_): Option<()> = ({ + return Err(())?; + }) else { + panic!(); + }; + Err(()) } + +fn issue11616() -> Result<(), ()> { + let _x: String = { + return Err(())?; + }; + let _x: () = { + Err(())?; + //~^ ERROR: unneeded `return` statement with `?` operator + }; + let _x = match 1 { + 1 => vec![1, 2], + _ => { + return Err(())?; + }, + }; + Ok(()) +} diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs index d253cae4d..66e1f438f 100644 --- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs +++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs @@ -4,6 +4,8 @@ clippy::no_effect, clippy::unit_arg, clippy::useless_conversion, + clippy::diverging_sub_expression, + clippy::let_unit_value, unused )] @@ -35,5 +37,43 @@ fn main() -> Result<(), ()> { with_span! { return Err(())?; } + + // Issue #11765 + // Should not lint + let Some(s) = Some("") else { + return Err(())?; + }; + + let Some(s) = Some("") else { + let Some(s) = Some("") else { + return Err(())?; + }; + + return Err(())?; + }; + + let Some(_): Option<()> = ({ + return Err(())?; + }) else { + panic!(); + }; + Err(()) } + +fn issue11616() -> Result<(), ()> { + let _x: String = { + return Err(())?; + }; + let _x: () = { + return Err(())?; + //~^ ERROR: unneeded `return` statement with `?` operator + }; + let _x = match 1 { + 1 => vec![1, 2], + _ => { + return Err(())?; + }, + }; + Ok(()) +} diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr b/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr index 0de063380..17aa212ae 100644 --- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr +++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr @@ -1,5 +1,5 @@ error: unneeded `return` statement with `?` operator - --> $DIR/needless_return_with_question_mark.rs:27:5 + --> $DIR/needless_return_with_question_mark.rs:29:5 | LL | return Err(())?; | ^^^^^^^ help: remove it @@ -7,5 +7,11 @@ LL | return Err(())?; = note: `-D clippy::needless-return-with-question-mark` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_return_with_question_mark)]` -error: aborting due to previous error +error: unneeded `return` statement with `?` operator + --> $DIR/needless_return_with_question_mark.rs:69:9 + | +LL | return Err(())?; + | ^^^^^^^ help: remove it + +error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/needless_update.stderr b/src/tools/clippy/tests/ui/needless_update.stderr index 3e9e2941a..60aeb0493 100644 --- a/src/tools/clippy/tests/ui/needless_update.stderr +++ b/src/tools/clippy/tests/ui/needless_update.stderr @@ -7,5 +7,5 @@ LL | S { a: 1, b: 1, ..base }; = note: `-D clippy::needless-update` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_update)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr index babb634fd..c0d6a74a5 100644 --- a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr +++ b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr @@ -4,6 +4,6 @@ error[E0275]: overflow evaluating the requirement `<i32 as std::ops::Add>::Outpu LL | pub fn new() -> X { | ^ -error: aborting due to previous error +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0275`. diff --git a/src/tools/clippy/tests/ui/no_effect.rs b/src/tools/clippy/tests/ui/no_effect.rs index c52f43891..777b1e52c 100644 --- a/src/tools/clippy/tests/ui/no_effect.rs +++ b/src/tools/clippy/tests/ui/no_effect.rs @@ -9,6 +9,30 @@ clippy::useless_vec )] +use std::fmt::Display; +use std::ops::{Neg, Shl}; + +struct Cout; + +impl<T> Shl<T> for Cout +where + T: Display, +{ + type Output = Self; + fn shl(self, rhs: T) -> Self::Output { + println!("{}", rhs); + self + } +} + +impl Neg for Cout { + type Output = Self; + fn neg(self) -> Self::Output { + println!("hello world"); + self + } +} + struct Unit; struct Tuple(i32); struct Struct { @@ -174,4 +198,11 @@ fn main() { GreetStruct1("world"); GreetStruct2()("world"); GreetStruct3 {}("world"); + + fn n() -> i32 { + 42 + } + + Cout << 142; + -Cout; } diff --git a/src/tools/clippy/tests/ui/no_effect.stderr b/src/tools/clippy/tests/ui/no_effect.stderr index feba35697..f5ba234b4 100644 --- a/src/tools/clippy/tests/ui/no_effect.stderr +++ b/src/tools/clippy/tests/ui/no_effect.stderr @@ -1,5 +1,5 @@ error: statement with no effect - --> $DIR/no_effect.rs:98:5 + --> $DIR/no_effect.rs:122:5 | LL | 0; | ^^ @@ -8,151 +8,151 @@ LL | 0; = help: to override `-D warnings` add `#[allow(clippy::no_effect)]` error: statement with no effect - --> $DIR/no_effect.rs:101:5 + --> $DIR/no_effect.rs:125:5 | LL | s2; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:103:5 + --> $DIR/no_effect.rs:127:5 | LL | Unit; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:105:5 + --> $DIR/no_effect.rs:129:5 | LL | Tuple(0); | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:107:5 + --> $DIR/no_effect.rs:131:5 | LL | Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:109:5 + --> $DIR/no_effect.rs:133:5 | LL | Struct { ..s }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:111:5 + --> $DIR/no_effect.rs:135:5 | LL | Union { a: 0 }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:113:5 + --> $DIR/no_effect.rs:137:5 | LL | Enum::Tuple(0); | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:115:5 + --> $DIR/no_effect.rs:139:5 | LL | Enum::Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:117:5 + --> $DIR/no_effect.rs:141:5 | LL | 5 + 6; | ^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:119:5 + --> $DIR/no_effect.rs:143:5 | LL | *&42; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:121:5 + --> $DIR/no_effect.rs:145:5 | LL | &6; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:123:5 + --> $DIR/no_effect.rs:147:5 | LL | (5, 6, 7); | ^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:125:5 + --> $DIR/no_effect.rs:149:5 | LL | ..; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:127:5 + --> $DIR/no_effect.rs:151:5 | LL | 5..; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:129:5 + --> $DIR/no_effect.rs:153:5 | LL | ..5; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:131:5 + --> $DIR/no_effect.rs:155:5 | LL | 5..6; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:133:5 + --> $DIR/no_effect.rs:157:5 | LL | 5..=6; | ^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:135:5 + --> $DIR/no_effect.rs:159:5 | LL | [42, 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:137:5 + --> $DIR/no_effect.rs:161:5 | LL | [42, 55][1]; | ^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:139:5 + --> $DIR/no_effect.rs:163:5 | LL | (42, 55).1; | ^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:141:5 + --> $DIR/no_effect.rs:165:5 | LL | [42; 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:143:5 + --> $DIR/no_effect.rs:167:5 | LL | [42; 55][13]; | ^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:146:5 + --> $DIR/no_effect.rs:170:5 | LL | || x += 5; | ^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:149:5 + --> $DIR/no_effect.rs:173:5 | LL | FooString { s: s }; | ^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:151:5 + --> $DIR/no_effect.rs:175:5 | LL | let _unused = 1; | ^^^^^^^^^^^^^^^^ @@ -161,19 +161,19 @@ LL | let _unused = 1; = help: to override `-D warnings` add `#[allow(clippy::no_effect_underscore_binding)]` error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:154:5 + --> $DIR/no_effect.rs:178:5 | LL | let _penguin = || println!("Some helpful closure"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:156:5 + --> $DIR/no_effect.rs:180:5 | LL | let _duck = Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:158:5 + --> $DIR/no_effect.rs:182:5 | LL | let _cat = [2, 4, 6, 8][2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr b/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr index 001fcddd9..036d38c22 100644 --- a/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr +++ b/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr @@ -7,5 +7,5 @@ LL | #[cfg(all())] = note: `-D clippy::non-minimal-cfg` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::non_minimal_cfg)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/obfuscated_if_else.stderr b/src/tools/clippy/tests/ui/obfuscated_if_else.stderr index ca9f5e1e3..abf5adce4 100644 --- a/src/tools/clippy/tests/ui/obfuscated_if_else.stderr +++ b/src/tools/clippy/tests/ui/obfuscated_if_else.stderr @@ -7,5 +7,5 @@ LL | true.then_some("a").unwrap_or("b"); = note: `-D clippy::obfuscated-if-else` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::obfuscated_if_else)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/option_as_ref_deref.stderr b/src/tools/clippy/tests/ui/option_as_ref_deref.stderr index eb0661c52..9d173e409 100644 --- a/src/tools/clippy/tests/ui/option_as_ref_deref.stderr +++ b/src/tools/clippy/tests/ui/option_as_ref_deref.stderr @@ -1,4 +1,4 @@ -error: called `.as_ref().map(Deref::deref)` on an Option value. This can be done more directly by calling `opt.clone().as_deref()` instead +error: called `.as_ref().map(Deref::deref)` on an `Option` value --> $DIR/option_as_ref_deref.rs:11:13 | LL | let _ = opt.clone().as_ref().map(Deref::deref).map(str::len); @@ -7,7 +7,7 @@ LL | let _ = opt.clone().as_ref().map(Deref::deref).map(str::len); = note: `-D clippy::option-as-ref-deref` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_deref)]` -error: called `.as_ref().map(Deref::deref)` on an Option value. This can be done more directly by calling `opt.clone().as_deref()` instead +error: called `.as_ref().map(Deref::deref)` on an `Option` value --> $DIR/option_as_ref_deref.rs:14:13 | LL | let _ = opt.clone() @@ -17,97 +17,97 @@ LL | | Deref::deref LL | | ) | |_________^ help: try using as_deref instead: `opt.clone().as_deref()` -error: called `.as_mut().map(DerefMut::deref_mut)` on an Option value. This can be done more directly by calling `opt.as_deref_mut()` instead +error: called `.as_mut().map(DerefMut::deref_mut)` on an `Option` value --> $DIR/option_as_ref_deref.rs:20:13 | LL | let _ = opt.as_mut().map(DerefMut::deref_mut); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()` -error: called `.as_ref().map(String::as_str)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead +error: called `.as_ref().map(String::as_str)` on an `Option` value --> $DIR/option_as_ref_deref.rs:22:13 | LL | let _ = opt.as_ref().map(String::as_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()` -error: called `.as_ref().map(|x| x.as_str())` on an Option value. This can be done more directly by calling `opt.as_deref()` instead +error: called `.as_ref().map(|x| x.as_str())` on an `Option` value --> $DIR/option_as_ref_deref.rs:23:13 | LL | let _ = opt.as_ref().map(|x| x.as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()` -error: called `.as_mut().map(String::as_mut_str)` on an Option value. This can be done more directly by calling `opt.as_deref_mut()` instead +error: called `.as_mut().map(String::as_mut_str)` on an `Option` value --> $DIR/option_as_ref_deref.rs:24:13 | LL | let _ = opt.as_mut().map(String::as_mut_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()` -error: called `.as_mut().map(|x| x.as_mut_str())` on an Option value. This can be done more directly by calling `opt.as_deref_mut()` instead +error: called `.as_mut().map(|x| x.as_mut_str())` on an `Option` value --> $DIR/option_as_ref_deref.rs:25:13 | LL | let _ = opt.as_mut().map(|x| x.as_mut_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()` -error: called `.as_ref().map(CString::as_c_str)` on an Option value. This can be done more directly by calling `Some(CString::new(vec![]).unwrap()).as_deref()` instead +error: called `.as_ref().map(CString::as_c_str)` on an `Option` value --> $DIR/option_as_ref_deref.rs:26:13 | LL | let _ = Some(CString::new(vec![]).unwrap()).as_ref().map(CString::as_c_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(CString::new(vec![]).unwrap()).as_deref()` -error: called `.as_ref().map(OsString::as_os_str)` on an Option value. This can be done more directly by calling `Some(OsString::new()).as_deref()` instead +error: called `.as_ref().map(OsString::as_os_str)` on an `Option` value --> $DIR/option_as_ref_deref.rs:27:13 | LL | let _ = Some(OsString::new()).as_ref().map(OsString::as_os_str); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(OsString::new()).as_deref()` -error: called `.as_ref().map(PathBuf::as_path)` on an Option value. This can be done more directly by calling `Some(PathBuf::new()).as_deref()` instead +error: called `.as_ref().map(PathBuf::as_path)` on an `Option` value --> $DIR/option_as_ref_deref.rs:28:13 | LL | let _ = Some(PathBuf::new()).as_ref().map(PathBuf::as_path); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(PathBuf::new()).as_deref()` -error: called `.as_ref().map(Vec::as_slice)` on an Option value. This can be done more directly by calling `Some(Vec::<()>::new()).as_deref()` instead +error: called `.as_ref().map(Vec::as_slice)` on an `Option` value --> $DIR/option_as_ref_deref.rs:29:13 | LL | let _ = Some(Vec::<()>::new()).as_ref().map(Vec::as_slice); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(Vec::<()>::new()).as_deref()` -error: called `.as_mut().map(Vec::as_mut_slice)` on an Option value. This can be done more directly by calling `Some(Vec::<()>::new()).as_deref_mut()` instead +error: called `.as_mut().map(Vec::as_mut_slice)` on an `Option` value --> $DIR/option_as_ref_deref.rs:30:13 | LL | let _ = Some(Vec::<()>::new()).as_mut().map(Vec::as_mut_slice); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `Some(Vec::<()>::new()).as_deref_mut()` -error: called `.as_ref().map(|x| x.deref())` on an Option value. This can be done more directly by calling `opt.as_deref()` instead +error: called `.as_ref().map(|x| x.deref())` on an `Option` value --> $DIR/option_as_ref_deref.rs:32:13 | LL | let _ = opt.as_ref().map(|x| x.deref()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()` -error: called `.as_mut().map(|x| x.deref_mut())` on an Option value. This can be done more directly by calling `opt.clone().as_deref_mut()` instead +error: called `.as_mut().map(|x| x.deref_mut())` on an `Option` value --> $DIR/option_as_ref_deref.rs:33:13 | LL | let _ = opt.clone().as_mut().map(|x| x.deref_mut()).map(|x| x.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.clone().as_deref_mut()` -error: called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead +error: called `.as_ref().map(|x| &**x)` on an `Option` value --> $DIR/option_as_ref_deref.rs:40:13 | LL | let _ = opt.as_ref().map(|x| &**x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()` -error: called `.as_mut().map(|x| &mut **x)` on an Option value. This can be done more directly by calling `opt.as_deref_mut()` instead +error: called `.as_mut().map(|x| &mut **x)` on an `Option` value --> $DIR/option_as_ref_deref.rs:41:13 | LL | let _ = opt.as_mut().map(|x| &mut **x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()` -error: called `.as_ref().map(std::ops::Deref::deref)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead +error: called `.as_ref().map(std::ops::Deref::deref)` on an `Option` value --> $DIR/option_as_ref_deref.rs:44:13 | LL | let _ = opt.as_ref().map(std::ops::Deref::deref); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()` -error: called `.as_ref().map(String::as_str)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead +error: called `.as_ref().map(String::as_str)` on an `Option` value --> $DIR/option_as_ref_deref.rs:56:13 | LL | let _ = opt.as_ref().map(String::as_str); diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed index f0113ca69..363520112 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.fixed +++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed @@ -92,11 +92,13 @@ fn pattern_to_vec(pattern: &str) -> Vec<String> { } // #10335 -fn test_result_impure_else(variable: Result<u32, &str>) { +fn test_result_impure_else(variable: Result<u32, &str>) -> bool { variable.map_or_else(|_| { println!("Err"); + false }, |binding| { println!("Ok {binding}"); + true }) } @@ -213,15 +215,19 @@ mod issue10729 { pub fn reproduce(initial: &Option<String>) { // 👇 needs `.as_ref()` because initial is an `&Option<_>` - initial.as_ref().map_or({}, |value| do_something(value)) + let _ = initial.as_ref().map_or(42, |value| do_something(value)); } pub fn reproduce2(initial: &mut Option<String>) { - initial.as_mut().map_or({}, |value| do_something2(value)) + let _ = initial.as_mut().map_or(42, |value| do_something2(value)); } - fn do_something(_value: &str) {} - fn do_something2(_value: &mut str) {} + fn do_something(_value: &str) -> u32 { + todo!() + } + fn do_something2(_value: &mut str) -> u32 { + todo!() + } } fn issue11429() { @@ -237,3 +243,13 @@ fn issue11429() { let mut _hm = opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone()); } + +fn issue11893() { + use std::io::Write; + let mut output = std::io::stdout().lock(); + if let Some(name) = Some("stuff") { + writeln!(output, "{name:?}").unwrap(); + } else { + panic!("Haven't thought about this condition."); + } +} diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs index 18b7af443..aaa87a0db 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.rs +++ b/src/tools/clippy/tests/ui/option_if_let_else.rs @@ -115,11 +115,13 @@ fn pattern_to_vec(pattern: &str) -> Vec<String> { } // #10335 -fn test_result_impure_else(variable: Result<u32, &str>) { +fn test_result_impure_else(variable: Result<u32, &str>) -> bool { if let Ok(binding) = variable { println!("Ok {binding}"); + true } else { println!("Err"); + false } } @@ -254,21 +256,25 @@ mod issue10729 { pub fn reproduce(initial: &Option<String>) { // 👇 needs `.as_ref()` because initial is an `&Option<_>` - match initial { + let _ = match initial { Some(value) => do_something(value), - None => {}, - } + None => 42, + }; } pub fn reproduce2(initial: &mut Option<String>) { - match initial { + let _ = match initial { Some(value) => do_something2(value), - None => {}, - } + None => 42, + }; } - fn do_something(_value: &str) {} - fn do_something2(_value: &mut str) {} + fn do_something(_value: &str) -> u32 { + todo!() + } + fn do_something2(_value: &mut str) -> u32 { + todo!() + } } fn issue11429() { @@ -288,3 +294,13 @@ fn issue11429() { let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; } + +fn issue11893() { + use std::io::Write; + let mut output = std::io::stdout().lock(); + if let Some(name) = Some("stuff") { + writeln!(output, "{name:?}").unwrap(); + } else { + panic!("Haven't thought about this condition."); + } +} diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr index e36357bcb..55a8360ff 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.stderr +++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr @@ -158,8 +158,10 @@ error: use Option::map_or_else instead of an if let/else | LL | / if let Ok(binding) = variable { LL | | println!("Ok {binding}"); +LL | | true LL | | } else { LL | | println!("Err"); +LL | | false LL | | } | |_____^ | @@ -167,19 +169,21 @@ help: try | LL ~ variable.map_or_else(|_| { LL + println!("Err"); +LL + false LL + }, |binding| { LL + println!("Ok {binding}"); +LL + true LL + }) | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:141:13 + --> $DIR/option_if_let_else.rs:143: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:151:13 + --> $DIR/option_if_let_else.rs:153:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -201,13 +205,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:179:13 + --> $DIR/option_if_let_else.rs:181: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:183:13 + --> $DIR/option_if_let_else.rs:185:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -227,7 +231,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:222:13 + --> $DIR/option_if_let_else.rs:224:13 | LL | let _ = match s { | _____________^ @@ -237,7 +241,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:226:13 + --> $DIR/option_if_let_else.rs:228:13 | LL | let _ = match Some(10) { | _____________^ @@ -247,7 +251,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:232:13 + --> $DIR/option_if_let_else.rs:234:13 | LL | let _ = match res { | _____________^ @@ -257,7 +261,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:236:13 + --> $DIR/option_if_let_else.rs:238:13 | LL | let _ = match res { | _____________^ @@ -267,31 +271,33 @@ 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:240:13 + --> $DIR/option_if_let_else.rs:242: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:257:9 + --> $DIR/option_if_let_else.rs:259:17 | -LL | / match initial { +LL | let _ = match initial { + | _________________^ LL | | Some(value) => do_something(value), -LL | | None => {}, -LL | | } - | |_________^ help: try: `initial.as_ref().map_or({}, |value| do_something(value))` +LL | | None => 42, +LL | | }; + | |_________^ help: try: `initial.as_ref().map_or(42, |value| do_something(value))` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:264:9 + --> $DIR/option_if_let_else.rs:266:17 | -LL | / match initial { +LL | let _ = match initial { + | _________________^ LL | | Some(value) => do_something2(value), -LL | | None => {}, -LL | | } - | |_________^ help: try: `initial.as_mut().map_or({}, |value| do_something2(value))` +LL | | None => 42, +LL | | }; + | |_________^ help: try: `initial.as_mut().map_or(42, |value| do_something2(value))` error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:283:24 + --> $DIR/option_if_let_else.rs:289:24 | LL | let mut _hashmap = if let Some(hm) = &opt { | ________________________^ @@ -302,7 +308,7 @@ 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 + --> $DIR/option_if_let_else.rs:295: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())` diff --git a/src/tools/clippy/tests/ui/option_map_or_err_ok.fixed b/src/tools/clippy/tests/ui/option_map_or_err_ok.fixed new file mode 100644 index 000000000..131f4b209 --- /dev/null +++ b/src/tools/clippy/tests/ui/option_map_or_err_ok.fixed @@ -0,0 +1,7 @@ +#![warn(clippy::option_map_or_err_ok)] + +fn main() { + let x = Some("a"); + let _ = x.ok_or("a"); + //~^ ERROR: called `map_or(Err(_), Ok)` on an `Option` value +} diff --git a/src/tools/clippy/tests/ui/option_map_or_err_ok.rs b/src/tools/clippy/tests/ui/option_map_or_err_ok.rs new file mode 100644 index 000000000..0f07a592a --- /dev/null +++ b/src/tools/clippy/tests/ui/option_map_or_err_ok.rs @@ -0,0 +1,7 @@ +#![warn(clippy::option_map_or_err_ok)] + +fn main() { + let x = Some("a"); + let _ = x.map_or(Err("a"), Ok); + //~^ ERROR: called `map_or(Err(_), Ok)` on an `Option` value +} diff --git a/src/tools/clippy/tests/ui/option_map_or_err_ok.stderr b/src/tools/clippy/tests/ui/option_map_or_err_ok.stderr new file mode 100644 index 000000000..a193e3c4c --- /dev/null +++ b/src/tools/clippy/tests/ui/option_map_or_err_ok.stderr @@ -0,0 +1,11 @@ +error: called `map_or(Err(_), Ok)` on an `Option` value + --> $DIR/option_map_or_err_ok.rs:5:13 + | +LL | let _ = x.map_or(Err("a"), Ok); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok_or` instead: `x.ok_or("a")` + | + = note: `-D clippy::option-map-or-err-ok` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]` + +error: aborting due to 1 previous error + diff --git a/src/tools/clippy/tests/ui/option_map_or_none.stderr b/src/tools/clippy/tests/ui/option_map_or_none.stderr index fa150718f..f2cfc3f9a 100644 --- a/src/tools/clippy/tests/ui/option_map_or_none.stderr +++ b/src/tools/clippy/tests/ui/option_map_or_none.stderr @@ -1,4 +1,4 @@ -error: called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling `map(..)` instead +error: called `map_or(None, ..)` on an `Option` value --> $DIR/option_map_or_none.rs:10:26 | LL | let _: Option<i32> = opt.map_or(None, |x| Some(x + 1)); @@ -7,7 +7,7 @@ LL | let _: Option<i32> = opt.map_or(None, |x| Some(x + 1)); = note: `-D clippy::option-map-or-none` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::option_map_or_none)]` -error: called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling `map(..)` instead +error: called `map_or(None, ..)` on an `Option` value --> $DIR/option_map_or_none.rs:13:26 | LL | let _: Option<i32> = opt.map_or(None, |x| { @@ -16,13 +16,13 @@ LL | | Some(x + 1) LL | | }); | |_________________________^ help: try using `map` instead: `opt.map(|x| x + 1)` -error: called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling `and_then(..)` instead +error: called `map_or(None, ..)` on an `Option` value --> $DIR/option_map_or_none.rs:17:26 | LL | let _: Option<i32> = opt.map_or(None, bar); | ^^^^^^^^^^^^^^^^^^^^^ help: try using `and_then` instead: `opt.and_then(bar)` -error: called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling `and_then(..)` instead +error: called `map_or(None, ..)` on an `Option` value --> $DIR/option_map_or_none.rs:18:26 | LL | let _: Option<i32> = opt.map_or(None, |x| { @@ -42,7 +42,7 @@ LL + Some(offset + height) LL ~ }); | -error: called `map_or(None, Some)` on a `Result` value. This can be done more directly by calling `ok()` instead +error: called `map_or(None, Some)` on a `Result` value --> $DIR/option_map_or_none.rs:25:26 | LL | let _: Option<i32> = r.map_or(None, Some); diff --git a/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr b/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr index 163d6b1dd..2210e706d 100644 --- a/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr +++ b/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr @@ -11,5 +11,5 @@ LL | | } = note: `-D clippy::partialeq-ne-impl` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::partialeq_ne_impl)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/path_buf_push_overwrite.stderr b/src/tools/clippy/tests/ui/path_buf_push_overwrite.stderr index 1453d020c..f96ce0de7 100644 --- a/src/tools/clippy/tests/ui/path_buf_push_overwrite.stderr +++ b/src/tools/clippy/tests/ui/path_buf_push_overwrite.stderr @@ -7,5 +7,5 @@ LL | x.push("/bar"); = note: `-D clippy::path-buf-push-overwrite` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::path_buf_push_overwrite)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/permissions_set_readonly_false.stderr b/src/tools/clippy/tests/ui/permissions_set_readonly_false.stderr index 58a7de84d..bd3446308 100644 --- a/src/tools/clippy/tests/ui/permissions_set_readonly_false.stderr +++ b/src/tools/clippy/tests/ui/permissions_set_readonly_false.stderr @@ -10,5 +10,5 @@ LL | permissions.set_readonly(false); = note: `-D clippy::permissions-set-readonly-false` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::permissions_set_readonly_false)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/proc_macro.stderr b/src/tools/clippy/tests/ui/proc_macro.stderr index d912b5027..122374ea8 100644 --- a/src/tools/clippy/tests/ui/proc_macro.stderr +++ b/src/tools/clippy/tests/ui/proc_macro.stderr @@ -7,5 +7,5 @@ LL | let _x = 3.14; = help: consider using the constant directly = note: `#[deny(clippy::approx_constant)]` on by default -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs index 91e2e7fd6..fcd716f41 100644 --- a/src/tools/clippy/tests/ui/ptr_arg.rs +++ b/src/tools/clippy/tests/ui/ptr_arg.rs @@ -22,6 +22,12 @@ fn do_vec_mut(x: &mut Vec<i64>) { //Nothing here } +fn do_vec_mut2(x: &mut Vec<i64>) { + //~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w + x.len(); + x.is_empty(); +} + fn do_str(x: &String) { //~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice will d //Nothing here either diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr index cccf2d62d..35bd85092 100644 --- a/src/tools/clippy/tests/ui/ptr_arg.stderr +++ b/src/tools/clippy/tests/ui/ptr_arg.stderr @@ -13,38 +13,44 @@ error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a sl LL | fn do_vec_mut(x: &mut Vec<i64>) { | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` +error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do + --> $DIR/ptr_arg.rs:25:19 + | +LL | fn do_vec_mut2(x: &mut Vec<i64>) { + | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` + error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:25:14 + --> $DIR/ptr_arg.rs:31:14 | LL | fn do_str(x: &String) { | ^^^^^^^ help: change this to: `&str` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:30:18 + --> $DIR/ptr_arg.rs:36:18 | LL | fn do_str_mut(x: &mut String) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:35:15 + --> $DIR/ptr_arg.rs:41:15 | LL | fn do_path(x: &PathBuf) { | ^^^^^^^^ help: change this to: `&Path` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:40:19 + --> $DIR/ptr_arg.rs:46:19 | LL | fn do_path_mut(x: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:49:18 + --> $DIR/ptr_arg.rs:55:18 | LL | fn do_vec(x: &Vec<i64>); | ^^^^^^^^^ help: change this to: `&[i64]` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:63:14 + --> $DIR/ptr_arg.rs:69:14 | LL | fn cloned(x: &Vec<u8>) -> Vec<u8> { | ^^^^^^^^ @@ -62,7 +68,7 @@ LL ~ x.to_owned() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:73:18 + --> $DIR/ptr_arg.rs:79:18 | LL | fn str_cloned(x: &String) -> String { | ^^^^^^^ @@ -79,7 +85,7 @@ LL ~ x.to_owned() | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:82:19 + --> $DIR/ptr_arg.rs:88:19 | LL | fn path_cloned(x: &PathBuf) -> PathBuf { | ^^^^^^^^ @@ -96,7 +102,7 @@ LL ~ x.to_path_buf() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:91:44 + --> $DIR/ptr_arg.rs:97:44 | LL | fn false_positive_capacity(x: &Vec<u8>, y: &String) { | ^^^^^^^ @@ -111,19 +117,19 @@ LL ~ let c = y; | error: using a reference to `Cow` is not recommended - --> $DIR/ptr_arg.rs:106:25 + --> $DIR/ptr_arg.rs:112:25 | LL | fn test_cow_with_ref(c: &Cow<[i32]>) {} | ^^^^^^^^^^^ help: change this to: `&[i32]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:136:66 + --> $DIR/ptr_arg.rs:142:66 | LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {} | ^^^^^^^ help: change this to: `&str` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:166:21 + --> $DIR/ptr_arg.rs:172:21 | LL | fn foo_vec(vec: &Vec<u8>) { | ^^^^^^^^ @@ -137,7 +143,7 @@ LL ~ let _ = vec.to_owned().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:172:23 + --> $DIR/ptr_arg.rs:178:23 | LL | fn foo_path(path: &PathBuf) { | ^^^^^^^^ @@ -151,7 +157,7 @@ LL ~ let _ = path.to_path_buf().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:178:21 + --> $DIR/ptr_arg.rs:184:21 | LL | fn foo_str(str: &PathBuf) { | ^^^^^^^^ @@ -165,46 +171,46 @@ LL ~ let _ = str.to_path_buf().clone(); | error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:185:29 + --> $DIR/ptr_arg.rs:191:29 | LL | fn mut_vec_slice_methods(v: &mut Vec<u32>) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:248:17 + --> $DIR/ptr_arg.rs:254:17 | LL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:248:35 + --> $DIR/ptr_arg.rs:254:35 | LL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:248:51 + --> $DIR/ptr_arg.rs:254:51 | LL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` error: using a reference to `Cow` is not recommended - --> $DIR/ptr_arg.rs:274:39 + --> $DIR/ptr_arg.rs:280:39 | LL | fn cow_elided_lifetime<'a>(input: &'a Cow<str>) -> &'a str { | ^^^^^^^^^^^^ help: change this to: `&str` error: using a reference to `Cow` is not recommended - --> $DIR/ptr_arg.rs:280:36 + --> $DIR/ptr_arg.rs:286:36 | LL | fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str { | ^^^^^^^^^^^^^^^^ help: change this to: `&str` error: using a reference to `Cow` is not recommended - --> $DIR/ptr_arg.rs:284:40 + --> $DIR/ptr_arg.rs:290:40 | LL | fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str { | ^^^^^^^^^^^^^^^^ help: change this to: `&str` -error: aborting due to 23 previous errors +error: aborting due to 24 previous errors diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed index ca13b52ae..fa15c3235 100644 --- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed +++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed @@ -71,3 +71,118 @@ fn _msrv_1_38() { let _ = ptr.cast::<i32>(); let _ = mut_ptr.cast::<i32>(); } + +#[allow(clippy::unnecessary_cast)] +mod null { + fn use_path_mut() -> *mut u32 { + use std::ptr; + ptr::null_mut::<u32>() + } + + fn full_path_mut() -> *mut u32 { + std::ptr::null_mut::<u32>() + } + + fn core_path_mut() -> *mut u32 { + use core::ptr; + ptr::null_mut::<u32>() + } + + fn full_core_path_mut() -> *mut u32 { + core::ptr::null_mut::<u32>() + } + + fn use_path() -> *const u32 { + use std::ptr; + ptr::null::<u32>() + } + + fn full_path() -> *const u32 { + std::ptr::null::<u32>() + } + + fn core_path() -> *const u32 { + use core::ptr; + ptr::null::<u32>() + } + + fn full_core_path() -> *const u32 { + core::ptr::null::<u32>() + } +} + +mod null_ptr_infer { + fn use_path_mut() -> *mut u32 { + use std::ptr; + ptr::null_mut() + } + + fn full_path_mut() -> *mut u32 { + std::ptr::null_mut() + } + + fn core_path_mut() -> *mut u32 { + use core::ptr; + ptr::null_mut() + } + + fn full_core_path_mut() -> *mut u32 { + core::ptr::null_mut() + } + + fn use_path() -> *const u32 { + use std::ptr; + ptr::null() + } + + fn full_path() -> *const u32 { + std::ptr::null() + } + + fn core_path() -> *const u32 { + use core::ptr; + ptr::null() + } + + fn full_core_path() -> *const u32 { + core::ptr::null() + } +} + +mod null_entire_infer { + fn use_path_mut() -> *mut u32 { + use std::ptr; + ptr::null_mut() + } + + fn full_path_mut() -> *mut u32 { + std::ptr::null_mut() + } + + fn core_path_mut() -> *mut u32 { + use core::ptr; + ptr::null_mut() + } + + fn full_core_path_mut() -> *mut u32 { + core::ptr::null_mut() + } + + fn use_path() -> *const u32 { + use std::ptr; + ptr::null() + } + + fn full_path() -> *const u32 { + std::ptr::null() + } + + fn core_path() -> *const u32 { + use core::ptr; + ptr::null() + } + + fn full_core_path() -> *const u32 { + core::ptr::null() + } +} diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs index 942c87344..7ab52e63d 100644 --- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs +++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs @@ -71,3 +71,118 @@ fn _msrv_1_38() { let _ = ptr as *const i32; let _ = mut_ptr as *mut i32; } + +#[allow(clippy::unnecessary_cast)] +mod null { + fn use_path_mut() -> *mut u32 { + use std::ptr; + ptr::null_mut() as *mut u32 + } + + fn full_path_mut() -> *mut u32 { + std::ptr::null_mut() as *mut u32 + } + + fn core_path_mut() -> *mut u32 { + use core::ptr; + ptr::null_mut() as *mut u32 + } + + fn full_core_path_mut() -> *mut u32 { + core::ptr::null_mut() as *mut u32 + } + + fn use_path() -> *const u32 { + use std::ptr; + ptr::null() as *const u32 + } + + fn full_path() -> *const u32 { + std::ptr::null() as *const u32 + } + + fn core_path() -> *const u32 { + use core::ptr; + ptr::null() as *const u32 + } + + fn full_core_path() -> *const u32 { + core::ptr::null() as *const u32 + } +} + +mod null_ptr_infer { + fn use_path_mut() -> *mut u32 { + use std::ptr; + ptr::null_mut() as *mut _ + } + + fn full_path_mut() -> *mut u32 { + std::ptr::null_mut() as *mut _ + } + + fn core_path_mut() -> *mut u32 { + use core::ptr; + ptr::null_mut() as *mut _ + } + + fn full_core_path_mut() -> *mut u32 { + core::ptr::null_mut() as *mut _ + } + + fn use_path() -> *const u32 { + use std::ptr; + ptr::null() as *const _ + } + + fn full_path() -> *const u32 { + std::ptr::null() as *const _ + } + + fn core_path() -> *const u32 { + use core::ptr; + ptr::null() as *const _ + } + + fn full_core_path() -> *const u32 { + core::ptr::null() as *const _ + } +} + +mod null_entire_infer { + fn use_path_mut() -> *mut u32 { + use std::ptr; + ptr::null_mut() as _ + } + + fn full_path_mut() -> *mut u32 { + std::ptr::null_mut() as _ + } + + fn core_path_mut() -> *mut u32 { + use core::ptr; + ptr::null_mut() as _ + } + + fn full_core_path_mut() -> *mut u32 { + core::ptr::null_mut() as _ + } + + fn use_path() -> *const u32 { + use std::ptr; + ptr::null() as _ + } + + fn full_path() -> *const u32 { + std::ptr::null() as _ + } + + fn core_path() -> *const u32 { + use core::ptr; + ptr::null() as _ + } + + fn full_core_path() -> *const u32 { + core::ptr::null() as _ + } +} diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr index c0ce69b43..ef64347e9 100644 --- a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr +++ b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr @@ -57,5 +57,149 @@ error: `as` casting between raw pointers without changing its mutability LL | let _ = mut_ptr as *mut i32; | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()` -error: aborting due to 9 previous errors +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:79:9 + | +LL | ptr::null_mut() as *mut u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:83:9 + | +LL | std::ptr::null_mut() as *mut u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut::<u32>()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:88:9 + | +LL | ptr::null_mut() as *mut u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:92:9 + | +LL | core::ptr::null_mut() as *mut u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut::<u32>()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:97:9 + | +LL | ptr::null() as *const u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:101:9 + | +LL | std::ptr::null() as *const u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u32>()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:106:9 + | +LL | ptr::null() as *const u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:110:9 + | +LL | core::ptr::null() as *const u32 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null::<u32>()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:117:9 + | +LL | ptr::null_mut() as *mut _ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:121:9 + | +LL | std::ptr::null_mut() as *mut _ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:126:9 + | +LL | ptr::null_mut() as *mut _ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:130:9 + | +LL | core::ptr::null_mut() as *mut _ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:135:9 + | +LL | ptr::null() as *const _ + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:139:9 + | +LL | std::ptr::null() as *const _ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:144:9 + | +LL | ptr::null() as *const _ + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:148:9 + | +LL | core::ptr::null() as *const _ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:155:9 + | +LL | ptr::null_mut() as _ + | ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:159:9 + | +LL | std::ptr::null_mut() as _ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:164:9 + | +LL | ptr::null_mut() as _ + | ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:168:9 + | +LL | core::ptr::null_mut() as _ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:173:9 + | +LL | ptr::null() as _ + | ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:177:9 + | +LL | std::ptr::null() as _ + | ^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:182:9 + | +LL | ptr::null() as _ + | ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` + +error: `as` casting between raw pointers without changing its mutability + --> $DIR/ptr_as_ptr.rs:186:9 + | +LL | core::ptr::null() as _ + | ^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()` + +error: aborting due to 33 previous errors diff --git a/src/tools/clippy/tests/ui/pub_use.stderr b/src/tools/clippy/tests/ui/pub_use.stderr index 781572736..f6f5db9a1 100644 --- a/src/tools/clippy/tests/ui/pub_use.stderr +++ b/src/tools/clippy/tests/ui/pub_use.stderr @@ -8,5 +8,5 @@ LL | pub use inner::Test; = note: `-D clippy::pub-use` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::pub_use)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/question_mark_used.stderr b/src/tools/clippy/tests/ui/question_mark_used.stderr index a3f440de8..b4e256ddb 100644 --- a/src/tools/clippy/tests/ui/question_mark_used.stderr +++ b/src/tools/clippy/tests/ui/question_mark_used.stderr @@ -8,5 +8,5 @@ LL | other_function()?; = note: `-D clippy::question-mark-used` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::question_mark_used)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/range.stderr b/src/tools/clippy/tests/ui/range.stderr index 9f174307b..78ef17b5b 100644 --- a/src/tools/clippy/tests/ui/range.stderr +++ b/src/tools/clippy/tests/ui/range.stderr @@ -7,5 +7,5 @@ LL | let _x = v1.iter().zip(0..v1.len()); = note: `-D clippy::range-zip-with-len` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::range_zip_with_len)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed index bf268d0b5..f272d8359 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed @@ -84,3 +84,21 @@ fn issue9956() { bar()(42, 5); foo(42, 5); } + +async fn issue11357() { + async {}.await; +} + +mod issue11707 { + use core::future::Future; + + fn spawn_on(fut: impl Future<Output = ()>) {} + + fn demo() { + spawn_on(async move {}); + } +} + +fn avoid_double_parens() { + std::convert::identity(13_i32 + 36_i32).leading_zeros(); +} diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs index c8a91049d..f45db8c9c 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs @@ -84,3 +84,21 @@ fn issue9956() { bar()((|| || 42)()(), 5); foo((|| || 42)()(), 5); } + +async fn issue11357() { + (|| async {})().await; +} + +mod issue11707 { + use core::future::Future; + + fn spawn_on(fut: impl Future<Output = ()>) {} + + fn demo() { + spawn_on((|| async move {})()); + } +} + +fn avoid_double_parens() { + std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros(); +} diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr index a7cdb4369..028d383ad 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr @@ -123,5 +123,23 @@ error: try not to call a closure in the expression where it is declared LL | foo((|| || 42)()(), 5); | ^^^^^^^^^^^^^^ help: try doing something like: `42` -error: aborting due to 14 previous errors +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:89:5 + | +LL | (|| async {})().await; + | ^^^^^^^^^^^^^^^ help: try doing something like: `async {}` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:98:18 + | +LL | spawn_on((|| async move {})()); + | ^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async move {}` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:103:28 + | +LL | std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32` + +error: aborting due to 17 previous errors diff --git a/src/tools/clippy/tests/ui/redundant_guards.fixed b/src/tools/clippy/tests/ui/redundant_guards.fixed index f8af90927..aef26ef22 100644 --- a/src/tools/clippy/tests/ui/redundant_guards.fixed +++ b/src/tools/clippy/tests/ui/redundant_guards.fixed @@ -193,3 +193,60 @@ mod issue11465 { } } } + +fn issue11807() { + #![allow(clippy::single_match)] + + match Some(Some("")) { + Some(Some("")) => {}, + _ => {}, + } + + match Some(Some(String::new())) { + // Do not lint: String deref-coerces to &str + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([])) => {}, + _ => {}, + } + + match Some(Some([] as [i32; 0])) { + Some(Some([])) => {}, + _ => {}, + } + + match Some(Some(Vec::<()>::new())) { + // Do not lint: Vec deref-coerces to &[T] + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([..])) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([1, ..])) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([1, 2, ..])) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([.., 1, 2])) => {}, + _ => {}, + } + + match Some(Some(Vec::<i32>::new())) { + // Do not lint: deref coercion + Some(Some(x)) if x.starts_with(&[1, 2]) => {}, + _ => {}, + } +} diff --git a/src/tools/clippy/tests/ui/redundant_guards.rs b/src/tools/clippy/tests/ui/redundant_guards.rs index b46f8a620..5d476f5b0 100644 --- a/src/tools/clippy/tests/ui/redundant_guards.rs +++ b/src/tools/clippy/tests/ui/redundant_guards.rs @@ -193,3 +193,60 @@ mod issue11465 { } } } + +fn issue11807() { + #![allow(clippy::single_match)] + + match Some(Some("")) { + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(String::new())) { + // Do not lint: String deref-coerces to &str + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some([] as [i32; 0])) { + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(Vec::<()>::new())) { + // Do not lint: Vec deref-coerces to &[T] + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.starts_with(&[]) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.starts_with(&[1]) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.starts_with(&[1, 2]) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.ends_with(&[1, 2]) => {}, + _ => {}, + } + + match Some(Some(Vec::<i32>::new())) { + // Do not lint: deref coercion + Some(Some(x)) if x.starts_with(&[1, 2]) => {}, + _ => {}, + } +} diff --git a/src/tools/clippy/tests/ui/redundant_guards.stderr b/src/tools/clippy/tests/ui/redundant_guards.stderr index b8d7834e3..f78d2a814 100644 --- a/src/tools/clippy/tests/ui/redundant_guards.stderr +++ b/src/tools/clippy/tests/ui/redundant_guards.stderr @@ -203,5 +203,89 @@ LL - B { ref c, .. } if matches!(c, &1) => {}, LL + B { c: 1, .. } => {}, | -error: aborting due to 17 previous errors +error: redundant guard + --> $DIR/redundant_guards.rs:201:26 + | +LL | Some(Some(x)) if x.is_empty() => {}, + | ^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.is_empty() => {}, +LL + Some(Some("")) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:212:26 + | +LL | Some(Some(x)) if x.is_empty() => {}, + | ^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.is_empty() => {}, +LL + Some(Some([])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:217:26 + | +LL | Some(Some(x)) if x.is_empty() => {}, + | ^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.is_empty() => {}, +LL + Some(Some([])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:228:26 + | +LL | Some(Some(x)) if x.starts_with(&[]) => {}, + | ^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.starts_with(&[]) => {}, +LL + Some(Some([..])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:233:26 + | +LL | Some(Some(x)) if x.starts_with(&[1]) => {}, + | ^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.starts_with(&[1]) => {}, +LL + Some(Some([1, ..])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:238:26 + | +LL | Some(Some(x)) if x.starts_with(&[1, 2]) => {}, + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.starts_with(&[1, 2]) => {}, +LL + Some(Some([1, 2, ..])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:243:26 + | +LL | Some(Some(x)) if x.ends_with(&[1, 2]) => {}, + | ^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.ends_with(&[1, 2]) => {}, +LL + Some(Some([.., 1, 2])) => {}, + | + +error: aborting due to 24 previous errors diff --git a/src/tools/clippy/tests/ui/regex.rs b/src/tools/clippy/tests/ui/regex.rs index 094d9574a..1ea0d65bf 100644 --- a/src/tools/clippy/tests/ui/regex.rs +++ b/src/tools/clippy/tests/ui/regex.rs @@ -112,6 +112,10 @@ fn trivial_regex() { // #6005: unicode classes in bytes::Regex let a_byte_of_unicode = BRegex::new(r"\p{C}"); + + // start and end word boundry, introduced in regex 0.10 + let _ = BRegex::new(r"\<word\>"); + let _ = BRegex::new(r"\b{start}word\b{end}"); } fn main() { diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 4df9be2c2..f4ff0f0b8 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -4,7 +4,7 @@ #![allow(clippy::almost_complete_range)] #![allow(clippy::disallowed_names)] -#![allow(clippy::blocks_in_if_conditions)] +#![allow(clippy::blocks_in_conditions)] #![allow(clippy::box_collection)] #![allow(clippy::redundant_static_lifetimes)] #![allow(clippy::cognitive_complexity)] @@ -51,10 +51,12 @@ #![allow(undropped_manually_drops)] #![allow(unknown_lints)] #![allow(unused_labels)] +#![allow(ambiguous_wide_pointer_comparisons)] #![warn(clippy::almost_complete_range)] #![warn(clippy::disallowed_names)] -#![warn(clippy::blocks_in_if_conditions)] -#![warn(clippy::blocks_in_if_conditions)] +#![warn(clippy::blocks_in_conditions)] +#![warn(clippy::blocks_in_conditions)] +#![warn(clippy::blocks_in_conditions)] #![warn(clippy::box_collection)] #![warn(clippy::redundant_static_lifetimes)] #![warn(clippy::cognitive_complexity)] @@ -107,5 +109,6 @@ #![warn(undropped_manually_drops)] #![warn(unknown_lints)] #![warn(unused_labels)] +#![warn(ambiguous_wide_pointer_comparisons)] fn main() {} diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 940e60068..0df1098f5 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -4,7 +4,7 @@ #![allow(clippy::almost_complete_range)] #![allow(clippy::disallowed_names)] -#![allow(clippy::blocks_in_if_conditions)] +#![allow(clippy::blocks_in_conditions)] #![allow(clippy::box_collection)] #![allow(clippy::redundant_static_lifetimes)] #![allow(clippy::cognitive_complexity)] @@ -51,10 +51,12 @@ #![allow(undropped_manually_drops)] #![allow(unknown_lints)] #![allow(unused_labels)] +#![allow(ambiguous_wide_pointer_comparisons)] #![warn(clippy::almost_complete_letter_range)] #![warn(clippy::blacklisted_name)] #![warn(clippy::block_in_if_condition_expr)] #![warn(clippy::block_in_if_condition_stmt)] +#![warn(clippy::blocks_in_if_conditions)] #![warn(clippy::box_vec)] #![warn(clippy::const_static_lifetime)] #![warn(clippy::cyclomatic_complexity)] @@ -107,5 +109,6 @@ #![warn(clippy::undropped_manually_drops)] #![warn(clippy::unknown_clippy_lints)] #![warn(clippy::unused_label)] +#![warn(clippy::vtable_address_comparisons)] fn main() {} diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 30824e154..f63ad82a7 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -8,334 +8,346 @@ LL | #![warn(clippy::almost_complete_letter_range)] = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` -error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:56:9 +error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_conditions` + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::block_in_if_condition_expr)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions` -error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:57:9 +error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_conditions` + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions` + +error: lint `clippy::blocks_in_if_conditions` has been renamed to `clippy::blocks_in_conditions` + --> $DIR/rename.rs:59:9 + | +LL | #![warn(clippy::blocks_in_if_conditions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl` error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl` error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects` - --> $DIR/rename.rs:69:9 + --> $DIR/rename.rs:71:9 | LL | #![warn(clippy::integer_arithmetic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> $DIR/rename.rs:70:9 + --> $DIR/rename.rs:72:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:71:9 + --> $DIR/rename.rs:73:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:72:9 + --> $DIR/rename.rs:74:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:73:9 + --> $DIR/rename.rs:75:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:74:9 + --> $DIR/rename.rs:76:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:75:9 + --> $DIR/rename.rs:77:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:76:9 + --> $DIR/rename.rs:78:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:77:9 + --> $DIR/rename.rs:79:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:78:9 + --> $DIR/rename.rs:80:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:79:9 + --> $DIR/rename.rs:81:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:80:9 + --> $DIR/rename.rs:82:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:81:9 + --> $DIR/rename.rs:83:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:82:9 + --> $DIR/rename.rs:84:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:83:9 + --> $DIR/rename.rs:85:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default` - --> $DIR/rename.rs:84:9 + --> $DIR/rename.rs:86:9 | LL | #![warn(clippy::unwrap_or_else_default)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:85:9 + --> $DIR/rename.rs:87:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting` - --> $DIR/rename.rs:86:9 + --> $DIR/rename.rs:88:9 | LL | #![warn(clippy::cast_ref_to_mut)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` - --> $DIR/rename.rs:87:9 + --> $DIR/rename.rs:89:9 | LL | #![warn(clippy::clone_double_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons` - --> $DIR/rename.rs:88:9 + --> $DIR/rename.rs:90:9 | LL | #![warn(clippy::cmp_nan)] | ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:89:9 + --> $DIR/rename.rs:91:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types` - --> $DIR/rename.rs:90:9 + --> $DIR/rename.rs:92:9 | LL | #![warn(clippy::drop_copy)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types` error: lint `clippy::drop_ref` has been renamed to `dropping_references` - --> $DIR/rename.rs:91:9 + --> $DIR/rename.rs:93:9 | LL | #![warn(clippy::drop_ref)] | ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references` error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks` - --> $DIR/rename.rs:92:9 + --> $DIR/rename.rs:94:9 | LL | #![warn(clippy::fn_null_check)] | ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:93:9 + --> $DIR/rename.rs:95:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:94:9 + --> $DIR/rename.rs:96:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:95:9 + --> $DIR/rename.rs:97:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types` - --> $DIR/rename.rs:96:9 + --> $DIR/rename.rs:98:9 | LL | #![warn(clippy::forget_copy)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types` error: lint `clippy::forget_ref` has been renamed to `forgetting_references` - --> $DIR/rename.rs:97:9 + --> $DIR/rename.rs:99:9 | LL | #![warn(clippy::forget_ref)] | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:98:9 + --> $DIR/rename.rs:100:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:99:9 + --> $DIR/rename.rs:101:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:100:9 + --> $DIR/rename.rs:102:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked` - --> $DIR/rename.rs:101:9 + --> $DIR/rename.rs:103:9 | LL | #![warn(clippy::invalid_utf8_in_unchecked)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> $DIR/rename.rs:102:9 + --> $DIR/rename.rs:104:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:103:9 + --> $DIR/rename.rs:105:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:104:9 + --> $DIR/rename.rs:106:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> $DIR/rename.rs:105:9 + --> $DIR/rename.rs:107:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:106:9 + --> $DIR/rename.rs:108:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops` - --> $DIR/rename.rs:107:9 + --> $DIR/rename.rs:109:9 | LL | #![warn(clippy::undropped_manually_drops)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:108:9 + --> $DIR/rename.rs:110:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:109:9 + --> $DIR/rename.rs:111:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 56 previous errors +error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons` + --> $DIR/rename.rs:112:9 + | +LL | #![warn(clippy::vtable_address_comparisons)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons` + +error: aborting due to 58 previous errors diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr index 636d88fcd..662188bba 100644 --- a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr +++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr @@ -4,5 +4,5 @@ error: usage of deprecated attribute LL | #[clippy::cyclomatic_complexity = "1"] | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `cognitive_complexity` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed new file mode 100644 index 000000000..2afe2f433 --- /dev/null +++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed @@ -0,0 +1,38 @@ +#![warn(clippy::repeat_vec_with_capacity)] + +fn main() { + { + (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>(); + //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + } + + { + let n = 123; + (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>(); + //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + } + + { + macro_rules! from_macro { + ($x:expr) => { + vec![$x; 123]; + }; + } + // vec expansion is from another macro, don't lint + from_macro!(Vec::<()>::with_capacity(42)); + } + + { + std::iter::repeat_with(|| Vec::<()>::with_capacity(42)); + //~^ ERROR: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity + } + + { + macro_rules! from_macro { + ($x:expr) => { + std::iter::repeat($x) + }; + } + from_macro!(Vec::<()>::with_capacity(42)); + } +} diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs new file mode 100644 index 000000000..659f2a395 --- /dev/null +++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs @@ -0,0 +1,38 @@ +#![warn(clippy::repeat_vec_with_capacity)] + +fn main() { + { + vec![Vec::<()>::with_capacity(42); 123]; + //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + } + + { + let n = 123; + vec![Vec::<()>::with_capacity(42); n]; + //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + } + + { + macro_rules! from_macro { + ($x:expr) => { + vec![$x; 123]; + }; + } + // vec expansion is from another macro, don't lint + from_macro!(Vec::<()>::with_capacity(42)); + } + + { + std::iter::repeat(Vec::<()>::with_capacity(42)); + //~^ ERROR: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity + } + + { + macro_rules! from_macro { + ($x:expr) => { + std::iter::repeat($x) + }; + } + from_macro!(Vec::<()>::with_capacity(42)); + } +} diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr new file mode 100644 index 000000000..10b5f1214 --- /dev/null +++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr @@ -0,0 +1,40 @@ +error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + --> $DIR/repeat_vec_with_capacity.rs:5:9 + | +LL | vec![Vec::<()>::with_capacity(42); 123]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only the last `Vec` will have the capacity + = note: `-D clippy::repeat-vec-with-capacity` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]` +help: if you intended to initialize multiple `Vec`s with an initial capacity, try + | +LL | (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity + --> $DIR/repeat_vec_with_capacity.rs:11:9 + | +LL | vec![Vec::<()>::with_capacity(42); n]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only the last `Vec` will have the capacity +help: if you intended to initialize multiple `Vec`s with an initial capacity, try + | +LL | (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity + --> $DIR/repeat_vec_with_capacity.rs:26:9 + | +LL | std::iter::repeat(Vec::<()>::with_capacity(42)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: none of the yielded `Vec`s will have the requested capacity +help: if you intended to create an iterator that yields `Vec`s with an initial capacity, try + | +LL | std::iter::repeat_with(|| Vec::<()>::with_capacity(42)); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/result_map_or_into_option.fixed b/src/tools/clippy/tests/ui/result_map_or_into_option.fixed index fb2db6cf5..cf42b24b2 100644 --- a/src/tools/clippy/tests/ui/result_map_or_into_option.fixed +++ b/src/tools/clippy/tests/ui/result_map_or_into_option.fixed @@ -3,6 +3,12 @@ fn main() { let opt: Result<u32, &str> = Ok(1); let _ = opt.ok(); + //~^ ERROR: called `map_or(None, Some)` on a `Result` value + let _ = opt.ok(); + //~^ ERROR: called `map_or_else(|_| None, Some)` on a `Result` value + #[rustfmt::skip] + let _ = opt.ok(); + //~^ ERROR: called `map_or_else(|_| None, Some)` on a `Result` value let rewrap = |s: u32| -> Option<u32> { Some(s) }; @@ -14,4 +20,5 @@ fn main() { // return should not emit the lint let opt: Result<u32, &str> = Ok(1); _ = opt.map_or(None, |_x| Some(1)); + let _ = opt.map_or_else(|a| a.parse::<u32>().ok(), Some); } diff --git a/src/tools/clippy/tests/ui/result_map_or_into_option.rs b/src/tools/clippy/tests/ui/result_map_or_into_option.rs index 06779a699..cdb45d6b8 100644 --- a/src/tools/clippy/tests/ui/result_map_or_into_option.rs +++ b/src/tools/clippy/tests/ui/result_map_or_into_option.rs @@ -3,6 +3,12 @@ fn main() { let opt: Result<u32, &str> = Ok(1); let _ = opt.map_or(None, Some); + //~^ ERROR: called `map_or(None, Some)` on a `Result` value + let _ = opt.map_or_else(|_| None, Some); + //~^ ERROR: called `map_or_else(|_| None, Some)` on a `Result` value + #[rustfmt::skip] + let _ = opt.map_or_else(|_| { None }, Some); + //~^ ERROR: called `map_or_else(|_| None, Some)` on a `Result` value let rewrap = |s: u32| -> Option<u32> { Some(s) }; @@ -14,4 +20,5 @@ fn main() { // return should not emit the lint let opt: Result<u32, &str> = Ok(1); _ = opt.map_or(None, |_x| Some(1)); + let _ = opt.map_or_else(|a| a.parse::<u32>().ok(), Some); } diff --git a/src/tools/clippy/tests/ui/result_map_or_into_option.stderr b/src/tools/clippy/tests/ui/result_map_or_into_option.stderr index 9396ea4c0..3d6bfef48 100644 --- a/src/tools/clippy/tests/ui/result_map_or_into_option.stderr +++ b/src/tools/clippy/tests/ui/result_map_or_into_option.stderr @@ -1,4 +1,4 @@ -error: called `map_or(None, Some)` on a `Result` value. This can be done more directly by calling `ok()` instead +error: called `map_or(None, Some)` on a `Result` value --> $DIR/result_map_or_into_option.rs:5:13 | LL | let _ = opt.map_or(None, Some); @@ -7,5 +7,17 @@ LL | let _ = opt.map_or(None, Some); = note: `-D clippy::result-map-or-into-option` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]` -error: aborting due to previous error +error: called `map_or_else(|_| None, Some)` on a `Result` value + --> $DIR/result_map_or_into_option.rs:7:13 + | +LL | let _ = opt.map_or_else(|_| None, Some); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `opt.ok()` + +error: called `map_or_else(|_| None, Some)` on a `Result` value + --> $DIR/result_map_or_into_option.rs:10:13 + | +LL | let _ = opt.map_or_else(|_| { None }, Some); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `opt.ok()` + +error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/seek_from_current.stderr b/src/tools/clippy/tests/ui/seek_from_current.stderr index 42eb342c1..4858cb82e 100644 --- a/src/tools/clippy/tests/ui/seek_from_current.stderr +++ b/src/tools/clippy/tests/ui/seek_from_current.stderr @@ -7,5 +7,5 @@ LL | f.seek(SeekFrom::Current(0))?; = note: `-D clippy::seek-from-current` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::seek_from_current)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/self_named_constructors.stderr b/src/tools/clippy/tests/ui/self_named_constructors.stderr index f299b860d..8083ff965 100644 --- a/src/tools/clippy/tests/ui/self_named_constructors.stderr +++ b/src/tools/clippy/tests/ui/self_named_constructors.stderr @@ -11,5 +11,5 @@ LL | | } = note: `-D clippy::self-named-constructors` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::self_named_constructors)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/serde.stderr b/src/tools/clippy/tests/ui/serde.stderr index e5d64e271..079ba42bd 100644 --- a/src/tools/clippy/tests/ui/serde.stderr +++ b/src/tools/clippy/tests/ui/serde.stderr @@ -13,5 +13,5 @@ LL | | } = note: `-D clippy::serde-api-misuse` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::serde_api_misuse)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/should_panic_without_expect.stderr b/src/tools/clippy/tests/ui/should_panic_without_expect.stderr index dfcef52a9..b13db83bd 100644 --- a/src/tools/clippy/tests/ui/should_panic_without_expect.stderr +++ b/src/tools/clippy/tests/ui/should_panic_without_expect.stderr @@ -10,5 +10,5 @@ note: the lint level is defined here LL | #![deny(clippy::should_panic_without_expect)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/single_element_loop.fixed b/src/tools/clippy/tests/ui/single_element_loop.fixed index a82eb6afc..4e59c7631 100644 --- a/src/tools/clippy/tests/ui/single_element_loop.fixed +++ b/src/tools/clippy/tests/ui/single_element_loop.fixed @@ -15,23 +15,19 @@ fn main() { dbg!(item); } - { - let item = &(0..5); + for item in 0..5 { dbg!(item); } - { - let item = &mut (0..5); + for item in 0..5 { dbg!(item); } - { - let item = 0..5; + for item in 0..5 { dbg!(item); } - { - let item = 0..5; + for item in 0..5 { dbg!(item); } diff --git a/src/tools/clippy/tests/ui/single_element_loop.stderr b/src/tools/clippy/tests/ui/single_element_loop.stderr index 603dd7406..952d70414 100644 --- a/src/tools/clippy/tests/ui/single_element_loop.stderr +++ b/src/tools/clippy/tests/ui/single_element_loop.stderr @@ -32,69 +32,29 @@ LL + dbg!(item); LL + } | -error: for loop over a single element - --> $DIR/single_element_loop.rs:16:5 - | -LL | / for item in &[0..5] { -LL | | dbg!(item); -LL | | } - | |_____^ - | -help: try - | -LL ~ { -LL + let item = &(0..5); -LL + dbg!(item); -LL + } +error: this loops only once with `item` being `0..5` + --> $DIR/single_element_loop.rs:16:17 | +LL | for item in &[0..5] { + | ^^^^^^^ help: did you mean to iterate over the range instead?: `0..5` -error: for loop over a single element - --> $DIR/single_element_loop.rs:20:5 - | -LL | / for item in [0..5].iter_mut() { -LL | | dbg!(item); -LL | | } - | |_____^ - | -help: try - | -LL ~ { -LL + let item = &mut (0..5); -LL + dbg!(item); -LL + } +error: this loops only once with `item` being `0..5` + --> $DIR/single_element_loop.rs:20:17 | +LL | for item in [0..5].iter_mut() { + | ^^^^^^^^^^^^^^^^^ help: did you mean to iterate over the range instead?: `0..5` -error: for loop over a single element - --> $DIR/single_element_loop.rs:24:5 - | -LL | / for item in [0..5] { -LL | | dbg!(item); -LL | | } - | |_____^ - | -help: try - | -LL ~ { -LL + let item = 0..5; -LL + dbg!(item); -LL + } +error: this loops only once with `item` being `0..5` + --> $DIR/single_element_loop.rs:24:17 | +LL | for item in [0..5] { + | ^^^^^^ help: did you mean to iterate over the range instead?: `0..5` -error: for loop over a single element - --> $DIR/single_element_loop.rs:28:5 - | -LL | / for item in [0..5].into_iter() { -LL | | dbg!(item); -LL | | } - | |_____^ - | -help: try - | -LL ~ { -LL + let item = 0..5; -LL + dbg!(item); -LL + } +error: this loops only once with `item` being `0..5` + --> $DIR/single_element_loop.rs:28:17 | +LL | for item in [0..5].into_iter() { + | ^^^^^^^^^^^^^^^^^^ help: did you mean to iterate over the range instead?: `0..5` error: for loop over a single element --> $DIR/single_element_loop.rs:47:5 diff --git a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.stderr b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.stderr index cf5688a97..4738bef3a 100644 --- a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.stderr +++ b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.stderr @@ -7,5 +7,5 @@ LL | let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]); = note: `-D clippy::string-from-utf8-as-bytes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::string_from_utf8_as_bytes)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/string_to_string.stderr b/src/tools/clippy/tests/ui/string_to_string.stderr index 27a844315..f1f8e176b 100644 --- a/src/tools/clippy/tests/ui/string_to_string.stderr +++ b/src/tools/clippy/tests/ui/string_to_string.stderr @@ -8,5 +8,5 @@ LL | let mut v = message.to_string(); = note: `-D clippy::string-to-string` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::string_to_string)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/test_attr_in_doctest.rs b/src/tools/clippy/tests/ui/test_attr_in_doctest.rs new file mode 100644 index 000000000..4c904f7a0 --- /dev/null +++ b/src/tools/clippy/tests/ui/test_attr_in_doctest.rs @@ -0,0 +1,51 @@ +/// This is a test for `#[test]` in doctests +/// +/// # Examples +/// +/// ``` +/// #[test] +/// fn should_be_linted() { +/// assert_eq!(1, 1); +/// } +/// ``` +/// +/// Make sure we catch multiple tests in one example, +/// and show that we really parse the attr: +/// +/// ``` +/// #[test] +/// fn should_also_be_linted() { +/// #[cfg(test)] +/// assert!(true); +/// } +/// +/// #[test] +/// fn should_be_linted_too() { +/// assert_eq!("#[test]", " +/// #[test] +/// "); +/// } +/// ``` +/// +/// We don't catch examples that aren't run: +/// +/// ```ignore +/// #[test] +/// fn ignored() { todo!() } +/// ``` +/// +/// ```no_run +/// #[test] +/// fn ignored() { todo!() } +/// ``` +/// +/// ```compile_fail +/// #[test] +/// fn ignored() { Err(()) } +/// ``` +/// +/// ```txt +/// #[test] +/// fn not_even_rust() { panic!("Ouch") } +/// ``` +fn test_attr_in_doctests() {} diff --git a/src/tools/clippy/tests/ui/test_attr_in_doctest.stderr b/src/tools/clippy/tests/ui/test_attr_in_doctest.stderr new file mode 100644 index 000000000..605259f3b --- /dev/null +++ b/src/tools/clippy/tests/ui/test_attr_in_doctest.stderr @@ -0,0 +1,29 @@ +error: unit tests in doctest are not executed + --> $DIR/test_attr_in_doctest.rs:6:5 + | +LL | /// #[test] + | _____^ +LL | | /// fn should_be_linted() { + | |_______________________^ + | + = note: `-D clippy::test-attr-in-doctest` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::test_attr_in_doctest)]` + +error: unit tests in doctest are not executed + --> $DIR/test_attr_in_doctest.rs:16:5 + | +LL | /// #[test] + | _____^ +LL | | /// fn should_also_be_linted() { + | |____________________________^ + +error: unit tests in doctest are not executed + --> $DIR/test_attr_in_doctest.rs:22:5 + | +LL | /// #[test] + | _____^ +LL | | /// fn should_be_linted_too() { + | |___________________________^ + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/tests_outside_test_module.stderr b/src/tools/clippy/tests/ui/tests_outside_test_module.stderr index 112d6ce1f..ec0cdea83 100644 --- a/src/tools/clippy/tests/ui/tests_outside_test_module.stderr +++ b/src/tools/clippy/tests/ui/tests_outside_test_module.stderr @@ -8,5 +8,5 @@ LL | fn my_test() {} = note: `-D clippy::tests-outside-test-module` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::tests_outside_test_module)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr index 39418d359..131adfd58 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics.stderr +++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr @@ -5,6 +5,6 @@ LL | const S: A = B; | ^ expected `A`, found `B` -Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC -error: aborting due to previous error +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed index 19abced98..4e145693c 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed @@ -43,6 +43,9 @@ fn transmute_ptr_to_ptr() { //~^ ERROR: transmute from a reference to a reference let _: &GenericParam<f32> = &*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>); //~^ ERROR: transmute from a reference to a reference + let u8_ref: &u8 = &0u8; + let u64_ref: &u64 = unsafe { &*(u8_ref as *const u8 as *const u64) }; + //~^ ERROR: transmute from a reference to a reference } // these are recommendations for solving the above; if these lint we need to update diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs index abba2b8e5..086aadc36 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs @@ -43,6 +43,9 @@ fn transmute_ptr_to_ptr() { //~^ ERROR: transmute from a reference to a reference let _: &GenericParam<f32> = std::mem::transmute(&GenericParam { t: 1u32 }); //~^ ERROR: transmute from a reference to a reference + let u8_ref: &u8 = &0u8; + let u64_ref: &u64 = unsafe { std::mem::transmute(u8_ref) }; + //~^ ERROR: transmute from a reference to a reference } // these are recommendations for solving the above; if these lint we need to update diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr index 564339c06..9f8599921 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr @@ -37,5 +37,11 @@ error: transmute from a reference to a reference LL | let _: &GenericParam<f32> = std::mem::transmute(&GenericParam { t: 1u32 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>)` -error: aborting due to 6 previous errors +error: transmute from a reference to a reference + --> $DIR/transmute_ptr_to_ptr.rs:47:38 + | +LL | let u64_ref: &u64 = unsafe { std::mem::transmute(u8_ref) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(u8_ref as *const u8 as *const u64)` + +error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs b/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs new file mode 100644 index 000000000..e7f35c574 --- /dev/null +++ b/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs @@ -0,0 +1,18 @@ +//@no-rustfix + +#![deny(clippy::transmute_ptr_to_ptr)] +#![allow(dead_code)] + +fn main() { + unsafe { + let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF]; + let bools: &[bool] = unsafe { std::mem::transmute(single_u64) }; + //~^ ERROR: transmute from a reference to a reference + let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321]; + let b: &[u8] = unsafe { std::mem::transmute(a) }; + //~^ ERROR: transmute from a reference to a reference + let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8]; + let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) }; + //~^ ERROR: transmute from a reference to a reference + } +} diff --git a/src/tools/clippy/tests/ui/transmute_ref_to_ref.stderr b/src/tools/clippy/tests/ui/transmute_ref_to_ref.stderr new file mode 100644 index 000000000..cc6b156b1 --- /dev/null +++ b/src/tools/clippy/tests/ui/transmute_ref_to_ref.stderr @@ -0,0 +1,26 @@ +error: transmute from a reference to a reference + --> $DIR/transmute_ref_to_ref.rs:9:39 + | +LL | let bools: &[bool] = unsafe { std::mem::transmute(single_u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(single_u64 as *const [u64] as *const [bool])` + | +note: the lint level is defined here + --> $DIR/transmute_ref_to_ref.rs:3:9 + | +LL | #![deny(clippy::transmute_ptr_to_ptr)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from a reference to a reference + --> $DIR/transmute_ref_to_ref.rs:12:33 + | +LL | let b: &[u8] = unsafe { std::mem::transmute(a) }; + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const [u32] as *const [u8])` + +error: transmute from a reference to a reference + --> $DIR/transmute_ref_to_ref.rs:15:42 + | +LL | let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])` + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/types.stderr b/src/tools/clippy/tests/ui/types.stderr index b253cf338..f7473e1c5 100644 --- a/src/tools/clippy/tests/ui/types.stderr +++ b/src/tools/clippy/tests/ui/types.stderr @@ -7,5 +7,5 @@ LL | let c_i64: i64 = c as i64; = note: `-D clippy::cast-lossless` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/uninhabited_references.rs b/src/tools/clippy/tests/ui/uninhabited_references.rs new file mode 100644 index 000000000..cd07b590a --- /dev/null +++ b/src/tools/clippy/tests/ui/uninhabited_references.rs @@ -0,0 +1,22 @@ +#![warn(clippy::uninhabited_references)] +#![feature(never_type)] + +fn ret_uninh_ref() -> &'static std::convert::Infallible { + unsafe { std::mem::transmute(&()) } +} + +macro_rules! ret_something { + ($name:ident, $ty:ty) => { + fn $name(x: &$ty) -> &$ty { + &*x + } + }; +} + +ret_something!(id_u32, u32); +ret_something!(id_never, !); + +fn main() { + let x = ret_uninh_ref(); + let _ = *x; +} diff --git a/src/tools/clippy/tests/ui/uninhabited_references.stderr b/src/tools/clippy/tests/ui/uninhabited_references.stderr new file mode 100644 index 000000000..2cdf320b8 --- /dev/null +++ b/src/tools/clippy/tests/ui/uninhabited_references.stderr @@ -0,0 +1,39 @@ +error: dereferencing a reference to an uninhabited type would be undefined behavior + --> $DIR/uninhabited_references.rs:4:23 + | +LL | fn ret_uninh_ref() -> &'static std::convert::Infallible { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::uninhabited-references` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::uninhabited_references)]` + +error: dereferencing a reference to an uninhabited type would be undefined behavior + --> $DIR/uninhabited_references.rs:10:30 + | +LL | fn $name(x: &$ty) -> &$ty { + | ^^^^ +... +LL | ret_something!(id_never, !); + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: dereferencing a reference to an uninhabited type is undefined behavior + --> $DIR/uninhabited_references.rs:11:14 + | +LL | &*x + | ^^ +... +LL | ret_something!(id_never, !); + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: dereferencing a reference to an uninhabited type is undefined behavior + --> $DIR/uninhabited_references.rs:21:13 + | +LL | let _ = *x; + | ^^ + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.stderr b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.stderr index 221efeb50..736a68ab1 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.stderr +++ b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.stderr @@ -12,5 +12,5 @@ LL - println!("val='{}'", var); LL + println!("val='{var}'"); | -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/unknown_attribute.stderr b/src/tools/clippy/tests/ui/unknown_attribute.stderr index 618c5980d..edad35d15 100644 --- a/src/tools/clippy/tests/ui/unknown_attribute.stderr +++ b/src/tools/clippy/tests/ui/unknown_attribute.stderr @@ -4,5 +4,5 @@ error: usage of unknown attribute LL | #[clippy::unknown] | ^^^^^^^ -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.stderr b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.stderr index b918fdf77..26b152515 100644 --- a/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions.stderr @@ -4,6 +4,7 @@ error: use of a fallible conversion when an infallible one could be used LL | let _: i64 = 0i32.try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^ help: use: `into()` | + = note: converting `i32` to `i64` cannot fail = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]` @@ -12,6 +13,8 @@ error: use of a fallible conversion when an infallible one could be used | LL | let _: i64 = 0i32.try_into().expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `into()` + | + = note: converting `i32` to `i64` cannot fail error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.stderr index 286decf8f..033de0e92 100644 --- a/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_fallible_conversions_unfixable.stderr @@ -4,6 +4,7 @@ error: use of a fallible conversion when an infallible one could be used LL | let _: Result<Foo, _> = 0i64.try_into(); | ^^^^^^^^ help: use: `into` | + = note: converting `i64` to `Foo` cannot fail = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]` @@ -12,30 +13,40 @@ error: use of a fallible conversion when an infallible one could be used | LL | let _: Result<Foo, _> = i64::try_into(0i64); | ^^^^^^^^^^^^^ help: use: `Into::into` + | + = note: converting `i64` to `Foo` cannot fail 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` + | + = note: converting `i64` to `Foo` cannot fail 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` + | + = note: converting `i32` to `i64` cannot fail 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` + | + = note: converting `i32` to `i64` cannot fail 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` + | + = note: converting `i32` to `i64` cannot fail error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed index 4778eaefd..66598f892 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed @@ -6,6 +6,8 @@ #![allow(clippy::needless_borrow)] #![allow(clippy::unnecessary_literal_unwrap)] #![allow(clippy::unit_arg)] +#![allow(arithmetic_overflow)] +#![allow(unconditional_panic)] use std::ops::Deref; @@ -190,3 +192,79 @@ fn issue9485() { // should not lint, is in proc macro with_span!(span Some(42).unwrap_or_else(|| 2);); } + +fn issue9422(x: usize) -> Option<usize> { + (x >= 5).then(|| x - 5) + // (x >= 5).then_some(x - 5) // clippy suggestion panics +} + +fn panicky_arithmetic_ops(x: usize, y: isize) { + #![allow(clippy::identity_op, clippy::eq_op)] + + // See comments in `eager_or_lazy.rs` for the rules that this is meant to follow + + let _x = false.then_some(i32::MAX + 1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(i32::MAX * 2); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(i32::MAX - 1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(i32::MIN - 1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(255u8 << 7); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(255u8 << 8); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(255u8 >> 8); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 255u8 >> x); + let _x = false.then_some(i32::MAX + -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(-i32::MAX); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(-i32::MIN); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| -y); + let _x = false.then_some(255 >> -7); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(255 << -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(1 / 0); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(x << -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(x << 2); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| x + x); + let _x = false.then(|| x * x); + let _x = false.then(|| x - x); + let _x = false.then(|| x / x); + let _x = false.then(|| x % x); + let _x = false.then(|| x + 1); + let _x = false.then(|| 1 + x); + + let _x = false.then_some(x / 0); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(x % 0); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| y / -1); + let _x = false.then_some(1 / -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(i32::MIN / -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| i32::MIN / x as i32); + let _x = false.then_some(i32::MIN / 0); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then_some(4 / 2); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 1 / x); + + // const eval doesn't read variables, but floating point math never panics, so we can still emit a + // warning + let f1 = 1.0; + let f2 = 2.0; + let _x = false.then_some(f1 + f2); + //~^ ERROR: unnecessary closure used with `bool::then` +} diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs index d4b7fd31b..5045fcd79 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs @@ -6,6 +6,8 @@ #![allow(clippy::needless_borrow)] #![allow(clippy::unnecessary_literal_unwrap)] #![allow(clippy::unit_arg)] +#![allow(arithmetic_overflow)] +#![allow(unconditional_panic)] use std::ops::Deref; @@ -190,3 +192,79 @@ fn issue9485() { // should not lint, is in proc macro with_span!(span Some(42).unwrap_or_else(|| 2);); } + +fn issue9422(x: usize) -> Option<usize> { + (x >= 5).then(|| x - 5) + // (x >= 5).then_some(x - 5) // clippy suggestion panics +} + +fn panicky_arithmetic_ops(x: usize, y: isize) { + #![allow(clippy::identity_op, clippy::eq_op)] + + // See comments in `eager_or_lazy.rs` for the rules that this is meant to follow + + let _x = false.then(|| i32::MAX + 1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| i32::MAX * 2); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| i32::MAX - 1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| i32::MIN - 1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 255u8 << 7); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 255u8 << 8); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 255u8 >> 8); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 255u8 >> x); + let _x = false.then(|| i32::MAX + -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| -i32::MAX); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| -i32::MIN); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| -y); + let _x = false.then(|| 255 >> -7); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 255 << -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 1 / 0); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| x << -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| x << 2); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| x + x); + let _x = false.then(|| x * x); + let _x = false.then(|| x - x); + let _x = false.then(|| x / x); + let _x = false.then(|| x % x); + let _x = false.then(|| x + 1); + let _x = false.then(|| 1 + x); + + let _x = false.then(|| x / 0); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| x % 0); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| y / -1); + let _x = false.then(|| 1 / -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| i32::MIN / -1); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| i32::MIN / x as i32); + let _x = false.then(|| i32::MIN / 0); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 4 / 2); + //~^ ERROR: unnecessary closure used with `bool::then` + let _x = false.then(|| 1 / x); + + // const eval doesn't read variables, but floating point math never panics, so we can still emit a + // warning + let f1 = 1.0; + let f2 = 2.0; + let _x = false.then(|| f1 + f2); + //~^ ERROR: unnecessary closure used with `bool::then` +} diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr index 1b0db4759..466664aee 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr @@ -1,5 +1,5 @@ error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:69:13 + --> $DIR/unnecessary_lazy_eval.rs:71:13 | LL | let _ = opt.unwrap_or_else(|| 2); | ^^^^-------------------- @@ -10,7 +10,7 @@ LL | let _ = opt.unwrap_or_else(|| 2); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:70:13 + --> $DIR/unnecessary_lazy_eval.rs:72:13 | LL | let _ = opt.unwrap_or_else(|| astronomers_pi); | ^^^^--------------------------------- @@ -18,7 +18,7 @@ LL | let _ = opt.unwrap_or_else(|| astronomers_pi); | help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:71:13 + --> $DIR/unnecessary_lazy_eval.rs:73:13 | LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); | ^^^^------------------------------------- @@ -26,7 +26,7 @@ LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); | help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:73:13 + --> $DIR/unnecessary_lazy_eval.rs:75:13 | LL | let _ = opt.and_then(|_| ext_opt); | ^^^^--------------------- @@ -34,7 +34,7 @@ LL | let _ = opt.and_then(|_| ext_opt); | help: use `and(..)` instead: `and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:74:13 + --> $DIR/unnecessary_lazy_eval.rs:76:13 | LL | let _ = opt.or_else(|| ext_opt); | ^^^^------------------- @@ -42,7 +42,7 @@ LL | let _ = opt.or_else(|| ext_opt); | help: use `or(..)` instead: `or(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:75:13 + --> $DIR/unnecessary_lazy_eval.rs:77:13 | LL | let _ = opt.or_else(|| None); | ^^^^---------------- @@ -50,7 +50,7 @@ LL | let _ = opt.or_else(|| None); | help: use `or(..)` instead: `or(None)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:76:13 + --> $DIR/unnecessary_lazy_eval.rs:78:13 | LL | let _ = opt.get_or_insert_with(|| 2); | ^^^^------------------------ @@ -58,7 +58,7 @@ LL | let _ = opt.get_or_insert_with(|| 2); | help: use `get_or_insert(..)` instead: `get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:77:13 + --> $DIR/unnecessary_lazy_eval.rs:79:13 | LL | let _ = opt.ok_or_else(|| 2); | ^^^^---------------- @@ -66,7 +66,7 @@ LL | let _ = opt.ok_or_else(|| 2); | help: use `ok_or(..)` instead: `ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:78:13 + --> $DIR/unnecessary_lazy_eval.rs:80:13 | LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); | ^^^^^^^^^^^^^^^^^------------------------------- @@ -74,7 +74,7 @@ LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); | help: use `unwrap_or(..)` instead: `unwrap_or(Some((1, 2)))` error: unnecessary closure used with `bool::then` - --> $DIR/unnecessary_lazy_eval.rs:79:13 + --> $DIR/unnecessary_lazy_eval.rs:81:13 | LL | let _ = cond.then(|| astronomers_pi); | ^^^^^----------------------- @@ -82,7 +82,7 @@ LL | let _ = cond.then(|| astronomers_pi); | help: use `then_some(..)` instead: `then_some(astronomers_pi)` error: unnecessary closure used with `bool::then` - --> $DIR/unnecessary_lazy_eval.rs:80:13 + --> $DIR/unnecessary_lazy_eval.rs:82:13 | LL | let _ = true.then(|| -> _ {}); | ^^^^^---------------- @@ -90,7 +90,7 @@ LL | let _ = true.then(|| -> _ {}); | help: use `then_some(..)` instead: `then_some({})` error: unnecessary closure used with `bool::then` - --> $DIR/unnecessary_lazy_eval.rs:81:13 + --> $DIR/unnecessary_lazy_eval.rs:83:13 | LL | let _ = true.then(|| {}); | ^^^^^----------- @@ -98,7 +98,7 @@ LL | let _ = true.then(|| {}); | help: use `then_some(..)` instead: `then_some({})` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:85:13 + --> $DIR/unnecessary_lazy_eval.rs:87:13 | LL | let _ = Some(1).unwrap_or_else(|| *r); | ^^^^^^^^--------------------- @@ -106,7 +106,7 @@ LL | let _ = Some(1).unwrap_or_else(|| *r); | help: use `unwrap_or(..)` instead: `unwrap_or(*r)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:87:13 + --> $DIR/unnecessary_lazy_eval.rs:89:13 | LL | let _ = Some(1).unwrap_or_else(|| *b); | ^^^^^^^^--------------------- @@ -114,7 +114,7 @@ LL | let _ = Some(1).unwrap_or_else(|| *b); | help: use `unwrap_or(..)` instead: `unwrap_or(*b)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:89:13 + --> $DIR/unnecessary_lazy_eval.rs:91:13 | LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); | ^^^^^^^^^^^^^^^^^--------------------- @@ -122,7 +122,7 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); | help: use `unwrap_or(..)` instead: `unwrap_or(&r)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:90:13 + --> $DIR/unnecessary_lazy_eval.rs:92:13 | LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); | ^^^^^^^^^^^^^^^^^--------------------- @@ -130,7 +130,7 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); | help: use `unwrap_or(..)` instead: `unwrap_or(&b)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:93:13 + --> $DIR/unnecessary_lazy_eval.rs:95:13 | LL | let _ = Some(10).unwrap_or_else(|| 2); | ^^^^^^^^^-------------------- @@ -138,7 +138,7 @@ LL | let _ = Some(10).unwrap_or_else(|| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:94:13 + --> $DIR/unnecessary_lazy_eval.rs:96:13 | LL | let _ = Some(10).and_then(|_| ext_opt); | ^^^^^^^^^--------------------- @@ -146,7 +146,7 @@ LL | let _ = Some(10).and_then(|_| ext_opt); | help: use `and(..)` instead: `and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:95:28 + --> $DIR/unnecessary_lazy_eval.rs:97:28 | LL | let _: Option<usize> = None.or_else(|| ext_opt); | ^^^^^------------------- @@ -154,7 +154,7 @@ LL | let _: Option<usize> = None.or_else(|| ext_opt); | help: use `or(..)` instead: `or(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:96:13 + --> $DIR/unnecessary_lazy_eval.rs:98:13 | LL | let _ = None.get_or_insert_with(|| 2); | ^^^^^------------------------ @@ -162,7 +162,7 @@ LL | let _ = None.get_or_insert_with(|| 2); | help: use `get_or_insert(..)` instead: `get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:97:35 + --> $DIR/unnecessary_lazy_eval.rs:99:35 | LL | let _: Result<usize, usize> = None.ok_or_else(|| 2); | ^^^^^---------------- @@ -170,7 +170,7 @@ LL | let _: Result<usize, usize> = None.ok_or_else(|| 2); | help: use `ok_or(..)` instead: `ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:98:28 + --> $DIR/unnecessary_lazy_eval.rs:100:28 | LL | let _: Option<usize> = None.or_else(|| None); | ^^^^^---------------- @@ -178,7 +178,7 @@ LL | let _: Option<usize> = None.or_else(|| None); | help: use `or(..)` instead: `or(None)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:101:13 + --> $DIR/unnecessary_lazy_eval.rs:103:13 | LL | let _ = deep.0.unwrap_or_else(|| 2); | ^^^^^^^-------------------- @@ -186,7 +186,7 @@ LL | let _ = deep.0.unwrap_or_else(|| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:102:13 + --> $DIR/unnecessary_lazy_eval.rs:104:13 | LL | let _ = deep.0.and_then(|_| ext_opt); | ^^^^^^^--------------------- @@ -194,7 +194,7 @@ LL | let _ = deep.0.and_then(|_| ext_opt); | help: use `and(..)` instead: `and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:103:13 + --> $DIR/unnecessary_lazy_eval.rs:105:13 | LL | let _ = deep.0.or_else(|| None); | ^^^^^^^---------------- @@ -202,7 +202,7 @@ LL | let _ = deep.0.or_else(|| None); | help: use `or(..)` instead: `or(None)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:104:13 + --> $DIR/unnecessary_lazy_eval.rs:106:13 | LL | let _ = deep.0.get_or_insert_with(|| 2); | ^^^^^^^------------------------ @@ -210,7 +210,7 @@ LL | let _ = deep.0.get_or_insert_with(|| 2); | help: use `get_or_insert(..)` instead: `get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:105:13 + --> $DIR/unnecessary_lazy_eval.rs:107:13 | LL | let _ = deep.0.ok_or_else(|| 2); | ^^^^^^^---------------- @@ -218,7 +218,7 @@ LL | let _ = deep.0.ok_or_else(|| 2); | help: use `ok_or(..)` instead: `ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:135:28 + --> $DIR/unnecessary_lazy_eval.rs:137:28 | LL | let _: Option<usize> = None.or_else(|| Some(3)); | ^^^^^------------------- @@ -226,7 +226,7 @@ LL | let _: Option<usize> = None.or_else(|| Some(3)); | help: use `or(..)` instead: `or(Some(3))` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:136:13 + --> $DIR/unnecessary_lazy_eval.rs:138:13 | LL | let _ = deep.0.or_else(|| Some(3)); | ^^^^^^^------------------- @@ -234,7 +234,7 @@ LL | let _ = deep.0.or_else(|| Some(3)); | help: use `or(..)` instead: `or(Some(3))` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:137:13 + --> $DIR/unnecessary_lazy_eval.rs:139:13 | LL | let _ = opt.or_else(|| Some(3)); | ^^^^------------------- @@ -242,7 +242,7 @@ LL | let _ = opt.or_else(|| Some(3)); | help: use `or(..)` instead: `or(Some(3))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:143:13 + --> $DIR/unnecessary_lazy_eval.rs:145:13 | LL | let _ = res2.unwrap_or_else(|_| 2); | ^^^^^--------------------- @@ -250,7 +250,7 @@ LL | let _ = res2.unwrap_or_else(|_| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:144:13 + --> $DIR/unnecessary_lazy_eval.rs:146:13 | LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); | ^^^^^---------------------------------- @@ -258,7 +258,7 @@ LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); | help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:145:13 + --> $DIR/unnecessary_lazy_eval.rs:147:13 | LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); | ^^^^^-------------------------------------- @@ -266,7 +266,7 @@ LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); | help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:167:35 + --> $DIR/unnecessary_lazy_eval.rs:169:35 | LL | let _: Result<usize, usize> = res.and_then(|_| Err(2)); | ^^^^-------------------- @@ -274,7 +274,7 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(2)); | help: use `and(..)` instead: `and(Err(2))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:168:35 + --> $DIR/unnecessary_lazy_eval.rs:170:35 | LL | let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi)); | ^^^^--------------------------------- @@ -282,7 +282,7 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi)); | help: use `and(..)` instead: `and(Err(astronomers_pi))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:169:35 + --> $DIR/unnecessary_lazy_eval.rs:171:35 | LL | let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field)); | ^^^^------------------------------------- @@ -290,7 +290,7 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field)) | help: use `and(..)` instead: `and(Err(ext_str.some_field))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:171:35 + --> $DIR/unnecessary_lazy_eval.rs:173:35 | LL | let _: Result<usize, usize> = res.or_else(|_| Ok(2)); | ^^^^------------------ @@ -298,7 +298,7 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(2)); | help: use `or(..)` instead: `or(Ok(2))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:172:35 + --> $DIR/unnecessary_lazy_eval.rs:174:35 | LL | let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi)); | ^^^^------------------------------- @@ -306,7 +306,7 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi)); | help: use `or(..)` instead: `or(Ok(astronomers_pi))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:173:35 + --> $DIR/unnecessary_lazy_eval.rs:175:35 | LL | let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field)); | ^^^^----------------------------------- @@ -314,7 +314,7 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field)); | help: use `or(..)` instead: `or(Ok(ext_str.some_field))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:174:35 + --> $DIR/unnecessary_lazy_eval.rs:176:35 | LL | let _: Result<usize, usize> = res. | ___________________________________^ @@ -328,5 +328,189 @@ LL | | or_else(|_| Ok(ext_str.some_field)); | | | help: use `or(..)` instead: `or(Ok(ext_str.some_field))` -error: aborting due to 40 previous errors +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:206:14 + | +LL | let _x = false.then(|| i32::MAX + 1); + | ^^^^^^--------------------- + | | + | help: use `then_some(..)` instead: `then_some(i32::MAX + 1)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:208:14 + | +LL | let _x = false.then(|| i32::MAX * 2); + | ^^^^^^--------------------- + | | + | help: use `then_some(..)` instead: `then_some(i32::MAX * 2)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:210:14 + | +LL | let _x = false.then(|| i32::MAX - 1); + | ^^^^^^--------------------- + | | + | help: use `then_some(..)` instead: `then_some(i32::MAX - 1)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:212:14 + | +LL | let _x = false.then(|| i32::MIN - 1); + | ^^^^^^--------------------- + | | + | help: use `then_some(..)` instead: `then_some(i32::MIN - 1)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:214:14 + | +LL | let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); + | ^^^^^^------------------------------------- + | | + | help: use `then_some(..)` instead: `then_some((1 + 2 * 3 - 2 / 3 + 9) << 2)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:216:14 + | +LL | let _x = false.then(|| 255u8 << 7); + | ^^^^^^------------------- + | | + | help: use `then_some(..)` instead: `then_some(255u8 << 7)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:218:14 + | +LL | let _x = false.then(|| 255u8 << 8); + | ^^^^^^------------------- + | | + | help: use `then_some(..)` instead: `then_some(255u8 << 8)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:220:14 + | +LL | let _x = false.then(|| 255u8 >> 8); + | ^^^^^^------------------- + | | + | help: use `then_some(..)` instead: `then_some(255u8 >> 8)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:223:14 + | +LL | let _x = false.then(|| i32::MAX + -1); + | ^^^^^^---------------------- + | | + | help: use `then_some(..)` instead: `then_some(i32::MAX + -1)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:225:14 + | +LL | let _x = false.then(|| -i32::MAX); + | ^^^^^^------------------ + | | + | help: use `then_some(..)` instead: `then_some(-i32::MAX)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:227:14 + | +LL | let _x = false.then(|| -i32::MIN); + | ^^^^^^------------------ + | | + | help: use `then_some(..)` instead: `then_some(-i32::MIN)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:230:14 + | +LL | let _x = false.then(|| 255 >> -7); + | ^^^^^^------------------ + | | + | help: use `then_some(..)` instead: `then_some(255 >> -7)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:232:14 + | +LL | let _x = false.then(|| 255 << -1); + | ^^^^^^------------------ + | | + | help: use `then_some(..)` instead: `then_some(255 << -1)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:234:14 + | +LL | let _x = false.then(|| 1 / 0); + | ^^^^^^-------------- + | | + | help: use `then_some(..)` instead: `then_some(1 / 0)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:236:14 + | +LL | let _x = false.then(|| x << -1); + | ^^^^^^---------------- + | | + | help: use `then_some(..)` instead: `then_some(x << -1)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:238:14 + | +LL | let _x = false.then(|| x << 2); + | ^^^^^^--------------- + | | + | help: use `then_some(..)` instead: `then_some(x << 2)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:248:14 + | +LL | let _x = false.then(|| x / 0); + | ^^^^^^-------------- + | | + | help: use `then_some(..)` instead: `then_some(x / 0)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:250:14 + | +LL | let _x = false.then(|| x % 0); + | ^^^^^^-------------- + | | + | help: use `then_some(..)` instead: `then_some(x % 0)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:253:14 + | +LL | let _x = false.then(|| 1 / -1); + | ^^^^^^--------------- + | | + | help: use `then_some(..)` instead: `then_some(1 / -1)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:255:14 + | +LL | let _x = false.then(|| i32::MIN / -1); + | ^^^^^^---------------------- + | | + | help: use `then_some(..)` instead: `then_some(i32::MIN / -1)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:258:14 + | +LL | let _x = false.then(|| i32::MIN / 0); + | ^^^^^^--------------------- + | | + | help: use `then_some(..)` instead: `then_some(i32::MIN / 0)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:260:14 + | +LL | let _x = false.then(|| 4 / 2); + | ^^^^^^-------------- + | | + | help: use `then_some(..)` instead: `then_some(4 / 2)` + +error: unnecessary closure used with `bool::then` + --> $DIR/unnecessary_lazy_eval.rs:268:14 + | +LL | let _x = false.then(|| f1 + f2); + | ^^^^^^---------------- + | | + | help: use `then_some(..)` instead: `then_some(f1 + f2)` + +error: aborting due to 63 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.fixed b/src/tools/clippy/tests/ui/unnecessary_operation.fixed index d0c0298ef..463412dae 100644 --- a/src/tools/clippy/tests/ui/unnecessary_operation.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_operation.fixed @@ -7,6 +7,9 @@ )] #![warn(clippy::unnecessary_operation)] +use std::fmt::Display; +use std::ops::Shl; + struct Tuple(i32); struct Struct { field: i32, @@ -50,6 +53,19 @@ fn get_drop_struct() -> DropStruct { DropStruct { field: 0 } } +struct Cout; + +impl<T> Shl<T> for Cout +where + T: Display, +{ + type Output = Self; + fn shl(self, rhs: T) -> Self::Output { + println!("{}", rhs); + self + } +} + fn main() { get_number(); get_number(); @@ -87,4 +103,7 @@ fn main() { ($($e:expr),*) => {{ $($e;)* }} } use_expr!(isize::MIN / -(one() as isize), i8::MIN / -one()); + + // Issue #11885 + Cout << 16; } diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.rs b/src/tools/clippy/tests/ui/unnecessary_operation.rs index e8e3a2d56..f0d28e289 100644 --- a/src/tools/clippy/tests/ui/unnecessary_operation.rs +++ b/src/tools/clippy/tests/ui/unnecessary_operation.rs @@ -7,6 +7,9 @@ )] #![warn(clippy::unnecessary_operation)] +use std::fmt::Display; +use std::ops::Shl; + struct Tuple(i32); struct Struct { field: i32, @@ -50,6 +53,19 @@ fn get_drop_struct() -> DropStruct { DropStruct { field: 0 } } +struct Cout; + +impl<T> Shl<T> for Cout +where + T: Display, +{ + type Output = Self; + fn shl(self, rhs: T) -> Self::Output { + println!("{}", rhs); + self + } +} + fn main() { Tuple(get_number()); Struct { field: get_number() }; @@ -91,4 +107,7 @@ fn main() { ($($e:expr),*) => {{ $($e;)* }} } use_expr!(isize::MIN / -(one() as isize), i8::MIN / -one()); + + // Issue #11885 + Cout << 16; } diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.stderr b/src/tools/clippy/tests/ui/unnecessary_operation.stderr index fbe495f51..eeee9ad60 100644 --- a/src/tools/clippy/tests/ui/unnecessary_operation.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_operation.stderr @@ -1,5 +1,5 @@ error: unnecessary operation - --> $DIR/unnecessary_operation.rs:54:5 + --> $DIR/unnecessary_operation.rs:70:5 | LL | Tuple(get_number()); | ^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` @@ -8,103 +8,103 @@ LL | Tuple(get_number()); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_operation)]` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:55:5 + --> $DIR/unnecessary_operation.rs:71:5 | LL | Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:56:5 + --> $DIR/unnecessary_operation.rs:72:5 | LL | Struct { ..get_struct() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_struct();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:57:5 + --> $DIR/unnecessary_operation.rs:73:5 | LL | Enum::Tuple(get_number()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:58:5 + --> $DIR/unnecessary_operation.rs:74:5 | LL | Enum::Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:59:5 + --> $DIR/unnecessary_operation.rs:75:5 | LL | 5 + get_number(); | ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:60:5 + --> $DIR/unnecessary_operation.rs:76:5 | LL | *&get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:61:5 + --> $DIR/unnecessary_operation.rs:77:5 | LL | &get_number(); | ^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:62:5 + --> $DIR/unnecessary_operation.rs:78:5 | LL | (5, 6, get_number()); | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;6;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:63:5 + --> $DIR/unnecessary_operation.rs:79:5 | LL | get_number()..; | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:64:5 + --> $DIR/unnecessary_operation.rs:80:5 | LL | ..get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:65:5 + --> $DIR/unnecessary_operation.rs:81:5 | LL | 5..get_number(); | ^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:66:5 + --> $DIR/unnecessary_operation.rs:82:5 | LL | [42, get_number()]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:67:5 + --> $DIR/unnecessary_operation.rs:83:5 | LL | [42, 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:68:5 + --> $DIR/unnecessary_operation.rs:84:5 | LL | (42, get_number()).1; | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:69:5 + --> $DIR/unnecessary_operation.rs:85:5 | LL | [get_number(); 55]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:70:5 + --> $DIR/unnecessary_operation.rs:86:5 | LL | [42; 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42; 55].len() > get_usize());` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:71:5 + --> $DIR/unnecessary_operation.rs:87:5 | LL | / { LL | | get_number() @@ -112,7 +112,7 @@ LL | | }; | |______^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:74:5 + --> $DIR/unnecessary_operation.rs:90:5 | LL | / FooString { LL | | s: String::from("blah"), diff --git a/src/tools/clippy/tests/ui/upper_case_acronyms.fixed b/src/tools/clippy/tests/ui/upper_case_acronyms.fixed index 460567b09..a8023ed00 100644 --- a/src/tools/clippy/tests/ui/upper_case_acronyms.fixed +++ b/src/tools/clippy/tests/ui/upper_case_acronyms.fixed @@ -59,4 +59,12 @@ enum Yaml { Str(String), } +// test for issue #7708 +enum AllowOnField { + Disallow, + //~^ ERROR: name `DISALLOW` contains a capitalized acronym + #[allow(clippy::upper_case_acronyms)] + ALLOW, +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/upper_case_acronyms.rs b/src/tools/clippy/tests/ui/upper_case_acronyms.rs index 6a20aee62..c4711b87e 100644 --- a/src/tools/clippy/tests/ui/upper_case_acronyms.rs +++ b/src/tools/clippy/tests/ui/upper_case_acronyms.rs @@ -59,4 +59,12 @@ enum YAML { Str(String), } +// test for issue #7708 +enum AllowOnField { + DISALLOW, + //~^ ERROR: name `DISALLOW` contains a capitalized acronym + #[allow(clippy::upper_case_acronyms)] + ALLOW, +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/upper_case_acronyms.stderr b/src/tools/clippy/tests/ui/upper_case_acronyms.stderr index c57b325e9..009c53c72 100644 --- a/src/tools/clippy/tests/ui/upper_case_acronyms.stderr +++ b/src/tools/clippy/tests/ui/upper_case_acronyms.stderr @@ -67,5 +67,11 @@ error: name `YAML` contains a capitalized acronym LL | enum YAML { | ^^^^ help: consider making the acronym lowercase, except the initial letter: `Yaml` -error: aborting due to 11 previous errors +error: name `DISALLOW` contains a capitalized acronym + --> $DIR/upper_case_acronyms.rs:64:5 + | +LL | DISALLOW, + | ^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `Disallow` + +error: aborting due to 12 previous errors diff --git a/src/tools/clippy/tests/ui/vec.fixed b/src/tools/clippy/tests/ui/vec.fixed index bcbca971a..81b8bd7da 100644 --- a/src/tools/clippy/tests/ui/vec.fixed +++ b/src/tools/clippy/tests/ui/vec.fixed @@ -176,3 +176,37 @@ fn below() { let _: String = a; } } + +fn func_needing_vec(_bar: usize, _baz: Vec<usize>) {} +fn func_not_needing_vec(_bar: usize, _baz: usize) {} + +fn issue11861() { + macro_rules! this_macro_needs_vec { + ($x:expr) => {{ + func_needing_vec($x.iter().sum(), $x); + for _ in $x {} + }}; + } + macro_rules! this_macro_doesnt_need_vec { + ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }}; + } + + // Do not lint the next line + this_macro_needs_vec!(vec![1]); + this_macro_doesnt_need_vec!([1]); //~ ERROR: useless use of `vec!` + + macro_rules! m { + ($x:expr) => { + fn f2() { + let _x: Vec<i32> = $x; + } + fn f() { + let _x = $x; + $x.starts_with(&[]); + } + }; + } + + // should not lint + m!(vec![1]); +} diff --git a/src/tools/clippy/tests/ui/vec.rs b/src/tools/clippy/tests/ui/vec.rs index 087425585..5aca9b292 100644 --- a/src/tools/clippy/tests/ui/vec.rs +++ b/src/tools/clippy/tests/ui/vec.rs @@ -176,3 +176,37 @@ fn below() { let _: String = a; } } + +fn func_needing_vec(_bar: usize, _baz: Vec<usize>) {} +fn func_not_needing_vec(_bar: usize, _baz: usize) {} + +fn issue11861() { + macro_rules! this_macro_needs_vec { + ($x:expr) => {{ + func_needing_vec($x.iter().sum(), $x); + for _ in $x {} + }}; + } + macro_rules! this_macro_doesnt_need_vec { + ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }}; + } + + // Do not lint the next line + this_macro_needs_vec!(vec![1]); + this_macro_doesnt_need_vec!(vec![1]); //~ ERROR: useless use of `vec!` + + macro_rules! m { + ($x:expr) => { + fn f2() { + let _x: Vec<i32> = $x; + } + fn f() { + let _x = $x; + $x.starts_with(&[]); + } + }; + } + + // should not lint + m!(vec![1]); +} diff --git a/src/tools/clippy/tests/ui/vec.stderr b/src/tools/clippy/tests/ui/vec.stderr index fc261838f..c9018f94f 100644 --- a/src/tools/clippy/tests/ui/vec.stderr +++ b/src/tools/clippy/tests/ui/vec.stderr @@ -115,5 +115,11 @@ error: useless use of `vec!` LL | for a in vec![String::new(), String::new()] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` -error: aborting due to 19 previous errors +error: useless use of `vec!` + --> $DIR/vec.rs:196:33 + | +LL | this_macro_doesnt_need_vec!(vec![1]); + | ^^^^^^^ help: you can use an array directly: `[1]` + +error: aborting due to 20 previous errors diff --git a/src/tools/clippy/tests/ui/vec_box_sized.fixed b/src/tools/clippy/tests/ui/vec_box_sized.fixed deleted file mode 100644 index 4363d2224..000000000 --- a/src/tools/clippy/tests/ui/vec_box_sized.fixed +++ /dev/null @@ -1,57 +0,0 @@ -#![allow(dead_code)] - -struct SizedStruct(i32); -struct UnsizedStruct([i32]); -struct BigStruct([i32; 10000]); - -/// The following should trigger the lint -mod should_trigger { - use super::SizedStruct; - const C: Vec<i32> = Vec::new(); - static S: Vec<i32> = Vec::new(); - - struct StructWithVecBox { - sized_type: Vec<SizedStruct>, - } - - struct A(Vec<SizedStruct>); - struct B(Vec<Vec<u32>>); -} - -/// The following should not trigger the lint -mod should_not_trigger { - use super::{BigStruct, UnsizedStruct}; - - struct C(Vec<Box<UnsizedStruct>>); - struct D(Vec<Box<BigStruct>>); - - struct StructWithVecBoxButItsUnsized { - unsized_type: Vec<Box<UnsizedStruct>>, - } - - struct TraitVec<T: ?Sized> { - // Regression test for #3720. This was causing an ICE. - inner: Vec<Box<T>>, - } -} - -mod inner_mod { - mod inner { - pub struct S; - } - - mod inner2 { - use super::inner::S; - - pub fn f() -> Vec<S> { - vec![] - } - } -} - -// https://github.com/rust-lang/rust-clippy/issues/11417 -fn in_closure() { - let _ = |_: Vec<Box<dyn ToString>>| {}; -} - -fn main() {} diff --git a/src/tools/clippy/tests/ui/vec_box_sized.rs b/src/tools/clippy/tests/ui/vec_box_sized.rs index f4e27fe4b..49eaf8e06 100644 --- a/src/tools/clippy/tests/ui/vec_box_sized.rs +++ b/src/tools/clippy/tests/ui/vec_box_sized.rs @@ -1,12 +1,28 @@ +//@no-rustfix + #![allow(dead_code)] +#![feature(allocator_api)] + +use std::alloc::{AllocError, Allocator, Layout}; +use std::ptr::NonNull; struct SizedStruct(i32); struct UnsizedStruct([i32]); struct BigStruct([i32; 10000]); +struct DummyAllocator; +unsafe impl Allocator for DummyAllocator { + fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { + todo!() + } + unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { + todo!() + } +} + /// The following should trigger the lint mod should_trigger { - use super::SizedStruct; + use super::{DummyAllocator, SizedStruct}; const C: Vec<Box<i32>> = Vec::new(); static S: Vec<Box<i32>> = Vec::new(); @@ -16,11 +32,21 @@ mod should_trigger { struct A(Vec<Box<SizedStruct>>); struct B(Vec<Vec<Box<(u32)>>>); + + fn allocator_global_defined_vec() -> Vec<Box<i32>, std::alloc::Global> { + Vec::new() + } + fn allocator_global_defined_box() -> Vec<Box<i32, std::alloc::Global>> { + Vec::new() + } + fn allocator_match() -> Vec<Box<i32, DummyAllocator>, DummyAllocator> { + Vec::new_in(DummyAllocator) + } } /// The following should not trigger the lint mod should_not_trigger { - use super::{BigStruct, UnsizedStruct}; + use super::{BigStruct, DummyAllocator, UnsizedStruct}; struct C(Vec<Box<UnsizedStruct>>); struct D(Vec<Box<BigStruct>>); @@ -33,6 +59,13 @@ mod should_not_trigger { // Regression test for #3720. This was causing an ICE. inner: Vec<Box<T>>, } + + fn allocator_mismatch() -> Vec<Box<i32, DummyAllocator>> { + Vec::new() + } + fn allocator_mismatch_2() -> Vec<Box<i32>, DummyAllocator> { + Vec::new_in(DummyAllocator) + } } mod inner_mod { diff --git a/src/tools/clippy/tests/ui/vec_box_sized.stderr b/src/tools/clippy/tests/ui/vec_box_sized.stderr index 9118f284b..d6479271f 100644 --- a/src/tools/clippy/tests/ui/vec_box_sized.stderr +++ b/src/tools/clippy/tests/ui/vec_box_sized.stderr @@ -1,5 +1,5 @@ error: `Vec<T>` is already on the heap, the boxing is unnecessary - --> $DIR/vec_box_sized.rs:10:14 + --> $DIR/vec_box_sized.rs:26:14 | LL | const C: Vec<Box<i32>> = Vec::new(); | ^^^^^^^^^^^^^ help: try: `Vec<i32>` @@ -8,34 +8,52 @@ LL | const C: Vec<Box<i32>> = Vec::new(); = help: to override `-D warnings` add `#[allow(clippy::vec_box)]` error: `Vec<T>` is already on the heap, the boxing is unnecessary - --> $DIR/vec_box_sized.rs:11:15 + --> $DIR/vec_box_sized.rs:27:15 | LL | static S: Vec<Box<i32>> = Vec::new(); | ^^^^^^^^^^^^^ help: try: `Vec<i32>` error: `Vec<T>` is already on the heap, the boxing is unnecessary - --> $DIR/vec_box_sized.rs:14:21 + --> $DIR/vec_box_sized.rs:30:21 | LL | sized_type: Vec<Box<SizedStruct>>, | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<SizedStruct>` error: `Vec<T>` is already on the heap, the boxing is unnecessary - --> $DIR/vec_box_sized.rs:17:14 + --> $DIR/vec_box_sized.rs:33:14 | LL | struct A(Vec<Box<SizedStruct>>); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<SizedStruct>` error: `Vec<T>` is already on the heap, the boxing is unnecessary - --> $DIR/vec_box_sized.rs:18:18 + --> $DIR/vec_box_sized.rs:34:18 | LL | struct B(Vec<Vec<Box<(u32)>>>); | ^^^^^^^^^^^^^^^ help: try: `Vec<u32>` error: `Vec<T>` is already on the heap, the boxing is unnecessary - --> $DIR/vec_box_sized.rs:46:23 + --> $DIR/vec_box_sized.rs:36:42 + | +LL | fn allocator_global_defined_vec() -> Vec<Box<i32>, std::alloc::Global> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<i32>` + +error: `Vec<T>` is already on the heap, the boxing is unnecessary + --> $DIR/vec_box_sized.rs:39:42 + | +LL | fn allocator_global_defined_box() -> Vec<Box<i32, std::alloc::Global>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<i32>` + +error: `Vec<T>` is already on the heap, the boxing is unnecessary + --> $DIR/vec_box_sized.rs:42:29 + | +LL | fn allocator_match() -> Vec<Box<i32, DummyAllocator>, DummyAllocator> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<i32>` + +error: `Vec<T>` is already on the heap, the boxing is unnecessary + --> $DIR/vec_box_sized.rs:79:23 | LL | pub fn f() -> Vec<Box<S>> { | ^^^^^^^^^^^ help: try: `Vec<S>` -error: aborting due to 6 previous errors +error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr index 715c9923b..c16ba4e52 100644 --- a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr +++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr @@ -10,5 +10,5 @@ LL | v.resize(0, 5); = note: `-D clippy::vec-resize-to-zero` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::vec_resize_to_zero)]` -error: aborting due to previous error +error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/vtable_address_comparisons.rs b/src/tools/clippy/tests/ui/vtable_address_comparisons.rs deleted file mode 100644 index 75647c027..000000000 --- a/src/tools/clippy/tests/ui/vtable_address_comparisons.rs +++ /dev/null @@ -1,52 +0,0 @@ -use std::fmt::Debug; -use std::ptr; -use std::rc::Rc; -use std::sync::Arc; - -#[warn(clippy::vtable_address_comparisons)] -#[allow(clippy::borrow_as_ptr)] - -fn main() { - let a: *const dyn Debug = &1 as &dyn Debug; - let b: *const dyn Debug = &1 as &dyn Debug; - - // These should fail: - let _ = a == b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a != b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a < b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a <= b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a > b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a >= b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - ptr::eq(a, b); - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - - let a = &1 as &dyn Debug; - let b = &1 as &dyn Debug; - ptr::eq(a, b); - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - - // These should be fine: - let a = &1; - ptr::eq(a, a); - - let a = Rc::new(1); - Rc::ptr_eq(&a, &a); - - let a = Arc::new(1); - Arc::ptr_eq(&a, &a); - - let a: Rc<dyn Debug> = Rc::new(1); - Rc::ptr_eq(&a, &a); - - let a: Arc<dyn Debug> = Arc::new(1); - Arc::ptr_eq(&a, &a); - - let a: &[u8] = b""; - ptr::eq(a, a); -} diff --git a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr b/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr deleted file mode 100644 index 83c82f379..000000000 --- a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr +++ /dev/null @@ -1,68 +0,0 @@ -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:14:13 - | -LL | let _ = a == b; - | ^^^^^^ - | - = help: consider extracting and comparing data pointers only - = note: `-D clippy::vtable-address-comparisons` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::vtable_address_comparisons)]` - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:16:13 - | -LL | let _ = a != b; - | ^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:18:13 - | -LL | let _ = a < b; - | ^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:20:13 - | -LL | let _ = a <= b; - | ^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:22:13 - | -LL | let _ = a > b; - | ^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:24:13 - | -LL | let _ = a >= b; - | ^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:26:5 - | -LL | ptr::eq(a, b); - | ^^^^^^^^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:31:5 - | -LL | ptr::eq(a, b); - | ^^^^^^^^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: aborting due to 8 previous errors - |