diff --git a/Cargo.toml b/Cargo.toml index d2f7e583af..357674b55e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ license = "MIT" edition = "2021" [workspace.lints.clippy] +allow_attributes = "warn" undocumented_unsafe_blocks = "warn" [workspace.dependencies] diff --git a/diskann-benchmark-runner/Cargo.toml b/diskann-benchmark-runner/Cargo.toml index 9f9b2d3bf9..3a12ccb566 100644 --- a/diskann-benchmark-runner/Cargo.toml +++ b/diskann-benchmark-runner/Cargo.toml @@ -17,6 +17,7 @@ serde_json = { workspace = true } thiserror.workspace = true [lints.clippy] +allow_attributes = "warn" undocumented_unsafe_blocks = "warn" uninlined_format_args = "allow" unwrap_used = "warn" diff --git a/diskann-benchmark-simd/src/lib.rs b/diskann-benchmark-simd/src/lib.rs index 25b021d8a9..f97f1e79c0 100644 --- a/diskann-benchmark-simd/src/lib.rs +++ b/diskann-benchmark-simd/src/lib.rs @@ -78,10 +78,10 @@ impl std::fmt::Display for SimilarityMeasure { #[serde(rename_all = "kebab-case")] enum Arch { #[serde(rename = "x86-64-v4")] - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] X86_64_V4, #[serde(rename = "x86-64-v3")] - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] X86_64_V3, Neon, Scalar, diff --git a/diskann-benchmark/Cargo.toml b/diskann-benchmark/Cargo.toml index 31739244c9..17d91d226d 100644 --- a/diskann-benchmark/Cargo.toml +++ b/diskann-benchmark/Cargo.toml @@ -42,6 +42,7 @@ itertools.workspace = true diskann-inmem = { workspace = true, optional = true } [lints] +clippy.allow_attributes = "warn" clippy.undocumented_unsafe_blocks = "warn" clippy.uninlined_format_args = "allow" diff --git a/diskann-benchmark/src/exhaustive/algos.rs b/diskann-benchmark/src/exhaustive/algos.rs index 2a973a4d08..2fc07045e1 100644 --- a/diskann-benchmark/src/exhaustive/algos.rs +++ b/diskann-benchmark/src/exhaustive/algos.rs @@ -62,7 +62,7 @@ where // Lints: Using `ParallelIterator::collect`. It's the caller's responsibility to invoke // this in a properly sized Rayon environment. - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] let times: Vec = output .par_row_iter_mut() .zip(queries.par_row_iter()) diff --git a/diskann-benchmark/src/exhaustive/product.rs b/diskann-benchmark/src/exhaustive/product.rs index 885ddb3d8b..43538117dd 100644 --- a/diskann-benchmark/src/exhaustive/product.rs +++ b/diskann-benchmark/src/exhaustive/product.rs @@ -336,7 +336,7 @@ mod imp { diskann_utils::views::Matrix::new(0, input.nrows(), quantizer.get_num_chunks()); // Compress the data. - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] data.par_row_iter_mut() .zip(input.par_row_iter()) .try_for_each(|(d, i)| -> anyhow::Result<()> { diff --git a/diskann-benchmark/src/exhaustive/spherical.rs b/diskann-benchmark/src/exhaustive/spherical.rs index 5e009c231a..1bf3c09349 100644 --- a/diskann-benchmark/src/exhaustive/spherical.rs +++ b/diskann-benchmark/src/exhaustive/spherical.rs @@ -419,7 +419,7 @@ mod imp { let mut data = diskann_utils::views::Matrix::new(0, input.nrows(), bytes); // Compress the data. - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] data.par_row_iter_mut() .zip(input.par_row_iter()) .try_for_each(|(d, i)| -> anyhow::Result<()> { diff --git a/diskann-benchmark/src/inputs/multi_vector.rs b/diskann-benchmark/src/inputs/multi_vector.rs index c74f9d232f..6f1ec9dddd 100644 --- a/diskann-benchmark/src/inputs/multi_vector.rs +++ b/diskann-benchmark/src/inputs/multi_vector.rs @@ -21,10 +21,10 @@ use serde::{Deserialize, Serialize}; #[non_exhaustive] pub(crate) enum BenchIsa { #[serde(rename = "x86-64-v4")] - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] X86_64_V4, #[serde(rename = "x86-64-v3")] - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] X86_64_V3, Neon, Scalar, diff --git a/diskann-bftree/Cargo.toml b/diskann-bftree/Cargo.toml index 79c8bb7ed4..e8fb92f847 100644 --- a/diskann-bftree/Cargo.toml +++ b/diskann-bftree/Cargo.toml @@ -38,6 +38,7 @@ default = [] experimental_diversity_search = ["diskann/experimental_diversity_search"] [lints.clippy] +allow_attributes = "warn" undocumented_unsafe_blocks = "warn" unwrap_used = "warn" expect_used = "warn" diff --git a/diskann-bftree/src/lib.rs b/diskann-bftree/src/lib.rs index a9d2f96e7f..bfb51d96f6 100644 --- a/diskann-bftree/src/lib.rs +++ b/diskann-bftree/src/lib.rs @@ -159,11 +159,10 @@ impl TestCallCount { } #[cfg(not(test))] -#[allow(dead_code)] pub(crate) struct TestCallCount {} #[cfg(not(test))] -#[allow(dead_code)] +#[expect(dead_code)] impl TestCallCount { pub fn new() -> Self { Self {} diff --git a/diskann-bftree/src/neighbors.rs b/diskann-bftree/src/neighbors.rs index e68a6275fd..84098947f1 100644 --- a/diskann-bftree/src/neighbors.rs +++ b/diskann-bftree/src/neighbors.rs @@ -23,7 +23,7 @@ use crate::{bftree_insert, TestCallCount}; pub struct NeighborProvider { adjacency_list_index: BfTree, dim: usize, // Max number of neighbors in a neighbor list + 1 for the neighbor count - #[allow(dead_code)] + #[cfg_attr(not(test), expect(dead_code))] pub(crate) num_get_calls: TestCallCount, _phantom: PhantomData, } diff --git a/diskann-disk/Cargo.toml b/diskann-disk/Cargo.toml index 693614381d..83254f1f1b 100644 --- a/diskann-disk/Cargo.toml +++ b/diskann-disk/Cargo.toml @@ -98,3 +98,6 @@ harness = false # Some 'cfg's in the source tree will be flagged by `cargo clippy -j 2 --workspace --no-deps --all-targets -- -D warnings` [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage)'] } + +[lints.clippy] +allow_attributes = "warn" diff --git a/diskann-disk/src/data_model/graph_metadata.rs b/diskann-disk/src/data_model/graph_metadata.rs index 7cbd0ba29f..21ab49f999 100644 --- a/diskann-disk/src/data_model/graph_metadata.rs +++ b/diskann-disk/src/data_model/graph_metadata.rs @@ -42,7 +42,7 @@ pub struct GraphMetadata { pub associated_data_length: usize, } -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] impl GraphMetadata { /// Create a new `GraphMetadata` object. pub fn new( diff --git a/diskann-disk/src/search/provider/aligned_file_reader/platform/linux.rs b/diskann-disk/src/search/provider/aligned_file_reader/platform/linux.rs index fce8313ea5..64612d6e70 100644 --- a/diskann-disk/src/search/provider/aligned_file_reader/platform/linux.rs +++ b/diskann-disk/src/search/provider/aligned_file_reader/platform/linux.rs @@ -11,7 +11,7 @@ use io_uring::IoUring; pub struct IOContext { // Kept alive so the file descriptor registered with the io_uring ring stays valid; // the fd is used via `register_files`, so this field is never read directly. - #[allow(dead_code)] + #[expect(dead_code)] pub file_handle: File, pub ring: IoUring, } diff --git a/diskann-disk/src/search/provider/aligned_file_reader/platform/windows/mod.rs b/diskann-disk/src/search/provider/aligned_file_reader/platform/windows/mod.rs index edd6af05fe..e9074c936a 100644 --- a/diskann-disk/src/search/provider/aligned_file_reader/platform/windows/mod.rs +++ b/diskann-disk/src/search/provider/aligned_file_reader/platform/windows/mod.rs @@ -13,9 +13,9 @@ mod file_io; mod io_completion_port; mod ssd_io_context; -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub type ULONG_PTR = usize; -#[allow(clippy::upper_case_acronyms)] +#[expect(clippy::upper_case_acronyms)] pub type DWORD = u32; -#[allow(clippy::upper_case_acronyms)] +#[expect(clippy::upper_case_acronyms)] pub type OVERLAPPED = windows_sys::Win32::System::IO::OVERLAPPED; diff --git a/diskann-disk/src/search/provider/aligned_file_reader/reader/linux.rs b/diskann-disk/src/search/provider/aligned_file_reader/reader/linux.rs index d897fb7362..5cda5ada5d 100644 --- a/diskann-disk/src/search/provider/aligned_file_reader/reader/linux.rs +++ b/diskann-disk/src/search/provider/aligned_file_reader/reader/linux.rs @@ -350,12 +350,10 @@ mod tests { } #[test] - #[allow(clippy::read_zero_byte_vec)] fn test_read_no_requests() { let mut reader = LinuxAlignedFileReader::new(TEST_INDEX_PATH).unwrap(); - let mut read_requests = Vec::>::new(); - let result = reader.read(&mut read_requests); + let result = reader.read(&mut []); assert!(result.is_ok()); } diff --git a/diskann-disk/src/search/provider/aligned_file_reader/reader/windows.rs b/diskann-disk/src/search/provider/aligned_file_reader/reader/windows.rs index 7a8b3ba5da..071fa513cc 100644 --- a/diskann-disk/src/search/provider/aligned_file_reader/reader/windows.rs +++ b/diskann-disk/src/search/provider/aligned_file_reader/reader/windows.rs @@ -295,12 +295,10 @@ mod tests { } #[test] - #[allow(clippy::read_zero_byte_vec)] fn test_read_no_requests() { let mut reader = WindowsAlignedFileReader::new(&test_index_path()).unwrap(); - let mut read_requests = Vec::>::new(); - let result = reader.read(&mut read_requests); + let result = reader.read(&mut []); assert!(result.is_ok()); } diff --git a/diskann-disk/src/search/provider/disk_provider.rs b/diskann-disk/src/search/provider/disk_provider.rs index da64ff9ce7..d16bfa4857 100644 --- a/diskann-disk/src/search/provider/disk_provider.rs +++ b/diskann-disk/src/search/provider/disk_provider.rs @@ -1349,7 +1349,7 @@ where /// Perform a raw search on the disk index. /// This is a lower-level API that allows more control over the search parameters and output buffers. - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] pub(crate) fn search_internal( &self, query: &[Data::VectorDataType], @@ -1376,7 +1376,7 @@ where ) } - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn search_internal_impl( &self, query: &[Data::VectorDataType], diff --git a/diskann-disk/src/storage/quant/pq/pq_generation.rs b/diskann-disk/src/storage/quant/pq/pq_generation.rs index eca343f58e..8f5def5f75 100644 --- a/diskann-disk/src/storage/quant/pq/pq_generation.rs +++ b/diskann-disk/src/storage/quant/pq/pq_generation.rs @@ -190,7 +190,7 @@ mod pq_generation_tests { 2.1f32, 2.1f32, 2.2f32, 2.2f32, 2.2f32, 2.2f32, 2.2f32, 2.2f32, 2.2f32, 2.2f32, 100.0f32, 100.0f32, 100.0f32, 100.0f32, 100.0f32, 100.0f32, 100.0f32, 100.0f32, ]; - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn create_context<'a, F: vfs::FileSystem>( provider: &'a VirtualStorageProvider, dim: usize, @@ -218,7 +218,7 @@ mod pq_generation_tests { } } - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn create_new_compressor<'a, F: vfs::FileSystem>( provider: &'a VirtualStorageProvider, dim: usize, diff --git a/diskann-disk/src/utils/instrumentation/timer.rs b/diskann-disk/src/utils/instrumentation/timer.rs index e53431ac17..fa7d1e5c0b 100644 --- a/diskann-disk/src/utils/instrumentation/timer.rs +++ b/diskann-disk/src/utils/instrumentation/timer.rs @@ -123,14 +123,9 @@ mod timer_tests { use super::*; #[test] - #[allow(clippy::if_same_then_else)] fn test_new() { let timer = Timer::new(); - if cfg!(windows) { - assert!(timer.cycles.is_some()); - } else if cfg!(target_os = "linux") { - assert!(timer.cycles.is_some()); - } else if cfg!(target_os = "macos") { + if cfg!(any(windows, target_os = "linux", target_os = "macos")) { assert!(timer.cycles.is_some()); } else { panic!("No timer::test_new defined for current configuration"); diff --git a/diskann-disk/src/utils/kmeans.rs b/diskann-disk/src/utils/kmeans.rs index b66ee65d15..f5e497ad96 100644 --- a/diskann-disk/src/utils/kmeans.rs +++ b/diskann-disk/src/utils/kmeans.rs @@ -32,7 +32,7 @@ use crate::error::{diskann_error, ErrorKind}; /// center to each data point, update centers, and also return inverted index. /// If closest_centers == NULL, will allocate memory and return. /// Similarly, if closest_docs == NULL, will allocate memory and return. -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] fn lloyds_iter( data: &[f32], num_points: usize, @@ -116,7 +116,7 @@ fn lloyds_iter( /// the results, else it will assume appropriate allocation as `closest_docs = /// new vec [num_centers]`, and `closest_center = new size_t[num_points]` /// Final centers are output in centers as row-major num_centers * dim. -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub fn run_lloyds( data: &[f32], num_points: usize, @@ -232,7 +232,7 @@ fn select_random_pivots( /// Returns an error if num_points > 8388608 (2^23). /// If there are are fewer than num_center distinct points, pick all unique points as pivots, /// and sample data randomly for the remaining pivots. -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub fn k_meanspp_selecting_pivots( data: &[f32], num_points: usize, @@ -399,7 +399,7 @@ pub fn k_meanspp_selecting_pivots( } /// k-means algorithm interface -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub fn k_means_clustering( data: &[f32], num_points: usize, diff --git a/diskann-disk/src/utils/math_util.rs b/diskann-disk/src/utils/math_util.rs index 30b7731088..12051fb1b0 100644 --- a/diskann-disk/src/utils/math_util.rs +++ b/diskann-disk/src/utils/math_util.rs @@ -134,7 +134,7 @@ pub fn compute_vecs_l2sq( /// Pre-allocated dist_matrix should be num_points * num_centers and contain squared distances /// Default value of k is 1 /// Ideally used only by compute_closest_centers -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub fn compute_closest_centers_in_block( data: &[f32], num_points: usize, @@ -253,7 +253,7 @@ pub fn compute_closest_centers_in_block( /// it will return inverted index for each center, assuming each of the inverted /// indices is an empty vector. Additionally, if pts_norms_squared is not null, /// then it will assume that point norms are pre-computed and use those values -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub fn compute_closest_centers( data: &[f32], num_points: usize, diff --git a/diskann-disk/src/utils/partition.rs b/diskann-disk/src/utils/partition.rs index a959af5ffd..fdd73e94c2 100644 --- a/diskann-disk/src/utils/partition.rs +++ b/diskann-disk/src/utils/partition.rs @@ -22,7 +22,7 @@ use crate::{ /// Block size for reading/processing large files and matrices in blocks const BLOCK_SIZE_LARGE_FILE: u32 = 10_000; -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub fn partition_with_ram_budget( dataset_file: &str, dim: usize, @@ -69,7 +69,7 @@ where Ok(num_parts) } -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] fn find_partition_size( dataset_file: &str, sampling_rate: f64, @@ -234,7 +234,7 @@ where partition_count } -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] fn shard_data_into_clusters_only_ids( dataset_file: &str, pivot_data: &[f32], @@ -358,7 +358,7 @@ where Ok(()) } -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] fn estimate_cluster_sizes( data_float: &[f32], num_pts: usize, diff --git a/diskann-garnet/Cargo.toml b/diskann-garnet/Cargo.toml index 19c56eb944..4ea4740381 100644 --- a/diskann-garnet/Cargo.toml +++ b/diskann-garnet/Cargo.toml @@ -9,6 +9,9 @@ publish = false [lib] crate-type = ["cdylib"] +[lints.clippy] +allow_attributes = "warn" + [dependencies] bytemuck.workspace = true crossbeam = "0.8.4" diff --git a/diskann-garnet/src/alloc.rs b/diskann-garnet/src/alloc.rs index 908ddd562f..c0f8108efb 100644 --- a/diskann-garnet/src/alloc.rs +++ b/diskann-garnet/src/alloc.rs @@ -23,7 +23,7 @@ unsafe impl AllocatorCore for AlignToEight { unsafe fn deallocate(&self, ptr: NonNull<[u8]>, layout: std::alloc::Layout) { // Lint: The given `layout` **should** be the same as that passed to `allocate`, // which must have succeeded for the pointer to be valid in the first place. - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] let layout = layout.align_to(8).expect("invalid layout provided"); unsafe { GlobalAllocator.deallocate(ptr, layout) } } diff --git a/diskann-inmem/Cargo.toml b/diskann-inmem/Cargo.toml index 72dec19bf5..be4b70ef96 100644 --- a/diskann-inmem/Cargo.toml +++ b/diskann-inmem/Cargo.toml @@ -30,6 +30,7 @@ diskann-benchmark-core = { workspace = true, optional = true } tokio = { workspace = true, optional = true } [lints.clippy] +allow_attributes = "warn" undocumented_unsafe_blocks = "warn" unwrap_used = "warn" expect_used = "warn" diff --git a/diskann-label-filter/Cargo.toml b/diskann-label-filter/Cargo.toml index 14102411ec..308eda52ff 100644 --- a/diskann-label-filter/Cargo.toml +++ b/diskann-label-filter/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true edition.workspace = true [lints] +clippy.allow_attributes = "warn" clippy.undocumented_unsafe_blocks = "warn" clippy.uninlined_format_args = "allow" diff --git a/diskann-label-filter/benches/benchmarks/parser_bench.rs b/diskann-label-filter/benches/benchmarks/parser_bench.rs index 73f48cd316..20848834df 100644 --- a/diskann-label-filter/benches/benchmarks/parser_bench.rs +++ b/diskann-label-filter/benches/benchmarks/parser_bench.rs @@ -89,7 +89,6 @@ fn bench_parsers_comparison(c: &mut Criterion) { group.finish(); } -#[allow(clippy::disallowed_methods)] fn rng() -> rand::prelude::ThreadRng { rand::rng() } diff --git a/diskann-label-filter/src/encoded_attribute_provider/roaring_attribute_store.rs b/diskann-label-filter/src/encoded_attribute_provider/roaring_attribute_store.rs index b315aaf30f..a2c999a8b7 100644 --- a/diskann-label-filter/src/encoded_attribute_provider/roaring_attribute_store.rs +++ b/diskann-label-filter/src/encoded_attribute_provider/roaring_attribute_store.rs @@ -31,9 +31,12 @@ impl RoaringAttributeStore where IT: VectorId + IntoUsize, { - #[allow( - dead_code, - reason = "This will be invoked by callers when they create a document provider." + #[cfg_attr( + not(test), + expect( + dead_code, + reason = "This will be invoked by callers when they create a document provider." + ) )] pub fn new() -> Self { Self { diff --git a/diskann-label-filter/src/kv_index/generic_index.rs b/diskann-label-filter/src/kv_index/generic_index.rs index 63bb943e42..1375dad842 100644 --- a/diskann-label-filter/src/kv_index/generic_index.rs +++ b/diskann-label-filter/src/kv_index/generic_index.rs @@ -20,6 +20,8 @@ const LOCATION_REVERSE_KEY_LIST: &str = "reverse_key_list"; const LOCATION_SERIALIZE_KEY_LIST: &str = "serialize_key_list"; pub(crate) const DATA_TYPE_POSTING_LIST: &str = "posting_list"; +pub(crate) type FieldNormalizer = dyn Fn(&str) -> String + Send + Sync; + /// A generic inverted index implementation. /// /// This index can work with any combination of: @@ -49,8 +51,7 @@ pub struct GenericIndex { pub(crate) _pl: PhantomData, pub(crate) _kc: PhantomData, /// Optional field normalizer function for query processing - #[allow(clippy::type_complexity)] - pub(crate) field_normalizer: Option String + Send + Sync>>, + pub(crate) field_normalizer: Option>, } impl GenericIndex @@ -321,7 +322,6 @@ where } #[cfg(test)] -#[allow(clippy::approx_constant)] mod tests { use super::*; use crate::stores::bftree_store::BfTreeStore; @@ -455,8 +455,8 @@ mod tests { assert_eq!(TestIndex::get_compare_value(&op), Some(42.0)); // Eq with float - let op = CompareOp::Eq(json!(3.14)); - assert_eq!(TestIndex::get_compare_value(&op), Some(3.14)); + let op = CompareOp::Eq(json!(3.13)); + assert_eq!(TestIndex::get_compare_value(&op), Some(3.13)); // Eq with string (no numeric value) let op = CompareOp::Eq(json!("hello")); @@ -547,7 +547,7 @@ mod tests { #[test] fn test_get_float_range_bounds_gte() { - let op = CompareOp::Gte(3.14); + let op = CompareOp::Gte(3.13); let (start, end) = TestIndex::get_float_range_bounds("price", &op); assert!(!start.is_empty()); diff --git a/diskann-label-filter/src/traits/key_codec.rs b/diskann-label-filter/src/traits/key_codec.rs index d0a30209ef..ca83897f0b 100644 --- a/diskann-label-filter/src/traits/key_codec.rs +++ b/diskann-label-filter/src/traits/key_codec.rs @@ -156,7 +156,6 @@ impl KeyCodec for DefaultKeyCodec { } #[cfg(test)] -#[allow(clippy::approx_constant)] mod tests { use super::*; use serde_json::json; @@ -341,7 +340,7 @@ mod tests { #[test] fn test_format_float_key() { - let key = DefaultKeyCodec::format_float_value("score", 3.14); + let key = DefaultKeyCodec::format_float_value("score", 3.13); let key_str = String::from_utf8(key.clone()).unwrap(); // Check structure diff --git a/diskann-linalg/Cargo.toml b/diskann-linalg/Cargo.toml index d60cbf3031..4f6a8b3b75 100644 --- a/diskann-linalg/Cargo.toml +++ b/diskann-linalg/Cargo.toml @@ -15,6 +15,7 @@ rand_distr.workspace = true rand.workspace = true [lints] +clippy.allow_attributes = "warn" clippy.undocumented_unsafe_blocks = "warn" clippy.uninlined_format_args = "allow" diff --git a/diskann-linalg/src/alternates/mkl.rs b/diskann-linalg/src/alternates/mkl.rs index 2160b8c4a4..2543fd3995 100644 --- a/diskann-linalg/src/alternates/mkl.rs +++ b/diskann-linalg/src/alternates/mkl.rs @@ -13,7 +13,7 @@ use thiserror::Error; /// /// The implementation may assume the the specified invariants hold for the sizes of the /// intermediate arrays. -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub(super) fn sgemm_impl( atranspose: Transpose, btranspose: Transpose, diff --git a/diskann-linalg/src/faer.rs b/diskann-linalg/src/faer.rs index 700396de4e..70ca0cb7a4 100644 --- a/diskann-linalg/src/faer.rs +++ b/diskann-linalg/src/faer.rs @@ -13,7 +13,7 @@ use super::common::Transpose; /// /// The implementation may assume the the specified invariants hold for the sizes of the /// intermediate arrays. -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub(super) fn sgemm_impl( atranspose: Transpose, btranspose: Transpose, diff --git a/diskann-linalg/src/lib.rs b/diskann-linalg/src/lib.rs index 7ee59d6b60..8b2b6644bc 100644 --- a/diskann-linalg/src/lib.rs +++ b/diskann-linalg/src/lib.rs @@ -143,7 +143,7 @@ mod reference; /// * `a.len() != m * k` /// * `b.len() != k * n` /// * `c.len() != m * n` -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub fn sgemm( atranspose: Transpose, btranspose: Transpose, diff --git a/diskann-linalg/src/reference.rs b/diskann-linalg/src/reference.rs index f780b77960..4217fd3bcc 100644 --- a/diskann-linalg/src/reference.rs +++ b/diskann-linalg/src/reference.rs @@ -10,7 +10,7 @@ use super::common::Transpose; /// Computes a matrix-matrix product with general matrices. /// This implementation is used for miri testing. /// Miri doesn't support cblas::sgemm(). -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] pub(super) fn sgemm_impl( atranspose: Transpose, btranspose: Transpose, @@ -102,7 +102,7 @@ impl GemmFunction for F where impl TestProblem { // We're in a world with too many arguments unfortunately. - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] pub(crate) fn new( atranspose: Transpose, btranspose: Transpose, @@ -278,7 +278,7 @@ mod tests { #[test] fn test_reference_implementation() { - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn sgemm_impl_wrapper( atranspose: Transpose, btranspose: Transpose, diff --git a/diskann-providers/Cargo.toml b/diskann-providers/Cargo.toml index 1da7fafdb3..a2c00398a6 100644 --- a/diskann-providers/Cargo.toml +++ b/diskann-providers/Cargo.toml @@ -66,6 +66,7 @@ virtual_storage = ["dep:vfs"] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage)'] } [lints.clippy] +allow_attributes = "warn" # Commenting out for now. It would give warnings. # undocumented_unsafe_blocks = "warn" uninlined_format_args = "allow" diff --git a/diskann-providers/src/common/ignore_lock_poison.rs b/diskann-providers/src/common/ignore_lock_poison.rs index 2c8ba10956..c8d53ffe09 100644 --- a/diskann-providers/src/common/ignore_lock_poison.rs +++ b/diskann-providers/src/common/ignore_lock_poison.rs @@ -16,7 +16,7 @@ where type Guard = std::sync::MutexGuard<'a, T>; fn lock_or_panic(&'a self) -> Self::Guard { - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] self.lock().expect("lock was poisoned") } } diff --git a/diskann-providers/src/common/minmax_repr.rs b/diskann-providers/src/common/minmax_repr.rs index be3260061c..f5c5e132a2 100644 --- a/diskann-providers/src/common/minmax_repr.rs +++ b/diskann-providers/src/common/minmax_repr.rs @@ -150,13 +150,13 @@ where >, Unsigned: Representation, { - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] // Lint: We're allowing panics in distance function for now. let xref = MinMaxElement::::from_raw(x).unwrap(); - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] // Lint: We're allowing panics in distance function for now. let yref = MinMaxElement::::from_raw(y).unwrap(); - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] // Lint: We're allowing panics in distance function for now. T::evaluate(xref, yref).unwrap() } diff --git a/diskann-providers/src/index/wrapped_async.rs b/diskann-providers/src/index/wrapped_async.rs index f207332472..9c8242f5a4 100644 --- a/diskann-providers/src/index/wrapped_async.rs +++ b/diskann-providers/src/index/wrapped_async.rs @@ -35,7 +35,7 @@ pub struct DiskANNIndex { /// Create a multi-threaded tokio runtime and return it together with its handle. fn create_multi_thread_runtime() -> (tokio::runtime::Runtime, tokio::runtime::Handle) { - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] let rt = tokio::runtime::Builder::new_multi_thread() .build() .expect("failed to create tokio runtime"); @@ -45,7 +45,7 @@ fn create_multi_thread_runtime() -> (tokio::runtime::Runtime, tokio::runtime::Ha /// Create a current-thread tokio runtime and return it together with its handle. fn create_current_thread_runtime() -> (tokio::runtime::Runtime, tokio::runtime::Handle) { - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] let rt = tokio::runtime::Builder::new_current_thread() .build() .expect("failed to create tokio runtime"); @@ -249,7 +249,6 @@ where .block_on(self.inner.drop_adj_list(accessor, vector_id)) } - #[allow(clippy::type_complexity)] pub fn get_undeleted_neighbors( &self, context: &DP::Context, diff --git a/diskann-providers/src/model/configuration/index_configuration.rs b/diskann-providers/src/model/configuration/index_configuration.rs index d279e73972..01bd2625b7 100644 --- a/diskann-providers/src/model/configuration/index_configuration.rs +++ b/diskann-providers/src/model/configuration/index_configuration.rs @@ -53,7 +53,6 @@ pub struct IndexConfiguration { impl IndexConfiguration { /// Create IndexConfiguration instance - #[allow(clippy::too_many_arguments)] pub fn new( dist_metric: Metric, dim: usize, diff --git a/diskann-providers/src/model/graph/provider/async_/common.rs b/diskann-providers/src/model/graph/provider/async_/common.rs index 9e3f3745b4..1170efaa17 100644 --- a/diskann-providers/src/model/graph/provider/async_/common.rs +++ b/diskann-providers/src/model/graph/provider/async_/common.rs @@ -179,7 +179,7 @@ impl AlignedMemoryVectorStore { /// /// This function will not synchronize access, but the memory is guaranteed to be valid. Callers must synchronize /// themselves if they require consistency. - #[allow(clippy::mut_from_ref)] + #[expect(clippy::mut_from_ref)] pub unsafe fn get_mut_slice(&self, index: usize) -> &mut [T] { assert!(index < self.max_vectors); let index = index * self.padded_vector_dim + self.start_index; diff --git a/diskann-providers/src/model/graph/provider/async_/distances.rs b/diskann-providers/src/model/graph/provider/async_/distances.rs index 9d1b6d7735..4c4d4a9ecf 100644 --- a/diskann-providers/src/model/graph/provider/async_/distances.rs +++ b/diskann-providers/src/model/graph/provider/async_/distances.rs @@ -145,7 +145,7 @@ pub mod pq { Hybrid::Quant(y) => { // SAFETY: This can only panic when T = `MinMaxElement` and the underlying slice is ill-defined. // we are ok with panicking in distance functions for now. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] self.quant.evaluate_similarity(&*T::as_f32(x).unwrap(), y) } }, @@ -153,7 +153,7 @@ pub mod pq { Hybrid::Full(y) => { // SAFETY: This can only panic when T = `MinMaxElement` and the underlying slice is ill-defined. // we are ok with panicking in distance functions for now. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] self.quant.evaluate_similarity(&*T::as_f32(y).unwrap(), x) } Hybrid::Quant(y) => self.quant.evaluate_similarity(x, y), diff --git a/diskann-providers/src/model/graph/provider/async_/simple_neighbor_provider.rs b/diskann-providers/src/model/graph/provider/async_/simple_neighbor_provider.rs index 98dcb2c7c2..724ec684c7 100644 --- a/diskann-providers/src/model/graph/provider/async_/simple_neighbor_provider.rs +++ b/diskann-providers/src/model/graph/provider/async_/simple_neighbor_provider.rs @@ -72,7 +72,7 @@ impl SimpleNeighborProviderAsync { ); // Lint: We don't have a good way of recovering from lock poisoning anyways. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] let _guard = self.locks[id].write().unwrap(); // SAFETY: We are holding the write lock for this id. @@ -94,7 +94,7 @@ impl SimpleNeighborProviderAsync { self.num_get_calls.increment(); // Lint: We don't have a good way of recovering from lock poisoning anyways. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] let _guard = self.locks[id].read().unwrap(); // SAFETY: We are holding the read lock for `id`. @@ -105,7 +105,7 @@ impl SimpleNeighborProviderAsync { pub fn append_vector_sync(&self, id: usize, new_neighbor_ids: &[u32]) -> ANNResult<()> { // Lint: We don't have a good way of recovering from lock poisoning anyways. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] let _guard = self.locks[id].write().unwrap(); // SAFETY: We took the write lock for `id` above. diff --git a/diskann-providers/src/model/pq/distance/multi.rs b/diskann-providers/src/model/pq/distance/multi.rs index 83ff44cb49..7d6dbf5f57 100644 --- a/diskann-providers/src/model/pq/distance/multi.rs +++ b/diskann-providers/src/model/pq/distance/multi.rs @@ -644,7 +644,7 @@ mod tests { //////////////////////////////////// /// Test that the table works correctly when there are two inner PQ tables. - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn test_distance_computer_multi_with_two( computer: &MultiDistanceComputer<'_, usize>, new: &FixedChunkPQTable, @@ -822,7 +822,7 @@ mod tests { // Query Computer - One Table // //////////////////////////////// - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn check_query_computer( computer: &MultiQueryComputer<'_, usize>, table: &FixedChunkPQTable, @@ -936,7 +936,7 @@ mod tests { // Query Computer - Two Tables // ///////////////////////////////// - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn test_query_computer_multi_with_two<'a, R>( create: impl Fn(usize, usize, &[f32]) -> MultiQueryComputer<'a, usize>, new: &'a FixedChunkPQTable, diff --git a/diskann-providers/src/model/pq/fixed_chunk_pq_table.rs b/diskann-providers/src/model/pq/fixed_chunk_pq_table.rs index 9ca23ac5b1..fe30125579 100644 --- a/diskann-providers/src/model/pq/fixed_chunk_pq_table.rs +++ b/diskann-providers/src/model/pq/fixed_chunk_pq_table.rs @@ -1077,7 +1077,6 @@ mod pq_index_prune_query_test { use super::*; #[test] - #[allow(clippy::identity_op)] fn pq_dist_lookup_test() { let pq_ids: Vec = vec![1u8, 3u8, 2u8, 2u8]; let mut pq_dists: Vec = Vec::with_capacity(256 * 2); @@ -1088,8 +1087,8 @@ mod pq_index_prune_query_test { let mut dists_out = vec![0.0f32; 2]; pq_dist_lookup(&pq_ids, 2, 2, &pq_dists, dists_out.as_mut_slice()).unwrap(); assert_eq!(dists_out.len(), 2); - assert_eq!(dists_out[0], pq_dists[0 + 1] + pq_dists[256 + 3]); - assert_eq!(dists_out[1], pq_dists[0 + 2] + pq_dists[256 + 2]); + assert_eq!(dists_out[0], pq_dists[1] + pq_dists[256 + 3]); + assert_eq!(dists_out[1], pq_dists[2] + pq_dists[256 + 2]); } #[test] diff --git a/diskann-providers/src/model/pq/generate_pivot_arguments.rs b/diskann-providers/src/model/pq/generate_pivot_arguments.rs index f42bc58a42..9a3e0d1764 100644 --- a/diskann-providers/src/model/pq/generate_pivot_arguments.rs +++ b/diskann-providers/src/model/pq/generate_pivot_arguments.rs @@ -40,21 +40,36 @@ pub struct GeneratePivotArguments { max_k_means_reps: usize, } +/// Invalid dimensions or chunk counts supplied to [`GeneratePivotArguments::new`]. #[derive(Error, Debug, PartialEq)] #[non_exhaustive] -#[allow(missing_docs)] pub enum GeneratePivotArgumentsError { + /// The number of PQ chunks exceeds the vector dimension. #[error("number of chunks {num_pq_chunks} more than dimension {dim}")] - NumChunksMoreThanDim { num_pq_chunks: usize, dim: usize }, + NumChunksMoreThanDim { + /// The requested number of PQ chunks. + num_pq_chunks: usize, + /// The supplied vector dimension. + dim: usize, + }, + /// At least one PQ chunk is required. #[error("invalid number of chunks 0 reatively to dimension")] NumChunksIsZero, + /// The vector dimension cannot be represented by the BLAS `i32` parameter. #[error("vector dimension {0} is greater than i32::MAX_VALUE")] - DimGreaterThanI32MaxValue(usize), + DimGreaterThanI32MaxValue( + /// The supplied vector dimension. + usize, + ), + /// The training vector count cannot be represented by the BLAS `i32` parameter. #[error("number of vectors {0} is greater than i32::MAX_VALUE")] - NumTrainGreaterThanI32MaxValue(usize), + NumTrainGreaterThanI32MaxValue( + /// The supplied number of training vectors. + usize, + ), } diskann::convert_error!(GeneratePivotArgumentsError); diff --git a/diskann-providers/src/model/pq/pq_construction.rs b/diskann-providers/src/model/pq/pq_construction.rs index 841f3cca1a..8db2e654fd 100644 --- a/diskann-providers/src/model/pq/pq_construction.rs +++ b/diskann-providers/src/model/pq/pq_construction.rs @@ -155,7 +155,6 @@ where /// The size of the `offsets` vector must be `num_pq_chunks + 1`. /// /// Result is stored in the `full_pivot_data`, which must be of size `num_centers * dim`. -#[allow(clippy::too_many_arguments)] pub fn generate_pq_pivots_from_membuf>( parameters: &GeneratePivotArguments, train_data_slice: &[T], diff --git a/diskann-providers/src/storage/virtual_storage_provider.rs b/diskann-providers/src/storage/virtual_storage_provider.rs index 8b99a6e35c..2ec8165b22 100644 --- a/diskann-providers/src/storage/virtual_storage_provider.rs +++ b/diskann-providers/src/storage/virtual_storage_provider.rs @@ -120,7 +120,7 @@ impl VirtualStorageProvider { /// Create a two-layer overlay filesystem with an in-memory filesystem for writes /// on top of the physical filesystem for reads. pub fn new_overlay>(path: P) -> Self { - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] let base_filesystem = PhysicalFS::new(path); let memory_filesystem = MemoryFS::new(); let overlay_filesystem = @@ -143,7 +143,7 @@ impl VirtualStorageProvider { /// Create a storage provider that uses the physical filesystem with a custom root path. /// This prevents operations from writing outside of the specified sandbox. pub fn new_physical>(path: P) -> Self { - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] let physical_filesystem = PhysicalFS::new(path); VirtualStorageProvider::new(physical_filesystem) diff --git a/diskann-providers/src/utils/file_util.rs b/diskann-providers/src/utils/file_util.rs index 548f43472b..e9870420bd 100644 --- a/diskann-providers/src/utils/file_util.rs +++ b/diskann-providers/src/utils/file_util.rs @@ -39,7 +39,6 @@ pub fn file_exists( /// * Data: [vec1 (len1 * dimension bytes), vec2 (len2 * dimension bytes), ..., vec npts (len npts * dimension bytes)] /// /// Returns the header information along with the loaded vectors as a vec of vecs -#[allow(clippy::type_complexity)] pub fn load_multivec_bin( storage_read_provider: &StorageReader, bin_file: &str, diff --git a/diskann-providers/src/utils/random.rs b/diskann-providers/src/utils/random.rs index 092af3e2ae..3ac1741f03 100644 --- a/diskann-providers/src/utils/random.rs +++ b/diskann-providers/src/utils/random.rs @@ -33,7 +33,6 @@ pub fn create_rnd_from_seed_in_tests(seed: u64) -> StandardRng { /// Creates a randomly seeded random number generator. #[cfg(not(any(test, feature = "testing")))] -#[allow(clippy::disallowed_methods)] pub fn create_rnd() -> StandardRng { rand::rngs::StdRng::from_os_rng() } diff --git a/diskann-providers/src/utils/rayon_util.rs b/diskann-providers/src/utils/rayon_util.rs index 744cbd6ccf..1285de8c70 100644 --- a/diskann-providers/src/utils/rayon_util.rs +++ b/diskann-providers/src/utils/rayon_util.rs @@ -18,7 +18,7 @@ pub fn create_thread_pool(num_threads: usize) -> ANNResult { /// Creates a thread pool with a configurable number of threads for testing purposes. /// The number of threads can be set using the environment variable `DISKANN_TEST_POOL_THREADS`. /// If the environment variable is not set or cannot be parsed, it defaults to 3 threads. -#[allow(clippy::unwrap_used)] +#[expect(clippy::unwrap_used)] pub fn create_thread_pool_for_test() -> RayonThreadPool { use std::env; @@ -33,7 +33,7 @@ pub fn create_thread_pool_for_test() -> RayonThreadPool { /// The Rayon runtime will automatically determine the optimal number of threads to use. /// It uses the `RAYON_NUM_THREADS` environment variable if set, /// or defaults to the number of logical CPUs otherwise -#[allow(clippy::unwrap_used)] +#[expect(clippy::unwrap_used)] pub fn create_thread_pool_for_bench() -> RayonThreadPool { let pool = rayon::ThreadPoolBuilder::new() .build() @@ -79,7 +79,7 @@ impl<'a> RayonThreadPoolRef<'a> { // Allow use of disallowed methods within this trait to provide custom // implementations of common parallel operations that enforce execution // within a specified thread pool. -#[allow(clippy::disallowed_methods)] +#[expect(clippy::disallowed_methods)] pub trait ParallelIteratorInPool: ParallelIterator + Sized { fn for_each_in_pool(self, pool: RayonThreadPoolRef<'_>, op: OP) where diff --git a/diskann-providers/src/utils/vector_data_iterator.rs b/diskann-providers/src/utils/vector_data_iterator.rs index e1287737b6..f5f2e9f162 100644 --- a/diskann-providers/src/utils/vector_data_iterator.rs +++ b/diskann-providers/src/utils/vector_data_iterator.rs @@ -88,7 +88,6 @@ impl self.num_points } - #[allow(clippy::type_complexity)] pub fn next_n(&mut self, n: usize) -> Option, A)>> where A: for<'de> Deserialize<'de> + Default, @@ -440,7 +439,7 @@ mod tests { .unwrap(); // nth(0) should be equivalent to next() - #[allow(clippy::iter_nth_zero)] + #[expect(clippy::iter_nth_zero)] let (vector, associated_data) = iterator.nth(0).unwrap(); assert_eq!(vector, vec![1_f32, 2_f32].into_boxed_slice()); assert_eq!(associated_data, 10_u32); diff --git a/diskann-quantization/Cargo.toml b/diskann-quantization/Cargo.toml index 31406e14f5..c87dcd7af0 100644 --- a/diskann-quantization/Cargo.toml +++ b/diskann-quantization/Cargo.toml @@ -21,6 +21,7 @@ half = { version = "2.6.0", features = ["bytemuck"] } diskann-utils = { workspace = true } [lints.clippy] +allow_attributes = "warn" undocumented_unsafe_blocks = "warn" unwrap_used = "warn" expect_used = "warn" diff --git a/diskann-quantization/src/algorithms/transforms/double_hadamard.rs b/diskann-quantization/src/algorithms/transforms/double_hadamard.rs index 22c171901c..bb84e10880 100644 --- a/diskann-quantization/src/algorithms/transforms/double_hadamard.rs +++ b/diskann-quantization/src/algorithms/transforms/double_hadamard.rs @@ -257,7 +257,7 @@ where // // If it is equal to the size of `tmp`, then we only run the first transform. Otherwise, // we perform two transforms on the head and tail of `tmp`. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] hadamard_transform(&mut tmp[..split]).unwrap(); // Apply the second transformation. @@ -267,7 +267,7 @@ where .zip(self.signs1.iter()) .for_each(|(dst, sign)| *dst = f32::from_bits(dst.to_bits() ^ sign)); - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] hadamard_transform(&mut tmp[intermediate_dim - split..]).unwrap(); match self.subsample.as_ref() { diff --git a/diskann-quantization/src/algorithms/transforms/padding_hadamard.rs b/diskann-quantization/src/algorithms/transforms/padding_hadamard.rs index 665f92da0c..1694b690f3 100644 --- a/diskann-quantization/src/algorithms/transforms/padding_hadamard.rs +++ b/diskann-quantization/src/algorithms/transforms/padding_hadamard.rs @@ -244,7 +244,7 @@ where // // 1. `output_dim` is a power of 2 by construction. // 2. We've checked that `dst.len() == output_dim`. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] hadamard_transform(dst).unwrap(); } Some(indices) => { @@ -256,7 +256,7 @@ where // // 1. `padded_dim` is a power of 2 by construction. // 2. We've checked that `tmp.len() == padded_dim`. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] hadamard_transform(&mut tmp).unwrap(); let rescale = ((tmp.len() as f32) / (indices.len() as f32)).sqrt(); diff --git a/diskann-quantization/src/algorithms/transforms/random_rotation.rs b/diskann-quantization/src/algorithms/transforms/random_rotation.rs index dc77941510..aeb28a16e3 100644 --- a/diskann-quantization/src/algorithms/transforms/random_rotation.rs +++ b/diskann-quantization/src/algorithms/transforms/random_rotation.rs @@ -87,7 +87,7 @@ impl RandomRotation { // Lint: By construction, the matrix returned from // `diskann_linalg::random_distance_preserving_matrix` will by `matrix_dim x matrix_dim`. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] let initial = diskann_utils::views::Matrix::try_from( diskann_linalg::random_distance_preserving_matrix(matrix_dim, rng).into(), matrix_dim, diff --git a/diskann-quantization/src/alloc/aligned.rs b/diskann-quantization/src/alloc/aligned.rs index 40dea03abb..4313224d2d 100644 --- a/diskann-quantization/src/alloc/aligned.rs +++ b/diskann-quantization/src/alloc/aligned.rs @@ -69,7 +69,7 @@ unsafe impl AllocatorCore for AlignedAllocator { unsafe fn deallocate(&self, ptr: NonNull<[u8]>, layout: std::alloc::Layout) { // Lint: The given `layout` **should** be the same as that passed to `allocate`, // which must have succeeded for the pointer to be valid in the first place. - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] let layout = layout .align_to(self.alignment()) .expect("invalid layout provided"); diff --git a/diskann-quantization/src/bits/distances.rs b/diskann-quantization/src/bits/distances.rs index e616e948ed..6cc0b4282a 100644 --- a/diskann-quantization/src/bits/distances.rs +++ b/diskann-quantization/src/bits/distances.rs @@ -2587,7 +2587,7 @@ impl let len = check_lengths!(x, y)?; diskann_wide::alias!(u8s_16 = ::u8x16); - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] type u8s_8 = diskann_wide::arch::aarch64::u8x8; diskann_wide::alias!(u32s = ::u32x4); @@ -2680,7 +2680,7 @@ impl ) -> MathematicalResult { let len = check_lengths!(x, y)?; - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] type u8s_8 = diskann_wide::arch::aarch64::u8x8; diskann_wide::alias!(u8s_16 = ::u8x16); diskann_wide::alias!(u8s_32 = ::u8x32); @@ -2816,7 +2816,7 @@ impl // returns number of quantized vectors let len = check_lengths!(x, y)?; - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] type u8s_8 = diskann_wide::arch::aarch64::u8x8; diskann_wide::alias!(u8s_16 = ::u8x16); diskann_wide::alias!(u8s_32 = ::u8x32); diff --git a/diskann-quantization/src/bits/slice.rs b/diskann-quantization/src/bits/slice.rs index 423962550c..dcfaeff7c2 100644 --- a/diskann-quantization/src/bits/slice.rs +++ b/diskann-quantization/src/bits/slice.rs @@ -89,7 +89,7 @@ impl Unsigned { 0..=2i64.pow(NBITS as u32) - 1 } - #[allow(clippy::panic)] + #[expect(clippy::panic)] const fn domain_str(nbits: usize) -> &'static &'static str { match nbits { 8 => &"[0, 255]", diff --git a/diskann-quantization/src/distances.rs b/diskann-quantization/src/distances.rs index 6ccda00e8c..5e93355974 100644 --- a/diskann-quantization/src/distances.rs +++ b/diskann-quantization/src/distances.rs @@ -30,7 +30,7 @@ pub struct UnequalLengths; impl UnequalLengths { /// Escalate the unequal length error to a full-blown panic. - #[allow(clippy::panic)] + #[expect(clippy::panic)] #[inline(never)] pub fn panic(self, xlen: usize, ylen: usize) -> ! { panic!( diff --git a/diskann-quantization/src/lib.rs b/diskann-quantization/src/lib.rs index 299fb5e10a..efb22314da 100644 --- a/diskann-quantization/src/lib.rs +++ b/diskann-quantization/src/lib.rs @@ -171,7 +171,14 @@ pub use traits::{AsFunctor, CompressInto, CompressIntoWith}; // serialization #[cfg(feature = "flatbuffers")] -#[allow(mismatched_lifetime_syntaxes)] // The generated code isn't clippy-clean. +#[expect( + clippy::allow_attributes, + reason = "FlatBuffers-generated bindings and their import macro use blanket allow attributes" +)] +#[expect( + mismatched_lifetime_syntaxes, + reason = "Generated bindings omit lifetime placeholders in return types" +)] pub(crate) mod flatbuffers; // common algorithms diff --git a/diskann-quantization/src/matrix_kernels/bounds.rs b/diskann-quantization/src/matrix_kernels/bounds.rs index 41672acfb2..b0d80fc845 100644 --- a/diskann-quantization/src/matrix_kernels/bounds.rs +++ b/diskann-quantization/src/matrix_kernels/bounds.rs @@ -246,13 +246,12 @@ pub(super) use __assert; pub(super) use check_eq; pub(super) use check_ge; -#[allow(unused_imports, reason = "this completes the comparison API")] +#[expect(unused_imports, reason = "this completes the comparison API")] pub(super) use check_gt; -#[allow(unused_imports, reason = "this completes the comparison API")] +#[expect(unused_imports, reason = "this completes the comparison API")] pub(super) use check_le; -#[allow(unused_imports, reason = "this completes the comparison API")] pub(super) use check_lt; #[cfg(any(test, debug_assertions))] diff --git a/diskann-quantization/src/minmax/quantizer.rs b/diskann-quantization/src/minmax/quantizer.rs index 344e3bb519..c28e88f9c8 100644 --- a/diskann-quantization/src/minmax/quantizer.rs +++ b/diskann-quantization/src/minmax/quantizer.rs @@ -171,7 +171,7 @@ impl MinMaxQuantizer { let mut vec = vec![f32::default(); self.output_dim()]; // We know vec.len() == self.output_dim() and `from.len() == self.dim` - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] self.transform .transform_into( &mut vec, @@ -401,7 +401,7 @@ where } // We know vec.len() == self.output_dim() and `from.len() == self.dim` - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] self.transform .transform_into(to.vector_mut(), &from, ScopedAllocator::global()) .unwrap(); diff --git a/diskann-quantization/src/multi_vector/block_transposed.rs b/diskann-quantization/src/multi_vector/block_transposed.rs index 159dc4bbba..5db9f8b87a 100644 --- a/diskann-quantization/src/multi_vector/block_transposed.rs +++ b/diskann-quantization/src/multi_vector/block_transposed.rs @@ -336,7 +336,7 @@ impl std::ops::Index type Output = T; #[inline] - #[allow(clippy::panic)] // Index is expected to panic on OOB + #[expect(clippy::panic)] // Index is expected to panic on OOB fn index(&self, col: usize) -> &Self::Output { self.get(col) .unwrap_or_else(|| panic!("column index {col} out of bounds (ncols = {})", self.ncols)) @@ -446,7 +446,7 @@ impl std::ops::Index type Output = T; #[inline] - #[allow(clippy::panic)] // Index is expected to panic on OOB + #[expect(clippy::panic)] // Index is expected to panic on OOB fn index(&self, col: usize) -> &Self::Output { self.get(col) .unwrap_or_else(|| panic!("column index {col} out of bounds (ncols = {})", self.ncols)) @@ -457,7 +457,7 @@ impl std::ops::IndexMut for RowMut<'_, T, GROUP, PACK> { #[inline] - #[allow(clippy::panic)] // IndexMut is expected to panic on OOB + #[expect(clippy::panic)] // IndexMut is expected to panic on OOB fn index_mut(&mut self, col: usize) -> &mut Self::Output { let ncols = self.ncols; self.get_mut(col) @@ -821,7 +821,7 @@ impl<'a, T: Copy, const GROUP: usize, const PACK: usize> BlockTransposedRef<'a, /// # Panics /// /// Panics if `block >= self.full_blocks()`. - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] pub fn block(&self, block: usize) -> MatrixView<'a, T> { assert!(block < self.full_blocks()); let offset = self.data.repr().block_offset(block); @@ -838,7 +838,7 @@ impl<'a, T: Copy, const GROUP: usize, const PACK: usize> BlockTransposedRef<'a, /// /// The returned view has the same dimensions as [`block()`](Self::block): /// `padded_ncols / PACK` rows and `GROUP * PACK` columns. - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] pub fn remainder_block(&self) -> Option> { if self.remainder() == 0 { None @@ -909,9 +909,9 @@ impl<'a, T: Copy, const GROUP: usize, const PACK: usize> BlockTransposedMut<'a, delegate_to_ref!(pub fn padded_nrows(&self) -> usize); delegate_to_ref!(pub fn as_ptr(&self) -> *const T); delegate_to_ref!(pub fn as_slice(&self) -> &[T]); - delegate_to_ref!(#[allow(clippy::missing_safety_doc)] unsafe pub fn block_ptr_unchecked(&self, block: usize) -> *const T); - delegate_to_ref!(#[allow(clippy::expect_used)] pub fn block(&self, block: usize) -> MatrixView<'_, T>); - delegate_to_ref!(#[allow(clippy::expect_used)] pub fn remainder_block(&self) -> Option>); + delegate_to_ref!(#[expect(clippy::missing_safety_doc)] unsafe pub fn block_ptr_unchecked(&self, block: usize) -> *const T); + delegate_to_ref!(pub fn block(&self, block: usize) -> MatrixView<'_, T>); + delegate_to_ref!(pub fn remainder_block(&self) -> Option>); delegate_to_ref!(pub fn get_element(&self, row: usize, col: usize) -> T); /// Group size (blocking factor `GROUP`). @@ -961,12 +961,11 @@ impl<'a, T: Copy, const GROUP: usize, const PACK: usize> BlockTransposedMut<'a, /// # Panics /// /// Panics if `block >= self.full_blocks()`. - #[allow(clippy::expect_used)] pub fn block_mut(&mut self, block: usize) -> MutMatrixView<'_, T> { self.reborrow_mut().block_mut_inner(block) } - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] fn block_mut_inner(mut self, block: usize) -> MutMatrixView<'a, T> { let repr = *self.data.repr(); assert!(block < repr.full_blocks()); @@ -986,12 +985,11 @@ impl<'a, T: Copy, const GROUP: usize, const PACK: usize> BlockTransposedMut<'a, /// Return a mutable view over the remainder block, or `None` if there is no /// remainder. - #[allow(clippy::expect_used)] pub fn remainder_block_mut(&mut self) -> Option> { self.reborrow_mut().remainder_block_mut_inner() } - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] fn remainder_block_mut_inner(mut self) -> Option> { let repr = *self.data.repr(); if repr.remainder() == 0 { @@ -1051,9 +1049,9 @@ impl BlockTransposed usize); delegate_to_ref!(pub fn as_ptr(&self) -> *const T); delegate_to_ref!(pub fn as_slice(&self) -> &[T]); - delegate_to_ref!(#[allow(clippy::missing_safety_doc)] unsafe pub fn block_ptr_unchecked(&self, block: usize) -> *const T); - delegate_to_ref!(#[allow(clippy::expect_used)] pub fn block(&self, block: usize) -> MatrixView<'_, T>); - delegate_to_ref!(#[allow(clippy::expect_used)] pub fn remainder_block(&self) -> Option>); + delegate_to_ref!(#[expect(clippy::missing_safety_doc)] unsafe pub fn block_ptr_unchecked(&self, block: usize) -> *const T); + delegate_to_ref!(pub fn block(&self, block: usize) -> MatrixView<'_, T>); + delegate_to_ref!(pub fn remainder_block(&self) -> Option>); delegate_to_ref!(pub fn get_element(&self, row: usize, col: usize) -> T); /// Group size (blocking factor `GROUP`). @@ -1086,13 +1084,11 @@ impl BlockTransposed MutMatrixView<'_, T> { self.as_view_mut().block_mut_inner(block) } /// See [`BlockTransposedMut::remainder_block_mut`]. - #[allow(clippy::expect_used)] pub fn remainder_block_mut(&mut self) -> Option> { self.as_view_mut().remainder_block_mut_inner() } @@ -1125,7 +1121,7 @@ impl BlockTransposed Self { let repr = BlockTransposedRepr::::new(nrows, ncols) .expect("dimensions should not overflow"); diff --git a/diskann-quantization/src/multi_vector/distance/isa.rs b/diskann-quantization/src/multi_vector/distance/isa.rs index f94424c519..a09731478c 100644 --- a/diskann-quantization/src/multi_vector/distance/isa.rs +++ b/diskann-quantization/src/multi_vector/distance/isa.rs @@ -16,7 +16,7 @@ /// serialization format. #[non_exhaustive] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub enum MaxSimIsa { /// Pick the highest ISA the host CPU supports. Auto, diff --git a/diskann-quantization/src/multi_vector/matrix.rs b/diskann-quantization/src/multi_vector/matrix.rs index ec19546c48..a960ca8fa3 100644 --- a/diskann-quantization/src/multi_vector/matrix.rs +++ b/diskann-quantization/src/multi_vector/matrix.rs @@ -884,7 +884,7 @@ impl<'a, T> MatRef<'a, Standard> { } /// Return a [`MatrixView`] over the backing data. - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] #[inline] pub fn as_matrix_view(&self) -> MatrixView<'a, T> { // `Standard::new` validates that `nrows * ncols` does not overflow, diff --git a/diskann-quantization/src/product/tables/transposed/table.rs b/diskann-quantization/src/product/tables/transposed/table.rs index bc527fd8a2..3d77e41e6f 100644 --- a/diskann-quantization/src/product/tables/transposed/table.rs +++ b/diskann-quantization/src/product/tables/transposed/table.rs @@ -69,7 +69,7 @@ impl TransposedTable { /// by the offsets. /// /// * `pivots.nrows() == 0`: The pivot table cannot be empty. - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] pub fn from_parts( pivots: views::MatrixView, offsets: ChunkOffsets, @@ -151,7 +151,7 @@ impl TransposedTable { /// Panics under the following conditions: /// * `data.cols() != self.dim()`: The number of columns in the source dataset must match /// the number of dimensions expected by the schema. - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] pub fn compress_batch( &self, data: views::MatrixView<'_, T>, diff --git a/diskann-quantization/src/spherical/quantizer.rs b/diskann-quantization/src/spherical/quantizer.rs index c6a69f4936..7b6341ce39 100644 --- a/diskann-quantization/src/spherical/quantizer.rs +++ b/diskann-quantization/src/spherical/quantizer.rs @@ -863,8 +863,6 @@ where struct AsNonZero; impl AsNonZero { - // Lint: Unwrap is being used in a const-context. - #[allow(clippy::unwrap_used)] const NON_ZERO: NonZeroUsize = NonZeroUsize::new(NBITS).unwrap(); } @@ -1025,7 +1023,7 @@ fn maximize_cosine_similarity( // Lint: This is a private method and all the callers have an invariant that they check // for non-empty inputs. - #[allow(clippy::expect_used)] + #[expect(clippy::expect_used)] let mut critical_values = SliceHeap::new(&mut base).expect("calling code should not allow the slice to be empty"); @@ -1196,7 +1194,7 @@ where // // Further, `c` has beem clamped to `[0, 2^NBITS - 1]` and is thus encodable // with the NBITS-bit unsigned representation. - #[allow(clippy::unwrap_used)] + #[expect(clippy::unwrap_used)] into.vector_mut().set(i, c as i64).unwrap(); }); diff --git a/diskann-tools/Cargo.toml b/diskann-tools/Cargo.toml index 92bcbc9499..9ea4a34a96 100644 --- a/diskann-tools/Cargo.toml +++ b/diskann-tools/Cargo.toml @@ -48,5 +48,6 @@ diskann-utils = { workspace = true, features = ["testing"] } default = [] [lints] +clippy.allow_attributes = "warn" clippy.undocumented_unsafe_blocks = "warn" clippy.uninlined_format_args = "allow" diff --git a/diskann-tools/src/bin/compute_streaming_groundtruth.rs b/diskann-tools/src/bin/compute_streaming_groundtruth.rs index 74c454cbe1..335d1c3a2f 100644 --- a/diskann-tools/src/bin/compute_streaming_groundtruth.rs +++ b/diskann-tools/src/bin/compute_streaming_groundtruth.rs @@ -80,8 +80,10 @@ fn compute_groundtruth_results( active_entries: &[(u32, usize)], recall_at: usize, ) -> anyhow::Result>> { - // using the global threadpool is generally fine in diskann-tools - #[allow(clippy::disallowed_methods)] + #[expect( + clippy::disallowed_methods, + reason = "using the global threadpool is generally fine in diskann-tools" + )] let results = (0..distance.n_queries()) .into_par_iter() .map(|query_id| { diff --git a/diskann-tools/src/utils/cmd_tool_error.rs b/diskann-tools/src/utils/cmd_tool_error.rs index b8c7293c70..4a263a7f7d 100644 --- a/diskann-tools/src/utils/cmd_tool_error.rs +++ b/diskann-tools/src/utils/cmd_tool_error.rs @@ -25,11 +25,7 @@ impl fmt::Debug for CMDToolError { } } -impl Error for CMDToolError { - fn description(&self) -> &str { - &self.details - } -} +impl Error for CMDToolError {} impl From for CMDToolError { fn from(err: std::io::Error) -> Self { @@ -115,17 +111,6 @@ mod tests { assert_eq!(format!("{:?}", error), "test error"); } - #[test] - fn test_cmd_tool_error_description() { - let error = CMDToolError { - details: "test error".to_string(), - }; - #[allow(deprecated)] - { - assert_eq!(error.description(), "test error"); - } - } - #[test] fn test_from_io_error() { let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found"); diff --git a/diskann-tools/src/utils/compute_bitmap.rs b/diskann-tools/src/utils/compute_bitmap.rs index ef5977e54c..15e550acf9 100644 --- a/diskann-tools/src/utils/compute_bitmap.rs +++ b/diskann-tools/src/utils/compute_bitmap.rs @@ -64,7 +64,7 @@ trait QueryAccelerator: Send + Sync { fn universe(&self) -> BitSet; // method for testing - #[allow(dead_code)] + #[cfg_attr(not(test), expect(dead_code))] fn as_any(&self) -> &dyn Any; } @@ -428,7 +428,7 @@ pub fn compute_query_bitmaps( let global_label_set = compute_global_label_set(&flattened_base_label_hashmaps)?; // Compute the accelerators for each label in the global set - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] let query_accelerators: HashMap> = global_label_set .par_iter() .map(|(key, value)| { @@ -438,7 +438,7 @@ pub fn compute_query_bitmaps( .collect::>()?; // Evaluate each query using the precomputed accelerators - #[allow(clippy::disallowed_methods)] + #[expect(clippy::disallowed_methods)] let query_bitmaps: Result, anyhow::Error> = query_labels .par_iter() .map(|(_query_id, query_expr)| { diff --git a/diskann-tools/src/utils/ground_truth.rs b/diskann-tools/src/utils/ground_truth.rs index 7ed422a389..2e8de3c48a 100644 --- a/diskann-tools/src/utils/ground_truth.rs +++ b/diskann-tools/src/utils/ground_truth.rs @@ -118,8 +118,7 @@ fn build_query_bitmaps( distance_function: Metric, dataset_iter: VectorDataIterator, @@ -387,8 +384,7 @@ impl FromStr for MultivecAggregationMethod { } } -#[allow(clippy::too_many_arguments)] -#[allow(clippy::panic)] +#[expect(clippy::too_many_arguments)] /// Computes the true nearest neighbors for a set of queries and writes them to a file. /// /// # Arguments @@ -585,7 +581,6 @@ type Npq = Vec>; /// * `insert_iter` - Optional iterator containing more dataset vectors. This may be useful if you are testing recall for an index that has points dynamically inserted into it. /// * `skip_base` - Optional number of base points to skip. This is useful if you want to compute the ground truth for a set where the first skip_base points are deleted from the index. /// * `query_bitmaps` - Optional per-query bitmaps restricting which base point ids contribute to that query's neighbors. -#[allow(clippy::too_many_arguments)] pub fn compute_ground_truth_from_data( distance_function: Metric, dataset_iter: VectorDataIterator, @@ -692,7 +687,6 @@ where Ok((neighbor_queues, id_to_associated_data)) } -#[allow(clippy::too_many_arguments)] pub fn compute_multivec_ground_truth_from_data( distance_function: Metric, aggregation_method: MultivecAggregationMethod, diff --git a/diskann-tools/src/utils/random_data_generator.rs b/diskann-tools/src/utils/random_data_generator.rs index 5060be49cf..1737ec9b85 100644 --- a/diskann-tools/src/utils/random_data_generator.rs +++ b/diskann-tools/src/utils/random_data_generator.rs @@ -19,7 +19,6 @@ Generate random points around a sphere with the specified radius and write them When data_type is int8 or uint8 radius must be <= 127.0 */ -#[allow(clippy::panic)] pub fn write_random_data( storage_provider: &StorageProvider, output_file: &str, @@ -55,7 +54,6 @@ Generate random points around a sphere with the specified radius and write them When data_type is int8 or uint8 radius must be <= 127.0 */ -#[allow(clippy::panic)] fn write_random_data_writer( mut writer: BufWriter, data_type: DataType, diff --git a/diskann-tools/src/utils/search_index_utils.rs b/diskann-tools/src/utils/search_index_utils.rs index 702c351e47..a475ebd125 100644 --- a/diskann-tools/src/utils/search_index_utils.rs +++ b/diskann-tools/src/utils/search_index_utils.rs @@ -117,7 +117,6 @@ impl KRecallAtN { /// Calculate the intersection between the top `k` ground truth elements and the top `n` /// obtained results. -#[allow(clippy::too_many_arguments)] pub fn calculate_recall( num_queries: usize, ground_truth: &[T], diff --git a/diskann-utils/src/views.rs b/diskann-utils/src/views.rs index a42f5cc44a..e205f66128 100644 --- a/diskann-utils/src/views.rs +++ b/diskann-utils/src/views.rs @@ -1796,7 +1796,7 @@ mod tests { // Ensure Debug doesn't require T: Debug by using a non-Debug type #[derive(Clone, Debug)] - struct NonDebug(#[allow(dead_code)] i32); + struct NonDebug(#[expect(dead_code)] i32); let non_debug_data: Box<[NonDebug]> = vec![NonDebug(1), NonDebug(2)].into(); let non_debug_err = Matrix::try_from(non_debug_data, 1, 3).unwrap_err(); diff --git a/diskann-vector/Cargo.toml b/diskann-vector/Cargo.toml index 19f3c6e005..fa5dab9d16 100644 --- a/diskann-vector/Cargo.toml +++ b/diskann-vector/Cargo.toml @@ -34,6 +34,7 @@ name = "bench_main_vector_iai" harness = false [lints] +clippy.allow_attributes = "warn" # Commenting out for now. It would give warnings. # clippy.undocumented_unsafe_blocks = "warn" clippy.uninlined_format_args = "allow" diff --git a/diskann-vector/benches/utils/record.rs b/diskann-vector/benches/utils/record.rs index 41f356274d..e51b6dd94f 100644 --- a/diskann-vector/benches/utils/record.rs +++ b/diskann-vector/benches/utils/record.rs @@ -62,7 +62,11 @@ impl From> for usize { /// /// * `aligned/unaligned`: Whether the vector pointers provided are *all* 32-byte aligned /// or not. -#[allow(dead_code)] // benchmark_iai doesn't use this ... +#[expect( + clippy::allow_attributes, + reason = "This shared helper is used by Criterion but not IAI" +)] +#[allow(dead_code)] pub(crate) fn format_benchmark(dim: Dim, aligned: bool) -> String where Dim: Dimensionality, diff --git a/diskann-vector/src/conversion.rs b/diskann-vector/src/conversion.rs index 3da74c8aa9..74125efdcb 100644 --- a/diskann-vector/src/conversion.rs +++ b/diskann-vector/src/conversion.rs @@ -180,7 +180,7 @@ trait SIMDConvert: Architecture { } #[inline(never)] -#[allow(clippy::panic)] +#[expect(clippy::panic)] fn emit_length_error(xlen: usize, ylen: usize) -> ! { panic!( "lengths must be equal, instead got: xlen = {}, ylen = {}", diff --git a/diskann-vector/src/distance/implementations.rs b/diskann-vector/src/distance/implementations.rs index 30bd80431c..03bffc50b0 100644 --- a/diskann-vector/src/distance/implementations.rs +++ b/diskann-vector/src/distance/implementations.rs @@ -116,7 +116,7 @@ where // Outline the panic formatting and keep the calling convention the same as // the top function. This keeps code generation extremely lightweight. #[inline(never)] -#[allow(clippy::panic)] +#[expect(clippy::panic)] fn fail_length_check(x: UnalignedSlice<'_, L>, y: UnalignedSlice<'_, R>, len: usize) -> ! { let message = if x.len() != len { ("first", x.len()) @@ -658,7 +658,7 @@ mod tests { max_relative: f32, } - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn run_test( under_test: fn(&[L], &[R]) -> To, reference: fn(&[L], &[R]) -> To, diff --git a/diskann-vector/src/distance/simd.rs b/diskann-vector/src/distance/simd.rs index 95b6e1c526..d49d66958a 100644 --- a/diskann-vector/src/distance/simd.rs +++ b/diskann-vector/src/distance/simd.rs @@ -669,7 +669,7 @@ where } #[inline(never)] -#[allow(clippy::panic)] +#[expect(clippy::panic)] fn emit_length_error(xlen: usize, ylen: usize) -> ! { panic!( "lengths must be equal, instead got: xlen = {}, ylen = {}", @@ -3814,7 +3814,7 @@ mod tests { test_util::test_distance_function(&mut checker, dist, dist, dim, 10, rng); } - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn stress_test( arch: A, reference: fn(&[L], &[R]) -> f32, diff --git a/diskann-vector/src/distance/test/mod.rs b/diskann-vector/src/distance/test/mod.rs index d4352dc29d..2f98b90196 100644 --- a/diskann-vector/src/distance/test/mod.rs +++ b/diskann-vector/src/distance/test/mod.rs @@ -15,8 +15,6 @@ pub(crate) trait FullPrecisionDistance { fn distance_compare(a: &[T; N], b: &[T; N], vec_type: Metric) -> f32; } -// reason = "Not supported Metric type Metric::Cosine" -#[allow(clippy::panic)] impl FullPrecisionDistance for [f32; N] { /// Calculate distance between two f32 Vertex #[inline(always)] @@ -30,8 +28,6 @@ impl FullPrecisionDistance for [f32; N] { } } -// reason = "Not supported Metric type Metric::Cosine" -#[allow(clippy::panic)] impl FullPrecisionDistance for [Half; N] { fn distance_compare(a: &[Half; N], b: &[Half; N], metric: Metric) -> f32 { match metric { diff --git a/diskann-wide/Cargo.toml b/diskann-wide/Cargo.toml index 1e4a7c742b..a4b44efd92 100644 --- a/diskann-wide/Cargo.toml +++ b/diskann-wide/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true edition = "2024" [lints] +clippy.allow_attributes = "warn" clippy.undocumented_unsafe_blocks = "warn" clippy.uninlined_format_args = "allow" diff --git a/diskann-wide/src/arch/aarch64/double.rs b/diskann-wide/src/arch/aarch64/double.rs index f5cef17ad1..b1b11870c0 100644 --- a/diskann-wide/src/arch/aarch64/double.rs +++ b/diskann-wide/src/arch/aarch64/double.rs @@ -35,7 +35,7 @@ macro_rules! double_alias { // Implement `SIMDVector` and friends for the `Double` type. doubled::double_vector!($scalar, $lanes, $subtype); - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] pub type $type = Doubled<$subtype>; }; } diff --git a/diskann-wide/src/arch/aarch64/macros.rs b/diskann-wide/src/arch/aarch64/macros.rs index 4960f73d53..80c4773448 100644 --- a/diskann-wide/src/arch/aarch64/macros.rs +++ b/diskann-wide/src/arch/aarch64/macros.rs @@ -8,7 +8,7 @@ use crate::SIMDVector; macro_rules! aarch64_define_register { ($type:ident, $impl:ty, $mask:ty, $scalar:ty, $lanes:literal, $arch:ty) => { #[derive(Debug, Clone, Copy)] - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] #[repr(transparent)] pub struct $type(pub $impl); diff --git a/diskann-wide/src/arch/aarch64/masks.rs b/diskann-wide/src/arch/aarch64/masks.rs index 23214aa330..3f093b3589 100644 --- a/diskann-wide/src/arch/aarch64/masks.rs +++ b/diskann-wide/src/arch/aarch64/masks.rs @@ -30,7 +30,7 @@ use super::Neon; macro_rules! define_mask { ($mask:ident, $repr:ident, $lanes:literal, $arch:ty) => { #[derive(Debug, Clone, Copy)] - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] #[repr(transparent)] pub struct $mask(pub(crate) $repr); diff --git a/diskann-wide/src/arch/mod.rs b/diskann-wide/src/arch/mod.rs index e014fc1599..00a182a289 100644 --- a/diskann-wide/src/arch/mod.rs +++ b/diskann-wide/src/arch/mod.rs @@ -524,7 +524,7 @@ macro_rules! vector { } } -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub trait Architecture: sealed::Sealed { // mask types type mask_f16x8: SIMDMask; diff --git a/diskann-wide/src/arch/x86_64/macros.rs b/diskann-wide/src/arch/x86_64/macros.rs index dfb4d73845..ad73f0fd0e 100644 --- a/diskann-wide/src/arch/x86_64/macros.rs +++ b/diskann-wide/src/arch/x86_64/macros.rs @@ -11,7 +11,7 @@ use crate::traits::{SIMDMask, SIMDVector}; macro_rules! x86_define_register { ($type:ident, $impl:ty, $mask:ty, $scalar:ty, $lanes:literal, $arch:ty) => { #[derive(Debug, Clone, Copy)] - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] #[repr(transparent)] pub struct $type(pub $impl); diff --git a/diskann-wide/src/arch/x86_64/v3/f32x16_.rs b/diskann-wide/src/arch/x86_64/v3/f32x16_.rs index 836193a452..3e6e7f32a5 100644 --- a/diskann-wide/src/arch/x86_64/v3/f32x16_.rs +++ b/diskann-wide/src/arch/x86_64/v3/f32x16_.rs @@ -13,7 +13,7 @@ use crate::doubled; doubled::double_vector!(f32, 16, f32x8); -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub type f32x16 = doubled::Doubled; /////////// diff --git a/diskann-wide/src/arch/x86_64/v3/i16x32_.rs b/diskann-wide/src/arch/x86_64/v3/i16x32_.rs index 8174f28184..80a40870b2 100644 --- a/diskann-wide/src/arch/x86_64/v3/i16x32_.rs +++ b/diskann-wide/src/arch/x86_64/v3/i16x32_.rs @@ -14,7 +14,7 @@ use crate::{LoHi, SplitJoin, doubled}; doubled::double_vector!(i16, 32, i16x16); doubled::double_scalar_shift!(Doubled); -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub type i16x32 = doubled::Doubled; impl From for i16x32 { diff --git a/diskann-wide/src/arch/x86_64/v3/i32x16_.rs b/diskann-wide/src/arch/x86_64/v3/i32x16_.rs index ec0e1fa087..38623858d3 100644 --- a/diskann-wide/src/arch/x86_64/v3/i32x16_.rs +++ b/diskann-wide/src/arch/x86_64/v3/i32x16_.rs @@ -14,7 +14,7 @@ use crate::doubled; doubled::double_vector!(i32, 16, i32x8); doubled::double_scalar_shift!(Doubled); -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub type i32x16 = doubled::Doubled; /////////// diff --git a/diskann-wide/src/arch/x86_64/v3/i8x64_.rs b/diskann-wide/src/arch/x86_64/v3/i8x64_.rs index b06cfd3cc2..ab7933eba7 100644 --- a/diskann-wide/src/arch/x86_64/v3/i8x64_.rs +++ b/diskann-wide/src/arch/x86_64/v3/i8x64_.rs @@ -14,7 +14,7 @@ use crate::doubled; doubled::double_vector!(i8, 64, i8x32); doubled::double_scalar_shift!(Doubled); -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub type i8x64 = doubled::Doubled; /////////// diff --git a/diskann-wide/src/arch/x86_64/v3/masks.rs b/diskann-wide/src/arch/x86_64/v3/masks.rs index 499ac5b648..2d455fe493 100644 --- a/diskann-wide/src/arch/x86_64/v3/masks.rs +++ b/diskann-wide/src/arch/x86_64/v3/masks.rs @@ -18,7 +18,7 @@ use crate::{ // mask8x16 #[derive(Debug, Clone, Copy)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] #[repr(transparent)] pub struct mask8x16(pub(crate) __m128i); @@ -144,7 +144,7 @@ impl From for BitMask<16, V3> { // mask8x32 #[derive(Debug, Clone, Copy)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] #[repr(transparent)] pub struct mask8x32(pub(crate) __m256i); @@ -287,7 +287,7 @@ impl From for BitMask<32, V3> { // mask32x4 #[derive(Debug, Clone, Copy)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] #[repr(transparent)] pub struct mask32x4(pub(crate) __m128i); @@ -379,7 +379,7 @@ impl From for BitMask<4, V3> { // mask32x8 #[derive(Debug, Clone, Copy)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] #[repr(transparent)] pub struct mask32x8(pub(crate) __m256i); @@ -482,7 +482,7 @@ impl From for BitMask<8, V3> { // mask64x2 #[derive(Debug, Clone, Copy)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] #[repr(transparent)] pub struct mask64x2(pub(crate) __m128i); @@ -573,7 +573,7 @@ impl From for BitMask<2, V3> { // mask64x4 #[derive(Debug, Clone, Copy)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] #[repr(transparent)] pub struct mask64x4(pub(crate) __m256i); diff --git a/diskann-wide/src/arch/x86_64/v3/u32x16_.rs b/diskann-wide/src/arch/x86_64/v3/u32x16_.rs index f39105d90c..b8aece713c 100644 --- a/diskann-wide/src/arch/x86_64/v3/u32x16_.rs +++ b/diskann-wide/src/arch/x86_64/v3/u32x16_.rs @@ -14,7 +14,7 @@ use crate::doubled; doubled::double_vector!(u32, 16, u32x8); doubled::double_scalar_shift!(Doubled); -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub type u32x16 = doubled::Doubled; /////////// diff --git a/diskann-wide/src/arch/x86_64/v3/u64x8_.rs b/diskann-wide/src/arch/x86_64/v3/u64x8_.rs index bc4ded7c2e..eff43104c1 100644 --- a/diskann-wide/src/arch/x86_64/v3/u64x8_.rs +++ b/diskann-wide/src/arch/x86_64/v3/u64x8_.rs @@ -13,7 +13,7 @@ use crate::doubled; doubled::double_vector!(u64, 8, u64x4); doubled::double_scalar_shift!(Doubled); -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub type u64x8 = doubled::Doubled; /////////// diff --git a/diskann-wide/src/arch/x86_64/v3/u8x64_.rs b/diskann-wide/src/arch/x86_64/v3/u8x64_.rs index 7df0f05292..cfd49eb47c 100644 --- a/diskann-wide/src/arch/x86_64/v3/u8x64_.rs +++ b/diskann-wide/src/arch/x86_64/v3/u8x64_.rs @@ -14,7 +14,7 @@ use crate::doubled; doubled::double_vector!(u8, 64, u8x32); doubled::double_scalar_shift!(Doubled); -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] pub type u8x64 = doubled::Doubled; /////////// diff --git a/diskann-wide/src/arch/x86_64/v4/mod.rs b/diskann-wide/src/arch/x86_64/v4/mod.rs index ac0a1edebd..ebbd0d4c28 100644 --- a/diskann-wide/src/arch/x86_64/v4/mod.rs +++ b/diskann-wide/src/arch/x86_64/v4/mod.rs @@ -75,7 +75,7 @@ use crate::{ macro_rules! maybe_miri { ($mod:ident, $type:ident, $T:ty, $N:literal) => { #[cfg(miri)] - #[allow(non_camel_case_types)] + #[expect(non_camel_case_types)] pub type $type = crate::Emulated<$T, $N, V4>; #[cfg(not(miri))] diff --git a/diskann-wide/src/lib.rs b/diskann-wide/src/lib.rs index 442babe9f6..4cb1b08216 100644 --- a/diskann-wide/src/lib.rs +++ b/diskann-wide/src/lib.rs @@ -207,14 +207,26 @@ macro_rules! alias { $crate::alias!($var = ::$type); }; ($var:ident = <$arch:ty>::$type:ident) => { + #[expect( + clippy::allow_attributes, + reason = "Keep allow: CamelCase aliases do not trigger the naming lint" + )] #[allow(non_camel_case_types)] type $var = <$arch as $crate::Architecture>::$type; }; ($var:ident<$arch:ident> = $type:ident) => { + #[expect( + clippy::allow_attributes, + reason = "Keep allow: CamelCase aliases do not trigger the naming lint" + )] #[allow(non_camel_case_types)] type $var<$arch> = <$arch as $crate::Architecture>::$type; }; ($var:ident = type $type:path) => { + #[expect( + clippy::allow_attributes, + reason = "Keep allow: CamelCase aliases do not trigger the naming lint" + )] #[allow(non_camel_case_types)] type $var = $type; }; diff --git a/diskann/Cargo.toml b/diskann/Cargo.toml index 14f6ba0746..b7793ed65a 100644 --- a/diskann/Cargo.toml +++ b/diskann/Cargo.toml @@ -46,6 +46,7 @@ dashmap = { workspace = true } unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage)'] } [lints.clippy] +allow_attributes = "warn" # Commenting out for now. It would give warnings. # undocumented_unsafe_blocks = "warn" uninlined_format_args = "allow" diff --git a/diskann/src/graph/adjacencylist.rs b/diskann/src/graph/adjacencylist.rs index 2923621870..063ace9b2d 100644 --- a/diskann/src/graph/adjacencylist.rs +++ b/diskann/src/graph/adjacencylist.rs @@ -242,11 +242,7 @@ where // runtime is `O(len^2)`. However, this is only meant to run in debug mode and // allows us to bypass requiring `Eq + Hash` (for hash tables) or `Ord` for sorting // and de-duplicating. - #[cfg(debug_assertions)] - #[allow(clippy::panic)] - if !self.all_unique() { - panic!("duplicate items detected: {:?}", self); - } + debug_assert!(self.all_unique(), "duplicate items detected: {:?}", self); } } diff --git a/diskann/src/graph/index.rs b/diskann/src/graph/index.rs index 4cea08dcc7..bd285759e5 100644 --- a/diskann/src/graph/index.rs +++ b/diskann/src/graph/index.rs @@ -2253,7 +2253,6 @@ where /// /// We're going through a temporary phase of moving the `Context` into the `Strategy`. /// For now - we unfortunately need both. - #[allow(clippy::too_many_arguments)] pub(crate) fn add_edge_and_prune<'a, A>( &'a self, accessor: &'a mut A, diff --git a/diskann/src/graph/search/range_search.rs b/diskann/src/graph/search/range_search.rs index 8c143e068a..169635e9a2 100644 --- a/diskann/src/graph/search/range_search.rs +++ b/diskann/src/graph/search/range_search.rs @@ -87,7 +87,6 @@ impl Range { } } - #[allow(clippy::too_many_arguments)] fn validate_and_create( max_returned: Option, starting_l: usize, diff --git a/diskann/src/graph/test/cases/inline.rs b/diskann/src/graph/test/cases/inline.rs index 33e0d566cb..1c134bbbb0 100644 --- a/diskann/src/graph/test/cases/inline.rs +++ b/diskann/src/graph/test/cases/inline.rs @@ -336,7 +336,7 @@ verbose_eq!(InlineFilterBaseline { hops, }); -#[allow(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments)] fn run_inline_on_grid( index: &graph::DiskANNIndex, filter: &dyn labeled::QueryLabelProvider, diff --git a/diskann/src/provider.rs b/diskann/src/provider.rs index e2a4699d68..bb2e9741ae 100644 --- a/diskann/src/provider.rs +++ b/diskann/src/provider.rs @@ -618,7 +618,7 @@ mod tests { /// This needs to be manually `async` so we can aply the `'static` bound. Since it's /// recursive, Rust struggles to properly deduce the hidden type for the opaque return /// type. - #[allow(clippy::manual_async_fn)] + #[expect(clippy::manual_async_fn)] fn test_spawning( context: Context, width: usize, diff --git a/diskann/src/utils/mod.rs b/diskann/src/utils/mod.rs index 86b78f0aba..11d4288451 100644 --- a/diskann/src/utils/mod.rs +++ b/diskann/src/utils/mod.rs @@ -5,7 +5,7 @@ pub mod async_tools; -#[allow(clippy::module_inception)] +#[expect(clippy::module_inception)] pub mod utils; pub use utils::*; diff --git a/diskann/src/utils/utils.rs b/diskann/src/utils/utils.rs index 373125663a..78d3fb33fc 100644 --- a/diskann/src/utils/utils.rs +++ b/diskann/src/utils/utils.rs @@ -72,8 +72,7 @@ macro_rules! impl_to_usize { unsafe impl IntoUsize for $type { fn into_usize(self) -> usize { // This breaks at compile time if somehow the `cfg` guard above fails. - #[allow(unused)] - const STATIC_ASSERT: () = { + const _: () = { if usize::BITS != 64 { panic!("diskann is not compatible with non-64-bit systems"); }