From 9fdd2e62b047d41d96018e2127ade977c51ddc91 Mon Sep 17 00:00:00 2001 From: lucarlig Date: Mon, 25 Mar 2024 16:18:22 +0000 Subject: [PATCH] add lint to handle deprecated rayon methods --- Cargo.lock | 70 +++++++++++++---------- Cargo.toml | 5 +- lints/deprecated_rayon/.gitignore | 1 + lints/deprecated_rayon/Cargo.toml | 34 +++++++++++ lints/deprecated_rayon/README.md | 17 ++++++ lints/deprecated_rayon/src/lib.rs | 82 +++++++++++++++++++++++++++ lints/deprecated_rayon/ui/main.fixed | 19 +++++++ lints/deprecated_rayon/ui/main.rs | 19 +++++++ lints/deprecated_rayon/ui/main.stderr | 25 ++++++++ 9 files changed, 242 insertions(+), 30 deletions(-) create mode 100644 lints/deprecated_rayon/.gitignore create mode 100644 lints/deprecated_rayon/Cargo.toml create mode 100644 lints/deprecated_rayon/README.md create mode 100644 lints/deprecated_rayon/src/lib.rs create mode 100644 lints/deprecated_rayon/ui/main.fixed create mode 100644 lints/deprecated_rayon/ui/main.rs create mode 100644 lints/deprecated_rayon/ui/main.stderr diff --git a/Cargo.lock b/Cargo.lock index 8501531..a0c2fa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -46,9 +46,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block-buffer" @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -204,6 +204,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "deprecated_rayon" +version = "0.1.1" +dependencies = [ + "clippy_utils", + "dylint_linting", + "dylint_testing", + "rayon", + "utils", +] + [[package]] name = "diff" version = "0.1.13" @@ -291,7 +302,7 @@ checksum = "d4c32056fd5a610d2c9abc98155d395eb3ce61989c89e78e417241d06a5cc41b" dependencies = [ "ansi_term", "anyhow", - "bitflags 2.4.2", + "bitflags 2.5.0", "cargo_metadata", "git2", "home", @@ -373,9 +384,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "filetime" @@ -549,11 +560,11 @@ dependencies = [ [[package]] name = "git2" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b3ba52851e73b46a4c3df1d89343741112003f0f6f13beb0dfac9e457c3fdcd" +checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "libc", "libgit2-sys", "log", @@ -620,9 +631,9 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", @@ -695,7 +706,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "libc", "redox_syscall", ] @@ -716,9 +727,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.15" +version = "1.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" dependencies = [ "cc", "libc", @@ -752,6 +763,7 @@ dependencies = [ name = "mate" version = "0.1.4" dependencies = [ + "deprecated_rayon", "dylint_linting", "dylint_testing", "filter", @@ -891,9 +903,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -942,9 +954,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -1024,11 +1036,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -1127,9 +1139,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.53" +version = "2.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" dependencies = [ "proc-macro2", "quote", @@ -1237,7 +1249,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.8", + "toml_edit 0.22.9", ] [[package]] @@ -1264,9 +1276,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.8" +version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c12219811e0c1ba077867254e5ad62ee2c9c190b0d957110750ac0cda1ae96cd" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ "indexmap", "serde", diff --git a/Cargo.toml b/Cargo.toml index 67e3c71..9652d0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,8 @@ fold = { path = "lints/fold", features = ["rlib"] } par_fold = { path = "lints/par_fold", features = ["rlib"] } par_iter = { path = "lints/par_iter", features = ["rlib"] } rayon_imports = { path = "lints/rayon_imports", features = ["rlib"] } +deprecated_rayon = { path = "lints/deprecated_rayon", features = ["rlib"] } + dylint_linting = { version = "3.0.0" } @@ -29,13 +31,14 @@ rustc_private = true [workspace] members = [ + "lints/rayon_imports", "lints/for_each", "lints/filter", "lints/map", "lints/fold", "lints/par_fold", "lints/par_iter", - "lints/rayon_imports", + "lints/deprecated_rayon", "utils", ] diff --git a/lints/deprecated_rayon/.gitignore b/lints/deprecated_rayon/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/lints/deprecated_rayon/.gitignore @@ -0,0 +1 @@ +/target diff --git a/lints/deprecated_rayon/Cargo.toml b/lints/deprecated_rayon/Cargo.toml new file mode 100644 index 0000000..c0be7f7 --- /dev/null +++ b/lints/deprecated_rayon/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "deprecated_rayon" +version = "0.1.1" +authors = ["authors go here"] +description = "description goes here" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +dylint_linting = "3.0.0" + +clippy_utils = { workspace = true } +utils = { workspace = true } + +[dev-dependencies] +dylint_testing = "3.0.0" +rayon = "1.9.0" + +[package.metadata.rust-analyzer] +rustc_private = true + +[features] +rlib = ["dylint_linting/constituent"] + +[[example]] +name = "deprecated_main" +path = "ui/main.rs" + + +[lints] +workspace = true diff --git a/lints/deprecated_rayon/README.md b/lints/deprecated_rayon/README.md new file mode 100644 index 0000000..269c7b7 --- /dev/null +++ b/lints/deprecated_rayon/README.md @@ -0,0 +1,17 @@ +# template + +### What it does + +### Why is this bad? + +### Known problems +Remove if none. + +### Example +```rust +// example code where a warning is issued +``` +Use instead: +```rust +// example code that does not raise a warning +``` diff --git a/lints/deprecated_rayon/src/lib.rs b/lints/deprecated_rayon/src/lib.rs new file mode 100644 index 0000000..bcadf79 --- /dev/null +++ b/lints/deprecated_rayon/src/lib.rs @@ -0,0 +1,82 @@ +#![feature(rustc_private)] +#![warn(unused_extern_crates)] +#![feature(let_chains)] + +extern crate rustc_errors; +extern crate rustc_hir; + +use clippy_utils::get_parent_expr; +use rustc_errors::Applicability; +use rustc_hir::{self as hir}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use utils::span_to_snippet_macro; + +dylint_linting::declare_late_lint! { + /// ### What it does + /// + /// ### Why is this bad? + /// + /// ### Known problems + /// + /// + /// ### Example + /// ```rust + /// + /// ``` + /// Use instead: + /// ```rust + /// + /// + /// + /// ``` + pub DEPRECATED_RAYON, + Warn, + "suggest replacing a deprecated method" +} + +impl<'tcx> LateLintPass<'tcx> for DeprecatedRayon { + // TODO: implement check crate to check if rayon is present + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { + if let hir::ExprKind::MethodCall(path, recv, _args, _span) = &expr.kind + && ["par_iter", "into+par_iter", "par_iter_mut"].contains(&path.ident.as_str()) + { + let mut top_expr = *recv; + while let Some(parent_expr) = get_parent_expr(cx, top_expr) { + match parent_expr.kind { + hir::ExprKind::MethodCall(method_name, _, _, _) => { + top_expr = parent_expr; + let snippet = + span_to_snippet_macro(cx.sess().source_map(), parent_expr.span); + let suggestion_text = match method_name.ident.as_str() { + "find" => Some(snippet.replace(".find(", ".find_first(")), + "position" => Some(snippet.replace(".position(", ".position_first(")), + _ => None, + }; + + if let Some(suggestion) = suggestion_text { + cx.span_lint( + DEPRECATED_RAYON, + top_expr.span, + "found a deprecated rayon method", + |diag| { + diag.span_suggestion( + parent_expr.span, + "try use this instead", + suggestion, + Applicability::MachineApplicable, + ); + }, + ); + } + } + _ => break, + } + } + } + } +} + +#[test] +fn ui() { + dylint_testing::ui_test_examples(env!("CARGO_PKG_NAME")); +} diff --git a/lints/deprecated_rayon/ui/main.fixed b/lints/deprecated_rayon/ui/main.fixed new file mode 100644 index 0000000..267989a --- /dev/null +++ b/lints/deprecated_rayon/ui/main.fixed @@ -0,0 +1,19 @@ +// run-rustfix +#![allow(dead_code, unused_variables, deprecated)] + +use rayon::prelude::*; + +fn main() {} + +fn find_simple() { + let bufs = vec![vec![1], vec![2], vec![2]]; + let buf = bufs + .par_iter() + .find_first(|b| !b.is_empty()) + .map_or(&[][..], |b| &**b); +} + +fn position_simple() { + let bufs = vec![vec![1], vec![2], vec![2]]; + let buf = bufs.par_iter().position_first(|b| !b.is_empty()); +} diff --git a/lints/deprecated_rayon/ui/main.rs b/lints/deprecated_rayon/ui/main.rs new file mode 100644 index 0000000..970d0e8 --- /dev/null +++ b/lints/deprecated_rayon/ui/main.rs @@ -0,0 +1,19 @@ +// run-rustfix +#![allow(dead_code, unused_variables, deprecated)] + +use rayon::prelude::*; + +fn main() {} + +fn find_simple() { + let bufs = vec![vec![1], vec![2], vec![2]]; + let buf = bufs + .par_iter() + .find(|b| !b.is_empty()) + .map_or(&[][..], |b| &**b); +} + +fn position_simple() { + let bufs = vec![vec![1], vec![2], vec![2]]; + let buf = bufs.par_iter().position(|b| !b.is_empty()); +} diff --git a/lints/deprecated_rayon/ui/main.stderr b/lints/deprecated_rayon/ui/main.stderr new file mode 100644 index 0000000..ff82b6d --- /dev/null +++ b/lints/deprecated_rayon/ui/main.stderr @@ -0,0 +1,25 @@ +warning: found a deprecated rayon method + --> $DIR/main.rs:10:15 + | +LL | let buf = bufs + | _______________^ +LL | | .par_iter() +LL | | .find(|b| !b.is_empty()) + | |________________________________^ + | + = note: `#[warn(deprecated_rayon)]` on by default +help: try use this instead + | +LL ~ let buf = bufs +LL + .par_iter() +LL + .find_first(|b| !b.is_empty()) + | + +warning: found a deprecated rayon method + --> $DIR/main.rs:18:15 + | +LL | let buf = bufs.par_iter().position(|b| !b.is_empty()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try use this instead: `bufs.par_iter().position_first(|b| !b.is_empty())` + +warning: 2 warnings emitted +