diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 71abc8aa..4079983d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -103,4 +103,4 @@ jobs: rustup install --profile default nightly rustup default nightly - uses: Swatinem/rust-cache@v2 - - run: cargo clippy --all-targets + - run: cargo clippy --all-targets -- -D warnings diff --git a/Cargo.toml b/Cargo.toml index 9fbc6e77..e577e19a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ authors = ["Samuel Tardieu "] categories = ["algorithms"] readme = "README.md" edition = "2021" -rust-version = "1.77.2" +rust-version = "1.82.0" [package.metadata.release] sign-commit = true @@ -46,7 +46,8 @@ version_check = "0.9.5" [lints.clippy] module_name_repetitions = { level = "allow", priority = 1 } too_long_first_doc_paragraph = { level = "allow", priority = 1 } # Temporary -pedantic = { level = "deny", priority = 0 } +pedantic = "deny" +allow_attributes = "deny" [[bench]] name = "algos" diff --git a/benches/matrices.rs b/benches/matrices.rs index 30b67045..0a94993a 100644 --- a/benches/matrices.rs +++ b/benches/matrices.rs @@ -1,7 +1,7 @@ use codspeed_criterion_compat::{criterion_group, criterion_main, Criterion}; use pathfinding::matrix::Matrix; -#[allow(clippy::missing_panics_doc)] +#[expect(clippy::missing_panics_doc)] pub fn transpose_benchmark(c: &mut Criterion) { // Generate a 100 x 100 square matrix with entries from 1 to 100^2 let data: Vec = (0..100 * 100).collect(); @@ -10,7 +10,7 @@ pub fn transpose_benchmark(c: &mut Criterion) { c.bench_function("transpose", |b| b.iter(|| m.transpose())); } -#[allow(clippy::missing_panics_doc)] +#[expect(clippy::missing_panics_doc)] pub fn transpose_non_square_benchmark(c: &mut Criterion) { // Generate a 1000 x 10 square matrix with entries from 1 to 100^2 let data: Vec = (0..100 * 100).collect(); diff --git a/benches/movingai.rs b/benches/movingai.rs index 5d841aa4..8429f89f 100644 --- a/benches/movingai.rs +++ b/benches/movingai.rs @@ -7,12 +7,12 @@ use noisy_float::prelude::*; use pathfinding::directed::astar::astar; use std::path::Path; -#[allow(clippy::cast_precision_loss)] +#[expect(clippy::cast_precision_loss)] fn distance(a: &Coords2D, b: &Coords2D) -> R64 { r64((a.0 as f64 - b.0 as f64).hypot(a.1 as f64 - b.1 as f64)) } -#[allow(clippy::missing_panics_doc)] +#[expect(clippy::missing_panics_doc)] pub fn arena(c: &mut Criterion) { c.bench_function("arena", |b| { b.iter(|| { diff --git a/examples/sliding-puzzle.rs b/examples/sliding-puzzle.rs index 79ee9921..66e61fff 100644 --- a/examples/sliding-puzzle.rs +++ b/examples/sliding-puzzle.rs @@ -12,8 +12,8 @@ const SIDE: u8 = 3; const SIDE: u8 = 4; const LIMIT: usize = (SIDE * SIDE) as usize; -#[allow(clippy::derived_hash_with_manual_eq)] #[derive(Clone, Debug, Hash)] +#[allow(clippy::derived_hash_with_manual_eq)] // expect doesn't work, clippy issue #13356 struct Game { positions: [u8; LIMIT], // Correct position of piece at every index hole_idx: u8, // Current index of the hole diff --git a/src/directed/astar.rs b/src/directed/astar.rs index 64a10d00..5e0dfbcd 100644 --- a/src/directed/astar.rs +++ b/src/directed/astar.rs @@ -77,7 +77,7 @@ use crate::FxIndexMap; /// |&p| p == GOAL); /// assert_eq!(result.expect("no path found").1, 4); /// ``` -#[allow(clippy::missing_panics_doc)] +#[expect(clippy::missing_panics_doc)] pub fn astar( start: &N, mut successors: FN, @@ -169,7 +169,7 @@ where /// /// Each path comprises both the start and an end node. Note that while every path shares the same /// start node, different paths may have different end nodes. -#[allow(clippy::missing_panics_doc)] +#[expect(clippy::missing_panics_doc)] pub fn astar_bag( start: &N, mut successors: FN, diff --git a/src/directed/dijkstra.rs b/src/directed/dijkstra.rs index ab6f3314..a1198106 100644 --- a/src/directed/dijkstra.rs +++ b/src/directed/dijkstra.rs @@ -168,7 +168,7 @@ where /// /// The [`build_path`] function can be used to build a full path from the starting point to one /// of the reachable targets. -#[allow(clippy::missing_panics_doc)] +#[expect(clippy::missing_panics_doc)] pub fn dijkstra_partial( start: &N, mut successors: FN, @@ -277,7 +277,7 @@ where /// assert_eq!(vec![1], build_path(&1, &parents)); /// assert_eq!(vec![101], build_path(&101, &parents)); /// ``` -#[allow(clippy::implicit_hasher)] +#[expect(clippy::implicit_hasher)] pub fn build_path(target: &N, parents: &HashMap) -> Vec where N: Eq + Hash + Clone, diff --git a/src/directed/fringe.rs b/src/directed/fringe.rs index 7c05f868..15b511a3 100644 --- a/src/directed/fringe.rs +++ b/src/directed/fringe.rs @@ -77,7 +77,7 @@ use std::mem; /// |&p| p == GOAL); /// assert_eq!(result.expect("no path found").1, 4); /// ``` -#[allow(clippy::missing_panics_doc)] +#[expect(clippy::missing_panics_doc)] pub fn fringe( start: &N, mut successors: FN, diff --git a/src/directed/mod.rs b/src/directed/mod.rs index ddd7a960..8913f7fa 100644 --- a/src/directed/mod.rs +++ b/src/directed/mod.rs @@ -17,7 +17,7 @@ pub mod strongly_connected_components; pub mod topological_sort; pub mod yen; -#[allow(clippy::needless_collect)] +#[expect(clippy::needless_collect)] fn reverse_path(parents: &FxIndexMap, mut parent: F, start: usize) -> Vec where N: Eq + Hash + Clone, diff --git a/src/directed/strongly_connected_components.rs b/src/directed/strongly_connected_components.rs index 8795a2b2..9645b644 100644 --- a/src/directed/strongly_connected_components.rs +++ b/src/directed/strongly_connected_components.rs @@ -104,7 +104,7 @@ where /// /// The function returns the strongly connected component containing the node, /// which is guaranteed to contain at least `node`. -#[allow(clippy::missing_panics_doc)] +#[expect(clippy::missing_panics_doc)] pub fn strongly_connected_component(node: &N, successors: FN) -> Vec where N: Clone + Hash + Eq, diff --git a/src/directed/topological_sort.rs b/src/directed/topological_sort.rs index c3ae336a..0e989451 100644 --- a/src/directed/topological_sort.rs +++ b/src/directed/topological_sort.rs @@ -152,8 +152,8 @@ where /// In this case, the strongly connected set(s) can then be found using the /// [`strongly_connected_components`](super::strongly_connected_components::strongly_connected_components) /// function on the list of remaining nodes. -#[allow(clippy::type_complexity)] -#[allow(clippy::missing_panics_doc)] +#[expect(clippy::type_complexity)] +#[expect(clippy::missing_panics_doc)] pub fn topological_sort_into_groups( nodes: &[N], mut successors: FN, diff --git a/src/undirected/connected_components.rs b/src/undirected/connected_components.rs index c9063ec9..129051b5 100644 --- a/src/undirected/connected_components.rs +++ b/src/undirected/connected_components.rs @@ -232,7 +232,7 @@ where /// This function returns a map between every vertex and the index of /// the set it belongs to in the `components` list. #[must_use] -#[allow(clippy::implicit_hasher)] +#[expect(clippy::implicit_hasher)] pub fn component_index(components: &[HashSet]) -> HashMap where N: Clone + Hash + Eq, diff --git a/src/utils.rs b/src/utils.rs index 0d3fd803..b43ed774 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -36,7 +36,7 @@ where /// assert_eq!(move_in_direction((1, 1), (-1, -2), board), None); /// ``` #[must_use] -#[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] +#[expect(clippy::cast_possible_wrap, clippy::cast_sign_loss)] pub fn move_in_direction( start: (usize, usize), direction: (isize, isize), @@ -90,7 +90,7 @@ pub fn in_direction( /// assert_eq!(constrain(-30, 7), 5); /// ``` #[must_use] -#[allow(clippy::cast_sign_loss)] +#[expect(clippy::cast_sign_loss)] pub const fn constrain(value: isize, upper: usize) -> usize { if value > 0 { value as usize % upper diff --git a/tests/codejam-2017-a.rs b/tests/codejam-2017-a.rs index f3bdcb64..3c2dbfe6 100644 --- a/tests/codejam-2017-a.rs +++ b/tests/codejam-2017-a.rs @@ -8,7 +8,7 @@ use std::io::{self, Cursor}; use std::num::ParseIntError; #[derive(Debug)] -#[allow(dead_code)] +#[expect(dead_code)] enum Error { Io(io::Error), Parse(ParseIntError), @@ -99,7 +99,7 @@ fn test>(n: usize, file: &mut dyn BufRead) -> Result= 0); - #[allow(clippy::cast_sign_loss)] + #[expect(clippy::cast_sign_loss)] let n = n as usize; if n > max { max = n; diff --git a/tests/edmondskarp.rs b/tests/edmondskarp.rs index e5f0e94e..e96ca6aa 100644 --- a/tests/edmondskarp.rs +++ b/tests/edmondskarp.rs @@ -60,7 +60,7 @@ fn wikipedia_example_sparse() { wikipedia_example::>(); } -#[allow(clippy::cast_possible_truncation)] +#[expect(clippy::cast_possible_truncation)] fn wikipedia_progressive_example>() { let successors = successors_wikipedia(); let size = successors.len(); diff --git a/tests/gps.rs b/tests/gps.rs index 4b8d2285..e4d5a14b 100644 --- a/tests/gps.rs +++ b/tests/gps.rs @@ -15,7 +15,7 @@ impl Coords { self.1.to_radians() } - #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] + #[expect(clippy::cast_possible_truncation, clippy::cast_sign_loss)] fn distance_in_meters(&self, other: &Coords) -> u64 { let x = (other.lon_rad() - self.lon_rad()) * ((other.lat_rad() + self.lat_rad()) / 2.0).cos(); diff --git a/tests/matrix.rs b/tests/matrix.rs index 6ba06e83..3aeacd3b 100644 --- a/tests/matrix.rs +++ b/tests/matrix.rs @@ -699,7 +699,7 @@ fn into_iter_is_fused() { } #[test] -#[allow(deprecated)] +#[expect(deprecated)] fn indices() { let m = matrix![[0, 1, 2], [2, 1, 0]]; assert_eq!( diff --git a/tests/pathfinding.rs b/tests/pathfinding.rs index 2248454a..24408c08 100644 --- a/tests/pathfinding.rs +++ b/tests/pathfinding.rs @@ -3,7 +3,7 @@ mod ex1 { use lazy_static::lazy_static; use pathfinding::prelude::*; - #[allow(clippy::trivially_copy_pass_by_ref)] + #[expect(clippy::trivially_copy_pass_by_ref)] fn successors(node: &u8) -> impl Iterator { lazy_static! { static ref SUCCESSORS: Vec> = vec![ diff --git a/tests/strongly_connected_components.rs b/tests/strongly_connected_components.rs index 4d408a83..87bae17e 100644 --- a/tests/strongly_connected_components.rs +++ b/tests/strongly_connected_components.rs @@ -5,7 +5,7 @@ use std::collections::hash_map::HashMap; // Tests in this file use the example at // https://en.wikipedia.org/wiki/Strongly_connected_component#/media/File:Graph_Condensation.svg -#[allow(clippy::trivially_copy_pass_by_ref)] +#[expect(clippy::trivially_copy_pass_by_ref)] fn successors(n: &usize) -> Vec { match *n { 0 => vec![2], diff --git a/tests/topological_sort.rs b/tests/topological_sort.rs index ea72438a..3bbe8d64 100644 --- a/tests/topological_sort.rs +++ b/tests/topological_sort.rs @@ -51,7 +51,7 @@ fn complexity() { // Wrapper around topological_sort_into_groups that sorts each group (since // topological_sort_into_groups makes no guarantees about node order within // each group). -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] fn tsig(succs: &[&[usize]]) -> Result>, (Vec>, Vec)> { let nodes: Vec = (0..succs.len()).collect(); match topological_sort_into_groups(&nodes, |&n| succs[n].iter().copied()) {