diff options
Diffstat (limited to 'src/tools/clippy/tests/ui')
74 files changed, 1484 insertions, 142 deletions
diff --git a/src/tools/clippy/tests/ui/assign_ops.fixed b/src/tools/clippy/tests/ui/assign_ops.fixed index 3bc6885d7c3..99beea850a2 100644 --- a/src/tools/clippy/tests/ui/assign_ops.fixed +++ b/src/tools/clippy/tests/ui/assign_ops.fixed @@ -91,7 +91,7 @@ mod issue14871 { impl<T> const NumberConstants for T where - T: Number + ~const core::ops::Add, + T: Number + [const] core::ops::Add, { fn constant(value: usize) -> Self { let mut res = Self::ZERO; diff --git a/src/tools/clippy/tests/ui/assign_ops.rs b/src/tools/clippy/tests/ui/assign_ops.rs index f1f8f9daff9..900d5ad38e0 100644 --- a/src/tools/clippy/tests/ui/assign_ops.rs +++ b/src/tools/clippy/tests/ui/assign_ops.rs @@ -91,7 +91,7 @@ mod issue14871 { impl<T> const NumberConstants for T where - T: Number + ~const core::ops::Add, + T: Number + [const] core::ops::Add, { fn constant(value: usize) -> Self { let mut res = Self::ZERO; diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.fixed b/src/tools/clippy/tests/ui/borrow_deref_ref.fixed index 765dd75fceb..6d06fcc3037 100644 --- a/src/tools/clippy/tests/ui/borrow_deref_ref.fixed +++ b/src/tools/clippy/tests/ui/borrow_deref_ref.fixed @@ -124,3 +124,50 @@ mod issue_11346 { //~^ borrow_deref_ref } } + +fn issue_14934() { + let x: &'static str = "x"; + let y = "y".to_string(); + { + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = &*x; // Do not lint + *x = &*y; + } + { + let mut x = x; + //~^ borrow_deref_ref + x = &*y; + } + { + #[expect(clippy::toplevel_ref_arg, clippy::needless_borrow)] + let ref x = x; + //~^ borrow_deref_ref + } + { + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = std::convert::identity(x); + //~^ borrow_deref_ref + *x = &*y; + } + { + #[derive(Clone)] + struct S(&'static str); + let s = S("foo"); + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = &*s.0; // Do not lint + *x = "bar"; + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = s.clone().0; + //~^ borrow_deref_ref + *x = "bar"; + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = &*std::convert::identity(&s).0; + *x = "bar"; + } + { + let y = &1; + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = { y }; + //~^ borrow_deref_ref + } +} diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.rs b/src/tools/clippy/tests/ui/borrow_deref_ref.rs index 8ee66bfa881..b43f4c93bf2 100644 --- a/src/tools/clippy/tests/ui/borrow_deref_ref.rs +++ b/src/tools/clippy/tests/ui/borrow_deref_ref.rs @@ -124,3 +124,50 @@ mod issue_11346 { //~^ borrow_deref_ref } } + +fn issue_14934() { + let x: &'static str = "x"; + let y = "y".to_string(); + { + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = &*x; // Do not lint + *x = &*y; + } + { + let mut x = &*x; + //~^ borrow_deref_ref + x = &*y; + } + { + #[expect(clippy::toplevel_ref_arg, clippy::needless_borrow)] + let ref x = &*x; + //~^ borrow_deref_ref + } + { + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = &*std::convert::identity(x); + //~^ borrow_deref_ref + *x = &*y; + } + { + #[derive(Clone)] + struct S(&'static str); + let s = S("foo"); + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = &*s.0; // Do not lint + *x = "bar"; + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = &*s.clone().0; + //~^ borrow_deref_ref + *x = "bar"; + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = &*std::convert::identity(&s).0; + *x = "bar"; + } + { + let y = &1; + #[expect(clippy::toplevel_ref_arg)] + let ref mut x = { &*y }; + //~^ borrow_deref_ref + } +} diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.stderr b/src/tools/clippy/tests/ui/borrow_deref_ref.stderr index 3d55da25b9b..3a1f968b4be 100644 --- a/src/tools/clippy/tests/ui/borrow_deref_ref.stderr +++ b/src/tools/clippy/tests/ui/borrow_deref_ref.stderr @@ -25,5 +25,35 @@ error: deref on an immutable reference LL | (&*s).foo(); | ^^^^^ help: if you would like to reborrow, try removing `&*`: `s` -error: aborting due to 4 previous errors +error: deref on an immutable reference + --> tests/ui/borrow_deref_ref.rs:137:21 + | +LL | let mut x = &*x; + | ^^^ help: if you would like to reborrow, try removing `&*`: `x` + +error: deref on an immutable reference + --> tests/ui/borrow_deref_ref.rs:143:21 + | +LL | let ref x = &*x; + | ^^^ help: if you would like to reborrow, try removing `&*`: `x` + +error: deref on an immutable reference + --> tests/ui/borrow_deref_ref.rs:148:25 + | +LL | let ref mut x = &*std::convert::identity(x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you would like to reborrow, try removing `&*`: `std::convert::identity(x)` + +error: deref on an immutable reference + --> tests/ui/borrow_deref_ref.rs:160:25 + | +LL | let ref mut x = &*s.clone().0; + | ^^^^^^^^^^^^^ help: if you would like to reborrow, try removing `&*`: `s.clone().0` + +error: deref on an immutable reference + --> tests/ui/borrow_deref_ref.rs:170:27 + | +LL | let ref mut x = { &*y }; + | ^^^ help: if you would like to reborrow, try removing `&*`: `y` + +error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs index 0f439f78915..674450a73ad 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs @@ -218,4 +218,20 @@ fn main() { let _ = &S::VALUE.1; //~ borrow_interior_mutable_const let _ = &S::VALUE.2; } + { + pub struct Foo<T, const N: usize>(pub Entry<N>, pub T); + + pub struct Entry<const N: usize>(pub Cell<[u32; N]>); + + impl<const N: usize> Entry<N> { + const INIT: Self = Self(Cell::new([42; N])); + } + + impl<T, const N: usize> Foo<T, N> { + pub fn make_foo(v: T) -> Self { + // Used to ICE due to incorrect instantiation. + Foo(Entry::INIT, v) + } + } + } } diff --git a/src/tools/clippy/tests/ui/box_default.fixed b/src/tools/clippy/tests/ui/box_default.fixed index 80000f5de4f..ed00494433b 100644 --- a/src/tools/clippy/tests/ui/box_default.fixed +++ b/src/tools/clippy/tests/ui/box_default.fixed @@ -126,7 +126,7 @@ fn issue_10381() { impl Bar for Foo {} fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> { - if i % 2 == 0 { + if i.is_multiple_of(2) { Some(Box::new(Foo::default())) } else { None diff --git a/src/tools/clippy/tests/ui/box_default.rs b/src/tools/clippy/tests/ui/box_default.rs index 4681016d7cd..801d92f5c29 100644 --- a/src/tools/clippy/tests/ui/box_default.rs +++ b/src/tools/clippy/tests/ui/box_default.rs @@ -126,7 +126,7 @@ fn issue_10381() { impl Bar for Foo {} fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> { - if i % 2 == 0 { + if i.is_multiple_of(2) { Some(Box::new(Foo::default())) } else { None diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.rs b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.rs index 922d30443fc..fa322dc28a7 100644 --- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.rs +++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.rs @@ -276,3 +276,27 @@ mod issue14873 { } } } + +fn issue15004() { + let a = 12u32; + let b = 13u32; + let mut c = 8u32; + + let mut result = if b > a { + c += 1; + 0 + } else { + c += 2; + 0 + //~^ branches_sharing_code + }; + + result = if b > a { + c += 1; + 1 + } else { + c += 2; + 1 + //~^ branches_sharing_code + }; +} diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr index f437db8b733..1c470fb0da5 100644 --- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr +++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr @@ -172,5 +172,35 @@ LL ~ } LL + let y = 1; | -error: aborting due to 10 previous errors +error: all if blocks contain the same code at the end + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:290:5 + | +LL | / 0 +LL | | +LL | | }; + | |_____^ + | + = note: the end suggestion probably needs some adjustments to use the expression result correctly +help: consider moving these statements after the if + | +LL ~ } +LL ~ 0; + | + +error: all if blocks contain the same code at the end + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:299:5 + | +LL | / 1 +LL | | +LL | | }; + | |_____^ + | + = note: the end suggestion probably needs some adjustments to use the expression result correctly +help: consider moving these statements after the if + | +LL ~ } +LL ~ 1; + | + +error: aborting due to 12 previous errors diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.fixed b/src/tools/clippy/tests/ui/collapsible_else_if.fixed index 9f530ad670a..fed75244c6f 100644 --- a/src/tools/clippy/tests/ui/collapsible_else_if.fixed +++ b/src/tools/clippy/tests/ui/collapsible_else_if.fixed @@ -86,3 +86,21 @@ fn issue_7318() { }else if false {} //~^^^ collapsible_else_if } + +fn issue14799() { + use std::ops::ControlFlow; + + let c: ControlFlow<_, ()> = ControlFlow::Break(Some(42)); + if let ControlFlow::Break(Some(_)) = c { + todo!(); + } else { + #[cfg(target_os = "freebsd")] + todo!(); + + if let ControlFlow::Break(None) = c { + todo!(); + } else { + todo!(); + } + } +} diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.rs b/src/tools/clippy/tests/ui/collapsible_else_if.rs index 2c646cd1d4d..e50e781fb69 100644 --- a/src/tools/clippy/tests/ui/collapsible_else_if.rs +++ b/src/tools/clippy/tests/ui/collapsible_else_if.rs @@ -102,3 +102,21 @@ fn issue_7318() { } //~^^^ collapsible_else_if } + +fn issue14799() { + use std::ops::ControlFlow; + + let c: ControlFlow<_, ()> = ControlFlow::Break(Some(42)); + if let ControlFlow::Break(Some(_)) = c { + todo!(); + } else { + #[cfg(target_os = "freebsd")] + todo!(); + + if let ControlFlow::Break(None) = c { + todo!(); + } else { + todo!(); + } + } +} diff --git a/src/tools/clippy/tests/ui/collapsible_if.fixed b/src/tools/clippy/tests/ui/collapsible_if.fixed index b553182a445..77bc791ea8e 100644 --- a/src/tools/clippy/tests/ui/collapsible_if.fixed +++ b/src/tools/clippy/tests/ui/collapsible_if.fixed @@ -154,3 +154,12 @@ fn issue14722() { None }; } + +fn issue14799() { + if true { + #[cfg(target_os = "freebsd")] + todo!(); + + if true {} + }; +} diff --git a/src/tools/clippy/tests/ui/collapsible_if.rs b/src/tools/clippy/tests/ui/collapsible_if.rs index f5998457ca6..d30df157d5e 100644 --- a/src/tools/clippy/tests/ui/collapsible_if.rs +++ b/src/tools/clippy/tests/ui/collapsible_if.rs @@ -164,3 +164,12 @@ fn issue14722() { None }; } + +fn issue14799() { + if true { + #[cfg(target_os = "freebsd")] + todo!(); + + if true {} + }; +} diff --git a/src/tools/clippy/tests/ui/doc/needless_doctest_main.rs b/src/tools/clippy/tests/ui/doc/needless_doctest_main.rs index 633a435ca5e..8c3217624d4 100644 --- a/src/tools/clippy/tests/ui/doc/needless_doctest_main.rs +++ b/src/tools/clippy/tests/ui/doc/needless_doctest_main.rs @@ -1,5 +1,3 @@ -//@ check-pass - #![warn(clippy::needless_doctest_main)] //! issue 10491: //! ```rust,no_test @@ -19,4 +17,114 @@ /// ``` fn foo() {} +#[rustfmt::skip] +/// Description +/// ```rust +/// fn main() { +//~^ error: needless `fn main` in doctest +/// let a = 0; +/// } +/// ``` +fn mulpipulpi() {} + +#[rustfmt::skip] +/// With a `#[no_main]` +/// ```rust +/// #[no_main] +/// fn a() { +/// let _ = 0; +/// } +/// ``` +fn pulpimulpi() {} + +// Without a `#[no_main]` attribute +/// ```rust +/// fn a() { +/// let _ = 0; +/// } +/// ``` +fn plumilupi() {} + +#[rustfmt::skip] +/// Additional function, shouldn't trigger +/// ```rust +/// fn additional_function() { +/// let _ = 0; +/// // Thus `fn main` is actually relevant! +/// } +/// fn main() { +/// let _ = 0; +/// } +/// ``` +fn mlupipupi() {} + +#[rustfmt::skip] +/// Additional function AFTER main, shouldn't trigger +/// ```rust +/// fn main() { +/// let _ = 0; +/// } +/// fn additional_function() { +/// let _ = 0; +/// // Thus `fn main` is actually relevant! +/// } +/// ``` +fn lumpimupli() {} + +#[rustfmt::skip] +/// Ignore code block, should not lint at all +/// ```rust, ignore +/// fn main() { +//~^ error: needless `fn main` in doctest +/// // Hi! +/// let _ = 0; +/// } +/// ``` +fn mpulpilumi() {} + +#[rustfmt::skip] +/// Spaces in weird positions (including an \u{A0} after `main`) +/// ```rust +/// fn main (){ +//~^ error: needless `fn main` in doctest +/// let _ = 0; +/// } +/// ``` +fn plumpiplupi() {} + +/// 4 Functions, this should not lint because there are several function +/// +/// ```rust +/// fn a() {let _ = 0; } +/// fn b() {let _ = 0; } +/// fn main() { let _ = 0; } +/// fn d() { let _ = 0; } +/// ``` +fn pulmipulmip() {} + +/// 3 Functions but main is first, should also not lint +/// +///```rust +/// fn main() { let _ = 0; } +/// fn b() { let _ = 0; } +/// fn c() { let _ = 0; } +/// ``` +fn pmuplimulip() {} + fn main() {} + +fn issue8244() -> Result<(), ()> { + //! ```compile_fail + //! fn test() -> Result< {} + //! ``` + Ok(()) +} + +/// # Examples +/// +/// ``` +/// use std::error::Error; +/// fn main() -> Result<(), Box<dyn Error>/* > */ { +/// } +/// ``` +fn issue15041() {} diff --git a/src/tools/clippy/tests/ui/doc/needless_doctest_main.stderr b/src/tools/clippy/tests/ui/doc/needless_doctest_main.stderr new file mode 100644 index 00000000000..dd5474ccb85 --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/needless_doctest_main.stderr @@ -0,0 +1,36 @@ +error: needless `fn main` in doctest + --> tests/ui/doc/needless_doctest_main.rs:23:5 + | +LL | /// fn main() { + | _____^ +LL | | +LL | | /// let a = 0; +LL | | /// } + | |_____^ + | + = note: `-D clippy::needless-doctest-main` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_doctest_main)]` + +error: needless `fn main` in doctest + --> tests/ui/doc/needless_doctest_main.rs:77:5 + | +LL | /// fn main() { + | _____^ +LL | | +LL | | /// // Hi! +LL | | /// let _ = 0; +LL | | /// } + | |_____^ + +error: needless `fn main` in doctest + --> tests/ui/doc/needless_doctest_main.rs:88:5 + | +LL | /// fn main (){ + | _____^ +LL | | +LL | | /// let _ = 0; +LL | | /// } + | |_____^ + +error: aborting due to 3 previous errors + diff --git a/src/tools/clippy/tests/ui/doc_broken_link.rs b/src/tools/clippy/tests/ui/doc_broken_link.rs new file mode 100644 index 00000000000..7d9c0ef13b3 --- /dev/null +++ b/src/tools/clippy/tests/ui/doc_broken_link.rs @@ -0,0 +1,72 @@ +#![warn(clippy::doc_broken_link)] + +fn main() {} + +pub struct FakeType {} + +/// This might be considered a link false positive +/// and should be ignored by this lint rule: +/// Example of referencing some code with brackets [FakeType]. +pub fn doc_ignore_link_false_positive_1() {} + +/// This might be considered a link false positive +/// and should be ignored by this lint rule: +/// [`FakeType`]. Continue text after brackets, +/// then (something in +/// parenthesis). +pub fn doc_ignore_link_false_positive_2() {} + +/// Test valid link, whole link single line. +/// [doc valid link](https://test.fake/doc_valid_link) +pub fn doc_valid_link() {} + +/// Test valid link, whole link single line but it has special chars such as brackets and +/// parenthesis. [doc invalid link url invalid char](https://test.fake/doc_valid_link_url_invalid_char?foo[bar]=1&bar(foo)=2) +pub fn doc_valid_link_url_invalid_char() {} + +/// Test valid link, text tag broken across multiple lines. +/// [doc valid link broken +/// text](https://test.fake/doc_valid_link_broken_text) +pub fn doc_valid_link_broken_text() {} + +/// Test valid link, url tag broken across multiple lines, but +/// the whole url part in a single line. +/// [doc valid link broken url tag two lines first](https://test.fake/doc_valid_link_broken_url_tag_two_lines_first +/// ) +pub fn doc_valid_link_broken_url_tag_two_lines_first() {} + +/// Test valid link, url tag broken across multiple lines, but +/// the whole url part in a single line. +/// [doc valid link broken url tag two lines second]( +/// https://test.fake/doc_valid_link_broken_url_tag_two_lines_second) +pub fn doc_valid_link_broken_url_tag_two_lines_second() {} + +/// Test valid link, url tag broken across multiple lines, but +/// the whole url part in a single line, but the closing pharentesis +/// in a third line. +/// [doc valid link broken url tag three lines]( +/// https://test.fake/doc_valid_link_broken_url_tag_three_lines +/// ) +pub fn doc_valid_link_broken_url_tag_three_lines() {} + +/// Test invalid link, url part broken across multiple lines. +/// [doc invalid link broken url scheme part](https:// +/// test.fake/doc_invalid_link_broken_url_scheme_part) +//~^^ ERROR: possible broken doc link: broken across multiple lines +pub fn doc_invalid_link_broken_url_scheme_part() {} + +/// Test invalid link, url part broken across multiple lines. +/// [doc invalid link broken url host part](https://test +/// .fake/doc_invalid_link_broken_url_host_part) +//~^^ ERROR: possible broken doc link: broken across multiple lines +pub fn doc_invalid_link_broken_url_host_part() {} + +/// Test invalid link, for multiple urls in the same block of comment. +/// There is a [fist link - invalid](https://test +/// .fake) then it continues +//~^^ ERROR: possible broken doc link: broken across multiple lines +/// with a [second link - valid](https://test.fake/doc_valid_link) and another [third link - invalid](https://test +/// .fake). It ends with another +//~^^ ERROR: possible broken doc link: broken across multiple lines +/// line of comment. +pub fn doc_multiple_invalid_link_broken_url() {} diff --git a/src/tools/clippy/tests/ui/doc_broken_link.stderr b/src/tools/clippy/tests/ui/doc_broken_link.stderr new file mode 100644 index 00000000000..179ed97635e --- /dev/null +++ b/src/tools/clippy/tests/ui/doc_broken_link.stderr @@ -0,0 +1,29 @@ +error: possible broken doc link: broken across multiple lines + --> tests/ui/doc_broken_link.rs:53:5 + | +LL | /// [doc invalid link broken url scheme part](https:// + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::doc-broken-link` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_broken_link)]` + +error: possible broken doc link: broken across multiple lines + --> tests/ui/doc_broken_link.rs:59:5 + | +LL | /// [doc invalid link broken url host part](https://test + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: possible broken doc link: broken across multiple lines + --> tests/ui/doc_broken_link.rs:65:16 + | +LL | /// There is a [fist link - invalid](https://test + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: possible broken doc link: broken across multiple lines + --> tests/ui/doc_broken_link.rs:68:80 + | +LL | /// with a [second link - valid](https://test.fake/doc_valid_link) and another [third link - invalid](https://test + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.1.fixed b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.1.fixed index 36d80a2c95b..e36e3c2aea6 100644 --- a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.1.fixed +++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.1.fixed @@ -105,4 +105,13 @@ second line ")] pub struct Args; +mod issue_14980 { + //~v empty_line_after_outer_attr + #[repr(align(536870912))] + enum Aligned { + Zero = 0, + One = 1, + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.2.fixed b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.2.fixed index 0e8e4129e85..b0908fc7214 100644 --- a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.2.fixed +++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.2.fixed @@ -108,4 +108,13 @@ second line ")] pub struct Args; +mod issue_14980 { + //~v empty_line_after_outer_attr + #[repr(align(536870912))] + enum Aligned { + Zero = 0, + One = 1, + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.rs b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.rs index 1295088ac00..4ae113c68f5 100644 --- a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.rs +++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.rs @@ -116,4 +116,14 @@ second line ")] pub struct Args; +mod issue_14980 { + //~v empty_line_after_outer_attr + #[repr(align(536870912))] + + enum Aligned { + Zero = 0, + One = 1, + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr index 519ba6e6761..331bc7c8856 100644 --- a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr +++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr @@ -111,5 +111,16 @@ LL | pub fn isolated_comment() {} | = help: if the empty lines are unintentional, remove them -error: aborting due to 9 previous errors +error: empty line after outer attribute + --> tests/ui/empty_line_after/outer_attribute.rs:121:5 + | +LL | / #[repr(align(536870912))] +LL | | + | |_^ +LL | enum Aligned { + | ------------ the attribute applies to this enum + | + = help: if the empty line is unintentional, remove it + +error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed index 0ba631fda05..c93b83f53ec 100644 --- a/src/tools/clippy/tests/ui/eta.fixed +++ b/src/tools/clippy/tests/ui/eta.fixed @@ -543,3 +543,21 @@ mod issue_13073 { //~^ redundant_closure } } + +fn issue_14789() { + _ = Some(1u8).map( + #[expect(clippy::redundant_closure)] + |a| foo(a), + ); + + _ = Some("foo").map( + #[expect(clippy::redundant_closure_for_method_calls)] + |s| s.to_owned(), + ); + + let _: Vec<u8> = None.map_or_else( + #[expect(clippy::redundant_closure)] + || vec![], + std::convert::identity, + ); +} diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs index 4d8b29d450c..273c8b21f4a 100644 --- a/src/tools/clippy/tests/ui/eta.rs +++ b/src/tools/clippy/tests/ui/eta.rs @@ -543,3 +543,21 @@ mod issue_13073 { //~^ redundant_closure } } + +fn issue_14789() { + _ = Some(1u8).map( + #[expect(clippy::redundant_closure)] + |a| foo(a), + ); + + _ = Some("foo").map( + #[expect(clippy::redundant_closure_for_method_calls)] + |s| s.to_owned(), + ); + + let _: Vec<u8> = None.map_or_else( + #[expect(clippy::redundant_closure)] + || vec![], + std::convert::identity, + ); +} diff --git a/src/tools/clippy/tests/ui/exhaustive_items.fixed b/src/tools/clippy/tests/ui/exhaustive_items.fixed index 79c74aeefbd..3b2f33dbd2c 100644 --- a/src/tools/clippy/tests/ui/exhaustive_items.fixed +++ b/src/tools/clippy/tests/ui/exhaustive_items.fixed @@ -1,3 +1,4 @@ +#![feature(default_field_values)] #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)] #![allow(unused)] @@ -90,3 +91,9 @@ pub mod structs { pub bar: String, } } + +pub mod issue14992 { + pub struct A { + pub a: isize = 42, + } +} diff --git a/src/tools/clippy/tests/ui/exhaustive_items.rs b/src/tools/clippy/tests/ui/exhaustive_items.rs index 4e851f4c492..b0a6a717076 100644 --- a/src/tools/clippy/tests/ui/exhaustive_items.rs +++ b/src/tools/clippy/tests/ui/exhaustive_items.rs @@ -1,3 +1,4 @@ +#![feature(default_field_values)] #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)] #![allow(unused)] @@ -87,3 +88,9 @@ pub mod structs { pub bar: String, } } + +pub mod issue14992 { + pub struct A { + pub a: isize = 42, + } +} diff --git a/src/tools/clippy/tests/ui/exhaustive_items.stderr b/src/tools/clippy/tests/ui/exhaustive_items.stderr index c92c8a9efaa..55928fa458d 100644 --- a/src/tools/clippy/tests/ui/exhaustive_items.stderr +++ b/src/tools/clippy/tests/ui/exhaustive_items.stderr @@ -1,5 +1,5 @@ error: exported enums should not be exhaustive - --> tests/ui/exhaustive_items.rs:9:5 + --> tests/ui/exhaustive_items.rs:10:5 | LL | / pub enum Exhaustive { LL | | @@ -11,7 +11,7 @@ LL | | } | |_____^ | note: the lint level is defined here - --> tests/ui/exhaustive_items.rs:1:9 + --> tests/ui/exhaustive_items.rs:2:9 | LL | #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL ~ pub enum Exhaustive { | error: exported enums should not be exhaustive - --> tests/ui/exhaustive_items.rs:19:5 + --> tests/ui/exhaustive_items.rs:20:5 | LL | / pub enum ExhaustiveWithAttrs { LL | | @@ -40,7 +40,7 @@ LL ~ pub enum ExhaustiveWithAttrs { | error: exported structs should not be exhaustive - --> tests/ui/exhaustive_items.rs:55:5 + --> tests/ui/exhaustive_items.rs:56:5 | LL | / pub struct Exhaustive { LL | | @@ -50,7 +50,7 @@ LL | | } | |_____^ | note: the lint level is defined here - --> tests/ui/exhaustive_items.rs:1:35 + --> tests/ui/exhaustive_items.rs:2:35 | LL | #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/identity_op.fixed b/src/tools/clippy/tests/ui/identity_op.fixed index a1b55602998..4e14e1a5e33 100644 --- a/src/tools/clippy/tests/ui/identity_op.fixed +++ b/src/tools/clippy/tests/ui/identity_op.fixed @@ -312,3 +312,49 @@ fn issue_13470() { let _: u64 = 1u64 + ((x as i32 + y as i32) as u64); //~^ identity_op } + +fn issue_14932() { + let _ = 0usize + &Default::default(); // no error + + 0usize + &Default::default(); // no error + + <usize as Default>::default(); + //~^ identity_op + + let _ = usize::default(); + //~^ identity_op + + let _n: usize = Default::default(); + //~^ identity_op +} + +// Expr's type can be inferred by the function's return type +fn issue_14932_2() -> usize { + Default::default() + //~^ identity_op +} + +trait Def { + fn def() -> Self; +} + +impl Def for usize { + fn def() -> Self { + 0 + } +} + +fn issue_14932_3() { + let _ = 0usize + &Def::def(); // no error + + 0usize + &Def::def(); // no error + + <usize as Def>::def(); + //~^ identity_op + + let _ = usize::def(); + //~^ identity_op + + let _n: usize = Def::def(); + //~^ identity_op +} diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs index f603e1078e4..ebbef5723ff 100644 --- a/src/tools/clippy/tests/ui/identity_op.rs +++ b/src/tools/clippy/tests/ui/identity_op.rs @@ -312,3 +312,49 @@ fn issue_13470() { let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64); //~^ identity_op } + +fn issue_14932() { + let _ = 0usize + &Default::default(); // no error + + 0usize + &Default::default(); // no error + + 0usize + &<usize as Default>::default(); + //~^ identity_op + + let _ = 0usize + &usize::default(); + //~^ identity_op + + let _n: usize = 0usize + &Default::default(); + //~^ identity_op +} + +// Expr's type can be inferred by the function's return type +fn issue_14932_2() -> usize { + 0usize + &Default::default() + //~^ identity_op +} + +trait Def { + fn def() -> Self; +} + +impl Def for usize { + fn def() -> Self { + 0 + } +} + +fn issue_14932_3() { + let _ = 0usize + &Def::def(); // no error + + 0usize + &Def::def(); // no error + + 0usize + &<usize as Def>::def(); + //~^ identity_op + + let _ = 0usize + &usize::def(); + //~^ identity_op + + let _n: usize = 0usize + &Def::def(); + //~^ identity_op +} diff --git a/src/tools/clippy/tests/ui/identity_op.stderr b/src/tools/clippy/tests/ui/identity_op.stderr index 8f9c2b603c4..24fa5db08ce 100644 --- a/src/tools/clippy/tests/ui/identity_op.stderr +++ b/src/tools/clippy/tests/ui/identity_op.stderr @@ -379,5 +379,47 @@ error: this operation has no effect LL | let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x as i32 + y as i32) as u64)` -error: aborting due to 63 previous errors +error: this operation has no effect + --> tests/ui/identity_op.rs:321:5 + | +LL | 0usize + &<usize as Default>::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `<usize as Default>::default()` + +error: this operation has no effect + --> tests/ui/identity_op.rs:324:13 + | +LL | let _ = 0usize + &usize::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `usize::default()` + +error: this operation has no effect + --> tests/ui/identity_op.rs:327:21 + | +LL | let _n: usize = 0usize + &Default::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `Default::default()` + +error: this operation has no effect + --> tests/ui/identity_op.rs:333:5 + | +LL | 0usize + &Default::default() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `Default::default()` + +error: this operation has no effect + --> tests/ui/identity_op.rs:352:5 + | +LL | 0usize + &<usize as Def>::def(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `<usize as Def>::def()` + +error: this operation has no effect + --> tests/ui/identity_op.rs:355:13 + | +LL | let _ = 0usize + &usize::def(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `usize::def()` + +error: this operation has no effect + --> tests/ui/identity_op.rs:358:21 + | +LL | let _n: usize = 0usize + &Def::def(); + | ^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `Def::def()` + +error: aborting due to 70 previous errors diff --git a/src/tools/clippy/tests/ui/infinite_iter.rs b/src/tools/clippy/tests/ui/infinite_iter.rs index 002a791a657..701a86534ba 100644 --- a/src/tools/clippy/tests/ui/infinite_iter.rs +++ b/src/tools/clippy/tests/ui/infinite_iter.rs @@ -38,7 +38,7 @@ fn infinite_iters() { //~^ infinite_iter // infinite iter - (0_u64..).filter(|x| x % 2 == 0).last(); + (0_u64..).filter(|x| x.is_multiple_of(2)).last(); //~^ infinite_iter // not an infinite, because ranges are double-ended diff --git a/src/tools/clippy/tests/ui/infinite_iter.stderr b/src/tools/clippy/tests/ui/infinite_iter.stderr index 47133a2ea62..b9e7c008f93 100644 --- a/src/tools/clippy/tests/ui/infinite_iter.stderr +++ b/src/tools/clippy/tests/ui/infinite_iter.stderr @@ -42,8 +42,8 @@ LL | (0_usize..).flat_map(|x| 0..x).product::<usize>(); error: infinite iteration detected --> tests/ui/infinite_iter.rs:41:5 | -LL | (0_u64..).filter(|x| x % 2 == 0).last(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (0_u64..).filter(|x| x.is_multiple_of(2)).last(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: possible infinite iteration detected --> tests/ui/infinite_iter.rs:53:5 diff --git a/src/tools/clippy/tests/ui/iter_kv_map.fixed b/src/tools/clippy/tests/ui/iter_kv_map.fixed index 874f749b33d..b18dda35887 100644 --- a/src/tools/clippy/tests/ui/iter_kv_map.fixed +++ b/src/tools/clippy/tests/ui/iter_kv_map.fixed @@ -30,15 +30,19 @@ fn main() { let _ = map.clone().values().collect::<Vec<_>>(); //~^ iter_kv_map - let _ = map.keys().filter(|x| *x % 2 == 0).count(); + let _ = map.keys().filter(|x| x.is_multiple_of(2)).count(); //~^ iter_kv_map // Don't lint - let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count(); + let _ = map + .iter() + .filter(|(_, val)| val.is_multiple_of(2)) + .map(|(key, _)| key) + .count(); let _ = map.iter().map(get_key).collect::<Vec<_>>(); // Linting the following could be an improvement to the lint - // map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count(); + // map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count(); // Lint let _ = map.keys().map(|key| key * 9).count(); @@ -84,15 +88,19 @@ fn main() { let _ = map.clone().values().collect::<Vec<_>>(); //~^ iter_kv_map - let _ = map.keys().filter(|x| *x % 2 == 0).count(); + let _ = map.keys().filter(|x| x.is_multiple_of(2)).count(); //~^ iter_kv_map // Don't lint - let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count(); + let _ = map + .iter() + .filter(|(_, val)| val.is_multiple_of(2)) + .map(|(key, _)| key) + .count(); let _ = map.iter().map(get_key).collect::<Vec<_>>(); // Linting the following could be an improvement to the lint - // map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count(); + // map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count(); // Lint let _ = map.keys().map(|key| key * 9).count(); diff --git a/src/tools/clippy/tests/ui/iter_kv_map.rs b/src/tools/clippy/tests/ui/iter_kv_map.rs index f570e3c32cb..729e4e8a266 100644 --- a/src/tools/clippy/tests/ui/iter_kv_map.rs +++ b/src/tools/clippy/tests/ui/iter_kv_map.rs @@ -30,15 +30,19 @@ fn main() { let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>(); //~^ iter_kv_map - let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count(); + let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count(); //~^ iter_kv_map // Don't lint - let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count(); + let _ = map + .iter() + .filter(|(_, val)| val.is_multiple_of(2)) + .map(|(key, _)| key) + .count(); let _ = map.iter().map(get_key).collect::<Vec<_>>(); // Linting the following could be an improvement to the lint - // map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count(); + // map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count(); // Lint let _ = map.iter().map(|(key, _value)| key * 9).count(); @@ -86,15 +90,19 @@ fn main() { let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>(); //~^ iter_kv_map - let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count(); + let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count(); //~^ iter_kv_map // Don't lint - let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count(); + let _ = map + .iter() + .filter(|(_, val)| val.is_multiple_of(2)) + .map(|(key, _)| key) + .count(); let _ = map.iter().map(get_key).collect::<Vec<_>>(); // Linting the following could be an improvement to the lint - // map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count(); + // map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count(); // Lint let _ = map.iter().map(|(key, _value)| key * 9).count(); diff --git a/src/tools/clippy/tests/ui/iter_kv_map.stderr b/src/tools/clippy/tests/ui/iter_kv_map.stderr index 31ee76c25b7..8f73541f503 100644 --- a/src/tools/clippy/tests/ui/iter_kv_map.stderr +++ b/src/tools/clippy/tests/ui/iter_kv_map.stderr @@ -52,29 +52,29 @@ LL | let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>(); error: iterating on a map's keys --> tests/ui/iter_kv_map.rs:33:13 | -LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count(); +LL | let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:44:13 + --> tests/ui/iter_kv_map.rs:48:13 | LL | let _ = map.iter().map(|(key, _value)| key * 9).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:46:13 + --> tests/ui/iter_kv_map.rs:50:13 | LL | let _ = map.iter().map(|(_key, value)| value * 17).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:50:13 + --> tests/ui/iter_kv_map.rs:54:13 | LL | let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:54:13 + --> tests/ui/iter_kv_map.rs:58:13 | LL | let _ = map | _____________^ @@ -97,85 +97,85 @@ LL + }) | error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:65:13 + --> tests/ui/iter_kv_map.rs:69:13 | LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:70:13 + --> tests/ui/iter_kv_map.rs:74:13 | LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:72:13 + --> tests/ui/iter_kv_map.rs:76:13 | LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:74:13 + --> tests/ui/iter_kv_map.rs:78: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 - --> tests/ui/iter_kv_map.rs:77:13 + --> tests/ui/iter_kv_map.rs:81: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 - --> tests/ui/iter_kv_map.rs:79:13 + --> tests/ui/iter_kv_map.rs:83: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 - --> tests/ui/iter_kv_map.rs:82:13 + --> tests/ui/iter_kv_map.rs:86: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 - --> tests/ui/iter_kv_map.rs:84:13 + --> tests/ui/iter_kv_map.rs:88: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 values - --> tests/ui/iter_kv_map.rs:87:13 + --> tests/ui/iter_kv_map.rs:91:13 | LL | let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:89:13 + --> tests/ui/iter_kv_map.rs:93:13 | -LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count(); +LL | let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:100:13 + --> tests/ui/iter_kv_map.rs:108:13 | LL | let _ = map.iter().map(|(key, _value)| key * 9).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:102:13 + --> tests/ui/iter_kv_map.rs:110:13 | LL | let _ = map.iter().map(|(_key, value)| value * 17).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:106:13 + --> tests/ui/iter_kv_map.rs:114:13 | LL | let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:110:13 + --> tests/ui/iter_kv_map.rs:118:13 | LL | let _ = map | _____________^ @@ -198,73 +198,73 @@ LL + }) | error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:121:13 + --> tests/ui/iter_kv_map.rs:129:13 | LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` error: iterating on a map's keys - --> tests/ui/iter_kv_map.rs:137:13 + --> tests/ui/iter_kv_map.rs:145:13 | LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:140:13 + --> tests/ui/iter_kv_map.rs:148:13 | LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:143:13 + --> tests/ui/iter_kv_map.rs:151: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 - --> tests/ui/iter_kv_map.rs:152:13 + --> tests/ui/iter_kv_map.rs:160: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 - --> tests/ui/iter_kv_map.rs:155:13 + --> tests/ui/iter_kv_map.rs:163: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 - --> tests/ui/iter_kv_map.rs:158:13 + --> tests/ui/iter_kv_map.rs:166: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 - --> tests/ui/iter_kv_map.rs:161:13 + --> tests/ui/iter_kv_map.rs:169: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 - --> tests/ui/iter_kv_map.rs:164:13 + --> tests/ui/iter_kv_map.rs:172:13 | LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:167:13 + --> tests/ui/iter_kv_map.rs:175:13 | LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` error: iterating on a map's values - --> tests/ui/iter_kv_map.rs:170:13 + --> tests/ui/iter_kv_map.rs:178: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 values - --> tests/ui/iter_kv_map.rs:185:13 + --> tests/ui/iter_kv_map.rs:193:13 | LL | let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::<Vec<_>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.as_ref().values()` diff --git a/src/tools/clippy/tests/ui/let_unit.fixed b/src/tools/clippy/tests/ui/let_unit.fixed index 5e7a2ad37a8..304eacecd94 100644 --- a/src/tools/clippy/tests/ui/let_unit.fixed +++ b/src/tools/clippy/tests/ui/let_unit.fixed @@ -61,7 +61,7 @@ fn multiline_sugg() { //~^ let_unit_value .into_iter() .map(|i| i * 2) - .filter(|i| i % 2 == 0) + .filter(|i| i.is_multiple_of(2)) .map(|_| ()) .next() .unwrap(); diff --git a/src/tools/clippy/tests/ui/let_unit.rs b/src/tools/clippy/tests/ui/let_unit.rs index 7b06f694012..a02cb346ff9 100644 --- a/src/tools/clippy/tests/ui/let_unit.rs +++ b/src/tools/clippy/tests/ui/let_unit.rs @@ -61,7 +61,7 @@ fn multiline_sugg() { //~^ let_unit_value .into_iter() .map(|i| i * 2) - .filter(|i| i % 2 == 0) + .filter(|i| i.is_multiple_of(2)) .map(|_| ()) .next() .unwrap(); diff --git a/src/tools/clippy/tests/ui/let_unit.stderr b/src/tools/clippy/tests/ui/let_unit.stderr index d7d01d304ca..d743110c99d 100644 --- a/src/tools/clippy/tests/ui/let_unit.stderr +++ b/src/tools/clippy/tests/ui/let_unit.stderr @@ -25,7 +25,7 @@ LL ~ v LL + LL + .into_iter() LL + .map(|i| i * 2) -LL + .filter(|i| i % 2 == 0) +LL + .filter(|i| i.is_multiple_of(2)) LL + .map(|_| ()) LL + .next() LL + .unwrap(); diff --git a/src/tools/clippy/tests/ui/manual_contains.fixed b/src/tools/clippy/tests/ui/manual_contains.fixed index d26c948a781..18171f0b2b4 100644 --- a/src/tools/clippy/tests/ui/manual_contains.fixed +++ b/src/tools/clippy/tests/ui/manual_contains.fixed @@ -58,7 +58,7 @@ fn should_not_lint() { let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6]; let values = &vec[..]; - let _ = values.iter().any(|&v| v % 2 == 0); + let _ = values.iter().any(|&v| v.is_multiple_of(2)); let _ = values.iter().any(|&v| v * 2 == 6); let _ = values.iter().any(|&v| v == v); let _ = values.iter().any(|&v| 4 == 4); diff --git a/src/tools/clippy/tests/ui/manual_contains.rs b/src/tools/clippy/tests/ui/manual_contains.rs index fe67d2ee5d5..918f4d6b8dd 100644 --- a/src/tools/clippy/tests/ui/manual_contains.rs +++ b/src/tools/clippy/tests/ui/manual_contains.rs @@ -58,7 +58,7 @@ fn should_not_lint() { let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6]; let values = &vec[..]; - let _ = values.iter().any(|&v| v % 2 == 0); + let _ = values.iter().any(|&v| v.is_multiple_of(2)); let _ = values.iter().any(|&v| v * 2 == 6); let _ = values.iter().any(|&v| v == v); let _ = values.iter().any(|&v| 4 == 4); diff --git a/src/tools/clippy/tests/ui/manual_find_fixable.fixed b/src/tools/clippy/tests/ui/manual_find_fixable.fixed index 01b3ebacbeb..c69b0cb11e3 100644 --- a/src/tools/clippy/tests/ui/manual_find_fixable.fixed +++ b/src/tools/clippy/tests/ui/manual_find_fixable.fixed @@ -11,7 +11,7 @@ fn lookup(n: u32) -> Option<u32> { } fn with_pat(arr: Vec<(u32, u32)>) -> Option<u32> { - arr.into_iter().map(|(a, _)| a).find(|&a| a % 2 == 0) + arr.into_iter().map(|(a, _)| a).find(|&a| a.is_multiple_of(2)) } struct Data { @@ -63,7 +63,7 @@ fn with_side_effects(arr: Vec<u32>) -> Option<u32> { fn with_else(arr: Vec<u32>) -> Option<u32> { for el in arr { - if el % 2 == 0 { + if el.is_multiple_of(2) { return Some(el); } else { println!("{}", el); diff --git a/src/tools/clippy/tests/ui/manual_find_fixable.rs b/src/tools/clippy/tests/ui/manual_find_fixable.rs index ce62a4beba1..db7092f020c 100644 --- a/src/tools/clippy/tests/ui/manual_find_fixable.rs +++ b/src/tools/clippy/tests/ui/manual_find_fixable.rs @@ -19,7 +19,7 @@ fn lookup(n: u32) -> Option<u32> { fn with_pat(arr: Vec<(u32, u32)>) -> Option<u32> { for (a, _) in arr { //~^ manual_find - if a % 2 == 0 { + if a.is_multiple_of(2) { return Some(a); } } @@ -111,7 +111,7 @@ fn with_side_effects(arr: Vec<u32>) -> Option<u32> { fn with_else(arr: Vec<u32>) -> Option<u32> { for el in arr { - if el % 2 == 0 { + if el.is_multiple_of(2) { return Some(el); } else { println!("{}", el); diff --git a/src/tools/clippy/tests/ui/manual_find_fixable.stderr b/src/tools/clippy/tests/ui/manual_find_fixable.stderr index 020635d90bb..0c05c0d2c44 100644 --- a/src/tools/clippy/tests/ui/manual_find_fixable.stderr +++ b/src/tools/clippy/tests/ui/manual_find_fixable.stderr @@ -17,11 +17,11 @@ error: manual implementation of `Iterator::find` | LL | / for (a, _) in arr { LL | | -LL | | if a % 2 == 0 { +LL | | if a.is_multiple_of(2) { LL | | return Some(a); ... | LL | | None - | |________^ help: replace with an iterator: `arr.into_iter().map(|(a, _)| a).find(|&a| a % 2 == 0)` + | |________^ help: replace with an iterator: `arr.into_iter().map(|(a, _)| a).find(|&a| a.is_multiple_of(2))` error: manual implementation of `Iterator::find` --> tests/ui/manual_find_fixable.rs:34:5 diff --git a/src/tools/clippy/tests/ui/manual_is_multiple_of.fixed b/src/tools/clippy/tests/ui/manual_is_multiple_of.fixed new file mode 100644 index 00000000000..6735b99f298 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_is_multiple_of.fixed @@ -0,0 +1,25 @@ +//@aux-build: proc_macros.rs +#![warn(clippy::manual_is_multiple_of)] + +fn main() {} + +#[clippy::msrv = "1.87"] +fn f(a: u64, b: u64) { + let _ = a.is_multiple_of(b); //~ manual_is_multiple_of + let _ = (a + 1).is_multiple_of(b + 1); //~ manual_is_multiple_of + let _ = !a.is_multiple_of(b); //~ manual_is_multiple_of + let _ = !(a + 1).is_multiple_of(b + 1); //~ manual_is_multiple_of + + let _ = !a.is_multiple_of(b); //~ manual_is_multiple_of + let _ = !a.is_multiple_of(b); //~ manual_is_multiple_of + + proc_macros::external! { + let a: u64 = 23424; + let _ = a % 4096 == 0; + } +} + +#[clippy::msrv = "1.86"] +fn g(a: u64, b: u64) { + let _ = a % b == 0; +} diff --git a/src/tools/clippy/tests/ui/manual_is_multiple_of.rs b/src/tools/clippy/tests/ui/manual_is_multiple_of.rs new file mode 100644 index 00000000000..00b638e4fd9 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_is_multiple_of.rs @@ -0,0 +1,25 @@ +//@aux-build: proc_macros.rs +#![warn(clippy::manual_is_multiple_of)] + +fn main() {} + +#[clippy::msrv = "1.87"] +fn f(a: u64, b: u64) { + let _ = a % b == 0; //~ manual_is_multiple_of + let _ = (a + 1) % (b + 1) == 0; //~ manual_is_multiple_of + let _ = a % b != 0; //~ manual_is_multiple_of + let _ = (a + 1) % (b + 1) != 0; //~ manual_is_multiple_of + + let _ = a % b > 0; //~ manual_is_multiple_of + let _ = 0 < a % b; //~ manual_is_multiple_of + + proc_macros::external! { + let a: u64 = 23424; + let _ = a % 4096 == 0; + } +} + +#[clippy::msrv = "1.86"] +fn g(a: u64, b: u64) { + let _ = a % b == 0; +} diff --git a/src/tools/clippy/tests/ui/manual_is_multiple_of.stderr b/src/tools/clippy/tests/ui/manual_is_multiple_of.stderr new file mode 100644 index 00000000000..0b1ae70c2a7 --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_is_multiple_of.stderr @@ -0,0 +1,41 @@ +error: manual implementation of `.is_multiple_of()` + --> tests/ui/manual_is_multiple_of.rs:8:13 + | +LL | let _ = a % b == 0; + | ^^^^^^^^^^ help: replace with: `a.is_multiple_of(b)` + | + = note: `-D clippy::manual-is-multiple-of` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_is_multiple_of)]` + +error: manual implementation of `.is_multiple_of()` + --> tests/ui/manual_is_multiple_of.rs:9:13 + | +LL | let _ = (a + 1) % (b + 1) == 0; + | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `(a + 1).is_multiple_of(b + 1)` + +error: manual implementation of `.is_multiple_of()` + --> tests/ui/manual_is_multiple_of.rs:10:13 + | +LL | let _ = a % b != 0; + | ^^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)` + +error: manual implementation of `.is_multiple_of()` + --> tests/ui/manual_is_multiple_of.rs:11:13 + | +LL | let _ = (a + 1) % (b + 1) != 0; + | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `!(a + 1).is_multiple_of(b + 1)` + +error: manual implementation of `.is_multiple_of()` + --> tests/ui/manual_is_multiple_of.rs:13:13 + | +LL | let _ = a % b > 0; + | ^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)` + +error: manual implementation of `.is_multiple_of()` + --> tests/ui/manual_is_multiple_of.rs:14:13 + | +LL | let _ = 0 < a % b; + | ^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)` + +error: aborting due to 6 previous errors + diff --git a/src/tools/clippy/tests/ui/manual_is_variant_and.fixed b/src/tools/clippy/tests/ui/manual_is_variant_and.fixed index 18a72188ab5..6425f32c09c 100644 --- a/src/tools/clippy/tests/ui/manual_is_variant_and.fixed +++ b/src/tools/clippy/tests/ui/manual_is_variant_and.fixed @@ -77,7 +77,7 @@ fn option_methods() { let _ = opt_map!(opt2, |x| x == 'a').unwrap_or_default(); // should not lint // Should not lint. - let _ = Foo::<u32>(0).map(|x| x % 2 == 0) == Some(true); + let _ = Foo::<u32>(0).map(|x| x.is_multiple_of(2)) == Some(true); let _ = Some(2).map(|x| x % 2 == 0) != foo(); let _ = mac!(eq Some(2).map(|x| x % 2 == 0), Some(true)); let _ = mac!(some 2).map(|x| x % 2 == 0) == Some(true); @@ -96,11 +96,11 @@ fn result_methods() { }); let _ = res.is_ok_and(|x| x > 1); - let _ = Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0); + let _ = Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2)); //~^ manual_is_variant_and - let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0); + let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2)); //~^ manual_is_variant_and - let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0); + let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2)); //~^ manual_is_variant_and // won't fix because the return type of the closure is not `bool` diff --git a/src/tools/clippy/tests/ui/manual_is_variant_and.rs b/src/tools/clippy/tests/ui/manual_is_variant_and.rs index a92f7c04369..e069e97a04d 100644 --- a/src/tools/clippy/tests/ui/manual_is_variant_and.rs +++ b/src/tools/clippy/tests/ui/manual_is_variant_and.rs @@ -83,7 +83,7 @@ fn option_methods() { let _ = opt_map!(opt2, |x| x == 'a').unwrap_or_default(); // should not lint // Should not lint. - let _ = Foo::<u32>(0).map(|x| x % 2 == 0) == Some(true); + let _ = Foo::<u32>(0).map(|x| x.is_multiple_of(2)) == Some(true); let _ = Some(2).map(|x| x % 2 == 0) != foo(); let _ = mac!(eq Some(2).map(|x| x % 2 == 0), Some(true)); let _ = mac!(some 2).map(|x| x % 2 == 0) == Some(true); @@ -105,11 +105,11 @@ fn result_methods() { //~^ manual_is_variant_and .unwrap_or_default(); - let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) == Ok(true); + let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) == Ok(true); //~^ manual_is_variant_and - let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) != Ok(true); + let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true); //~^ manual_is_variant_and - let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) != Ok(true); + let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true); //~^ manual_is_variant_and // won't fix because the return type of the closure is not `bool` diff --git a/src/tools/clippy/tests/ui/manual_is_variant_and.stderr b/src/tools/clippy/tests/ui/manual_is_variant_and.stderr index 1fb437a8bc7..f770319a268 100644 --- a/src/tools/clippy/tests/ui/manual_is_variant_and.stderr +++ b/src/tools/clippy/tests/ui/manual_is_variant_and.stderr @@ -105,20 +105,20 @@ LL | | .unwrap_or_default(); error: called `.map() == Ok()` --> tests/ui/manual_is_variant_and.rs:108:13 | -LL | let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) == Ok(true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0)` +LL | let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) == Ok(true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2))` error: called `.map() != Ok()` --> tests/ui/manual_is_variant_and.rs:110:13 | -LL | let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) != Ok(true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0)` +LL | let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2))` error: called `.map() != Ok()` --> tests/ui/manual_is_variant_and.rs:112:13 | -LL | let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) != Ok(true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0)` +LL | let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2))` error: called `map(<f>).unwrap_or_default()` on a `Result` value --> tests/ui/manual_is_variant_and.rs:119:18 diff --git a/src/tools/clippy/tests/ui/manual_ok_err.fixed b/src/tools/clippy/tests/ui/manual_ok_err.fixed index e6f799aa58d..9b70ce0df43 100644 --- a/src/tools/clippy/tests/ui/manual_ok_err.fixed +++ b/src/tools/clippy/tests/ui/manual_ok_err.fixed @@ -103,3 +103,27 @@ fn issue14239() { }; //~^^^^^ manual_ok_err } + +mod issue15051 { + struct Container { + field: Result<bool, ()>, + } + + #[allow(clippy::needless_borrow)] + fn with_addr_of(x: &Container) -> Option<&bool> { + (&x.field).as_ref().ok() + } + + fn from_fn(x: &Container) -> Option<&bool> { + let result_with_ref = || &x.field; + result_with_ref().as_ref().ok() + } + + fn result_with_ref_mut(x: &mut Container) -> &mut Result<bool, ()> { + &mut x.field + } + + fn from_fn_mut(x: &mut Container) -> Option<&mut bool> { + result_with_ref_mut(x).as_mut().ok() + } +} diff --git a/src/tools/clippy/tests/ui/manual_ok_err.rs b/src/tools/clippy/tests/ui/manual_ok_err.rs index 972b2c41ee7..dee90463824 100644 --- a/src/tools/clippy/tests/ui/manual_ok_err.rs +++ b/src/tools/clippy/tests/ui/manual_ok_err.rs @@ -141,3 +141,39 @@ fn issue14239() { }; //~^^^^^ manual_ok_err } + +mod issue15051 { + struct Container { + field: Result<bool, ()>, + } + + #[allow(clippy::needless_borrow)] + fn with_addr_of(x: &Container) -> Option<&bool> { + match &x.field { + //~^ manual_ok_err + Ok(panel) => Some(panel), + Err(_) => None, + } + } + + fn from_fn(x: &Container) -> Option<&bool> { + let result_with_ref = || &x.field; + match result_with_ref() { + //~^ manual_ok_err + Ok(panel) => Some(panel), + Err(_) => None, + } + } + + fn result_with_ref_mut(x: &mut Container) -> &mut Result<bool, ()> { + &mut x.field + } + + fn from_fn_mut(x: &mut Container) -> Option<&mut bool> { + match result_with_ref_mut(x) { + //~^ manual_ok_err + Ok(panel) => Some(panel), + Err(_) => None, + } + } +} diff --git a/src/tools/clippy/tests/ui/manual_ok_err.stderr b/src/tools/clippy/tests/ui/manual_ok_err.stderr index 040e170f397..448fbffc050 100644 --- a/src/tools/clippy/tests/ui/manual_ok_err.stderr +++ b/src/tools/clippy/tests/ui/manual_ok_err.stderr @@ -111,5 +111,35 @@ LL + "1".parse::<u8>().ok() LL ~ }; | -error: aborting due to 9 previous errors +error: manual implementation of `ok` + --> tests/ui/manual_ok_err.rs:152:9 + | +LL | / match &x.field { +LL | | +LL | | Ok(panel) => Some(panel), +LL | | Err(_) => None, +LL | | } + | |_________^ help: replace with: `(&x.field).as_ref().ok()` + +error: manual implementation of `ok` + --> tests/ui/manual_ok_err.rs:161:9 + | +LL | / match result_with_ref() { +LL | | +LL | | Ok(panel) => Some(panel), +LL | | Err(_) => None, +LL | | } + | |_________^ help: replace with: `result_with_ref().as_ref().ok()` + +error: manual implementation of `ok` + --> tests/ui/manual_ok_err.rs:173:9 + | +LL | / match result_with_ref_mut(x) { +LL | | +LL | | Ok(panel) => Some(panel), +LL | | Err(_) => None, +LL | | } + | |_________^ help: replace with: `result_with_ref_mut(x).as_mut().ok()` + +error: aborting due to 12 previous errors diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.fixed index 7e0d4fccaae..f1d5579a723 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.fixed +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.fixed @@ -25,7 +25,7 @@ const fn can_be_const() { 0u64.method(); } -// False negative, see FIXME comment in `clipy_utils::qualify_min_const` +// False negative, see FIXME comment in `clippy_utils::qualify_min_const_fn` fn could_be_const_but_does_not_trigger<T>(t: T) where T: const ConstTrait, diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.rs index 439da4622d7..d495759526d 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.rs @@ -25,7 +25,7 @@ fn can_be_const() { 0u64.method(); } -// False negative, see FIXME comment in `clipy_utils::qualify_min_const` +// False negative, see FIXME comment in `clippy_utils::qualify_min_const_fn` fn could_be_const_but_does_not_trigger<T>(t: T) where T: const ConstTrait, diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed index 65eb2d5938b..95bf63ed1df 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed @@ -221,3 +221,60 @@ const fn mut_add(x: &mut i32) { //~^ missing_const_for_fn *x += 1; } + +mod issue_15079 { + pub trait Trait {} + + pub struct Struct<T: Trait> { + _t: Option<T>, + } + + impl<T: Trait> Struct<T> { + #[clippy::msrv = "1.60"] + pub fn new_1_60() -> Self { + Self { _t: None } + } + + #[clippy::msrv = "1.61"] + pub const fn new_1_61() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + } + + pub struct S2<T> { + _t: Option<T>, + } + + impl<T> S2<T> { + #[clippy::msrv = "1.60"] + pub const fn new_1_60() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + + #[clippy::msrv = "1.61"] + pub const fn new_1_61() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + } + + pub struct S3<T: ?Sized + 'static> { + _t: Option<&'static T>, + } + + impl<T: ?Sized + 'static> S3<T> { + #[clippy::msrv = "1.60"] + pub const fn new_1_60() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + + #[clippy::msrv = "1.61"] + pub const fn new_1_61() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + } +} diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs index 3690d2f799f..8290be67546 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs @@ -221,3 +221,60 @@ fn mut_add(x: &mut i32) { //~^ missing_const_for_fn *x += 1; } + +mod issue_15079 { + pub trait Trait {} + + pub struct Struct<T: Trait> { + _t: Option<T>, + } + + impl<T: Trait> Struct<T> { + #[clippy::msrv = "1.60"] + pub fn new_1_60() -> Self { + Self { _t: None } + } + + #[clippy::msrv = "1.61"] + pub fn new_1_61() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + } + + pub struct S2<T> { + _t: Option<T>, + } + + impl<T> S2<T> { + #[clippy::msrv = "1.60"] + pub fn new_1_60() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + + #[clippy::msrv = "1.61"] + pub fn new_1_61() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + } + + pub struct S3<T: ?Sized + 'static> { + _t: Option<&'static T>, + } + + impl<T: ?Sized + 'static> S3<T> { + #[clippy::msrv = "1.60"] + pub fn new_1_60() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + + #[clippy::msrv = "1.61"] + pub fn new_1_61() -> Self { + //~^ missing_const_for_fn + Self { _t: None } + } + } +} diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr index 10e07d12f5a..17cbc431276 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -332,5 +332,75 @@ help: make the function `const` LL | const fn mut_add(x: &mut i32) { | +++++ -error: aborting due to 25 previous errors +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:239:9 + | +LL | / pub fn new_1_61() -> Self { +LL | | +LL | | Self { _t: None } +LL | | } + | |_________^ + | +help: make the function `const` + | +LL | pub const fn new_1_61() -> Self { + | +++++ + +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:251:9 + | +LL | / pub fn new_1_60() -> Self { +LL | | +LL | | Self { _t: None } +LL | | } + | |_________^ + | +help: make the function `const` + | +LL | pub const fn new_1_60() -> Self { + | +++++ + +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:257:9 + | +LL | / pub fn new_1_61() -> Self { +LL | | +LL | | Self { _t: None } +LL | | } + | |_________^ + | +help: make the function `const` + | +LL | pub const fn new_1_61() -> Self { + | +++++ + +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:269:9 + | +LL | / pub fn new_1_60() -> Self { +LL | | +LL | | Self { _t: None } +LL | | } + | |_________^ + | +help: make the function `const` + | +LL | pub const fn new_1_60() -> Self { + | +++++ + +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:275:9 + | +LL | / pub fn new_1_61() -> Self { +LL | | +LL | | Self { _t: None } +LL | | } + | |_________^ + | +help: make the function `const` + | +LL | pub const fn new_1_61() -> Self { + | +++++ + +error: aborting due to 30 previous errors diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr index 0e3e4cf7988..ecb82a23da0 100644 --- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr +++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr @@ -179,7 +179,7 @@ error: inequality checks against true can be replaced by a negation --> tests/ui/nonminimal_bool.rs:186:8 | LL | if !b != true {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` + | ^^^^^^^^^^ help: try simplifying it as shown: `!!b` error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:189:8 @@ -209,7 +209,7 @@ error: inequality checks against true can be replaced by a negation --> tests/ui/nonminimal_bool.rs:193:8 | LL | if true != !b {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` + | ^^^^^^^^^^ help: try simplifying it as shown: `!!b` error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:196:8 diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed index a1119d75c23..34f3e046841 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.fixed +++ b/src/tools/clippy/tests/ui/or_fun_call.fixed @@ -5,6 +5,7 @@ clippy::uninlined_format_args, clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap, + clippy::unnecessary_result_map_or_else, clippy::useless_vec )] @@ -409,4 +410,33 @@ fn fn_call_in_nested_expr() { //~^ or_fun_call } +mod result_map_or { + fn g() -> i32 { + 3 + } + + fn f(n: i32) -> i32 { + n + } + + fn test_map_or() { + let x: Result<i32, ()> = Ok(4); + let _ = x.map_or_else(|_| g(), |v| v); + //~^ or_fun_call + let _ = x.map_or_else(|_| g(), f); + //~^ or_fun_call + let _ = x.map_or(0, f); + } +} + +fn test_option_get_or_insert() { + // assume that this is slow call + fn g() -> u8 { + 99 + } + let mut x = Some(42_u8); + let _ = x.get_or_insert_with(g); + //~^ or_fun_call +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs index a7cd632bf16..dc57bd6060a 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.rs +++ b/src/tools/clippy/tests/ui/or_fun_call.rs @@ -5,6 +5,7 @@ clippy::uninlined_format_args, clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap, + clippy::unnecessary_result_map_or_else, clippy::useless_vec )] @@ -409,4 +410,33 @@ fn fn_call_in_nested_expr() { //~^ or_fun_call } +mod result_map_or { + fn g() -> i32 { + 3 + } + + fn f(n: i32) -> i32 { + n + } + + fn test_map_or() { + let x: Result<i32, ()> = Ok(4); + let _ = x.map_or(g(), |v| v); + //~^ or_fun_call + let _ = x.map_or(g(), f); + //~^ or_fun_call + let _ = x.map_or(0, f); + } +} + +fn test_option_get_or_insert() { + // assume that this is slow call + fn g() -> u8 { + 99 + } + let mut x = Some(42_u8); + let _ = x.get_or_insert(g()); + //~^ or_fun_call +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr index 35bda7e4d33..0f159fe8bff 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.stderr +++ b/src/tools/clippy/tests/ui/or_fun_call.stderr @@ -1,5 +1,5 @@ error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:52:22 + --> tests/ui/or_fun_call.rs:53:22 | LL | with_constructor.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(make)` @@ -8,7 +8,7 @@ LL | with_constructor.unwrap_or(make()); = help: to override `-D warnings` add `#[allow(clippy::or_fun_call)]` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:56:14 + --> tests/ui/or_fun_call.rs:57:14 | LL | with_new.unwrap_or(Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` @@ -17,199 +17,199 @@ LL | with_new.unwrap_or(Vec::new()); = help: to override `-D warnings` add `#[allow(clippy::unwrap_or_default)]` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:60:21 + --> tests/ui/or_fun_call.rs:61:21 | LL | with_const_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Vec::with_capacity(12))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:64:14 + --> tests/ui/or_fun_call.rs:65:14 | LL | with_err.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| make())` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:68:19 + --> tests/ui/or_fun_call.rs:69:19 | LL | with_err_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Vec::with_capacity(12))` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:72:24 + --> tests/ui/or_fun_call.rs:73:24 | LL | with_default_trait.unwrap_or(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:76:23 + --> tests/ui/or_fun_call.rs:77:23 | LL | with_default_type.unwrap_or(u64::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:80:18 + --> tests/ui/or_fun_call.rs:81:18 | LL | self_default.unwrap_or(<FakeDefault>::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(<FakeDefault>::default)` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:84:18 + --> tests/ui/or_fun_call.rs:85:18 | LL | real_default.unwrap_or(<FakeDefault as Default>::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:88:14 + --> tests/ui/or_fun_call.rs:89:14 | LL | with_vec.unwrap_or(vec![]); | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:92:21 + --> tests/ui/or_fun_call.rs:93:21 | LL | without_default.unwrap_or(Foo::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(Foo::new)` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:96:19 + --> tests/ui/or_fun_call.rs:97:19 | LL | map.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:100:23 + --> tests/ui/or_fun_call.rs:101:23 | LL | map_vec.entry(42).or_insert(vec![]); | ^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:104:21 + --> tests/ui/or_fun_call.rs:105:21 | LL | btree.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:108:25 + --> tests/ui/or_fun_call.rs:109:25 | LL | btree_vec.entry(42).or_insert(vec![]); | ^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:112:21 + --> tests/ui/or_fun_call.rs:113:21 | LL | let _ = stringy.unwrap_or(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `ok_or` - --> tests/ui/or_fun_call.rs:117:17 + --> tests/ui/or_fun_call.rs:118:17 | LL | let _ = opt.ok_or(format!("{} world.", hello)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ok_or_else(|| format!("{} world.", hello))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:122:21 + --> tests/ui/or_fun_call.rs:123:21 | LL | let _ = Some(1).unwrap_or(map[&1]); | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:125:21 + --> tests/ui/or_fun_call.rs:126:21 | LL | let _ = Some(1).unwrap_or(map[&1]); | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])` error: function call inside of `or` - --> tests/ui/or_fun_call.rs:150:35 + --> tests/ui/or_fun_call.rs:151:35 | LL | let _ = Some("a".to_string()).or(Some("b".to_string())); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_else(|| Some("b".to_string()))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:193:18 + --> tests/ui/or_fun_call.rs:194:18 | LL | None.unwrap_or(ptr_to_ref(s)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| ptr_to_ref(s))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:201:14 + --> tests/ui/or_fun_call.rs:202:14 | LL | None.unwrap_or(unsafe { ptr_to_ref(s) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:204:14 + --> tests/ui/or_fun_call.rs:205:14 | LL | None.unwrap_or( unsafe { ptr_to_ref(s) } ); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:280:25 + --> tests/ui/or_fun_call.rs:281:25 | LL | let _ = Some(4).map_or(g(), |v| v); | ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(g, |v| v)` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:282:25 + --> tests/ui/or_fun_call.rs:283:25 | LL | let _ = Some(4).map_or(g(), f); | ^^^^^^^^^^^^^^ help: try: `map_or_else(g, f)` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:314:18 + --> tests/ui/or_fun_call.rs:315:18 | LL | with_new.unwrap_or_else(Vec::new); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:318:28 + --> tests/ui/or_fun_call.rs:319:28 | LL | with_default_trait.unwrap_or_else(Default::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:322:27 + --> tests/ui/or_fun_call.rs:323:27 | LL | with_default_type.unwrap_or_else(u64::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:326:22 + --> tests/ui/or_fun_call.rs:327:22 | LL | real_default.unwrap_or_else(<FakeDefault as Default>::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `or_insert_with` to construct default value - --> tests/ui/or_fun_call.rs:330:23 + --> tests/ui/or_fun_call.rs:331:23 | LL | map.entry(42).or_insert_with(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert_with` to construct default value - --> tests/ui/or_fun_call.rs:334:25 + --> tests/ui/or_fun_call.rs:335:25 | LL | btree.entry(42).or_insert_with(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:338:25 + --> tests/ui/or_fun_call.rs:339:25 | LL | let _ = stringy.unwrap_or_else(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:380:17 + --> tests/ui/or_fun_call.rs:381:17 | LL | let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(f)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:385:17 + --> tests/ui/or_fun_call.rs:386:17 | LL | let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| f() + 1)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:390:17 + --> tests/ui/or_fun_call.rs:391:17 | LL | let _ = opt.unwrap_or({ | _________________^ @@ -229,22 +229,40 @@ LL ~ }); | error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:396:17 + --> tests/ui/or_fun_call.rs:397:17 | LL | let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)` | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| f() + 1, |v| v)` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:401:17 + --> tests/ui/or_fun_call.rs:402:17 | LL | let _ = opt.unwrap_or({ i32::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:408:21 + --> tests/ui/or_fun_call.rs:409:21 | LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })` -error: aborting due to 38 previous errors +error: function call inside of `map_or` + --> tests/ui/or_fun_call.rs:424:19 + | +LL | let _ = x.map_or(g(), |v| v); + | ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), |v| v)` + +error: function call inside of `map_or` + --> tests/ui/or_fun_call.rs:426:19 + | +LL | let _ = x.map_or(g(), f); + | ^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), f)` + +error: function call inside of `get_or_insert` + --> tests/ui/or_fun_call.rs:438:15 + | +LL | let _ = x.get_or_insert(g()); + | ^^^^^^^^^^^^^^^^^^ help: try: `get_or_insert_with(g)` + +error: aborting due to 41 previous errors diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed index 60dc1c101b6..8d6f5fbadca 100644 --- a/src/tools/clippy/tests/ui/question_mark.fixed +++ b/src/tools/clippy/tests/ui/question_mark.fixed @@ -453,3 +453,15 @@ fn const_in_pattern(x: Option<(i32, i32)>) -> Option<()> { None } + +fn issue_13642(x: Option<i32>) -> Option<()> { + let Some(x) = x else { + #[cfg(false)] + panic!(); + + #[cfg(true)] + return None; + }; + + None +} diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs index 99d0122a98f..f13eee29c11 100644 --- a/src/tools/clippy/tests/ui/question_mark.rs +++ b/src/tools/clippy/tests/ui/question_mark.rs @@ -549,3 +549,15 @@ fn const_in_pattern(x: Option<(i32, i32)>) -> Option<()> { None } + +fn issue_13642(x: Option<i32>) -> Option<()> { + let Some(x) = x else { + #[cfg(false)] + panic!(); + + #[cfg(true)] + return None; + }; + + None +} diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs b/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs new file mode 100644 index 00000000000..2e67fb65efc --- /dev/null +++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs @@ -0,0 +1,22 @@ +//@compile-flags: -Z track-diagnostics +//@no-rustfix + +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +//@normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" + +#![warn(clippy::let_and_return, clippy::unnecessary_cast)] + +fn main() { + // Check the provenance of a lint sent through `LintContext::span_lint()` + let a = 3u32; + let b = a as u32; + //~^ unnecessary_cast + + // Check the provenance of a lint sent through `TyCtxt::node_span_lint()` + let c = { + let d = 42; + d + //~^ let_and_return + }; +} diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr new file mode 100644 index 00000000000..f3aca685417 --- /dev/null +++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr @@ -0,0 +1,29 @@ +error: casting to the same type is unnecessary (`u32` -> `u32`) + --> tests/ui/track-diagnostics-clippy.rs:LL:CC + | +LL | let b = a as u32; + | ^^^^^^^^ help: try: `a` +-Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs:LL:CC + | + = note: `-D clippy::unnecessary-cast` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]` + +error: returning the result of a `let` binding from a block + --> tests/ui/track-diagnostics-clippy.rs:LL:CC + | +LL | let d = 42; + | ----------- unnecessary `let` binding +LL | d + | ^ +-Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/returns.rs:LL:CC + | + = note: `-D clippy::let-and-return` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]` +help: return the expression directly + | +LL ~ +LL ~ 42 + | + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed index 666ff78b218..cf52ecf2f03 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed @@ -169,9 +169,9 @@ where // #13476 #[const_trait] trait ConstTrait {} -const fn const_trait_bounds_good<T: ConstTrait + ~const ConstTrait>() {} +const fn const_trait_bounds_good<T: ConstTrait + [const] ConstTrait>() {} -const fn const_trait_bounds_bad<T: ~const ConstTrait>() {} +const fn const_trait_bounds_bad<T: [const] ConstTrait>() {} //~^ trait_duplication_in_bounds fn projections<T, U, V>() diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs index a1a86fe058e..955562f08dc 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs @@ -169,9 +169,9 @@ where // #13476 #[const_trait] trait ConstTrait {} -const fn const_trait_bounds_good<T: ConstTrait + ~const ConstTrait>() {} +const fn const_trait_bounds_good<T: ConstTrait + [const] ConstTrait>() {} -const fn const_trait_bounds_bad<T: ~const ConstTrait + ~const ConstTrait>() {} +const fn const_trait_bounds_bad<T: [const] ConstTrait + [const] ConstTrait>() {} //~^ trait_duplication_in_bounds fn projections<T, U, V>() diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr index d76b4e45848..ab31721ef51 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr @@ -61,8 +61,8 @@ LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { error: these bounds contain repeated elements --> tests/ui/trait_duplication_in_bounds.rs:174:36 | -LL | const fn const_trait_bounds_bad<T: ~const ConstTrait + ~const ConstTrait>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `~const ConstTrait` +LL | const fn const_trait_bounds_bad<T: [const] ConstTrait + [const] ConstTrait>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[const] ConstTrait` error: these where clauses contain repeated elements --> tests/ui/trait_duplication_in_bounds.rs:181:8 diff --git a/src/tools/clippy/tests/ui/unnecessary_os_str_debug_formatting.rs b/src/tools/clippy/tests/ui/unnecessary_os_str_debug_formatting.rs index 6652efd9ae1..66590be3d05 100644 --- a/src/tools/clippy/tests/ui/unnecessary_os_str_debug_formatting.rs +++ b/src/tools/clippy/tests/ui/unnecessary_os_str_debug_formatting.rs @@ -21,3 +21,16 @@ fn main() { let _: String = format!("{:?}", os_str); //~ unnecessary_debug_formatting let _: String = format!("{:?}", os_string); //~ unnecessary_debug_formatting } + +#[clippy::msrv = "1.86"] +fn msrv_1_86() { + let os_str = OsStr::new("test"); + println!("{:?}", os_str); +} + +#[clippy::msrv = "1.87"] +fn msrv_1_87() { + let os_str = OsStr::new("test"); + println!("{:?}", os_str); + //~^ unnecessary_debug_formatting +} diff --git a/src/tools/clippy/tests/ui/unnecessary_os_str_debug_formatting.stderr b/src/tools/clippy/tests/ui/unnecessary_os_str_debug_formatting.stderr index 382e59b0461..f04d2d5bdc8 100644 --- a/src/tools/clippy/tests/ui/unnecessary_os_str_debug_formatting.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_os_str_debug_formatting.stderr @@ -54,5 +54,14 @@ LL | let _: String = format!("{:?}", os_string); = help: use `Display` formatting and change this to `os_string.display()` = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed -error: aborting due to 6 previous errors +error: unnecessary `Debug` formatting in `println!` args + --> tests/ui/unnecessary_os_str_debug_formatting.rs:34:22 + | +LL | println!("{:?}", os_str); + | ^^^^^^ + | + = help: use `Display` formatting and change this to `os_str.display()` + = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed + +error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr index b56e8b35493..732e6767c17 100644 --- a/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr @@ -1,4 +1,4 @@ -error: constant item has unnecessary safety comment +error: constant has unnecessary safety comment --> tests/ui/unnecessary_safety_comment.rs:6:5 | LL | const CONST: u32 = 0; @@ -12,7 +12,7 @@ LL | // SAFETY: = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` -error: static item has unnecessary safety comment +error: static has unnecessary safety comment --> tests/ui/unnecessary_safety_comment.rs:10:5 | LL | static STATIC: u32 = 0; diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed index 141ff6eb2ac..5f738a254dc 100644 --- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed +++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed @@ -91,6 +91,21 @@ fn main() { } { + pub enum Enum { + A, + B, + C(u8), + D(u8, u8), + E { e: u8 }, + }; + match Enum::A { + Enum::A => (), + Enum::B | Enum::C(_) | Enum::D(..) | Enum::E { .. } => (), + //~^ wildcard_enum_match_arm + } + } + + { #![allow(clippy::manual_non_exhaustive)] pub enum Enum { A, @@ -105,3 +120,17 @@ fn main() { } } } + +fn issue15091() { + enum Foo { + A, + B, + C, + } + + match Foo::A { + Foo::A => {}, + r#type @ Foo::B | r#type @ Foo::C => {}, + //~^ wildcard_enum_match_arm + } +} diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs index a13684e9100..4bc4bfdcb79 100644 --- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs +++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs @@ -91,6 +91,21 @@ fn main() { } { + pub enum Enum { + A, + B, + C(u8), + D(u8, u8), + E { e: u8 }, + }; + match Enum::A { + Enum::A => (), + _ => (), + //~^ wildcard_enum_match_arm + } + } + + { #![allow(clippy::manual_non_exhaustive)] pub enum Enum { A, @@ -105,3 +120,17 @@ fn main() { } } } + +fn issue15091() { + enum Foo { + A, + B, + C, + } + + match Foo::A { + Foo::A => {}, + r#type => {}, + //~^ wildcard_enum_match_arm + } +} diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr index 088c6b7b284..d0929989494 100644 --- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr +++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr @@ -38,7 +38,19 @@ error: wildcard match will also match any future added variants --> tests/ui/wildcard_enum_match_arm.rs:103:13 | LL | _ => (), + | ^ help: try: `Enum::B | Enum::C(_) | Enum::D(..) | Enum::E { .. }` + +error: wildcard match will also match any future added variants + --> tests/ui/wildcard_enum_match_arm.rs:118:13 + | +LL | _ => (), | ^ help: try: `Enum::B | Enum::__Private` -error: aborting due to 6 previous errors +error: wildcard match will also match any future added variants + --> tests/ui/wildcard_enum_match_arm.rs:133:9 + | +LL | r#type => {}, + | ^^^^^^ help: try: `r#type @ Foo::B | r#type @ Foo::C` + +error: aborting due to 8 previous errors |
