From 62026c32288f86b4337dcf17bf4fabd15a140a92 Mon Sep 17 00:00:00 2001 From: ROMemories <152802150+ROMemories@users.noreply.github.com> Date: Thu, 26 Sep 2024 09:30:28 +0200 Subject: [PATCH 01/99] Add units/unit prefixes of frequency to doc-valid-idents --- book/src/lint_configuration.md | 2 +- clippy_config/src/conf.rs | 1 + tests/ui/doc/doc-fixable.fixed | 1 + tests/ui/doc/doc-fixable.rs | 1 + tests/ui/doc/doc-fixable.stderr | 44 ++++++++++++++++----------------- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 91159bc79c511..6d7420c12ec3b 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -455,7 +455,7 @@ default configuration of Clippy. By default, any configuration will replace the * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`. * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list. -**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "AccessKit", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` +**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` --- **Affected lints:** diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 757620341ccc1..6ed3221c31f87 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -17,6 +17,7 @@ use std::{cmp, env, fmt, fs, io}; #[rustfmt::skip] const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", + "MHz", "GHz", "THz", "AccessKit", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", diff --git a/tests/ui/doc/doc-fixable.fixed b/tests/ui/doc/doc-fixable.fixed index edfffe8fcfe36..c2e4a124d2ae8 100644 --- a/tests/ui/doc/doc-fixable.fixed +++ b/tests/ui/doc/doc-fixable.fixed @@ -54,6 +54,7 @@ fn test_units() { /// This tests allowed identifiers. /// KiB MiB GiB TiB PiB EiB +/// MHz GHz THz /// AccessKit /// CoreFoundation CoreGraphics CoreText /// Direct2D Direct3D DirectWrite DirectX diff --git a/tests/ui/doc/doc-fixable.rs b/tests/ui/doc/doc-fixable.rs index 3c0f6913e3289..de71cf73ffe81 100644 --- a/tests/ui/doc/doc-fixable.rs +++ b/tests/ui/doc/doc-fixable.rs @@ -54,6 +54,7 @@ fn test_units() { /// This tests allowed identifiers. /// KiB MiB GiB TiB PiB EiB +/// MHz GHz THz /// AccessKit /// CoreFoundation CoreGraphics CoreText /// Direct2D Direct3D DirectWrite DirectX diff --git a/tests/ui/doc/doc-fixable.stderr b/tests/ui/doc/doc-fixable.stderr index 67c0464149c6e..27a04e4b55830 100644 --- a/tests/ui/doc/doc-fixable.stderr +++ b/tests/ui/doc/doc-fixable.stderr @@ -133,7 +133,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:78:5 + --> tests/ui/doc/doc-fixable.rs:79:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:95:5 + --> tests/ui/doc/doc-fixable.rs:96:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:103:8 + --> tests/ui/doc/doc-fixable.rs:104:8 | LL | /// ## CamelCaseThing | ^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | /// ## `CamelCaseThing` | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:106:7 + --> tests/ui/doc/doc-fixable.rs:107:7 | LL | /// # CamelCaseThing | ^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | /// # `CamelCaseThing` | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:108:22 + --> tests/ui/doc/doc-fixable.rs:109:22 | LL | /// Not a title #897 CamelCaseThing | ^^^^^^^^^^^^^^ @@ -188,7 +188,7 @@ LL | /// Not a title #897 `CamelCaseThing` | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:109:5 + --> tests/ui/doc/doc-fixable.rs:110:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:116:5 + --> tests/ui/doc/doc-fixable.rs:117:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,7 +210,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:129:5 + --> tests/ui/doc/doc-fixable.rs:130:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +221,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:140:43 + --> tests/ui/doc/doc-fixable.rs:141:43 | LL | /** E.g., serialization of an empty list: FooBar | ^^^^^^ @@ -232,7 +232,7 @@ LL | /** E.g., serialization of an empty list: `FooBar` | ~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:145:5 + --> tests/ui/doc/doc-fixable.rs:146:5 | LL | And BarQuz too. | ^^^^^^ @@ -243,7 +243,7 @@ LL | And `BarQuz` too. | ~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:146:1 + --> tests/ui/doc/doc-fixable.rs:147:1 | LL | be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -254,7 +254,7 @@ LL | `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:151:43 + --> tests/ui/doc/doc-fixable.rs:152:43 | LL | /** E.g., serialization of an empty list: FooBar | ^^^^^^ @@ -265,7 +265,7 @@ LL | /** E.g., serialization of an empty list: `FooBar` | ~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:156:5 + --> tests/ui/doc/doc-fixable.rs:157:5 | LL | And BarQuz too. | ^^^^^^ @@ -276,7 +276,7 @@ LL | And `BarQuz` too. | ~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:157:1 + --> tests/ui/doc/doc-fixable.rs:158:1 | LL | be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -287,7 +287,7 @@ LL | `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:168:5 + --> tests/ui/doc/doc-fixable.rs:169:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -298,7 +298,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:187:22 + --> tests/ui/doc/doc-fixable.rs:188:22 | LL | /// An iterator over mycrate::Collection's values. | ^^^^^^^^^^^^^^^^^^^ @@ -309,7 +309,7 @@ LL | /// An iterator over `mycrate::Collection`'s values. | ~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:211:34 + --> tests/ui/doc/doc-fixable.rs:212:34 | LL | /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint | ^^^^^^^^^^^^^^^ @@ -320,7 +320,7 @@ LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint` | ~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:234:22 + --> tests/ui/doc/doc-fixable.rs:235:22 | LL | /// There is no try (do() or do_not()). | ^^^^ @@ -331,7 +331,7 @@ LL | /// There is no try (`do()` or do_not()). | ~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:234:30 + --> tests/ui/doc/doc-fixable.rs:235:30 | LL | /// There is no try (do() or do_not()). | ^^^^^^^^ @@ -342,7 +342,7 @@ LL | /// There is no try (do() or `do_not()`). | ~~~~~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:237:5 + --> tests/ui/doc/doc-fixable.rs:238:5 | LL | /// ABes | ^^^^ @@ -353,7 +353,7 @@ LL | /// `ABes` | ~~~~~~ error: item in documentation is missing backticks - --> tests/ui/doc/doc-fixable.rs:243:9 + --> tests/ui/doc/doc-fixable.rs:244:9 | LL | /// foo() | ^^^^^ @@ -364,7 +364,7 @@ LL | /// `foo()` | ~~~~~~~ error: you should put bare URLs between `<`/`>` or make a proper Markdown link - --> tests/ui/doc/doc-fixable.rs:247:5 + --> tests/ui/doc/doc-fixable.rs:248:5 | LL | /// https://github.com/rust-lang/rust-clippy/pull/12836 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `` From b95aa31a75fd181ff1f84e1bb0a160854d8d383f Mon Sep 17 00:00:00 2001 From: "Chai T. Rex" Date: Tue, 8 Oct 2024 00:13:59 -0400 Subject: [PATCH 02/99] Stabilize `isqrt` feature --- tests/ui/cast.rs | 1 - tests/ui/cast.stderr | 184 +++++++++++++++++++++---------------------- 2 files changed, 92 insertions(+), 93 deletions(-) diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index 146b04ab8131d..0de53a75c6236 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -1,7 +1,6 @@ //@no-rustfix #![feature(repr128)] -#![feature(isqrt)] #![allow(incomplete_features)] #![warn( clippy::cast_precision_loss, diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 7824bdfac25ef..452482fc88e28 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -1,5 +1,5 @@ error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:26:5 + --> tests/ui/cast.rs:25:5 | LL | x0 as f32; | ^^^^^^^^^ @@ -8,37 +8,37 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:30:5 + --> tests/ui/cast.rs:29:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:32:5 + --> tests/ui/cast.rs:31:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:35:5 + --> tests/ui/cast.rs:34:5 | LL | x2 as f32; | ^^^^^^^^^ error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:38:5 + --> tests/ui/cast.rs:37:5 | LL | x3 as f32; | ^^^^^^^^^ error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:40:5 + --> tests/ui/cast.rs:39:5 | LL | x3 as f64; | ^^^^^^^^^ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:43:5 + --> tests/ui/cast.rs:42:5 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | 1f32 as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]` error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:45:5 + --> tests/ui/cast.rs:44:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | 1f32 as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:45:5 + --> tests/ui/cast.rs:44:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | 1f32 as u32; = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]` error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:49:5 + --> tests/ui/cast.rs:48:5 | LL | 1f64 as f32; | ^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | 1f64 as f32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:51:5 + --> tests/ui/cast.rs:50:5 | LL | 1i32 as i8; | ^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | i8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u8` may truncate the value - --> tests/ui/cast.rs:53:5 + --> tests/ui/cast.rs:52:5 | LL | 1i32 as u8; | ^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | u8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `f64` to `isize` may truncate the value - --> tests/ui/cast.rs:55:5 + --> tests/ui/cast.rs:54:5 | LL | 1f64 as isize; | ^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | 1f64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may truncate the value - --> tests/ui/cast.rs:57:5 + --> tests/ui/cast.rs:56:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ @@ -113,13 +113,13 @@ LL | 1f64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:57:5 + --> tests/ui/cast.rs:56:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ error: casting `u32` to `u16` may truncate the value - --> tests/ui/cast.rs:60:5 + --> tests/ui/cast.rs:59:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | u16::try_from(1f32 as u32); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:60:5 + --> tests/ui/cast.rs:59:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ @@ -139,13 +139,13 @@ LL | 1f32 as u32 as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:60:5 + --> tests/ui/cast.rs:59:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:65:22 + --> tests/ui/cast.rs:64:22 | LL | let _x: i8 = 1i32 as _; | ^^^^^^^^^ @@ -157,7 +157,7 @@ LL | let _x: i8 = 1i32.try_into(); | ~~~~~~~~~~~~~~~ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:67:9 + --> tests/ui/cast.rs:66:9 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | 1f32 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `i32` may truncate the value - --> tests/ui/cast.rs:69:9 + --> tests/ui/cast.rs:68:9 | LL | 1f64 as i32; | ^^^^^^^^^^^ @@ -173,7 +173,7 @@ LL | 1f64 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may truncate the value - --> tests/ui/cast.rs:71:9 + --> tests/ui/cast.rs:70:9 | LL | 1f32 as u8; | ^^^^^^^^^^ @@ -181,13 +181,13 @@ LL | 1f32 as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:71:9 + --> tests/ui/cast.rs:70:9 | LL | 1f32 as u8; | ^^^^^^^^^^ error: casting `u8` to `i8` may wrap around the value - --> tests/ui/cast.rs:76:5 + --> tests/ui/cast.rs:75:5 | LL | 1u8 as i8; | ^^^^^^^^^ @@ -196,31 +196,31 @@ LL | 1u8 as i8; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `u16` to `i16` may wrap around the value - --> tests/ui/cast.rs:79:5 + --> tests/ui/cast.rs:78:5 | LL | 1u16 as i16; | ^^^^^^^^^^^ error: casting `u32` to `i32` may wrap around the value - --> tests/ui/cast.rs:81:5 + --> tests/ui/cast.rs:80:5 | LL | 1u32 as i32; | ^^^^^^^^^^^ error: casting `u64` to `i64` may wrap around the value - --> tests/ui/cast.rs:83:5 + --> tests/ui/cast.rs:82:5 | LL | 1u64 as i64; | ^^^^^^^^^^^ error: casting `usize` to `isize` may wrap around the value - --> tests/ui/cast.rs:85:5 + --> tests/ui/cast.rs:84:5 | LL | 1usize as isize; | ^^^^^^^^^^^^^^^ error: casting `usize` to `i8` may truncate the value - --> tests/ui/cast.rs:88:5 + --> tests/ui/cast.rs:87:5 | LL | 1usize as i8; | ^^^^^^^^^^^^ @@ -232,7 +232,7 @@ LL | i8::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may truncate the value - --> tests/ui/cast.rs:91:5 + --> tests/ui/cast.rs:90:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -244,7 +244,7 @@ LL | i16::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:91:5 + --> tests/ui/cast.rs:90:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | 1usize as i16; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:96:5 + --> tests/ui/cast.rs:95:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -265,19 +265,19 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:96:5 + --> tests/ui/cast.rs:95:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:100:5 + --> tests/ui/cast.rs:99:5 | LL | 1usize as i64; | ^^^^^^^^^^^^^ error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:105:5 + --> tests/ui/cast.rs:104:5 | LL | 1u16 as isize; | ^^^^^^^^^^^^^ @@ -286,13 +286,13 @@ LL | 1u16 as isize; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:109:5 + --> tests/ui/cast.rs:108:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:112:5 + --> tests/ui/cast.rs:111:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -304,55 +304,55 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:112:5 + --> tests/ui/cast.rs:111:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:117:5 + --> tests/ui/cast.rs:116:5 | LL | -1i32 as u32; | ^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:120:5 + --> tests/ui/cast.rs:119:5 | LL | -1isize as usize; | ^^^^^^^^^^^^^^^^ error: casting `i8` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:131:5 + --> tests/ui/cast.rs:130:5 | LL | (i8::MIN).abs() as u8; | ^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:135:5 + --> tests/ui/cast.rs:134:5 | LL | (-1i64).abs() as u64; | ^^^^^^^^^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:136:5 + --> tests/ui/cast.rs:135:5 | LL | (-1isize).abs() as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:143:5 + --> tests/ui/cast.rs:142:5 | LL | (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:158:5 + --> tests/ui/cast.rs:157:5 | LL | (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `i8` may truncate the value - --> tests/ui/cast.rs:209:5 + --> tests/ui/cast.rs:208:5 | LL | (-99999999999i64).min(1) as i8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -364,7 +364,7 @@ LL | i8::try_from((-99999999999i64).min(1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:223:5 + --> tests/ui/cast.rs:222:5 | LL | 999999u64.clamp(0, 256) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -376,7 +376,7 @@ LL | u8::try_from(999999u64.clamp(0, 256)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E2` to `u8` may truncate the value - --> tests/ui/cast.rs:246:21 + --> tests/ui/cast.rs:245:21 | LL | let _ = self as u8; | ^^^^^^^^^^ @@ -388,7 +388,7 @@ LL | let _ = u8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E2::B` to `u8` will truncate the value - --> tests/ui/cast.rs:248:21 + --> tests/ui/cast.rs:247:21 | LL | let _ = Self::B as u8; | ^^^^^^^^^^^^^ @@ -397,7 +397,7 @@ LL | let _ = Self::B as u8; = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]` error: casting `main::E5` to `i8` may truncate the value - --> tests/ui/cast.rs:290:21 + --> tests/ui/cast.rs:289:21 | LL | let _ = self as i8; | ^^^^^^^^^^ @@ -409,13 +409,13 @@ LL | let _ = i8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E5::A` to `i8` will truncate the value - --> tests/ui/cast.rs:292:21 + --> tests/ui/cast.rs:291:21 | LL | let _ = Self::A as i8; | ^^^^^^^^^^^^^ error: casting `main::E6` to `i16` may truncate the value - --> tests/ui/cast.rs:309:21 + --> tests/ui/cast.rs:308:21 | LL | let _ = self as i16; | ^^^^^^^^^^^ @@ -427,7 +427,7 @@ LL | let _ = i16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:328:21 + --> tests/ui/cast.rs:327:21 | LL | let _ = self as usize; | ^^^^^^^^^^^^^ @@ -439,7 +439,7 @@ LL | let _ = usize::try_from(self); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E10` to `u16` may truncate the value - --> tests/ui/cast.rs:375:21 + --> tests/ui/cast.rs:374:21 | LL | let _ = self as u16; | ^^^^^^^^^^^ @@ -451,7 +451,7 @@ LL | let _ = u16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:386:13 + --> tests/ui/cast.rs:385:13 | LL | let c = (q >> 16) as u8; | ^^^^^^^^^^^^^^^ @@ -463,7 +463,7 @@ LL | let c = u8::try_from(q >> 16); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:390:13 + --> tests/ui/cast.rs:389:13 | LL | let c = (q / 1000) as u8; | ^^^^^^^^^^^^^^^^ @@ -475,85 +475,85 @@ LL | let c = u8::try_from(q / 1000); | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:402:9 + --> tests/ui/cast.rs:401:9 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:407:32 + --> tests/ui/cast.rs:406:32 | LL | let _a = |x: i32| -> u32 { (x * x * x * x) as u32 }; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:409:5 + --> tests/ui/cast.rs:408:5 | LL | (2_i32).checked_pow(3).unwrap() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:410:5 + --> tests/ui/cast.rs:409:5 | LL | (-2_i32).pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:415:5 + --> tests/ui/cast.rs:414:5 | LL | (-5_i32 % 2) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:417:5 + --> tests/ui/cast.rs:416:5 | LL | (-5_i32 % -2) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:420:5 + --> tests/ui/cast.rs:419:5 | LL | (-2_i32 >> 1) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:424:5 + --> tests/ui/cast.rs:423:5 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:425:5 + --> tests/ui/cast.rs:424:5 | LL | (x * x * x) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:429:5 + --> tests/ui/cast.rs:428:5 | LL | (y * y * y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:431:5 + --> tests/ui/cast.rs:430:5 | LL | (y * y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:432:5 + --> tests/ui/cast.rs:431:5 | LL | (y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:434:5 + --> tests/ui/cast.rs:433:5 | LL | (y / y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `/` - --> tests/ui/cast.rs:434:6 + --> tests/ui/cast.rs:433:6 | LL | (y / y * y * -2) as u16; | ^^^^^ @@ -561,97 +561,97 @@ LL | (y / y * y * -2) as u16; = note: `#[deny(clippy::eq_op)]` on by default error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:437:5 + --> tests/ui/cast.rs:436:5 | LL | (y + y + y + -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:439:5 + --> tests/ui/cast.rs:438:5 | LL | (y + y + y + 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:443:5 + --> tests/ui/cast.rs:442:5 | LL | (z + -2) as u16; | ^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:445:5 + --> tests/ui/cast.rs:444:5 | LL | (z + z + 2) as u16; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:448:9 + --> tests/ui/cast.rs:447:9 | LL | (a * a * b * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:449:9 + --> tests/ui/cast.rs:448:9 | LL | (a * b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:451:9 + --> tests/ui/cast.rs:450:9 | LL | (a * -b * c) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:453:9 + --> tests/ui/cast.rs:452:9 | LL | (a * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:454:9 + --> tests/ui/cast.rs:453:9 | LL | (a * -2) as u32; | ^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:456:9 + --> tests/ui/cast.rs:455:9 | LL | (a * b * c * -2) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:458:9 + --> tests/ui/cast.rs:457:9 | LL | (a / b) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:459:9 + --> tests/ui/cast.rs:458:9 | LL | (a / b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:461:9 + --> tests/ui/cast.rs:460:9 | LL | (a / b + b * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:463:9 + --> tests/ui/cast.rs:462:9 | LL | a.saturating_pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:465:9 + --> tests/ui/cast.rs:464:9 | LL | (a.abs() * b.pow(2) / c.abs()) as u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:473:21 + --> tests/ui/cast.rs:472:21 | LL | let _ = i32::MIN as u32; // cast_sign_loss | ^^^^^^^^^^^^^^^ @@ -662,7 +662,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:474:21 + --> tests/ui/cast.rs:473:21 | LL | let _ = u32::MAX as u8; // cast_possible_truncation | ^^^^^^^^^^^^^^ @@ -678,7 +678,7 @@ LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:475:21 + --> tests/ui/cast.rs:474:21 | LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -690,7 +690,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:484:5 + --> tests/ui/cast.rs:483:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -702,13 +702,13 @@ LL | usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:484:5 + --> tests/ui/cast.rs:483:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:499:5 + --> tests/ui/cast.rs:498:5 | LL | (256 & 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ LL | u8::try_from(256 & 999999u64); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:501:5 + --> tests/ui/cast.rs:500:5 | LL | (255 % 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ From 6b1779b0ee1eb2a660543c816536f66c8f822d57 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Sat, 12 Oct 2024 23:32:50 +0100 Subject: [PATCH 03/99] Add lint to check for slow symbol comparisons --- clippy_lints/src/declared_lints.rs | 2 + clippy_lints/src/lib.rs | 1 + clippy_lints/src/utils/internal_lints.rs | 1 + .../internal_lints/slow_symbol_comparisons.rs | 69 +++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 0f9dbec8a755b..f75be5fc48f44 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -28,6 +28,8 @@ pub static LINTS: &[&crate::LintInfo] = &[ #[cfg(feature = "internal")] crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO, #[cfg(feature = "internal")] + crate::utils::internal_lints::slow_symbol_comparisons::SLOW_SYMBOL_COMPARISONS_INFO, + #[cfg(feature = "internal")] crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO, #[cfg(feature = "internal")] crate::utils::internal_lints::unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index b2229b53afd23..a817f63790441 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -605,6 +605,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| { Box::new(utils::internal_lints::almost_standard_lint_formulation::AlmostStandardFormulation::new()) }); + store.register_late_pass(|_| Box::new(utils::internal_lints::slow_symbol_comparisons::SlowSymbolComparisons)); } store.register_late_pass(move |_| Box::new(operators::arithmetic_side_effects::ArithmeticSideEffects::new(conf))); diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index f662c7651f6bb..deb983b6971dc 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -6,5 +6,6 @@ pub mod lint_without_lint_pass; pub mod msrv_attr_impl; pub mod outer_expn_data_pass; pub mod produce_ice; +pub mod slow_symbol_comparisons; pub mod unnecessary_def_path; pub mod unsorted_clippy_utils_paths; diff --git a/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs b/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs new file mode 100644 index 0000000000000..3742be0e103d6 --- /dev/null +++ b/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs @@ -0,0 +1,69 @@ +use clippy_utils::consts::{ConstEvalCtxt, Constant}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::ty::match_type; +use clippy_utils::{match_function_call, paths}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; +use rustc_span::Span; + +declare_clippy_lint! { + /// ### What it does + /// + /// Detects symbol comparision using `Symbol::intern`. + /// + /// ### Why is this bad? + /// + /// Comparision via `Symbol::as_str()` is faster if the interned symbols are not reused. + /// + /// ### Example + /// + /// None, see suggestion. + pub SLOW_SYMBOL_COMPARISONS, + internal, + "detects slow comparisions of symbol" +} + +declare_lint_pass!(SlowSymbolComparisons => [SLOW_SYMBOL_COMPARISONS]); + +fn check_slow_comparison<'tcx>( + cx: &LateContext<'tcx>, + op1: &'tcx Expr<'tcx>, + op2: &'tcx Expr<'tcx>, +) -> Option<(Span, String)> { + if match_type(cx, cx.typeck_results().expr_ty(op1), &paths::SYMBOL) + && let Some([symbol_name_expr]) = match_function_call(cx, op2, &paths::SYMBOL_INTERN) + && let Some(Constant::Str(symbol_name)) = ConstEvalCtxt::new(cx).eval_simple(symbol_name_expr) + { + Some((op1.span, symbol_name)) + } else { + None + } +} + +impl<'tcx> LateLintPass<'tcx> for SlowSymbolComparisons { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + if let ExprKind::Binary(op, left, right) = expr.kind + && (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne) + && let Some((symbol_span, symbol_name)) = + check_slow_comparison(cx, left, right).or_else(|| check_slow_comparison(cx, right, left)) + { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + SLOW_SYMBOL_COMPARISONS, + expr.span, + "comparing `Symbol` via `Symbol::intern`", + "use `Symbol::as_str` and check the string instead", + format!( + "{}.as_str() {} \"{symbol_name}\"", + snippet_with_applicability(cx, symbol_span, "symbol", &mut applicability), + op.node.as_str() + ), + applicability, + ); + }; + } +} From dedc380df91748eeed88c269682554d8a3ab44fb Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Sun, 13 Oct 2024 16:27:05 +0100 Subject: [PATCH 04/99] Apply fixes from lint --- clippy_lints/src/casts/cast_ptr_alignment.rs | 2 +- clippy_lints/src/explicit_write.rs | 2 +- clippy_lints/src/from_raw_with_void_ptr.rs | 2 +- clippy_lints/src/implicit_hasher.rs | 4 ++-- clippy_lints/src/infinite_iter.rs | 6 +++--- clippy_lints/src/iter_without_into_iter.rs | 2 +- clippy_lints/src/manual_hash_one.rs | 4 ++-- clippy_lints/src/manual_is_ascii_check.rs | 2 +- clippy_lints/src/matches/redundant_guards.rs | 12 ++++++------ clippy_lints/src/methods/filter_map.rs | 4 ++-- clippy_lints/src/methods/needless_collect.rs | 2 +- clippy_lints/src/methods/read_line_without_trim.rs | 4 ++-- clippy_lints/src/methods/unnecessary_filter_map.rs | 2 +- clippy_lints/src/minmax.rs | 4 ++-- clippy_lints/src/missing_fields_in_debug.rs | 2 +- clippy_lints/src/non_octal_unix_permissions.rs | 4 ++-- clippy_lints/src/operators/float_cmp.rs | 2 +- clippy_lints/src/ptr_offset_with_cast.rs | 2 +- clippy_lints/src/question_mark.rs | 4 ++-- clippy_lints/src/slow_vector_initialization.rs | 6 +++--- clippy_lints/src/strings.rs | 6 +++--- clippy_lints/src/transmute/eager_transmute.rs | 4 ++-- .../utils/internal_lints/lint_without_lint_pass.rs | 4 +--- .../src/utils/internal_lints/msrv_attr_impl.rs | 2 +- tests/ui-internal/unnecessary_symbol_str.fixed | 1 + tests/ui-internal/unnecessary_symbol_str.rs | 1 + tests/ui-internal/unnecessary_symbol_str.stderr | 10 +++++----- 27 files changed, 50 insertions(+), 50 deletions(-) diff --git a/clippy_lints/src/casts/cast_ptr_alignment.rs b/clippy_lints/src/casts/cast_ptr_alignment.rs index b11b967f8bc78..205357afd8408 100644 --- a/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -20,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { ); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); } else if let ExprKind::MethodCall(method_path, self_arg, [], _) = &expr.kind { - if method_path.ident.name == sym!(cast) + if method_path.ident.name.as_str() == "cast" && let Some(generic_args) = method_path.args && let [GenericArg::Type(cast_to)] = generic_args.args // There probably is no obvious reason to do this, just to be consistent with `as` cases. diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index 4e4434ec7d19c..0550c22761a56 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite { // match call to write_fmt && let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind) && let ExprKind::Call(write_recv_path, []) = write_recv.kind - && write_fun.ident.name == sym!(write_fmt) + && write_fun.ident.name.as_str() == "write_fmt" && let Some(def_id) = path_def_id(cx, write_recv_path) { // match calls to std::io::stdout() / std::io::stderr () diff --git a/clippy_lints/src/from_raw_with_void_ptr.rs b/clippy_lints/src/from_raw_with_void_ptr.rs index d62d008d480f7..c8828c9361576 100644 --- a/clippy_lints/src/from_raw_with_void_ptr.rs +++ b/clippy_lints/src/from_raw_with_void_ptr.rs @@ -41,7 +41,7 @@ impl LateLintPass<'_> for FromRawWithVoidPtr { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if let ExprKind::Call(box_from_raw, [arg]) = expr.kind && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_from_raw.kind - && seg.ident.name == sym!(from_raw) + && seg.ident.name.as_str() == "from_raw" && let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id)) && let arg_kind = cx.typeck_results().expr_ty(arg).kind() && let ty::RawPtr(ty, _) = arg_kind diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 4c5375730b8e3..c370f206c8f83 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -340,7 +340,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> { if self.cx.tcx.is_diagnostic_item(sym::HashMap, ty_did) { if method.ident.name == sym::new { self.suggestions.insert(e.span, "HashMap::default()".to_string()); - } else if method.ident.name == sym!(with_capacity) { + } else if method.ident.name.as_str() == "with_capacity" { self.suggestions.insert( e.span, format!( @@ -352,7 +352,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> { } else if self.cx.tcx.is_diagnostic_item(sym::HashSet, ty_did) { if method.ident.name == sym::new { self.suggestions.insert(e.span, "HashSet::default()".to_string()); - } else if method.ident.name == sym!(with_capacity) { + } else if method.ident.name.as_str() == "with_capacity" { self.suggestions.insert( e.span, format!( diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index 71c317552ee1a..48874d6064b6b 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -157,7 +157,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { .and(cap); } } - if method.ident.name == sym!(flat_map) && args.len() == 1 { + if method.ident.name.as_str() == "flat_map" && args.len() == 1 { if let ExprKind::Closure(&Closure { body, .. }) = args[0].kind { let body = cx.tcx.hir().body(body); return is_infinite(cx, body.value); @@ -224,7 +224,7 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { return MaybeInfinite.and(is_infinite(cx, receiver)); } } - if method.ident.name == sym!(last) && args.is_empty() { + if method.ident.name.as_str() == "last" && args.is_empty() { let not_double_ended = cx .tcx .get_diagnostic_item(sym::DoubleEndedIterator) @@ -234,7 +234,7 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { if not_double_ended { return is_infinite(cx, receiver); } - } else if method.ident.name == sym!(collect) { + } else if method.ident.name.as_str() == "collect" { let ty = cx.typeck_results().expr_ty(expr); if matches!( get_type_diagnostic_name(cx, ty), diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs index 1e6404190d3cf..36e94593e6fc1 100644 --- a/clippy_lints/src/iter_without_into_iter.rs +++ b/clippy_lints/src/iter_without_into_iter.rs @@ -142,7 +142,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter { ty.peel_refs().is_slice() || get_adt_inherent_method(cx, ty, expected_method_name).is_some() }) && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| { - if item.ident.name == sym!(IntoIter) { + if item.ident.name.as_str() == "IntoIter" { Some(cx.tcx.hir().impl_item(item.id).expect_type().span) } else { None diff --git a/clippy_lints/src/manual_hash_one.rs b/clippy_lints/src/manual_hash_one.rs index c62bd65bea683..7a9c99637428a 100644 --- a/clippy_lints/src/manual_hash_one.rs +++ b/clippy_lints/src/manual_hash_one.rs @@ -68,7 +68,7 @@ impl LateLintPass<'_> for ManualHashOne { && let Some(init) = local.init && !init.span.from_expansion() && let ExprKind::MethodCall(seg, build_hasher, [], _) = init.kind - && seg.ident.name == sym!(build_hasher) + && seg.ident.name.as_str() == "build_hasher" && let Node::Stmt(local_stmt) = cx.tcx.parent_hir_node(local.hir_id) && let Node::Block(block) = cx.tcx.parent_hir_node(local_stmt.hir_id) @@ -96,7 +96,7 @@ impl LateLintPass<'_> for ManualHashOne { && let Node::Expr(finish_expr) = cx.tcx.parent_hir_node(path_expr.hir_id) && !finish_expr.span.from_expansion() && let ExprKind::MethodCall(seg, _, [], _) = finish_expr.kind - && seg.ident.name == sym!(finish) + && seg.ident.name.as_str() == "finish" && self.msrv.meets(msrvs::BUILD_HASHER_HASH_ONE) { diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs index 24207705743d1..dec8c5d85dec2 100644 --- a/clippy_lints/src/manual_is_ascii_check.rs +++ b/clippy_lints/src/manual_is_ascii_check.rs @@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck { check_is_ascii(cx, macro_call.span, recv, &range, None); } } else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind - && path.ident.name == sym!(contains) + && path.ident.name.as_str() == "contains" && let Some(higher::Range { start: Some(start), end: Some(end), diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index 564c598a334c7..051a4eceab840 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -10,7 +10,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, MatchSource, Node, PatKind, UnOp}; use rustc_lint::LateContext; use rustc_span::symbol::Ident; -use rustc_span::{Span, Symbol, sym}; +use rustc_span::{Span, sym}; use std::borrow::Cow; use std::ops::ControlFlow; @@ -95,7 +95,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: } else if let ExprKind::MethodCall(path, recv, args, ..) = guard.kind && let Some(binding) = get_pat_binding(cx, recv, outer_arm) { - check_method_calls(cx, outer_arm, path.ident.name, recv, args, guard, &binding); + check_method_calls(cx, outer_arm, path.ident.name.as_str(), recv, args, guard, &binding); } } } @@ -103,7 +103,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: fn check_method_calls<'tcx>( cx: &LateContext<'tcx>, arm: &Arm<'tcx>, - method: Symbol, + method: &str, recv: &Expr<'_>, args: &[Expr<'_>], if_expr: &Expr<'_>, @@ -112,7 +112,7 @@ fn check_method_calls<'tcx>( let ty = cx.typeck_results().expr_ty(recv).peel_refs(); let slice_like = ty.is_slice() || ty.is_array(); - let sugg = if method == sym!(is_empty) { + let sugg = if method == "is_empty" { // `s if s.is_empty()` becomes "" // `arr if arr.is_empty()` becomes [] @@ -137,9 +137,9 @@ fn check_method_calls<'tcx>( if needles.is_empty() { sugg.insert_str(1, ".."); - } else if method == sym!(starts_with) { + } else if method == "starts_with" { sugg.insert_str(sugg.len() - 1, ", .."); - } else if method == sym!(ends_with) { + } else if method == "ends_with" { sugg.insert_str(1, ".., "); } else { return; diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs index 06482a743ddf4..c181e944fff88 100644 --- a/clippy_lints/src/methods/filter_map.rs +++ b/clippy_lints/src/methods/filter_map.rs @@ -234,12 +234,12 @@ impl<'tcx> OffendingFilterExpr<'tcx> { // the latter only calls `effect` once let side_effect_expr_span = receiver.can_have_side_effects().then_some(receiver.span); - if cx.tcx.is_diagnostic_item(sym::Option, recv_ty.did()) && path.ident.name == sym!(is_some) { + if cx.tcx.is_diagnostic_item(sym::Option, recv_ty.did()) && path.ident.name.as_str() == "is_some" { Some(Self::IsSome { receiver, side_effect_expr_span, }) - } else if cx.tcx.is_diagnostic_item(sym::Result, recv_ty.did()) && path.ident.name == sym!(is_ok) { + } else if cx.tcx.is_diagnostic_item(sym::Result, recv_ty.did()) && path.ident.name.as_str() == "is_ok" { Some(Self::IsOk { receiver, side_effect_expr_span, diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 96a31812ca475..055107068ae03 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -322,7 +322,7 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> { // Check function calls on our collection if let ExprKind::MethodCall(method_name, recv, args, _) = &expr.kind { if args.is_empty() - && method_name.ident.name == sym!(collect) + && method_name.ident.name.as_str() == "collect" && is_trait_method(self.cx, expr, sym::Iterator) { self.current_mutably_captured_ids = get_captured_ids(self.cx, self.cx.typeck_results().expr_ty(recv)); diff --git a/clippy_lints/src/methods/read_line_without_trim.rs b/clippy_lints/src/methods/read_line_without_trim.rs index 65e545ed03a02..db2b9d4d92fb6 100644 --- a/clippy_lints/src/methods/read_line_without_trim.rs +++ b/clippy_lints/src/methods/read_line_without_trim.rs @@ -44,7 +44,7 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr< if let Some(parent) = get_parent_expr(cx, expr) { let data = if let ExprKind::MethodCall(segment, recv, args, span) = parent.kind { if args.is_empty() - && segment.ident.name == sym!(parse) + && segment.ident.name.as_str() == "parse" && let parse_result_ty = cx.typeck_results().expr_ty(parent) && is_type_diagnostic_item(cx, parse_result_ty, sym::Result) && let ty::Adt(_, substs) = parse_result_ty.kind() @@ -58,7 +58,7 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr< "calling `.parse()` on a string without trimming the trailing newline character", "checking", )) - } else if segment.ident.name == sym!(ends_with) + } else if segment.ident.name.as_str() == "ends_with" && recv.span == expr.span && let [arg] = args && expr_is_string_literal_without_trailing_newline(arg) diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index ca46da81fa053..1cbb1bcc663e2 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -78,7 +78,7 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc (true, true) }, hir::ExprKind::MethodCall(segment, recv, [arg], _) => { - if segment.ident.name == sym!(then_some) + if segment.ident.name.as_str() == "then_some" && cx.typeck_results().expr_ty(recv).is_bool() && path_to_local_id(arg, arg_id) { diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index e95864c6db8b5..ed89b3b34386f 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -79,9 +79,9 @@ fn min_max<'a, 'tcx>(cx: &LateContext<'tcx>, expr: &'a Expr<'a>) -> Option<(MinM }, ExprKind::MethodCall(path, receiver, args @ [_], _) => { if cx.typeck_results().expr_ty(receiver).is_floating_point() || is_trait_method(cx, expr, sym::Ord) { - if path.ident.name == sym!(max) { + if path.ident.name.as_str() == "max" { fetch_const(cx, Some(receiver), args, MinMax::Max) - } else if path.ident.name == sym!(min) { + } else if path.ident.name.as_str() == "min" { fetch_const(cx, Some(receiver), args, MinMax::Min) } else { None diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs index fc01b6753f1c7..f28b431ab997e 100644 --- a/clippy_lints/src/missing_fields_in_debug.rs +++ b/clippy_lints/src/missing_fields_in_debug.rs @@ -116,7 +116,7 @@ fn should_lint<'tcx>( if path.ident.name == sym::debug_struct && is_type_diagnostic_item(cx, recv_ty, sym::Formatter) { has_debug_struct = true; - } else if path.ident.name == sym!(finish_non_exhaustive) + } else if path.ident.name.as_str() == "finish_non_exhaustive" && is_type_diagnostic_item(cx, recv_ty, sym::DebugStruct) { has_finish_non_exhaustive = true; diff --git a/clippy_lints/src/non_octal_unix_permissions.rs b/clippy_lints/src/non_octal_unix_permissions.rs index 3f156aa551040..0caa19cd84436 100644 --- a/clippy_lints/src/non_octal_unix_permissions.rs +++ b/clippy_lints/src/non_octal_unix_permissions.rs @@ -43,12 +43,12 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions { match &expr.kind { ExprKind::MethodCall(path, func, [param], _) => { if let Some(adt) = cx.typeck_results().expr_ty(func).peel_refs().ty_adt_def() - && ((path.ident.name == sym!(mode) + && ((path.ident.name.as_str() == "mode" && matches!( cx.tcx.get_diagnostic_name(adt.did()), Some(sym::FsOpenOptions | sym::DirBuilder) )) - || (path.ident.name == sym!(set_mode) + || (path.ident.name.as_str() == "set_mode" && cx.tcx.is_diagnostic_item(sym::FsPermissions, adt.did()))) && let ExprKind::Lit(_) = param.kind && param.span.eq_ctxt(expr.span) diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 8e394944c2130..ab5f91c1d6725 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -107,7 +107,7 @@ fn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { } if let ExprKind::MethodCall(method_name, self_arg, [], _) = expr.kind - && sym!(signum) == method_name.ident.name + && method_name.ident.name.as_str() == "signum" // Check that the receiver of the signum() is a float (expressions[0] is the receiver of // the method call) { diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs index 56d07aeae1758..808a7e005c679 100644 --- a/clippy_lints/src/ptr_offset_with_cast.rs +++ b/clippy_lints/src/ptr_offset_with_cast.rs @@ -96,7 +96,7 @@ fn expr_as_ptr_offset_call<'tcx>( if path_segment.ident.name == sym::offset { return Some((arg_0, arg_1, Method::Offset)); } - if path_segment.ident.name == sym!(wrapping_offset) { + if path_segment.ident.name.as_str() == "wrapping_offset" { return Some((arg_0, arg_1, Method::WrappingOffset)); } } diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index 9344cb41993a7..28968866e1f8e 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -163,8 +163,8 @@ fn is_early_return(smbl: Symbol, cx: &LateContext<'_>, if_block: &IfBlockType<'_ is_type_diagnostic_item(cx, caller_ty, smbl) && expr_return_none_or_err(smbl, cx, if_then, caller, None) && match smbl { - sym::Option => call_sym == sym!(is_none), - sym::Result => call_sym == sym!(is_err), + sym::Option => call_sym.as_str() == "is_none", + sym::Result => call_sym.as_str() == "is_err", _ => false, } }, diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index ec6e45256d149..8c8f11569c8c2 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -235,7 +235,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> { if self.initialization_found && let ExprKind::MethodCall(path, self_arg, [extend_arg], _) = expr.kind && path_to_local_id(self_arg, self.vec_alloc.local_id) - && path.ident.name == sym!(extend) + && path.ident.name.as_str() == "extend" && self.is_repeat_take(extend_arg) { self.slow_expression = Some(InitializationType::Extend(expr)); @@ -247,7 +247,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> { if self.initialization_found && let ExprKind::MethodCall(path, self_arg, [len_arg, fill_arg], _) = expr.kind && path_to_local_id(self_arg, self.vec_alloc.local_id) - && path.ident.name == sym!(resize) + && path.ident.name.as_str() == "resize" // Check that is filled with 0 && is_integer_literal(fill_arg, 0) { @@ -269,7 +269,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> { /// Returns `true` if give expression is `repeat(0).take(...)` fn is_repeat_take(&mut self, expr: &'tcx Expr<'tcx>) -> bool { if let ExprKind::MethodCall(take_path, recv, [len_arg], _) = expr.kind - && take_path.ident.name == sym!(take) + && take_path.ident.name.as_str() == "take" // Check that take is applied to `repeat(0)` && self.is_repeat_zero(recv) { diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index bf49bb6016293..e09c07060065c 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -286,7 +286,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { if !in_external_macro(cx.sess(), e.span) && let ExprKind::MethodCall(path, receiver, ..) = &e.kind - && path.ident.name == sym!(as_bytes) + && path.ident.name.as_str() == "as_bytes" && let ExprKind::Lit(lit) = &receiver.kind && let LitKind::Str(lit_content, _) = &lit.node { @@ -332,7 +332,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { } if let ExprKind::MethodCall(path, recv, [], _) = &e.kind - && path.ident.name == sym!(into_bytes) + && path.ident.name.as_str() == "into_bytes" && let ExprKind::MethodCall(path, recv, [], _) = &recv.kind && matches!(path.ident.name.as_str(), "to_owned" | "to_string") && let ExprKind::Lit(lit) = &recv.kind @@ -493,7 +493,7 @@ impl<'tcx> LateLintPass<'tcx> for TrimSplitWhitespace { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { let tyckres = cx.typeck_results(); if let ExprKind::MethodCall(path, split_recv, [], split_ws_span) = expr.kind - && path.ident.name == sym!(split_whitespace) + && path.ident.name.as_str() == "split_whitespace" && let Some(split_ws_def_id) = tyckres.type_dependent_def_id(expr.hir_id) && cx.tcx.is_diagnostic_item(sym::str_split_whitespace, split_ws_def_id) && let ExprKind::MethodCall(path, _trim_recv, [], trim_span) = split_recv.kind diff --git a/clippy_lints/src/transmute/eager_transmute.rs b/clippy_lints/src/transmute/eager_transmute.rs index 1dfc9f7091e8c..ca9daf2d2a037 100644 --- a/clippy_lints/src/transmute/eager_transmute.rs +++ b/clippy_lints/src/transmute/eager_transmute.rs @@ -43,7 +43,7 @@ fn binops_with_local(cx: &LateContext<'_>, local_expr: &Expr<'_>, expr: &Expr<'_ binops_with_local(cx, local_expr, lhs) || binops_with_local(cx, local_expr, rhs) }, ExprKind::MethodCall(path, receiver, [arg], _) - if path.ident.name == sym!(contains) + if path.ident.name.as_str() == "contains" // ... `contains` called on some kind of range && let Some(receiver_adt) = cx.typeck_results().expr_ty(receiver).peel_refs().ty_adt_def() && let lang_items = cx.tcx.lang_items() @@ -81,7 +81,7 @@ pub(super) fn check<'tcx>( if let Some(then_some_call) = peel_parent_unsafe_blocks(cx, expr) && let ExprKind::MethodCall(path, receiver, [arg], _) = then_some_call.kind && cx.typeck_results().expr_ty(receiver).is_bool() - && path.ident.name == sym!(then_some) + && path.ident.name.as_str() == "then_some" && is_local_with_projections(transmutable) && binops_with_local(cx, transmutable, receiver) && is_normalizable(cx, cx.param_env, from_ty) diff --git a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index dd45602221267..6b007e3030d6b 100644 --- a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -218,9 +218,7 @@ pub(super) fn is_lint_ref_type(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool { fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'_>) { if let Some(value) = extract_clippy_version_value(cx, item) { - // The `sym!` macro doesn't work as it only expects a single token. - // It's better to keep it this way and have a direct `Symbol::intern` call here. - if value == Symbol::intern("pre 1.29.0") { + if value.as_str() == "pre 1.29.0" { return; } diff --git a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs index 63fcbd61528d2..6869224615303 100644 --- a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs +++ b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs @@ -42,7 +42,7 @@ impl LateLintPass<'_> for MsrvAttrImpl { .filter(|t| matches!(t.unpack(), GenericArgKind::Type(_))) .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV)) }) - && !items.iter().any(|item| item.ident.name == sym!(check_attributes)) + && !items.iter().any(|item| item.ident.name.as_str() == "check_attributes") { let context = if is_late_pass { "LateContext" } else { "EarlyContext" }; let lint_pass = if is_late_pass { "LateLintPass" } else { "EarlyLintPass" }; diff --git a/tests/ui-internal/unnecessary_symbol_str.fixed b/tests/ui-internal/unnecessary_symbol_str.fixed index eb79fdbc4b4c8..8e7f020c1f659 100644 --- a/tests/ui-internal/unnecessary_symbol_str.fixed +++ b/tests/ui-internal/unnecessary_symbol_str.fixed @@ -1,6 +1,7 @@ #![feature(rustc_private)] #![deny(clippy::internal)] #![allow( + clippy::slow_symbol_comparisons, clippy::borrow_deref_ref, clippy::unnecessary_operation, unused_must_use, diff --git a/tests/ui-internal/unnecessary_symbol_str.rs b/tests/ui-internal/unnecessary_symbol_str.rs index bbea13af92a54..9aeeb9aaf3aa3 100644 --- a/tests/ui-internal/unnecessary_symbol_str.rs +++ b/tests/ui-internal/unnecessary_symbol_str.rs @@ -1,6 +1,7 @@ #![feature(rustc_private)] #![deny(clippy::internal)] #![allow( + clippy::slow_symbol_comparisons, clippy::borrow_deref_ref, clippy::unnecessary_operation, unused_must_use, diff --git a/tests/ui-internal/unnecessary_symbol_str.stderr b/tests/ui-internal/unnecessary_symbol_str.stderr index 551167a9ff58b..668c11722f91c 100644 --- a/tests/ui-internal/unnecessary_symbol_str.stderr +++ b/tests/ui-internal/unnecessary_symbol_str.stderr @@ -1,5 +1,5 @@ error: unnecessary `Symbol` to string conversion - --> tests/ui-internal/unnecessary_symbol_str.rs:15:5 + --> tests/ui-internal/unnecessary_symbol_str.rs:16:5 | LL | Symbol::intern("foo").as_str() == "clippy"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::sym::clippy` @@ -12,25 +12,25 @@ LL | #![deny(clippy::internal)] = note: `#[deny(clippy::unnecessary_symbol_str)]` implied by `#[deny(clippy::internal)]` error: unnecessary `Symbol` to string conversion - --> tests/ui-internal/unnecessary_symbol_str.rs:16:5 + --> tests/ui-internal/unnecessary_symbol_str.rs:17:5 | LL | Symbol::intern("foo").to_string() == "self"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower` error: unnecessary `Symbol` to string conversion - --> tests/ui-internal/unnecessary_symbol_str.rs:17:5 + --> tests/ui-internal/unnecessary_symbol_str.rs:18:5 | LL | Symbol::intern("foo").to_ident_string() != "Self"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper` error: unnecessary `Symbol` to string conversion - --> tests/ui-internal/unnecessary_symbol_str.rs:18:5 + --> tests/ui-internal/unnecessary_symbol_str.rs:19:5 | LL | &*Ident::empty().as_str() == "clippy"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ident::empty().name == rustc_span::sym::clippy` error: unnecessary `Symbol` to string conversion - --> tests/ui-internal/unnecessary_symbol_str.rs:19:5 + --> tests/ui-internal/unnecessary_symbol_str.rs:20:5 | LL | "clippy" == Ident::empty().to_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::clippy == Ident::empty().name` From a650692f8d53fb1ff3abf2ebb000721d1f4a4035 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Sun, 13 Oct 2024 16:36:08 +0100 Subject: [PATCH 05/99] Add test --- .../ui-internal/slow_symbol_comparisons.fixed | 24 +++++++++++++++++++ tests/ui-internal/slow_symbol_comparisons.rs | 24 +++++++++++++++++++ .../slow_symbol_comparisons.stderr | 23 ++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/ui-internal/slow_symbol_comparisons.fixed create mode 100644 tests/ui-internal/slow_symbol_comparisons.rs create mode 100644 tests/ui-internal/slow_symbol_comparisons.stderr diff --git a/tests/ui-internal/slow_symbol_comparisons.fixed b/tests/ui-internal/slow_symbol_comparisons.fixed new file mode 100644 index 0000000000000..2cbd646a0fd5d --- /dev/null +++ b/tests/ui-internal/slow_symbol_comparisons.fixed @@ -0,0 +1,24 @@ +#![feature(rustc_private)] +#![warn(clippy::slow_symbol_comparisons)] + +extern crate rustc_span; + +use clippy_utils::sym; +use rustc_span::Symbol; + +fn main() { + let symbol = sym!(example); + let other_symbol = sym!(other_example); + + // Should lint + let slow_comparison = symbol.as_str() == "example"; + //~^ error: comparing `Symbol` via `Symbol::intern` + let slow_comparison_macro = symbol.as_str() == "example"; + //~^ error: comparing `Symbol` via `Symbol::intern` + let slow_comparison_backwards = symbol.as_str() == "example"; + //~^ error: comparing `Symbol` via `Symbol::intern` + + // Should not lint + let faster_comparison = symbol.as_str() == "other_example"; + let preinterned_comparison = symbol == other_symbol; +} diff --git a/tests/ui-internal/slow_symbol_comparisons.rs b/tests/ui-internal/slow_symbol_comparisons.rs new file mode 100644 index 0000000000000..0cea3c3fcff9f --- /dev/null +++ b/tests/ui-internal/slow_symbol_comparisons.rs @@ -0,0 +1,24 @@ +#![feature(rustc_private)] +#![warn(clippy::slow_symbol_comparisons)] + +extern crate rustc_span; + +use clippy_utils::sym; +use rustc_span::Symbol; + +fn main() { + let symbol = sym!(example); + let other_symbol = sym!(other_example); + + // Should lint + let slow_comparison = symbol == Symbol::intern("example"); + //~^ error: comparing `Symbol` via `Symbol::intern` + let slow_comparison_macro = symbol == sym!(example); + //~^ error: comparing `Symbol` via `Symbol::intern` + let slow_comparison_backwards = sym!(example) == symbol; + //~^ error: comparing `Symbol` via `Symbol::intern` + + // Should not lint + let faster_comparison = symbol.as_str() == "other_example"; + let preinterned_comparison = symbol == other_symbol; +} diff --git a/tests/ui-internal/slow_symbol_comparisons.stderr b/tests/ui-internal/slow_symbol_comparisons.stderr new file mode 100644 index 0000000000000..72cb20a7fed90 --- /dev/null +++ b/tests/ui-internal/slow_symbol_comparisons.stderr @@ -0,0 +1,23 @@ +error: comparing `Symbol` via `Symbol::intern` + --> tests/ui-internal/slow_symbol_comparisons.rs:14:27 + | +LL | let slow_comparison = symbol == Symbol::intern("example"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `Symbol::as_str` and check the string instead: `symbol.as_str() == "example"` + | + = note: `-D clippy::slow-symbol-comparisons` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::slow_symbol_comparisons)]` + +error: comparing `Symbol` via `Symbol::intern` + --> tests/ui-internal/slow_symbol_comparisons.rs:16:33 + | +LL | let slow_comparison_macro = symbol == sym!(example); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `Symbol::as_str` and check the string instead: `symbol.as_str() == "example"` + +error: comparing `Symbol` via `Symbol::intern` + --> tests/ui-internal/slow_symbol_comparisons.rs:18:37 + | +LL | let slow_comparison_backwards = sym!(example) == symbol; + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `Symbol::as_str` and check the string instead: `symbol.as_str() == "example"` + +error: aborting due to 3 previous errors + From 979e2971897e8aa4a02d914a6336b5291a0839c7 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Sun, 13 Oct 2024 18:44:21 +0100 Subject: [PATCH 06/99] Update book --- .../src/development/common_tools_writing_lints.md | 4 ++-- book/src/development/method_checking.md | 15 ++++----------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/book/src/development/common_tools_writing_lints.md b/book/src/development/common_tools_writing_lints.md index 09171d86a2097..77910917963ee 100644 --- a/book/src/development/common_tools_writing_lints.md +++ b/book/src/development/common_tools_writing_lints.md @@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for MyStructLint { // Check our expr is calling a method if let hir::ExprKind::MethodCall(path, _, _self_arg, ..) = &expr.kind // Check the name of this method is `some_method` - && path.ident.name == sym!(some_method) + && path.ident.name.as_str() == "some_method" // Optionally, check the type of the self argument. // - See "Checking for a specific type" { @@ -167,7 +167,7 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl { // Check if item is a method/function if let ImplItemKind::Fn(ref signature, _) = impl_item.kind // Check the method is named `some_method` - && impl_item.ident.name == sym!(some_method) + && impl_item.ident.name.as_str() == "some_method" // We can also check it has a parameter `self` && signature.decl.implicit_self.has_implicit_self() // We can go further and even check if its return type is `String` diff --git a/book/src/development/method_checking.md b/book/src/development/method_checking.md index 56d1be37519e9..9c5d4b516db2c 100644 --- a/book/src/development/method_checking.md +++ b/book/src/development/method_checking.md @@ -3,8 +3,8 @@ In some scenarios we might want to check for methods when developing a lint. There are two kinds of questions that we might be curious about: -- Invocation: Does an expression call a specific method? -- Definition: Does an `impl` define a method? +- Invocation: Does an expression call a specific method? +- Definition: Does an `impl` define a method? ## Checking if an `expr` is calling a specific method @@ -23,7 +23,7 @@ impl<'tcx> LateLintPass<'tcx> for OurFancyMethodLint { // Check our expr is calling a method with pattern matching if let hir::ExprKind::MethodCall(path, _, [self_arg, ..]) = &expr.kind // Check if the name of this method is `our_fancy_method` - && path.ident.name == sym!(our_fancy_method) + && path.ident.name.as_str() == "our_fancy_method" // We can check the type of the self argument whenever necessary. // (It's necessary if we want to check that method is specifically belonging to a specific trait, // for example, a `map` method could belong to user-defined trait instead of to `Iterator`) @@ -41,10 +41,6 @@ information on the pattern matching. As mentioned in [Define Lints](defining_lints.md#lint-types), the `methods` lint type is full of pattern matching with `MethodCall` in case the reader wishes to explore more. -Additionally, we use the [`clippy_utils::sym!`][sym] macro to conveniently -convert an input `our_fancy_method` into a `Symbol` and compare that symbol to -the [`Ident`]'s name in the [`PathSegment`] in the [`MethodCall`]. - ## Checking if a `impl` block implements a method While sometimes we want to check whether a method is being called or not, other @@ -71,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl { // Check if item is a method/function if let ImplItemKind::Fn(ref signature, _) = impl_item.kind // Check the method is named `our_fancy_method` - && impl_item.ident.name == sym!(our_fancy_method) + && impl_item.ident.name.as_str() == "our_fancy_method" // We can also check it has a parameter `self` && signature.decl.implicit_self.has_implicit_self() // We can go even further and even check if its return type is `String` @@ -85,9 +81,6 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl { [`check_impl_item`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_impl_item [`ExprKind`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/enum.ExprKind.html -[`Ident`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_span/symbol/struct.Ident.html [`ImplItem`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_hir/hir/struct.ImplItem.html [`LateLintPass`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/trait.LateLintPass.html [`MethodCall`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/enum.ExprKind.html#variant.MethodCall -[`PathSegment`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/struct.PathSegment.html -[sym]: https://doc.rust-lang.org/stable/nightly-rustc/clippy_utils/macro.sym.html From 11162d1b4808f85362048a816a0f5f4c79f2f747 Mon Sep 17 00:00:00 2001 From: wowinter13 Date: Tue, 15 Oct 2024 00:18:50 +0200 Subject: [PATCH 07/99] fix: remove unnecessary unfilter_map usages --- .../src/methods/unnecessary_filter_map.rs | 31 +++++++++-- tests/ui/unnecessary_filter_map.rs | 13 +++-- tests/ui/unnecessary_filter_map.stderr | 53 +++++++++++++------ tests/ui/unnecessary_find_map.rs | 9 ++-- tests/ui/unnecessary_find_map.stderr | 30 +++++------ 5 files changed, 92 insertions(+), 44 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index ca46da81fa053..33f073e75a616 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -1,13 +1,15 @@ use super::utils::clone_or_copy_needed; -use clippy_utils::diagnostics::span_lint; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::ty::is_copy; use clippy_utils::usage::mutated_variables; use clippy_utils::visitors::{Descend, for_each_expr_without_closures}; -use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id}; +use clippy_utils::{MaybePath, is_res_lang_ctor, is_trait_method, path_res, path_to_local_id}; use core::ops::ControlFlow; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::LangItem::{OptionNone, OptionSome}; use rustc_lint::LateContext; +use rustc_middle::query::Key; use rustc_middle::ty; use rustc_span::sym; @@ -36,9 +38,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a ControlFlow::Continue(Descend::Yes) } }); - let in_ty = cx.typeck_results().node_type(body.params[0].hir_id); let sugg = if !found_filtering { + // Check if the closure is .filter_map(|x| Some(x)) + if name == "filter_map" + && let hir::ExprKind::Call(expr, args) = body.value.kind + && is_res_lang_ctor(cx, path_res(cx, expr), OptionSome) + && arg_id.ty_def_id() == args[0].hir_id().ty_def_id() + && let hir::ExprKind::Path(_) = args[0].kind + { + span_lint_and_sugg( + cx, + UNNECESSARY_FILTER_MAP, + expr.span, + format!("{name} is unnecessary"), + "try removing the filter_map", + String::new(), + Applicability::MaybeIncorrect, + ); + } if name == "filter_map" { "map" } else { "map(..).next()" } } else if !found_mapping && !mutates_arg && (!clone_or_copy_needed || is_copy(cx, in_ty)) { match cx.typeck_results().expr_ty(body.value).kind() { @@ -52,7 +70,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a } else { return; }; - span_lint( + span_lint_and_sugg( cx, if name == "filter_map" { UNNECESSARY_FILTER_MAP @@ -60,7 +78,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a UNNECESSARY_FIND_MAP }, expr.span, - format!("this `.{name}` can be written more simply using `.{sugg}`"), + format!("this `.{name}` can be written more simply"), + format!("try replacing with `.{sugg}`"), + sugg.to_string(), + Applicability::MaybeIncorrect, ); } } diff --git a/tests/ui/unnecessary_filter_map.rs b/tests/ui/unnecessary_filter_map.rs index 1e0d7d12965c2..8cf102ab0a557 100644 --- a/tests/ui/unnecessary_filter_map.rs +++ b/tests/ui/unnecessary_filter_map.rs @@ -1,26 +1,31 @@ +//@no-rustfix #![allow(dead_code)] fn main() { let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None }); - //~^ ERROR: this `.filter_map` can be written more simply using `.filter` + //~^ ERROR: this `.filter_map` can be written more simply //~| NOTE: `-D clippy::unnecessary-filter-map` implied by `-D warnings` let _ = (0..4).filter_map(|x| { - //~^ ERROR: this `.filter_map` can be written more simply using `.filter` + //~^ ERROR: this `.filter_map` can be written more simply if x > 1 { return Some(x); }; None }); let _ = (0..4).filter_map(|x| match x { - //~^ ERROR: this `.filter_map` can be written more simply using `.filter` + //~^ ERROR: this `.filter_map` can be written more simply 0 | 1 => None, _ => Some(x), }); let _ = (0..4).filter_map(|x| Some(x + 1)); - //~^ ERROR: this `.filter_map` can be written more simply using `.map` + //~^ ERROR: this `.filter_map` can be written more simply let _ = (0..4).filter_map(i32::checked_abs); + + let _ = (0..4).filter_map(Some); + + let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); } fn filter_map_none_changes_item_type() -> impl Iterator { diff --git a/tests/ui/unnecessary_filter_map.stderr b/tests/ui/unnecessary_filter_map.stderr index f32d444ba9e09..7ef3d970420b8 100644 --- a/tests/ui/unnecessary_filter_map.stderr +++ b/tests/ui/unnecessary_filter_map.stderr @@ -1,14 +1,14 @@ -error: this `.filter_map` can be written more simply using `.filter` - --> tests/ui/unnecessary_filter_map.rs:4:13 +error: this `.filter_map` can be written more simply + --> tests/ui/unnecessary_filter_map.rs:5:13 | LL | let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.filter`: `filter` | = note: `-D clippy::unnecessary-filter-map` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_filter_map)]` -error: this `.filter_map` can be written more simply using `.filter` - --> tests/ui/unnecessary_filter_map.rs:7:13 +error: this `.filter_map` can be written more simply + --> tests/ui/unnecessary_filter_map.rs:8:13 | LL | let _ = (0..4).filter_map(|x| { | _____________^ @@ -18,10 +18,10 @@ LL | | return Some(x); LL | | }; LL | | None LL | | }); - | |______^ + | |______^ help: try replacing with `.filter`: `filter` -error: this `.filter_map` can be written more simply using `.filter` - --> tests/ui/unnecessary_filter_map.rs:14:13 +error: this `.filter_map` can be written more simply + --> tests/ui/unnecessary_filter_map.rs:15:13 | LL | let _ = (0..4).filter_map(|x| match x { | _____________^ @@ -29,19 +29,40 @@ LL | | LL | | 0 | 1 => None, LL | | _ => Some(x), LL | | }); - | |______^ + | |______^ help: try replacing with `.filter`: `filter` -error: this `.filter_map` can be written more simply using `.map` - --> tests/ui/unnecessary_filter_map.rs:20:13 +error: this `.filter_map` can be written more simply + --> tests/ui/unnecessary_filter_map.rs:21:13 | LL | let _ = (0..4).filter_map(|x| Some(x + 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.map`: `map` -error: this `.filter_map` can be written more simply using `.filter` - --> tests/ui/unnecessary_filter_map.rs:160:14 +error: redundant closure + --> tests/ui/unnecessary_filter_map.rs:28:57 + | +LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); + | ^^^^^^^^^^^ help: replace the closure with the function itself: `Some` + | + = note: `-D clippy::redundant-closure` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]` + +error: filter_map is unnecessary + --> tests/ui/unnecessary_filter_map.rs:28:61 + | +LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); + | ^^^^ help: try removing the filter_map + +error: this `.filter_map` can be written more simply + --> tests/ui/unnecessary_filter_map.rs:28:13 + | +LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.map`: `map` + +error: this `.filter_map` can be written more simply + --> tests/ui/unnecessary_filter_map.rs:165:14 | LL | let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.filter`: `filter` -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors diff --git a/tests/ui/unnecessary_find_map.rs b/tests/ui/unnecessary_find_map.rs index 9972b68092abf..c357d85324819 100644 --- a/tests/ui/unnecessary_find_map.rs +++ b/tests/ui/unnecessary_find_map.rs @@ -1,24 +1,25 @@ +//@no-rustfix #![allow(dead_code)] fn main() { let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None }); - //~^ ERROR: this `.find_map` can be written more simply using `.find` + //~^ ERROR: this `.find_map` can be written more simply //~| NOTE: `-D clippy::unnecessary-find-map` implied by `-D warnings` let _ = (0..4).find_map(|x| { - //~^ ERROR: this `.find_map` can be written more simply using `.find` + //~^ ERROR: this `.find_map` can be written more simply if x > 1 { return Some(x); }; None }); let _ = (0..4).find_map(|x| match x { - //~^ ERROR: this `.find_map` can be written more simply using `.find` + //~^ ERROR: this `.find_map` can be written more simply 0 | 1 => None, _ => Some(x), }); let _ = (0..4).find_map(|x| Some(x + 1)); - //~^ ERROR: this `.find_map` can be written more simply using `.map(..).next()` + //~^ ERROR: this `.find_map` can be written more simply let _ = (0..4).find_map(i32::checked_abs); } diff --git a/tests/ui/unnecessary_find_map.stderr b/tests/ui/unnecessary_find_map.stderr index bb939a9921467..650b6d64d35b7 100644 --- a/tests/ui/unnecessary_find_map.stderr +++ b/tests/ui/unnecessary_find_map.stderr @@ -1,14 +1,14 @@ -error: this `.find_map` can be written more simply using `.find` - --> tests/ui/unnecessary_find_map.rs:4:13 +error: this `.find_map` can be written more simply + --> tests/ui/unnecessary_find_map.rs:5:13 | LL | let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.find`: `find` | = note: `-D clippy::unnecessary-find-map` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_find_map)]` -error: this `.find_map` can be written more simply using `.find` - --> tests/ui/unnecessary_find_map.rs:7:13 +error: this `.find_map` can be written more simply + --> tests/ui/unnecessary_find_map.rs:8:13 | LL | let _ = (0..4).find_map(|x| { | _____________^ @@ -18,10 +18,10 @@ LL | | return Some(x); LL | | }; LL | | None LL | | }); - | |______^ + | |______^ help: try replacing with `.find`: `find` -error: this `.find_map` can be written more simply using `.find` - --> tests/ui/unnecessary_find_map.rs:14:13 +error: this `.find_map` can be written more simply + --> tests/ui/unnecessary_find_map.rs:15:13 | LL | let _ = (0..4).find_map(|x| match x { | _____________^ @@ -29,19 +29,19 @@ LL | | LL | | 0 | 1 => None, LL | | _ => Some(x), LL | | }); - | |______^ + | |______^ help: try replacing with `.find`: `find` -error: this `.find_map` can be written more simply using `.map(..).next()` - --> tests/ui/unnecessary_find_map.rs:20:13 +error: this `.find_map` can be written more simply + --> tests/ui/unnecessary_find_map.rs:21:13 | LL | let _ = (0..4).find_map(|x| Some(x + 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.map(..).next()`: `map(..).next()` -error: this `.find_map` can be written more simply using `.find` - --> tests/ui/unnecessary_find_map.rs:32:14 +error: this `.find_map` can be written more simply + --> tests/ui/unnecessary_find_map.rs:33:14 | LL | let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.find`: `find` error: aborting due to 5 previous errors From 40cb24f23c9b74bba8009d0dfe8ef84d265e4d9c Mon Sep 17 00:00:00 2001 From: wowinter13 Date: Wed, 16 Oct 2024 01:42:43 +0200 Subject: [PATCH 08/99] fix: simplify suggestion --- clippy_lints/src/methods/unnecessary_filter_map.rs | 2 +- tests/ui/unnecessary_filter_map.stderr | 12 ++++++------ tests/ui/unnecessary_find_map.stderr | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 33f073e75a616..49d5d7318f696 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -79,7 +79,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a }, expr.span, format!("this `.{name}` can be written more simply"), - format!("try replacing with `.{sugg}`"), + format!("try instead"), sugg.to_string(), Applicability::MaybeIncorrect, ); diff --git a/tests/ui/unnecessary_filter_map.stderr b/tests/ui/unnecessary_filter_map.stderr index 7ef3d970420b8..b21589c5f8445 100644 --- a/tests/ui/unnecessary_filter_map.stderr +++ b/tests/ui/unnecessary_filter_map.stderr @@ -2,7 +2,7 @@ error: this `.filter_map` can be written more simply --> tests/ui/unnecessary_filter_map.rs:5:13 | LL | let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.filter`: `filter` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `filter` | = note: `-D clippy::unnecessary-filter-map` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_filter_map)]` @@ -18,7 +18,7 @@ LL | | return Some(x); LL | | }; LL | | None LL | | }); - | |______^ help: try replacing with `.filter`: `filter` + | |______^ help: try instead: `filter` error: this `.filter_map` can be written more simply --> tests/ui/unnecessary_filter_map.rs:15:13 @@ -29,13 +29,13 @@ LL | | LL | | 0 | 1 => None, LL | | _ => Some(x), LL | | }); - | |______^ help: try replacing with `.filter`: `filter` + | |______^ help: try instead: `filter` error: this `.filter_map` can be written more simply --> tests/ui/unnecessary_filter_map.rs:21:13 | LL | let _ = (0..4).filter_map(|x| Some(x + 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.map`: `map` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map` error: redundant closure --> tests/ui/unnecessary_filter_map.rs:28:57 @@ -56,13 +56,13 @@ error: this `.filter_map` can be written more simply --> tests/ui/unnecessary_filter_map.rs:28:13 | LL | let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.map`: `map` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map` error: this `.filter_map` can be written more simply --> tests/ui/unnecessary_filter_map.rs:165:14 | LL | let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.filter`: `filter` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `filter` error: aborting due to 8 previous errors diff --git a/tests/ui/unnecessary_find_map.stderr b/tests/ui/unnecessary_find_map.stderr index 650b6d64d35b7..98a6c3d164a63 100644 --- a/tests/ui/unnecessary_find_map.stderr +++ b/tests/ui/unnecessary_find_map.stderr @@ -2,7 +2,7 @@ error: this `.find_map` can be written more simply --> tests/ui/unnecessary_find_map.rs:5:13 | LL | let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.find`: `find` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `find` | = note: `-D clippy::unnecessary-find-map` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_find_map)]` @@ -18,7 +18,7 @@ LL | | return Some(x); LL | | }; LL | | None LL | | }); - | |______^ help: try replacing with `.find`: `find` + | |______^ help: try instead: `find` error: this `.find_map` can be written more simply --> tests/ui/unnecessary_find_map.rs:15:13 @@ -29,19 +29,19 @@ LL | | LL | | 0 | 1 => None, LL | | _ => Some(x), LL | | }); - | |______^ help: try replacing with `.find`: `find` + | |______^ help: try instead: `find` error: this `.find_map` can be written more simply --> tests/ui/unnecessary_find_map.rs:21:13 | LL | let _ = (0..4).find_map(|x| Some(x + 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.map(..).next()`: `map(..).next()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map(..).next()` error: this `.find_map` can be written more simply --> tests/ui/unnecessary_find_map.rs:33:14 | LL | let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing with `.find`: `find` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `find` error: aborting due to 5 previous errors From ad002ea99f5e5ca6e47a9550964bf0a882083e5b Mon Sep 17 00:00:00 2001 From: wowinter13 Date: Wed, 16 Oct 2024 01:49:15 +0200 Subject: [PATCH 09/99] fix: linter --- clippy_lints/src/methods/unnecessary_filter_map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 49d5d7318f696..264363aadfbc8 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -79,7 +79,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a }, expr.span, format!("this `.{name}` can be written more simply"), - format!("try instead"), + "try instead", sugg.to_string(), Applicability::MaybeIncorrect, ); From 85559223519ee0d72fa90dc48d92faab36758bd0 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 17 Oct 2024 22:36:26 +0500 Subject: [PATCH 10/99] Don't trigger const_is_empty for inline const assertions --- clippy_lints/src/methods/is_empty.rs | 13 ++++++++++++- tests/ui/const_is_empty.rs | 14 ++++++++++++++ tests/ui/const_is_empty.stderr | 8 +++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/methods/is_empty.rs b/clippy_lints/src/methods/is_empty.rs index cc82f6cfd6384..a0c21faaa4cc8 100644 --- a/clippy_lints/src/methods/is_empty.rs +++ b/clippy_lints/src/methods/is_empty.rs @@ -1,6 +1,7 @@ use clippy_utils::consts::ConstEvalCtxt; use clippy_utils::diagnostics::span_lint; -use clippy_utils::{find_binding_init, path_to_local}; +use clippy_utils::macros::{is_assert_macro, root_macro_call}; +use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context, path_to_local}; use rustc_hir::{Expr, HirId}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; @@ -14,6 +15,16 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ if in_external_macro(cx.sess(), expr.span) || !receiver.span.eq_ctxt(expr.span) { return; } + if let Some(parent) = get_parent_expr(cx, expr) { + if let Some(parent) = get_parent_expr(cx, parent) { + if is_inside_always_const_context(cx.tcx, expr.hir_id) + && let Some(macro_call) = root_macro_call(parent.span) + && is_assert_macro(cx, macro_call.def_id) + { + return; + } + } + } let init_expr = expr_or_init(cx, receiver); if !receiver.span.eq_ctxt(init_expr.span) { return; diff --git a/tests/ui/const_is_empty.rs b/tests/ui/const_is_empty.rs index 04e0de91ecfbf..b5e27b61548a0 100644 --- a/tests/ui/const_is_empty.rs +++ b/tests/ui/const_is_empty.rs @@ -171,3 +171,17 @@ fn constant_from_external_crate() { let _ = std::env::consts::EXE_EXTENSION.is_empty(); // Do not lint, `exe_ext` comes from the `std` crate } + +fn issue_13106() { + const { + assert!(!NON_EMPTY_STR.is_empty()); + } + + const { + assert!(EMPTY_STR.is_empty()); + } + + const { + EMPTY_STR.is_empty(); + } +} diff --git a/tests/ui/const_is_empty.stderr b/tests/ui/const_is_empty.stderr index 7f80b520b1a44..0afba940d8b4b 100644 --- a/tests/ui/const_is_empty.stderr +++ b/tests/ui/const_is_empty.stderr @@ -157,5 +157,11 @@ error: this expression always evaluates to true LL | let _ = val.is_empty(); | ^^^^^^^^^^^^^^ -error: aborting due to 26 previous errors +error: this expression always evaluates to true + --> tests/ui/const_is_empty.rs:185:9 + | +LL | EMPTY_STR.is_empty(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 27 previous errors From fea5e77da1dedea3a64711cb1b75c141e72ba248 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 18 Oct 2024 13:44:06 +0200 Subject: [PATCH 11/99] Merge commit 'a109190d7060236e655fc75533373fa274ec5343' into clippy-subtree-update --- .github/deploy.sh | 2 +- .gitignore | 1 + CHANGELOG.md | 42 +- Cargo.toml | 8 +- book/src/lint_configuration.md | 2 +- clippy_config/Cargo.toml | 2 +- clippy_config/src/conf.rs | 26 +- clippy_config/src/lib.rs | 2 +- clippy_config/src/msrvs.rs | 3 +- clippy_dev/Cargo.toml | 2 +- clippy_dev/src/new_lint.rs | 24 +- clippy_dev/src/serve.rs | 4 +- clippy_lints/Cargo.toml | 3 +- clippy_lints/src/box_default.rs | 2 +- clippy_lints/src/byte_char_slices.rs | 2 +- .../src/casts/cast_abs_to_unsigned.rs | 2 +- clippy_lints/src/casts/cast_ptr_alignment.rs | 2 +- clippy_lints/src/create_dir.rs | 2 +- clippy_lints/src/declare_clippy_lint.rs | 162 +++ clippy_lints/src/declared_lints.rs | 3 + clippy_lints/src/default.rs | 4 +- clippy_lints/src/doc/mod.rs | 2 +- clippy_lints/src/exit.rs | 2 +- clippy_lints/src/explicit_write.rs | 2 +- clippy_lints/src/floating_point_arithmetic.rs | 4 +- clippy_lints/src/format_impl.rs | 2 +- clippy_lints/src/if_let_mutex.rs | 2 +- clippy_lints/src/implicit_saturating_sub.rs | 25 +- clippy_lints/src/implied_bounds_in_impls.rs | 4 +- clippy_lints/src/item_name_repetitions.rs | 35 +- clippy_lints/src/large_futures.rs | 2 +- clippy_lints/src/large_stack_arrays.rs | 19 +- clippy_lints/src/len_zero.rs | 18 +- clippy_lints/src/lib.rs | 17 +- clippy_lints/src/lifetimes.rs | 4 +- clippy_lints/src/literal_representation.rs | 1 - clippy_lints/src/loops/infinite_loop.rs | 19 +- .../src/loops/manual_while_let_some.rs | 11 +- clippy_lints/src/loops/same_item_push.rs | 6 +- clippy_lints/src/macro_use.rs | 1 - clippy_lints/src/main_recursion.rs | 2 +- clippy_lints/src/manual_bits.rs | 2 +- clippy_lints/src/manual_float_methods.rs | 22 +- clippy_lints/src/manual_ignore_case_cmp.rs | 127 ++ clippy_lints/src/manual_is_power_of_two.rs | 10 +- .../src/manual_slice_size_calculation.rs | 18 +- clippy_lints/src/manual_string_new.rs | 19 +- .../src/matches/redundant_pattern_match.rs | 2 +- clippy_lints/src/matches/try_err.rs | 4 +- clippy_lints/src/methods/clone_on_copy.rs | 2 +- clippy_lints/src/methods/expect_fun_call.rs | 4 +- clippy_lints/src/methods/iter_filter.rs | 4 +- .../src/methods/manual_c_str_literals.rs | 5 +- .../methods/manual_saturating_arithmetic.rs | 3 +- clippy_lints/src/methods/map_clone.rs | 3 +- clippy_lints/src/methods/mod.rs | 4 +- clippy_lints/src/methods/needless_collect.rs | 5 +- clippy_lints/src/methods/or_fun_call.rs | 4 +- .../src/methods/read_line_without_trim.rs | 3 +- .../src/methods/readonly_write_lock.rs | 2 +- clippy_lints/src/methods/seek_from_current.rs | 5 +- .../seek_to_start_instead_of_rewind.rs | 5 +- .../src/methods/single_char_insert_string.rs | 2 +- .../src/methods/single_char_push_string.rs | 2 +- clippy_lints/src/methods/str_splitn.rs | 2 +- .../src/methods/uninit_assumed_init.rs | 3 +- .../methods/unnecessary_first_then_check.rs | 2 +- clippy_lints/src/methods/useless_asref.rs | 5 +- .../src/missing_asserts_for_indexing.rs | 2 +- clippy_lints/src/missing_doc.rs | 2 +- clippy_lints/src/mut_key.rs | 13 +- clippy_lints/src/mut_reference.rs | 6 +- clippy_lints/src/needless_maybe_sized.rs | 2 +- clippy_lints/src/non_canonical_impls.rs | 2 +- clippy_lints/src/non_zero_suggestions.rs | 2 +- clippy_lints/src/operators/float_cmp.rs | 2 +- clippy_lints/src/pathbuf_init_then_push.rs | 2 +- clippy_lints/src/ptr.rs | 8 +- clippy_lints/src/ptr_offset_with_cast.rs | 2 +- clippy_lints/src/question_mark.rs | 7 +- clippy_lints/src/raw_strings.rs | 192 +-- clippy_lints/src/rc_clone_in_vec_init.rs | 4 +- clippy_lints/src/regex.rs | 65 +- clippy_lints/src/returns.rs | 2 +- .../src/significant_drop_tightening.rs | 3 +- clippy_lints/src/size_of_in_element_count.rs | 2 +- .../src/slow_vector_initialization.rs | 4 +- clippy_lints/src/strings.rs | 11 +- clippy_lints/src/to_digit_is_some.rs | 5 +- clippy_lints/src/trait_bounds.rs | 96 +- clippy_lints/src/unit_types/unit_arg.rs | 9 +- clippy_lints/src/unnecessary_literal_bound.rs | 158 +++ .../src/unnecessary_map_on_constructor.rs | 10 +- .../src/unnecessary_owned_empty_strings.rs | 4 +- clippy_lints/src/unused_io_amount.rs | 4 +- clippy_lints/src/unused_result_ok.rs | 2 +- clippy_lints/src/unwrap.rs | 9 +- clippy_lints/src/useless_conversion.rs | 4 +- .../utils/internal_lints/collapsible_calls.rs | 31 +- .../internal_lints/lint_without_lint_pass.rs | 8 +- clippy_lints/src/vec.rs | 3 +- clippy_utils/Cargo.toml | 2 +- clippy_utils/src/consts.rs | 5 +- clippy_utils/src/hir_utils.rs | 119 +- clippy_utils/src/lib.rs | 2 +- clippy_utils/src/ty.rs | 48 +- declare_clippy_lint/Cargo.toml | 13 - declare_clippy_lint/src/lib.rs | 182 --- lintcheck/ci_crates.toml | 18 +- lintcheck/src/json.rs | 2 +- rinja.toml | 3 + rust-toolchain | 2 +- rustc_tools_util/CHANGELOG.md | 9 + rustc_tools_util/Cargo.toml | 2 +- rustc_tools_util/README.md | 4 +- rustc_tools_util/src/lib.rs | 75 +- tests/compile-test.rs | 41 +- tests/config-metadata.rs | 4 +- .../array_size_threshold.stderr | 14 +- .../allowed_prefixes/item_name_repetitions.rs | 2 +- .../item_name_repetitions.rs | 2 +- tests/ui/expect_fun_call.stderr | 30 +- tests/ui/implicit_saturating_sub.fixed | 6 + tests/ui/implicit_saturating_sub.rs | 10 + tests/ui/implicit_saturating_sub.stderr | 13 +- tests/ui/infinite_loops.rs | 38 + tests/ui/infinite_loops.stderr | 64 +- tests/ui/invalid_null_ptr_usage.fixed | 44 +- tests/ui/invalid_null_ptr_usage.stderr | 44 +- tests/ui/invalid_null_ptr_usage_no_std.fixed | 57 + tests/ui/invalid_null_ptr_usage_no_std.rs | 57 + tests/ui/invalid_null_ptr_usage_no_std.stderr | 136 +++ tests/ui/large_const_arrays.fixed | 18 +- tests/ui/large_const_arrays.rs | 18 +- tests/ui/large_stack_arrays.rs | 44 +- tests/ui/large_stack_arrays.stderr | 48 +- ...> manual_c_str_literals.edition2021.fixed} | 3 + ... manual_c_str_literals.edition2021.stderr} | 26 +- tests/ui/manual_c_str_literals.rs | 3 + tests/ui/manual_float_methods.rs | 5 +- tests/ui/manual_float_methods.stderr | 8 +- tests/ui/manual_ignore_case_cmp.fixed | 107 ++ tests/ui/manual_ignore_case_cmp.rs | 107 ++ tests/ui/manual_ignore_case_cmp.stderr | 546 +++++++++ tests/ui/manual_slice_size_calculation.fixed | 4 + tests/ui/manual_slice_size_calculation.rs | 4 + tests/ui/manual_slice_size_calculation.stderr | 26 +- tests/ui/module_name_repetitions.rs | 18 +- tests/ui/module_name_repetitions.stderr | 8 +- tests/ui/mut_key.stderr | 60 + tests/ui/needless_raw_string.fixed | 9 + tests/ui/needless_raw_string.rs | 9 + tests/ui/needless_raw_string.stderr | 38 +- tests/ui/needless_raw_string_hashes.fixed | 10 + tests/ui/needless_raw_string_hashes.rs | 10 + tests/ui/needless_raw_string_hashes.stderr | 38 +- tests/ui/or_fun_call.fixed | 10 +- tests/ui/or_fun_call.rs | 10 +- tests/ui/or_fun_call.stderr | 40 +- tests/ui/regex.rs | 30 +- tests/ui/regex.stderr | 52 +- tests/ui/trait_duplication_in_bounds.fixed | 31 + tests/ui/trait_duplication_in_bounds.rs | 31 + tests/ui/trait_duplication_in_bounds.stderr | 32 +- .../transmutes_expressible_as_ptr_casts.fixed | 5 +- .../ui/transmutes_expressible_as_ptr_casts.rs | 5 +- tests/ui/unnecessary_literal_bound.fixed | 65 + tests/ui/unnecessary_literal_bound.rs | 65 + tests/ui/unnecessary_literal_bound.stderr | 23 + tests/ui/unwrap_or.fixed | 4 +- tests/ui/unwrap_or.rs | 4 +- tests/ui/unwrap_or.stderr | 4 +- tests/versioncheck.rs | 1 - triagebot.toml | 1 + util/gh-pages/index.html | 330 ------ util/gh-pages/index_template.html | 232 ++++ util/gh-pages/script.js | 1050 ++++++++--------- util/gh-pages/style.css | 51 +- util/gh-pages/theme.js | 56 + 179 files changed, 4025 insertions(+), 1745 deletions(-) create mode 100644 clippy_lints/src/declare_clippy_lint.rs create mode 100644 clippy_lints/src/manual_ignore_case_cmp.rs create mode 100644 clippy_lints/src/unnecessary_literal_bound.rs delete mode 100644 declare_clippy_lint/Cargo.toml delete mode 100644 declare_clippy_lint/src/lib.rs create mode 100644 rinja.toml create mode 100644 tests/ui/invalid_null_ptr_usage_no_std.fixed create mode 100644 tests/ui/invalid_null_ptr_usage_no_std.rs create mode 100644 tests/ui/invalid_null_ptr_usage_no_std.stderr rename tests/ui/{manual_c_str_literals.fixed => manual_c_str_literals.edition2021.fixed} (93%) rename tests/ui/{manual_c_str_literals.stderr => manual_c_str_literals.edition2021.stderr} (84%) create mode 100644 tests/ui/manual_ignore_case_cmp.fixed create mode 100644 tests/ui/manual_ignore_case_cmp.rs create mode 100644 tests/ui/manual_ignore_case_cmp.stderr create mode 100644 tests/ui/unnecessary_literal_bound.fixed create mode 100644 tests/ui/unnecessary_literal_bound.rs create mode 100644 tests/ui/unnecessary_literal_bound.stderr delete mode 100644 util/gh-pages/index.html create mode 100644 util/gh-pages/index_template.html create mode 100644 util/gh-pages/theme.js diff --git a/.github/deploy.sh b/.github/deploy.sh index 5b4b4be4e36b5..ea118a3b6fce5 100644 --- a/.github/deploy.sh +++ b/.github/deploy.sh @@ -8,8 +8,8 @@ rm -rf out/master/ || exit 0 echo "Making the docs for master" mkdir out/master/ cp util/gh-pages/index.html out/master +cp util/gh-pages/theme.js out/master cp util/gh-pages/script.js out/master -cp util/gh-pages/lints.json out/master cp util/gh-pages/style.css out/master if [[ -n $TAG_NAME ]]; then diff --git a/.gitignore b/.gitignore index 181b71a658b9a..a7c25b29021fb 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ out # gh pages docs util/gh-pages/lints.json +util/gh-pages/index.html # rustfmt backups *.rs.bk diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d253d52531e6..4bdbc91db9397 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,46 @@ document. ## Unreleased / Beta / In Rust Nightly -[b794b8e0...master](https://github.com/rust-lang/rust-clippy/compare/b794b8e0...master) +[0f8eabd6...master](https://github.com/rust-lang/rust-clippy/compare/0f8eabd6...master) + +## Rust 1.82 + +Current stable, released 2024-10-17 + +[View all 108 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-07-11T20%3A12%3A07Z..2024-08-24T20%3A55%3A35Z+base%3Amaster) + +### New Lints + +* Added [`too_long_first_doc_paragraph`] to `nursery` + [#12993](https://github.com/rust-lang/rust-clippy/pull/12993) +* Added [`unused_result_ok`] to `restriction` + [#12150](https://github.com/rust-lang/rust-clippy/pull/12150) +* Added [`pathbuf_init_then_push`] to `restriction` + [#11700](https://github.com/rust-lang/rust-clippy/pull/11700) + +### Enhancements + +* [`explicit_iter_loop`]: Now respects the `msrv` configuration + [#13288](https://github.com/rust-lang/rust-clippy/pull/13288) +* [`assigning_clones`]: No longer lints in test code + [#13273](https://github.com/rust-lang/rust-clippy/pull/13273) +* [`inconsistent_struct_constructor`]: Lint attributes now work on the struct definition + [#13211](https://github.com/rust-lang/rust-clippy/pull/13211) +* [`set_contains_or_insert`]: Now also checks for `BTreeSet` + [#13053](https://github.com/rust-lang/rust-clippy/pull/13053) +* [`doc_markdown`]: Added the following identifiers to [`doc-valid-idents`]: AccessKit, + CoreFoundation, CoreGraphics, CoreText, Direct2D, Direct3D, DirectWrite, PostScript, + OpenAL, OpenType, WebRTC, WebSocket, WebTransport, NetBSD, and OpenBSD + [#13093](https://github.com/rust-lang/rust-clippy/pull/13093) + +### ICE Fixes + +* [`uninit_vec`] + [rust#128720](https://github.com/rust-lang/rust/pull/128720) ## Rust 1.81 -Current stable, released 2024-09-05 +Released 2024-09-05 ### New Lints @@ -5621,6 +5656,7 @@ Released 2018-09-13 [`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map [`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten [`manual_hash_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one +[`manual_ignore_case_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ignore_case_cmp [`manual_inspect`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_inspect [`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed [`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check @@ -5874,6 +5910,7 @@ Released 2018-09-13 [`ref_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option [`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref [`ref_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_patterns +[`regex_creation_in_loops`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_creation_in_loops [`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro [`renamed_function_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#renamed_function_params [`repeat_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_once @@ -6027,6 +6064,7 @@ Released 2018-09-13 [`unnecessary_get_then_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check [`unnecessary_join`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_join [`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations +[`unnecessary_literal_bound`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_bound [`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap [`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_on_constructor [`unnecessary_min_or_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_min_or_max diff --git a/Cargo.toml b/Cargo.toml index cf810798d8cc1..1f7784fc489f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.83" +version = "0.1.84" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" @@ -23,7 +23,7 @@ path = "src/driver.rs" [dependencies] clippy_config = { path = "clippy_config" } clippy_lints = { path = "clippy_lints" } -rustc_tools_util = "0.3.0" +rustc_tools_util = "0.4.0" tempfile = { version = "3.3", optional = true } termize = "0.1" color-print = "0.3.4" @@ -39,6 +39,8 @@ toml = "0.7.3" walkdir = "2.3" filetime = "0.2.9" itertools = "0.12" +pulldown-cmark = "0.11" +rinja = { version = "0.3", default-features = false, features = ["config"] } # UI test dependencies clippy_utils = { path = "clippy_utils" } @@ -50,7 +52,7 @@ parking_lot = "0.12" tokio = { version = "1", features = ["io-util"] } [build-dependencies] -rustc_tools_util = "0.3.0" +rustc_tools_util = "0.4.0" [features] integration = ["tempfile"] diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 07a56fb33df11..43b551ae21617 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -329,7 +329,7 @@ arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] ## `array-size-threshold` The maximum allowed size for arrays on the stack -**Default Value:** `512000` +**Default Value:** `16384` --- **Affected lints:** diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 9da7112345de9..d21df202dcaba 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.83" +version = "0.1.84" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index e4e2c97fdc1d9..4757c0b1339a7 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -97,6 +97,30 @@ impl ConfError { } } +// Remove code tags and code behind '# 's, as they are not needed for the lint docs and --explain +pub fn sanitize_explanation(raw_docs: &str) -> String { + // Remove tags and hidden code: + let mut explanation = String::with_capacity(128); + let mut in_code = false; + for line in raw_docs.lines().map(str::trim) { + if let Some(lang) = line.strip_prefix("```") { + let tag = lang.split_once(',').map_or(lang, |(left, _)| left); + if !in_code && matches!(tag, "" | "rust" | "ignore" | "should_panic" | "no_run" | "compile_fail") { + explanation += "```rust\n"; + } else { + explanation += line; + explanation.push('\n'); + } + in_code = !in_code; + } else if !(in_code && line.starts_with("# ")) { + explanation += line; + explanation.push('\n'); + } + } + + explanation +} + macro_rules! wrap_option { () => { None @@ -366,7 +390,7 @@ define_Conf! { arithmetic_side_effects_allowed_unary: Vec = <_>::default(), /// The maximum allowed size for arrays on the stack #[lints(large_const_arrays, large_stack_arrays)] - array_size_threshold: u64 = 512_000, + array_size_threshold: u64 = 16 * 1024, /// Suppress lints whenever the suggested change would cause breakage for other crates. #[lints( box_collection, diff --git a/clippy_config/src/lib.rs b/clippy_config/src/lib.rs index c63d98a0a13f9..42651521f8d7a 100644 --- a/clippy_config/src/lib.rs +++ b/clippy_config/src/lib.rs @@ -26,5 +26,5 @@ mod metadata; pub mod msrvs; pub mod types; -pub use conf::{Conf, get_configuration_metadata, lookup_conf_file}; +pub use conf::{Conf, get_configuration_metadata, lookup_conf_file, sanitize_explanation}; pub use metadata::ClippyConfiguration; diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs index 68a3b11d3848f..2f4da4cba3df3 100644 --- a/clippy_config/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -17,8 +17,7 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { - 1,83,0 { CONST_EXTERN_FN } - 1,83,0 { CONST_FLOAT_BITS_CONV } + 1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY } 1,82,0 { IS_NONE_OR } 1,81,0 { LINT_REASONS_STABILIZATION } 1,80,0 { BOX_INTO_ITER} diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml index a5d72c3a559df..952a8711fb4e4 100644 --- a/clippy_dev/Cargo.toml +++ b/clippy_dev/Cargo.toml @@ -9,7 +9,7 @@ aho-corasick = "1.0" clap = { version = "4.4", features = ["derive"] } indoc = "1.0" itertools = "0.12" -opener = "0.6" +opener = "0.7" shell-escape = "0.1" walkdir = "2.3" diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index 5fd65017cfb97..e15ba3397178a 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -207,13 +207,13 @@ pub(crate) fn get_stabilization_version() -> String { fn get_test_file_contents(lint_name: &str, msrv: bool) -> String { let mut test = formatdoc!( - r#" + r" #![warn(clippy::{lint_name})] fn main() {{ // test code goes here }} - "# + " ); if msrv { @@ -272,23 +272,23 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { result.push_str(&if enable_msrv { formatdoc!( - r#" + r" use clippy_config::msrvs::{{self, Msrv}}; use clippy_config::Conf; {pass_import} use rustc_lint::{{{context_import}, {pass_type}, LintContext}}; use rustc_session::impl_lint_pass; - "# + " ) } else { formatdoc!( - r#" + r" {pass_import} use rustc_lint::{{{context_import}, {pass_type}}}; use rustc_session::declare_lint_pass; - "# + " ) }); @@ -296,7 +296,7 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { result.push_str(&if enable_msrv { formatdoc!( - r#" + r" pub struct {name_camel} {{ msrv: Msrv, }} @@ -315,15 +315,15 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String { // TODO: Add MSRV level to `clippy_config/src/msrvs.rs` if needed. // TODO: Update msrv config comment in `clippy_config/src/conf.rs` - "# + " ) } else { formatdoc!( - r#" + r" declare_lint_pass!({name_camel} => [{name_upper}]); impl {pass_type}{pass_lifetimes} for {name_camel} {{}} - "# + " ) }); @@ -416,7 +416,7 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R } else { let _: fmt::Result = writedoc!( lint_file_contents, - r#" + r" use rustc_lint::{{{context_import}, LintContext}}; use super::{name_upper}; @@ -425,7 +425,7 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R pub(super) fn check(cx: &{context_import}{pass_lifetimes}) {{ todo!(); }} - "# + " ); } diff --git a/clippy_dev/src/serve.rs b/clippy_dev/src/serve.rs index cc14cd8dae69e..d367fefec619c 100644 --- a/clippy_dev/src/serve.rs +++ b/clippy_dev/src/serve.rs @@ -19,7 +19,9 @@ pub fn run(port: u16, lint: Option) -> ! { }); loop { - if mtime("util/gh-pages/lints.json") < mtime("clippy_lints/src") { + let index_time = mtime("util/gh-pages/index.html"); + + if index_time < mtime("clippy_lints/src") || index_time < mtime("util/gh-pages/index_template.html") { Command::new(env::var("CARGO").unwrap_or("cargo".into())) .arg("collect-metadata") .spawn() diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index d1188940b46a8..63ea6faf60dbd 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.83" +version = "0.1.84" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" @@ -13,7 +13,6 @@ arrayvec = { version = "0.7", default-features = false } cargo_metadata = "0.18" clippy_config = { path = "../clippy_config" } clippy_utils = { path = "../clippy_utils" } -declare_clippy_lint = { path = "../declare_clippy_lint" } itertools = "0.12" quine-mc_cluskey = "0.2" regex-syntax = "0.8" diff --git a/clippy_lints/src/box_default.rs b/clippy_lints/src/box_default.rs index 40d154c0bdfe3..bf1d077fec28f 100644 --- a/clippy_lints/src/box_default.rs +++ b/clippy_lints/src/box_default.rs @@ -47,7 +47,7 @@ impl LateLintPass<'_> for BoxDefault { // And the call is that of a `Box` method && path_def_id(cx, ty).map_or(false, |id| Some(id) == cx.tcx.lang_items().owned_box()) // And the single argument to the call is another function call - // This is the `T::default()` of `Box::new(T::default())` + // This is the `T::default()` (or default equivalent) of `Box::new(T::default())` && let ExprKind::Call(arg_path, _) = arg.kind // And we are not in a foreign crate's macro && !in_external_macro(cx.sess(), expr.span) diff --git a/clippy_lints/src/byte_char_slices.rs b/clippy_lints/src/byte_char_slices.rs index dd2620b0b9df9..d88c0711b3971 100644 --- a/clippy_lints/src/byte_char_slices.rs +++ b/clippy_lints/src/byte_char_slices.rs @@ -41,7 +41,7 @@ impl EarlyLintPass for ByteCharSlice { "can be more succinctly written as a byte str", "try", format!("b\"{slice}\""), - Applicability::MaybeIncorrect, + Applicability::MachineApplicable, ); } } diff --git a/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/clippy_lints/src/casts/cast_abs_to_unsigned.rs index d4d5ee37bccbb..b7b63250864e6 100644 --- a/clippy_lints/src/casts/cast_abs_to_unsigned.rs +++ b/clippy_lints/src/casts/cast_abs_to_unsigned.rs @@ -19,7 +19,7 @@ pub(super) fn check( if msrv.meets(msrvs::UNSIGNED_ABS) && let ty::Int(from) = cast_from.kind() && let ty::Uint(to) = cast_to.kind() - && let ExprKind::MethodCall(method_path, receiver, ..) = cast_expr.kind + && let ExprKind::MethodCall(method_path, receiver, [], _) = cast_expr.kind && method_path.ident.name.as_str() == "abs" { let span = if from.bit_width() == to.bit_width() { diff --git a/clippy_lints/src/casts/cast_ptr_alignment.rs b/clippy_lints/src/casts/cast_ptr_alignment.rs index 960c81045e36f..b11b967f8bc78 100644 --- a/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -19,7 +19,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { cx.typeck_results().expr_ty(expr), ); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); - } else if let ExprKind::MethodCall(method_path, self_arg, ..) = &expr.kind { + } else if let ExprKind::MethodCall(method_path, self_arg, [], _) = &expr.kind { if method_path.ident.name == sym!(cast) && let Some(generic_args) = method_path.args && let [GenericArg::Type(cast_to)] = generic_args.args diff --git a/clippy_lints/src/create_dir.rs b/clippy_lints/src/create_dir.rs index 24570d8f4401c..b43906903a0e0 100644 --- a/clippy_lints/src/create_dir.rs +++ b/clippy_lints/src/create_dir.rs @@ -34,7 +34,7 @@ declare_lint_pass!(CreateDir => [CREATE_DIR]); impl LateLintPass<'_> for CreateDir { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if let ExprKind::Call(func, [arg, ..]) = expr.kind + if let ExprKind::Call(func, [arg]) = expr.kind && let ExprKind::Path(ref path) = func.kind && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id() && cx.tcx.is_diagnostic_item(sym::fs_create_dir, def_id) diff --git a/clippy_lints/src/declare_clippy_lint.rs b/clippy_lints/src/declare_clippy_lint.rs new file mode 100644 index 0000000000000..b1e39c70baa2b --- /dev/null +++ b/clippy_lints/src/declare_clippy_lint.rs @@ -0,0 +1,162 @@ +#[macro_export] +#[allow(clippy::crate_in_macro_def)] +macro_rules! declare_clippy_lint { + (@ + $(#[doc = $lit:literal])* + pub $lint_name:ident, + $category:ident, + $lintcategory:expr, + $desc:literal, + $version_expr:expr, + $version_lit:literal + ) => { + rustc_session::declare_tool_lint! { + $(#[doc = $lit])* + #[clippy::version = $version_lit] + pub clippy::$lint_name, + $category, + $desc, + report_in_external_macro:true + } + + pub(crate) static ${concat($lint_name, _INFO)}: &'static crate::LintInfo = &crate::LintInfo { + lint: &$lint_name, + category: $lintcategory, + explanation: concat!($($lit,"\n",)*), + location: concat!(file!(), "#L", line!()), + version: $version_expr + }; + }; + ( + $(#[doc = $lit:literal])* + #[clippy::version = $version:literal] + pub $lint_name:ident, + restriction, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Allow, crate::LintCategory::Restriction, $desc, + Some($version), $version + } + }; + ( + $(#[doc = $lit:literal])* + #[clippy::version = $version:literal] + pub $lint_name:ident, + style, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Warn, crate::LintCategory::Style, $desc, + Some($version), $version + + } + }; + ( + $(#[doc = $lit:literal])* + #[clippy::version = $version:literal] + pub $lint_name:ident, + correctness, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Deny, crate::LintCategory::Correctness, $desc, + Some($version), $version + + } + }; + ( + $(#[doc = $lit:literal])* + #[clippy::version = $version:literal] + pub $lint_name:ident, + perf, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Warn, crate::LintCategory::Perf, $desc, + Some($version), $version + } + }; + ( + $(#[doc = $lit:literal])* + #[clippy::version = $version:literal] + pub $lint_name:ident, + complexity, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Warn, crate::LintCategory::Complexity, $desc, + Some($version), $version + } + }; + ( + $(#[doc = $lit:literal])* + #[clippy::version = $version:literal] + pub $lint_name:ident, + suspicious, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Warn, crate::LintCategory::Suspicious, $desc, + Some($version), $version + } + }; + ( + $(#[doc = $lit:literal])* + #[clippy::version = $version:literal] + pub $lint_name:ident, + nursery, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Allow, crate::LintCategory::Nursery, $desc, + Some($version), $version + } + }; + ( + $(#[doc = $lit:literal])* + #[clippy::version = $version:literal] + pub $lint_name:ident, + pedantic, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Allow, crate::LintCategory::Pedantic, $desc, + Some($version), $version + } + }; + ( + $(#[doc = $lit:literal])* + #[clippy::version = $version:literal] + pub $lint_name:ident, + cargo, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Allow, crate::LintCategory::Cargo, $desc, + Some($version), $version + } + }; + + ( + $(#[doc = $lit:literal])* + pub $lint_name:ident, + internal, + $desc:literal + ) => { + declare_clippy_lint! {@ + $(#[doc = $lit])* + pub $lint_name, Allow, crate::LintCategory::Internal, $desc, + None, "0.0.0" + } + }; +} diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 9cec672beb004..3c4e75df8abe4 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -306,6 +306,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::manual_float_methods::MANUAL_IS_FINITE_INFO, crate::manual_float_methods::MANUAL_IS_INFINITE_INFO, crate::manual_hash_one::MANUAL_HASH_ONE_INFO, + crate::manual_ignore_case_cmp::MANUAL_IGNORE_CASE_CMP_INFO, crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO, crate::manual_is_power_of_two::MANUAL_IS_POWER_OF_TWO_INFO, crate::manual_let_else::MANUAL_LET_ELSE_INFO, @@ -639,6 +640,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::ref_patterns::REF_PATTERNS_INFO, crate::reference::DEREF_ADDROF_INFO, crate::regex::INVALID_REGEX_INFO, + crate::regex::REGEX_CREATION_IN_LOOPS_INFO, crate::regex::TRIVIAL_REGEX_INFO, crate::repeat_vec_with_capacity::REPEAT_VEC_WITH_CAPACITY_INFO, crate::reserve_after_initialization::RESERVE_AFTER_INITIALIZATION_INFO, @@ -736,6 +738,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::unit_types::UNIT_CMP_INFO, crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO, crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO, + crate::unnecessary_literal_bound::UNNECESSARY_LITERAL_BOUND_INFO, crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO, crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO, crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO, diff --git a/clippy_lints/src/default.rs b/clippy_lints/src/default.rs index dc10b64698b4f..de775b647952e 100644 --- a/clippy_lints/src/default.rs +++ b/clippy_lints/src/default.rs @@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for Default { if !expr.span.from_expansion() // Avoid cases already linted by `field_reassign_with_default` && !self.reassigned_linted.contains(&expr.span) - && let ExprKind::Call(path, ..) = expr.kind + && let ExprKind::Call(path, []) = expr.kind && !in_automatically_derived(cx.tcx, expr.hir_id) && let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() @@ -253,7 +253,7 @@ impl<'tcx> LateLintPass<'tcx> for Default { /// Checks if the given expression is the `default` method belonging to the `Default` trait. fn is_expr_default<'tcx>(expr: &'tcx Expr<'tcx>, cx: &LateContext<'tcx>) -> bool { - if let ExprKind::Call(fn_expr, _) = &expr.kind + if let ExprKind::Call(fn_expr, []) = &expr.kind && let ExprKind::Path(qpath) = &fn_expr.kind && let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id) { diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index e090644ae4410..89c6a4e08dc44 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -452,7 +452,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.82.0"] pub TOO_LONG_FIRST_DOC_PARAGRAPH, - style, + nursery, "ensure that the first line of a documentation paragraph isn't too long" } diff --git a/clippy_lints/src/exit.rs b/clippy_lints/src/exit.rs index f37d11f7eb9b7..3c235fab0098b 100644 --- a/clippy_lints/src/exit.rs +++ b/clippy_lints/src/exit.rs @@ -43,7 +43,7 @@ declare_lint_pass!(Exit => [EXIT]); impl<'tcx> LateLintPass<'tcx> for Exit { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { - if let ExprKind::Call(path_expr, _args) = e.kind + if let ExprKind::Call(path_expr, [_]) = e.kind && let ExprKind::Path(ref path) = path_expr.kind && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id() && cx.tcx.is_diagnostic_item(sym::process_exit, def_id) diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index 5b423a96918f6..4e4434ec7d19c 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite { && unwrap_fun.ident.name == sym::unwrap // match call to write_fmt && let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind) - && let ExprKind::Call(write_recv_path, _) = write_recv.kind + && let ExprKind::Call(write_recv_path, []) = write_recv.kind && write_fun.ident.name == sym!(write_fmt) && let Some(def_id) = path_def_id(cx, write_recv_path) { diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 8da6623f34de9..daa199779e3cb 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -436,12 +436,12 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { lhs, rhs, ) = expr.kind + && let ExprKind::MethodCall(path, self_arg, [], _) = &lhs.kind + && path.ident.name.as_str() == "exp" && cx.typeck_results().expr_ty(lhs).is_floating_point() && let Some(value) = ConstEvalCtxt::new(cx).eval(rhs) && (F32(1.0) == value || F64(1.0) == value) - && let ExprKind::MethodCall(path, self_arg, ..) = &lhs.kind && cx.typeck_results().expr_ty(self_arg).is_floating_point() - && path.ident.name.as_str() == "exp" { span_lint_and_sugg( cx, diff --git a/clippy_lints/src/format_impl.rs b/clippy_lints/src/format_impl.rs index 7c0515b8c5608..5619cb0ab1b06 100644 --- a/clippy_lints/src/format_impl.rs +++ b/clippy_lints/src/format_impl.rs @@ -151,7 +151,7 @@ struct FormatImplExpr<'a, 'tcx> { impl FormatImplExpr<'_, '_> { fn check_to_string_in_display(&self) { if self.format_trait_impl.name == sym::Display - && let ExprKind::MethodCall(path, self_arg, ..) = self.expr.kind + && let ExprKind::MethodCall(path, self_arg, [], _) = self.expr.kind // Get the hir_id of the object we are calling the method on // Is the method to_string() ? && path.ident.name == sym::to_string diff --git a/clippy_lints/src/if_let_mutex.rs b/clippy_lints/src/if_let_mutex.rs index 1c52514a330d4..ba80c099a0153 100644 --- a/clippy_lints/src/if_let_mutex.rs +++ b/clippy_lints/src/if_let_mutex.rs @@ -82,7 +82,7 @@ fn mutex_lock_call<'tcx>( expr: &'tcx Expr<'_>, op_mutex: Option<&'tcx Expr<'_>>, ) -> ControlFlow<&'tcx Expr<'tcx>> { - if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind + if let ExprKind::MethodCall(path, self_arg, [], _) = &expr.kind && path.ident.as_str() == "lock" && let ty = cx.typeck_results().expr_ty(self_arg).peel_refs() && is_type_diagnostic_item(cx, ty, sym::Mutex) diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs index f4a64f5c20b44..3b84b569c3edf 100644 --- a/clippy_lints/src/implicit_saturating_sub.rs +++ b/clippy_lints/src/implicit_saturating_sub.rs @@ -139,6 +139,13 @@ fn check_manual_check<'tcx>( if_block, else_block, msrv, + matches!( + clippy_utils::get_parent_expr(cx, expr), + Some(Expr { + kind: ExprKind::If(..), + .. + }) + ), ), BinOpKind::Lt | BinOpKind::Le => check_gt( cx, @@ -149,6 +156,13 @@ fn check_manual_check<'tcx>( if_block, else_block, msrv, + matches!( + clippy_utils::get_parent_expr(cx, expr), + Some(Expr { + kind: ExprKind::If(..), + .. + }) + ), ), _ => {}, } @@ -165,6 +179,7 @@ fn check_gt( if_block: &Expr<'_>, else_block: &Expr<'_>, msrv: &Msrv, + is_composited: bool, ) { if let Some(big_var) = Var::new(big_var) && let Some(little_var) = Var::new(little_var) @@ -178,6 +193,7 @@ fn check_gt( if_block, else_block, msrv, + is_composited, ); } } @@ -206,6 +222,7 @@ fn check_subtraction( if_block: &Expr<'_>, else_block: &Expr<'_>, msrv: &Msrv, + is_composited: bool, ) { let if_block = peel_blocks(if_block); let else_block = peel_blocks(else_block); @@ -226,6 +243,7 @@ fn check_subtraction( else_block, if_block, msrv, + is_composited, ); return; } @@ -242,13 +260,18 @@ fn check_subtraction( && let Some(little_var_snippet) = snippet_opt(cx, little_var.span) && (!is_in_const_context(cx) || msrv.meets(msrvs::SATURATING_SUB_CONST)) { + let sugg = format!( + "{}{big_var_snippet}.saturating_sub({little_var_snippet}){}", + if is_composited { "{ " } else { "" }, + if is_composited { " }" } else { "" } + ); span_lint_and_sugg( cx, IMPLICIT_SATURATING_SUB, expr_span, "manual arithmetic check found", "replace it with", - format!("{big_var_snippet}.saturating_sub({little_var_snippet})"), + sugg, Applicability::MachineApplicable, ); } diff --git a/clippy_lints/src/implied_bounds_in_impls.rs b/clippy_lints/src/implied_bounds_in_impls.rs index 590d9afd1b437..f4c00d8287def 100644 --- a/clippy_lints/src/implied_bounds_in_impls.rs +++ b/clippy_lints/src/implied_bounds_in_impls.rs @@ -3,8 +3,8 @@ use clippy_utils::source::snippet; use rustc_errors::{Applicability, SuggestionStyle}; use rustc_hir::def_id::DefId; use rustc_hir::{ - AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifier, - TyKind, WherePredicate, + AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifier, TyKind, + WherePredicate, }; use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; diff --git a/clippy_lints/src/item_name_repetitions.rs b/clippy_lints/src/item_name_repetitions.rs index 66a8a3167a4f2..dd90e2a6e94f4 100644 --- a/clippy_lints/src/item_name_repetitions.rs +++ b/clippy_lints/src/item_name_repetitions.rs @@ -50,11 +50,28 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Detects type names that are prefixed or suffixed by the - /// containing module's name. + /// Detects public item names that are prefixed or suffixed by the + /// containing public module's name. /// /// ### Why is this bad? - /// It requires the user to type the module name twice. + /// It requires the user to type the module name twice in each usage, + /// especially if they choose to import the module rather than its contents. + /// + /// Lack of such repetition is also the style used in the Rust standard library; + /// e.g. `io::Error` and `fmt::Error` rather than `io::IoError` and `fmt::FmtError`; + /// and `array::from_ref` rather than `array::array_from_ref`. + /// + /// ### Known issues + /// Glob re-exports are ignored; e.g. this will not warn even though it should: + /// + /// ```no_run + /// pub mod foo { + /// mod iteration { + /// pub struct FooIter {} + /// } + /// pub use iteration::*; // creates the path `foo::FooIter` + /// } + /// ``` /// /// ### Example /// ```no_run @@ -71,7 +88,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.33.0"] pub MODULE_NAME_REPETITIONS, - pedantic, + restriction, "type names prefixed/postfixed with their containing module's name" } @@ -389,12 +406,12 @@ impl LateLintPass<'_> for ItemNameRepetitions { let item_name = item.ident.name.as_str(); let item_camel = to_camel_case(item_name); if !item.span.from_expansion() && is_present_in_source(cx, item.span) { - if let [.., (mod_name, mod_camel, owner_id)] = &*self.modules { + if let [.., (mod_name, mod_camel, mod_owner_id)] = &*self.modules { // constants don't have surrounding modules if !mod_camel.is_empty() { if mod_name == &item.ident.name && let ItemKind::Mod(..) = item.kind - && (!self.allow_private_module_inception || cx.tcx.visibility(owner_id.def_id).is_public()) + && (!self.allow_private_module_inception || cx.tcx.visibility(mod_owner_id.def_id).is_public()) { span_lint( cx, @@ -403,9 +420,13 @@ impl LateLintPass<'_> for ItemNameRepetitions { "module has the same name as its containing module", ); } + // The `module_name_repetitions` lint should only trigger if the item has the module in its // name. Having the same name is accepted. - if cx.tcx.visibility(item.owner_id).is_public() && item_camel.len() > mod_camel.len() { + if cx.tcx.visibility(item.owner_id).is_public() + && cx.tcx.visibility(mod_owner_id.def_id).is_public() + && item_camel.len() > mod_camel.len() + { let matching = count_match_start(mod_camel, &item_camel); let rmatching = count_match_end(mod_camel, &item_camel); let nchars = mod_camel.chars().count(); diff --git a/clippy_lints/src/large_futures.rs b/clippy_lints/src/large_futures.rs index 6f5065e4936cb..25f9be8b2d7a4 100644 --- a/clippy_lints/src/large_futures.rs +++ b/clippy_lints/src/large_futures.rs @@ -57,7 +57,7 @@ impl_lint_pass!(LargeFuture => [LARGE_FUTURES]); impl<'tcx> LateLintPass<'tcx> for LargeFuture { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if let ExprKind::Match(scrutinee, _, MatchSource::AwaitDesugar) = expr.kind - && let ExprKind::Call(func, [arg, ..]) = scrutinee.kind + && let ExprKind::Call(func, [arg]) = scrutinee.kind && let ExprKind::Path(QPath::LangItem(LangItem::IntoFutureIntoFuture, ..)) = func.kind && !expr.span.from_expansion() && let ty = cx.typeck_results().expr_ty(arg) diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index 0f061d6de504f..4ef881f11d599 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -1,3 +1,5 @@ +use std::num::Saturating; + use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_from_proc_macro; @@ -30,6 +32,7 @@ declare_clippy_lint! { pub struct LargeStackArrays { maximum_allowed_size: u64, prev_vec_macro_callsite: Option, + const_item_counter: Saturating, } impl LargeStackArrays { @@ -37,6 +40,7 @@ impl LargeStackArrays { Self { maximum_allowed_size: conf.array_size_threshold, prev_vec_macro_callsite: None, + const_item_counter: Saturating(0), } } @@ -60,8 +64,21 @@ impl LargeStackArrays { impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]); impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { + fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { + if matches!(item.kind, ItemKind::Static(..) | ItemKind::Const(..)) { + self.const_item_counter += 1; + } + } + + fn check_item_post(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { + if matches!(item.kind, ItemKind::Static(..) | ItemKind::Const(..)) { + self.const_item_counter -= 1; + } + } + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { - if let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind + if self.const_item_counter.0 == 0 + && let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind && !self.is_from_vec_macro(cx, expr.span) && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind() diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 035ee40348c77..47c65ee6d0ba9 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -513,7 +513,7 @@ fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_> return; } - if let (&ExprKind::MethodCall(method_path, receiver, args, _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) { + if let (&ExprKind::MethodCall(method_path, receiver, [], _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) { // check if we are in an is_empty() method if let Some(name) = get_item_name(cx, method) { if name.as_str() == "is_empty" { @@ -521,29 +521,17 @@ fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_> } } - check_len( - cx, - span, - method_path.ident.name, - receiver, - args, - &lit.node, - op, - compare_to, - ); + check_len(cx, span, method_path.ident.name, receiver, &lit.node, op, compare_to); } else { check_empty_expr(cx, span, method, lit, op); } } -// FIXME(flip1995): Figure out how to reduce the number of arguments -#[allow(clippy::too_many_arguments)] fn check_len( cx: &LateContext<'_>, span: Span, method_name: Symbol, receiver: &Expr<'_>, - args: &[Expr<'_>], lit: &LitKind, op: &str, compare_to: u32, @@ -554,7 +542,7 @@ fn check_len( return; } - if method_name == sym::len && args.is_empty() && has_is_empty(cx, receiver) { + if method_name == sym::len && has_is_empty(cx, receiver) { let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 6ee064a6124b9..6e29dde2211fb 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1,6 +1,7 @@ #![feature(array_windows)] #![feature(binary_heap_into_iter_sorted)] #![feature(box_patterns)] +#![feature(macro_metavar_expr_concat)] #![feature(f128)] #![feature(f16)] #![feature(if_let_guard)] @@ -56,9 +57,10 @@ extern crate rustc_trait_selection; extern crate thin_vec; #[macro_use] -extern crate clippy_utils; +mod declare_clippy_lint; + #[macro_use] -extern crate declare_clippy_lint; +extern crate clippy_utils; #[cfg_attr(feature = "internal", allow(clippy::missing_clippy_version_attribute))] mod utils; @@ -203,6 +205,7 @@ mod manual_clamp; mod manual_div_ceil; mod manual_float_methods; mod manual_hash_one; +mod manual_ignore_case_cmp; mod manual_is_ascii_check; mod manual_is_power_of_two; mod manual_let_else; @@ -360,6 +363,7 @@ mod unit_return_expecting_ord; mod unit_types; mod unnamed_address; mod unnecessary_box_returns; +mod unnecessary_literal_bound; mod unnecessary_map_on_constructor; mod unnecessary_owned_empty_strings; mod unnecessary_self_imports; @@ -391,7 +395,7 @@ mod zero_sized_map_values; mod zombie_processes; // end lints modules, do not remove this comment, it’s used in `update_lints` -use clippy_config::{Conf, get_configuration_metadata}; +use clippy_config::{Conf, get_configuration_metadata, sanitize_explanation}; use clippy_utils::macros::FormatArgsStorage; use rustc_data_structures::fx::FxHashSet; use rustc_lint::{Lint, LintId}; @@ -519,8 +523,9 @@ impl LintInfo { pub fn explain(name: &str) -> i32 { let target = format!("clippy::{}", name.to_ascii_uppercase()); + if let Some(info) = declared_lints::LINTS.iter().find(|info| info.lint.name == target) { - println!("{}", info.explanation); + println!("{}", sanitize_explanation(info.explanation)); // Check if the lint has configuration let mut mdconf = get_configuration_metadata(); let name = name.to_ascii_lowercase(); @@ -896,7 +901,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::new(manual_range_patterns::ManualRangePatterns)); store.register_early_pass(|| Box::new(visibility::Visibility)); store.register_late_pass(move |_| Box::new(tuple_array_conversions::TupleArrayConversions::new(conf))); - store.register_late_pass(|_| Box::new(manual_float_methods::ManualFloatMethods)); + store.register_late_pass(move |_| Box::new(manual_float_methods::ManualFloatMethods::new(conf))); store.register_late_pass(|_| Box::new(four_forward_slashes::FourForwardSlashes)); store.register_late_pass(|_| Box::new(error_impl_error::ErrorImplError)); store.register_late_pass(move |_| Box::new(absolute_paths::AbsolutePaths::new(conf))); @@ -941,5 +946,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::new(manual_is_power_of_two::ManualIsPowerOfTwo)); store.register_late_pass(|_| Box::new(non_zero_suggestions::NonZeroSuggestions)); store.register_late_pass(move |_| Box::new(unused_trait_names::UnusedTraitNames::new(conf))); + store.register_late_pass(|_| Box::new(manual_ignore_case_cmp::ManualIgnoreCaseCmp)); + store.register_late_pass(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index a7c48eb216aa4..5a3930b8bb846 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -6,8 +6,8 @@ use rustc_errors::Applicability; use rustc_hir::FnRetTy::Return; use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter}; use rustc_hir::intravisit::{ - Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_param_bound, - walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_where_predicate, + Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_param_bound, walk_poly_trait_ref, + walk_trait_ref, walk_ty, walk_where_predicate, }; use rustc_hir::{ BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics, diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index 81f2a03fb55fb..e2dcb20f906d3 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -412,7 +412,6 @@ impl LiteralDigitGrouping { } } -#[expect(clippy::module_name_repetitions)] pub struct DecimalLiteralRepresentation { threshold: u64, } diff --git a/clippy_lints/src/loops/infinite_loop.rs b/clippy_lints/src/loops/infinite_loop.rs index 858e3be5093ef..e25c03db53442 100644 --- a/clippy_lints/src/loops/infinite_loop.rs +++ b/clippy_lints/src/loops/infinite_loop.rs @@ -42,6 +42,7 @@ pub(super) fn check<'tcx>( let mut loop_visitor = LoopVisitor { cx, label, + inner_labels: label.into_iter().collect(), is_finite: false, loop_depth: 0, }; @@ -93,6 +94,7 @@ fn get_parent_fn_ret_ty<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option struct LoopVisitor<'hir, 'tcx> { cx: &'hir LateContext<'tcx>, label: Option