From 26830dd9c68c54969b904a6154ffd7032dffd519 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 4 Aug 2026 23:01:06 +0200 Subject: [PATCH 01/13] Enable `clippy::precedence_bits` lint Parenthesizes shifts mixed with `|`. Applied with `cargo clippy --fix`; `<<` already binds tighter than `|`, so this only makes the existing grouping explicit. --- Cargo.toml | 1 + arrow-buffer/src/util/bit_util.rs | 2 +- parquet-variant/src/builder.rs | 4 ++-- parquet-variant/src/builder/metadata.rs | 2 +- parquet-variant/src/decoder.rs | 4 ++-- parquet/benches/metadata.rs | 6 +++--- parquet/src/basic.rs | 2 +- parquet/src/column/writer/mod.rs | 2 +- parquet/src/parquet_thrift.rs | 4 ++-- 9 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 39ec344fcd5f..01ad5500032f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -212,6 +212,7 @@ option_as_ref_cloned = "warn" option_option = "warn" path_buf_push_overwrite = "warn" pathbuf_init_then_push = "warn" +precedence_bits = "warn" ptr_cast_constness = "warn" ptr_offset_by_literal = "warn" pub_without_shorthand = "warn" diff --git a/arrow-buffer/src/util/bit_util.rs b/arrow-buffer/src/util/bit_util.rs index fbe064233d37..6fe4acb83968 100644 --- a/arrow-buffer/src/util/bit_util.rs +++ b/arrow-buffer/src/util/bit_util.rs @@ -809,7 +809,7 @@ fn get_remainder_bits(remainder: &[u8], remainder_len: usize) -> u64 { .iter() .enumerate() .fold(0_u64, |acc, (index, &byte)| { - acc | (byte as u64) << (index * 8) + acc | ((byte as u64) << (index * 8)) }); bits & ((1 << remainder_len) - 1) diff --git a/parquet-variant/src/builder.rs b/parquet-variant/src/builder.rs index b176b4e6150a..2624cafcdb3f 100644 --- a/parquet-variant/src/builder.rs +++ b/parquet-variant/src/builder.rs @@ -36,11 +36,11 @@ pub(crate) const UNIX_EPOCH_DATE: chrono::NaiveDate = chrono::NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(); fn primitive_header(primitive_type: VariantPrimitiveType) -> u8 { - (primitive_type as u8) << 2 | VariantBasicType::Primitive as u8 + ((primitive_type as u8) << 2) | VariantBasicType::Primitive as u8 } fn short_string_header(len: usize) -> u8 { - (len as u8) << 2 | VariantBasicType::ShortString as u8 + ((len as u8) << 2) | VariantBasicType::ShortString as u8 } pub(crate) fn int_size(v: usize) -> OffsetSizeBytes { diff --git a/parquet-variant/src/builder/metadata.rs b/parquet-variant/src/builder/metadata.rs index ea1a6d46947c..003407847aad 100644 --- a/parquet-variant/src/builder/metadata.rs +++ b/parquet-variant/src/builder/metadata.rs @@ -215,7 +215,7 @@ impl WritableMetadataBuilder { metadata_buffer.reserve(metadata_size); // Write header: version=1, field names are sorted, with calculated offset_size - metadata_buffer.push(0x01 | (is_sorted as u8) << 4 | ((offset_size - 1) << 6)); + metadata_buffer.push(0x01 | ((is_sorted as u8) << 4) | ((offset_size - 1) << 6)); // Write dictionary size write_offset(metadata_buffer, nkeys, offset_size); diff --git a/parquet-variant/src/decoder.rs b/parquet-variant/src/decoder.rs index ea03f2e2a4d9..ce7c09a36cc0 100644 --- a/parquet-variant/src/decoder.rs +++ b/parquet-variant/src/decoder.rs @@ -589,14 +589,14 @@ mod tests { #[test] fn test_short_string_exact_length() { let data = b"Helloo"; - let result = decode_short_string(1 | 5 << 2, data).unwrap(); + let result = decode_short_string(1 | (5 << 2), data).unwrap(); assert_eq!(result.0, "Hello"); } #[test] fn test_short_string_truncated_length() { let data = b"Hel"; - let result = decode_short_string(1 | 5 << 2, data); + let result = decode_short_string(1 | (5 << 2), data); assert!(matches!(result, Err(ArrowError::InvalidArgumentError(_)))); } diff --git a/parquet/benches/metadata.rs b/parquet/benches/metadata.rs index 8bbc017f7110..39a5855f0ecc 100644 --- a/parquet/benches/metadata.rs +++ b/parquet/benches/metadata.rs @@ -158,9 +158,9 @@ fn encoded_meta(is_nullable: bool, has_lists: bool, write_path_in_schema: bool) fn get_footer_bytes(data: Bytes) -> Bytes { let footer_bytes = data.slice(data.len() - 8..); let footer_len = footer_bytes[0] as u32 - | (footer_bytes[1] as u32) << 8 - | (footer_bytes[2] as u32) << 16 - | (footer_bytes[3] as u32) << 24; + | ((footer_bytes[1] as u32) << 8) + | ((footer_bytes[2] as u32) << 16) + | ((footer_bytes[3] as u32) << 24); let meta_start = data.len() - footer_len as usize - 8; let meta_end = data.len() - 8; data.slice(meta_start..meta_end) diff --git a/parquet/src/basic.rs b/parquet/src/basic.rs index 1cb0552660b8..5cff938f54e5 100644 --- a/parquet/src/basic.rs +++ b/parquet/src/basic.rs @@ -516,7 +516,7 @@ impl EncodingMask { /// A mask consisting of unused bit positions, used for validation. This includes the never /// used GROUP_VAR_INT encoding value of `1`. const ALLOWED_MASK: u32 = - !(1u32 << (EncodingMask::MAX_ENCODING as u32 + 1)).wrapping_sub(1) | 1 << 1; + !(1u32 << (EncodingMask::MAX_ENCODING as u32 + 1)).wrapping_sub(1) | (1 << 1); /// Attempt to create a new `EncodingMask` from an integer. /// diff --git a/parquet/src/column/writer/mod.rs b/parquet/src/column/writer/mod.rs index eb27af2cfb29..314440f15f3c 100644 --- a/parquet/src/column/writer/mod.rs +++ b/parquet/src/column/writer/mod.rs @@ -1730,7 +1730,7 @@ fn is_nan(basic_type_info: &BasicTypeInfo, val: &T) -> bool // taken from f16 impl, but skips creating f16. just compare the bits as u16. let val = val.as_bytes(); // Float16 is stored little endian - let uval = (val[1] as u16) << 8 | val[0] as u16; + let uval = ((val[1] as u16) << 8) | val[0] as u16; uval & 0x7FFFu16 > 0x7C00u16 } _ => false, diff --git a/parquet/src/parquet_thrift.rs b/parquet/src/parquet_thrift.rs index 84d6825f5045..65c7eae5e07c 100644 --- a/parquet/src/parquet_thrift.rs +++ b/parquet/src/parquet_thrift.rs @@ -829,7 +829,7 @@ impl ThriftCompactOutputProtocol { ) -> Result<()> { let delta = field_id.wrapping_sub(last_field_id); if delta > 0 && delta <= 0xf { - self.write_byte((delta as u8) << 4 | field_type as u8) + self.write_byte(((delta as u8) << 4) | field_type as u8) } else { self.write_byte(field_type as u8)?; self.write_i16(field_id) @@ -839,7 +839,7 @@ impl ThriftCompactOutputProtocol { /// Used to indicate the start of a list of `element_type` elements. pub(crate) fn write_list_begin(&mut self, element_type: ElementType, len: usize) -> Result<()> { if len < 15 { - self.write_byte((len as u8) << 4 | element_type as u8) + self.write_byte(((len as u8) << 4) | element_type as u8) } else { self.write_byte(0xf0u8 | element_type as u8)?; self.write_vlq(len as _) From b97111cc2e13f1526762320817f30d57e2f7dd43 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 4 Aug 2026 23:03:31 +0200 Subject: [PATCH 02/13] Enable `clippy::doc_link_with_quotes` lint Ten intra-doc links were written with `'` instead of backticks, so they rendered as text instead of linking. The eight `['Err'](Result::Err)` cases become just [`Err`], since the explicit target is redundant once the link resolves. The remaining `["null", "string"]` is a JSON example rather than a link, so it is now inline code. --- Cargo.toml | 1 + arrow-avro/src/schema.rs | 2 +- arrow-flight/src/encode.rs | 2 +- arrow-ipc/src/reader.rs | 4 ++-- arrow-ipc/src/writer.rs | 12 ++++++------ arrow-json/src/lib.rs | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 01ad5500032f..b2e0f438e464 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -166,6 +166,7 @@ default_union_representation = "warn" disallowed_script_idents = "warn" doc_comment_double_space_linebreaks = "warn" doc_include_without_cfg = "warn" +doc_link_with_quotes = "warn" empty_enum_variants_with_brackets = "warn" exit = "warn" expl_impl_clone_on_copy = "warn" diff --git a/arrow-avro/src/schema.rs b/arrow-avro/src/schema.rs index a22373ac6cc4..b95158e1aa28 100644 --- a/arrow-avro/src/schema.rs +++ b/arrow-avro/src/schema.rs @@ -177,7 +177,7 @@ pub(crate) enum Schema<'a> { /// A direct type name (primitive or reference) #[serde(borrow)] TypeName(TypeName<'a>), - /// A union of multiple schemas (e.g., ["null", "string"]) + /// A union of multiple schemas (e.g., `["null", "string"]`) #[serde(borrow)] Union(Vec>), /// A complex type such as record, array, map, etc. diff --git a/arrow-flight/src/encode.rs b/arrow-flight/src/encode.rs index 95fde96e377b..437d910debd4 100644 --- a/arrow-flight/src/encode.rs +++ b/arrow-flight/src/encode.rs @@ -442,7 +442,7 @@ impl Stream for FlightDataEncoder { /// [`DictionaryArray`]: arrow_array::DictionaryArray /// /// In the arrow flight protocol dictionary values and keys are sent as two separate messages. -/// When a sender is encoding a [`RecordBatch`] containing ['DictionaryArray'] columns, it will +/// When a sender is encoding a [`RecordBatch`] containing [`DictionaryArray`] columns, it will /// first send a dictionary batch (a batch with header `MessageHeader::DictionaryBatch`) containing /// the dictionary values. The receiver is responsible for reading this batch and maintaining state that associates /// those dictionary values with the corresponding array using the `dict_id` as a key. diff --git a/arrow-ipc/src/reader.rs b/arrow-ipc/src/reader.rs index 6e2a35690dd4..aa12e9589c8c 100644 --- a/arrow-ipc/src/reader.rs +++ b/arrow-ipc/src/reader.rs @@ -1386,7 +1386,7 @@ impl FileReader { /// /// # Errors /// - /// An ['Err'](Result::Err) may be returned if: + /// An [`Err`] may be returned if: /// - the file does not meet the Arrow Format footer requirements, or /// - file endianness does not match the target endianness. pub fn try_new(reader: R, projection: Option>) -> Result { @@ -1570,7 +1570,7 @@ impl StreamReader { /// /// # Errors /// - /// An ['Err'](Result::Err) may be returned if the reader does not encounter a schema + /// An [`Err`] may be returned if the reader does not encounter a schema /// as the first message in the stream. pub fn try_new( reader: R, diff --git a/arrow-ipc/src/writer.rs b/arrow-ipc/src/writer.rs index ae2c261324d3..c7b8675df579 100644 --- a/arrow-ipc/src/writer.rs +++ b/arrow-ipc/src/writer.rs @@ -1631,7 +1631,7 @@ impl FileWriter { /// /// # Errors /// - /// An ['Err'](Result::Err) may be returned if writing the header to the writer fails. + /// An [`Err`] may be returned if writing the header to the writer fails. pub fn try_new(writer: W, schema: &Schema) -> Result { let write_options = IpcWriteOptions::default(); Self::try_new_with_options(writer, schema, write_options) @@ -1643,7 +1643,7 @@ impl FileWriter { /// /// # Errors /// - /// An ['Err'](Result::Err) may be returned if writing the header to the writer fails. + /// An [`Err`] may be returned if writing the header to the writer fails. pub fn try_new_with_options( mut writer: W, schema: &Schema, @@ -1801,7 +1801,7 @@ impl FileWriter { /// /// # Errors /// - /// An ['Err'](Result::Err) may be returned if an error occurs while finishing the StreamWriter + /// An [`Err`] may be returned if an error occurs while finishing the StreamWriter /// or while flushing the writer. pub fn into_inner(mut self) -> Result { if !self.finished { @@ -2043,7 +2043,7 @@ impl StreamWriter { /// /// # Errors /// - /// An ['Err'](Result::Err) may be returned if writing the header to the writer fails. + /// An [`Err`] may be returned if writing the header to the writer fails. pub fn try_new(writer: W, schema: &Schema) -> Result { let write_options = IpcWriteOptions::default(); Self::try_new_with_options(writer, schema, write_options) @@ -2053,7 +2053,7 @@ impl StreamWriter { /// /// # Errors /// - /// An ['Err'](Result::Err) may be returned if writing the header to the writer fails. + /// An [`Err`] may be returned if writing the header to the writer fails. pub fn try_new_with_options( mut writer: W, schema: &Schema, @@ -2143,7 +2143,7 @@ impl StreamWriter { /// /// # Errors /// - /// An ['Err'](Result::Err) may be returned if an error occurs while finishing the StreamWriter + /// An [`Err`] may be returned if an error occurs while finishing the StreamWriter /// or while flushing the writer. /// /// # Example diff --git a/arrow-json/src/lib.rs b/arrow-json/src/lib.rs index 9f2a9e3a81ca..bc7cc668013b 100644 --- a/arrow-json/src/lib.rs +++ b/arrow-json/src/lib.rs @@ -101,7 +101,7 @@ use serde_json::{Number, Value}; /// Writer will produce. For example, if the RecordBatch Schema is /// `[("a", Int32), ("r", Struct("b": Boolean, "c" Utf8))]` /// then a Reader with [`StructMode::ObjectOnly`] would read rows of the form -/// `{"a": 1, "r": {"b": true, "c": "cat"}}` while with ['StructMode::ListOnly'] +/// `{"a": 1, "r": {"b": true, "c": "cat"}}` while with [`StructMode::ListOnly`] /// would read rows of the form `[1, [true, "cat"]]`. A Writer would produce /// rows formatted similarly. /// From 0af1e97ab03ec152c265bc536ece15ed3b4a11f0 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 4 Aug 2026 23:06:47 +0200 Subject: [PATCH 03/13] Enable `clippy::manual_string_new` lint Replaces `"".to_string()` and friends with `String::new()`, applied with `cargo clippy --fix`. One site then tripped `unwrap_or_else(String::new)`, which became `unwrap_or_default()`. --- Cargo.toml | 1 + arrow-array/src/ffi_stream.rs | 2 +- arrow-schema/src/extension/canonical/json.rs | 4 ++-- arrow-schema/src/ffi.rs | 4 ++-- arrow-schema/src/field.rs | 2 +- arrow-select/src/coalesce.rs | 2 +- parquet-variant-json/src/to_json.rs | 4 ++-- parquet/src/arrow/arrow_reader/mod.rs | 4 ++-- parquet/src/arrow/arrow_writer/levels.rs | 4 ++-- parquet/src/arrow/schema/mod.rs | 4 ++-- parquet/src/schema/printer.rs | 2 +- 11 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b2e0f438e464..4dee10a0bf6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -202,6 +202,7 @@ macro_use_imports = "warn" manual_instant_elapsed = "warn" manual_is_power_of_two = "warn" manual_midpoint = "warn" +manual_string_new = "warn" match_wild_err_arm = "warn" mismatching_type_param_order = "warn" mut_mut = "warn" diff --git a/arrow-array/src/ffi_stream.rs b/arrow-array/src/ffi_stream.rs index 011f3a8b0f74..f307416bbf52 100644 --- a/arrow-array/src/ffi_stream.rs +++ b/arrow-array/src/ffi_stream.rs @@ -544,7 +544,7 @@ mod tests { fn test_error_import() -> Result<()> { let schema = Arc::new(Schema::new(vec![Field::new("a", DataType::Int32, true)])); - let iter = Box::new(vec![Err(ArrowError::MemoryError("".to_string()))].into_iter()); + let iter = Box::new(vec![Err(ArrowError::MemoryError(String::new()))].into_iter()); let reader = Box::new(TestRecordBatchReader::new(schema.clone(), iter)); diff --git a/arrow-schema/src/extension/canonical/json.rs b/arrow-schema/src/extension/canonical/json.rs index 1188a6dda439..59f226bd80a4 100644 --- a/arrow-schema/src/extension/canonical/json.rs +++ b/arrow-schema/src/extension/canonical/json.rs @@ -137,7 +137,7 @@ impl ExtensionType for Json { .as_ref() .map(serde_json::to_string) .map(Result::unwrap) - .unwrap_or_else(|| "".to_owned()), + .unwrap_or_default(), ) } @@ -196,7 +196,7 @@ mod tests { field.try_with_extension_type(Json::default())?; assert_eq!( field.metadata().get(EXTENSION_TYPE_METADATA_KEY), - Some(&"".to_owned()) + Some(&String::new()) ); assert_eq!( field.try_extension_type::()?, diff --git a/arrow-schema/src/ffi.rs b/arrow-schema/src/ffi.rs index 7b6332632e17..11149e1042f1 100644 --- a/arrow-schema/src/ffi.rs +++ b/arrow-schema/src/ffi.rs @@ -1001,9 +1001,9 @@ mod tests { [].into(), [("key".to_string(), "value".to_string())].into(), [ - ("key".to_string(), "".to_string()), + ("key".to_string(), String::new()), ("ascii123".to_string(), "你好".to_string()), - ("".to_string(), "value".to_string()), + (String::new(), "value".to_string()), ] .into(), ]; diff --git a/arrow-schema/src/field.rs b/arrow-schema/src/field.rs index a0f6fb9a3e2f..bf7358a101b5 100644 --- a/arrow-schema/src/field.rs +++ b/arrow-schema/src/field.rs @@ -1497,7 +1497,7 @@ mod test { #[test] fn test_field_with_nonempty_metadata_serde() { let mut metadata = HashMap::new(); - metadata.insert("hi".to_owned(), "".to_owned()); + metadata.insert("hi".to_owned(), String::new()); let field = Field::new("name", DataType::Boolean, false).with_metadata(metadata); assert_binary_serde_round_trip(field) diff --git a/arrow-select/src/coalesce.rs b/arrow-select/src/coalesce.rs index d1d73abdd8f6..58e4598d5010 100644 --- a/arrow-select/src/coalesce.rs +++ b/arrow-select/src/coalesce.rs @@ -1693,7 +1693,7 @@ mod tests { impl Default for Test { fn default() -> Self { Self { - name: "".to_string(), + name: String::new(), input_batches: vec![], filters: vec![], schema: None, diff --git a/parquet-variant-json/src/to_json.rs b/parquet-variant-json/src/to_json.rs index 9e538877fb61..799a752285c9 100644 --- a/parquet-variant-json/src/to_json.rs +++ b/parquet-variant-json/src/to_json.rs @@ -887,7 +887,7 @@ mod tests { JsonTest { variant: Variant::from(""), expected_json: "\"\"", - expected_value: Value::String("".to_string()), + expected_value: Value::String(String::new()), } .run(); @@ -917,7 +917,7 @@ mod tests { JsonTest { variant: Variant::Binary(b""), expected_json: "\"\"", // empty base64 - expected_value: Value::String("".to_string()), + expected_value: Value::String(String::new()), } .run(); diff --git a/parquet/src/arrow/arrow_reader/mod.rs b/parquet/src/arrow/arrow_reader/mod.rs index 29ba9a4ab36d..c61b3c8f7af1 100644 --- a/parquet/src/arrow/arrow_reader/mod.rs +++ b/parquet/src/arrow/arrow_reader/mod.rs @@ -2154,7 +2154,7 @@ pub(crate) mod tests { ) .with_metadata(HashMap::from_iter(vec![( "adjusted_to_utc".to_string(), - "".to_string(), + String::new(), )])), Field::new( "time_micros", @@ -2163,7 +2163,7 @@ pub(crate) mod tests { ) .with_metadata(HashMap::from_iter(vec![( "adjusted_to_utc".to_string(), - "".to_string(), + String::new(), )])), ])); diff --git a/parquet/src/arrow/arrow_writer/levels.rs b/parquet/src/arrow/arrow_writer/levels.rs index ead1ba0d9af2..aad7c1a4051f 100644 --- a/parquet/src/arrow/arrow_writer/levels.rs +++ b/parquet/src/arrow/arrow_writer/levels.rs @@ -2162,8 +2162,8 @@ mod tests { let list_field = Field::new("col", list_type, true); let expected = vec![ - r#""#.to_string(), - r#""#.to_string(), + String::new(), + String::new(), r#"[]"#.to_string(), r#"[{list: [3, ], integers: }]"#.to_string(), r#"[, {list: , integers: 5}]"#.to_string(), diff --git a/parquet/src/arrow/schema/mod.rs b/parquet/src/arrow/schema/mod.rs index 500745c6e714..110c799b4276 100644 --- a/parquet/src/arrow/schema/mod.rs +++ b/parquet/src/arrow/schema/mod.rs @@ -1880,7 +1880,7 @@ mod tests { ) .with_metadata(HashMap::from_iter(vec![( "adjusted_to_utc".to_string(), - "".to_string(), + String::new(), )])), Field::new("time_micro", DataType::Time64(TimeUnit::Microsecond), true), Field::new( @@ -1890,7 +1890,7 @@ mod tests { ) .with_metadata(HashMap::from_iter(vec![( "adjusted_to_utc".to_string(), - "".to_string(), + String::new(), )])), Field::new( "ts_milli", diff --git a/parquet/src/schema/printer.rs b/parquet/src/schema/printer.rs index e43e09b30fcd..67d8861aaf46 100644 --- a/parquet/src/schema/printer.rs +++ b/parquet/src/schema/printer.rs @@ -83,7 +83,7 @@ pub fn print_file_metadata(out: &mut dyn io::Write, file_metadata: &FileMetaData out, " {}: {}", kv.key, - kv.value.as_ref().unwrap_or(&"".to_owned()) + kv.value.as_ref().unwrap_or(&String::new()) ); } } From ee0c1bec035b53d555ed11b4dc276eeb3e262ac1 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 4 Aug 2026 23:09:41 +0200 Subject: [PATCH 04/13] Enable `clippy::explicit_into_iter_loop` lint Drops explicit `.into_iter()` from `for` loops, applied with `cargo clippy --fix`. One site then tripped `useless_vec`, so its `vec!` became an array. --- Cargo.toml | 1 + arrow-arith/src/aggregate.rs | 2 +- arrow-avro/src/reader/async_reader/async_file_reader.rs | 2 +- arrow-avro/src/reader/record.rs | 2 +- arrow-buffer/src/bigint/mod.rs | 2 +- arrow-cast/src/cast/mod.rs | 4 ++-- arrow-integration-test/src/lib.rs | 2 +- arrow-ipc/src/reader.rs | 2 +- arrow-schema/src/ffi.rs | 2 +- arrow-schema/src/schema.rs | 2 +- arrow-select/src/take.rs | 2 +- parquet-variant/src/builder/list.rs | 2 +- parquet-variant/src/builder/object.rs | 2 +- parquet/src/arrow/arrow_reader/statistics.rs | 2 +- parquet/src/arrow/async_reader/mod.rs | 2 +- parquet/tests/encryption/encryption_async.rs | 6 +++--- 16 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4dee10a0bf6c..d51d26c7f4f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -171,6 +171,7 @@ empty_enum_variants_with_brackets = "warn" exit = "warn" expl_impl_clone_on_copy = "warn" explicit_deref_methods = "warn" +explicit_into_iter_loop = "warn" filter_map_next = "warn" flat_map_option = "warn" float_cmp_const = "warn" diff --git a/arrow-arith/src/aggregate.rs b/arrow-arith/src/aggregate.rs index 2e5713dd7d06..3f0bf193d5a8 100644 --- a/arrow-arith/src/aggregate.rs +++ b/arrow-arith/src/aggregate.rs @@ -2005,7 +2005,7 @@ mod tests { ItemType: Clone + Into> + 'static, { let mut builder = arrow_array::builder::PrimitiveRunBuilder::::new(); - for v in values.into_iter() { + for v in values { builder.append_option((*v).clone().into()); } builder.finish() diff --git a/arrow-avro/src/reader/async_reader/async_file_reader.rs b/arrow-avro/src/reader/async_reader/async_file_reader.rs index e7f567bcd8cd..0e6af9fba352 100644 --- a/arrow-avro/src/reader/async_reader/async_file_reader.rs +++ b/arrow-avro/src/reader/async_reader/async_file_reader.rs @@ -96,7 +96,7 @@ pub trait AsyncFileReader: Send { async move { let mut result = Vec::with_capacity(ranges.len()); - for range in ranges.into_iter() { + for range in ranges { let data = self.get_bytes(range).await?; result.push(data); } diff --git a/arrow-avro/src/reader/record.rs b/arrow-avro/src/reader/record.rs index beb4102de19c..b4619f196aaa 100644 --- a/arrow-avro/src/reader/record.rs +++ b/arrow-avro/src/reader/record.rs @@ -4430,7 +4430,7 @@ mod tests { ) -> AvroDataType { let mut avro_children: Vec = Vec::with_capacity(children.len()); let mut fields: Vec = Vec::with_capacity(children.len()); - for (codec, name, dt) in children.into_iter() { + for (codec, name, dt) in children { avro_children.push(AvroDataType::new(codec, Default::default(), None)); fields.push(arrow_schema::Field::new(name, dt, true)); } diff --git a/arrow-buffer/src/bigint/mod.rs b/arrow-buffer/src/bigint/mod.rs index d8328cb06f9e..e9db73ece37d 100644 --- a/arrow-buffer/src/bigint/mod.rs +++ b/arrow-buffer/src/bigint/mod.rs @@ -1478,7 +1478,7 @@ mod tests { } // Exponentiation - for exp in vec![0, 1, 2, 3, 8, 100].into_iter() { + for exp in [0, 1, 2, 3, 8, 100] { let actual = il.wrapping_pow(exp); let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone().pow(exp)); assert_eq!(actual.to_string(), expected.to_string()); diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs index d88fd2847be5..85c32b948e26 100644 --- a/arrow-cast/src/cast/mod.rs +++ b/arrow-cast/src/cast/mod.rs @@ -7606,7 +7606,7 @@ mod tests { let string_view_array = { let mut builder = StringViewBuilder::new().with_fixed_block_size(8); // multiple buffers. - for v in typed_dict.into_iter() { + for v in typed_dict { builder.append_option(v); } builder.finish() @@ -7623,7 +7623,7 @@ mod tests { let binary_view_array = { let mut builder = BinaryViewBuilder::new().with_fixed_block_size(8); // multiple buffers. - for v in typed_binary_dict.into_iter() { + for v in typed_binary_dict { builder.append_option(v); } builder.finish() diff --git a/arrow-integration-test/src/lib.rs b/arrow-integration-test/src/lib.rs index 0d5477e955e3..a752aed7d819 100644 --- a/arrow-integration-test/src/lib.rs +++ b/arrow-integration-test/src/lib.rs @@ -223,7 +223,7 @@ impl ArrowJson { return Ok(false); } - for json_batch in self.get_record_batches()?.into_iter() { + for json_batch in self.get_record_batches()? { let batch = reader.next(); match batch { Some(Ok(batch)) => { diff --git a/arrow-ipc/src/reader.rs b/arrow-ipc/src/reader.rs index aa12e9589c8c..46b6ac61c2c4 100644 --- a/arrow-ipc/src/reader.rs +++ b/arrow-ipc/src/reader.rs @@ -1260,7 +1260,7 @@ impl FileReaderBuilder { let mut custom_metadata = HashMap::new(); if let Some(fb_custom_metadata) = footer.custom_metadata() { - for kv in fb_custom_metadata.into_iter() { + for kv in fb_custom_metadata { custom_metadata.insert( kv.key().unwrap().to_string(), kv.value().unwrap().to_string(), diff --git a/arrow-schema/src/ffi.rs b/arrow-schema/src/ffi.rs index 11149e1042f1..3f6fcd0f2c9b 100644 --- a/arrow-schema/src/ffi.rs +++ b/arrow-schema/src/ffi.rs @@ -207,7 +207,7 @@ impl FFI_ArrowSchema { })?; metadata_serialized.extend(num_entries.to_ne_bytes()); - for (key, value) in metadata.into_iter() { + for (key, value) in metadata { let key_len: i32 = key.as_ref().len().try_into().map_err(|_| { ArrowError::CDataInterface(format!( "metadata key can only have {} bytes, but {} were provided", diff --git a/arrow-schema/src/schema.rs b/arrow-schema/src/schema.rs index 809b2a33a54c..3964591eb22d 100644 --- a/arrow-schema/src/schema.rs +++ b/arrow-schema/src/schema.rs @@ -293,7 +293,7 @@ impl Schema { let Schema { metadata, fields } = schema; // merge metadata - for (key, value) in metadata.into_iter() { + for (key, value) in metadata { if let Some(old_val) = out_meta.get(&key) && old_val != &value { diff --git a/arrow-select/src/take.rs b/arrow-select/src/take.rs index fccf354b9487..f8ff461d2cee 100644 --- a/arrow-select/src/take.rs +++ b/arrow-select/src/take.rs @@ -599,7 +599,7 @@ fn take_bytes( let mut offset = 0; - for (start, end) in source_ranges.into_iter() { + for (start, end) in source_ranges { let value_len = end - start; // SAFETY: caller guarantees each (start, end) is in-bounds of `src`. // `dst` asserted above to include the required capacity. diff --git a/parquet-variant/src/builder/list.rs b/parquet-variant/src/builder/list.rs index 4cbce2a09391..3084ffd4fe7d 100644 --- a/parquet-variant/src/builder/list.rs +++ b/parquet-variant/src/builder/list.rs @@ -222,7 +222,7 @@ where V: Into>, { fn extend>(&mut self, iter: T) { - for v in iter.into_iter() { + for v in iter { self.append_value(v); } } diff --git a/parquet-variant/src/builder/object.rs b/parquet-variant/src/builder/object.rs index 670e3f7d768c..41d5e40c9dc4 100644 --- a/parquet-variant/src/builder/object.rs +++ b/parquet-variant/src/builder/object.rs @@ -331,7 +331,7 @@ where V: Into>, { fn extend>(&mut self, iter: T) { - for (key, value) in iter.into_iter() { + for (key, value) in iter { self.insert(key.as_ref(), value); } } diff --git a/parquet/src/arrow/arrow_reader/statistics.rs b/parquet/src/arrow/arrow_reader/statistics.rs index 755d7831caff..7ff4a3a4e102 100644 --- a/parquet/src/arrow/arrow_reader/statistics.rs +++ b/parquet/src/arrow/arrow_reader/statistics.rs @@ -1541,7 +1541,7 @@ impl<'a> StatisticsConverter<'a> { }; let mut builder = UInt64Array::builder(10); - for metadata in metadatas.into_iter() { + for metadata in metadatas { let row_count = metadata.num_rows(); let row_count: u64 = row_count.try_into().map_err(|e| { arrow_err!(format!( diff --git a/parquet/src/arrow/async_reader/mod.rs b/parquet/src/arrow/async_reader/mod.rs index 1d276df2a611..57e857d7d1a3 100644 --- a/parquet/src/arrow/async_reader/mod.rs +++ b/parquet/src/arrow/async_reader/mod.rs @@ -168,7 +168,7 @@ pub trait AsyncFileReader: Send { async move { let mut result = Vec::with_capacity(ranges.len()); - for range in ranges.into_iter() { + for range in ranges { let data = self.get_bytes(range).await?; result.push(data); } diff --git a/parquet/tests/encryption/encryption_async.rs b/parquet/tests/encryption/encryption_async.rs index a2ec2ed29768..ea64f0bd90db 100644 --- a/parquet/tests/encryption/encryption_async.rs +++ b/parquet/tests/encryption/encryption_async.rs @@ -773,7 +773,7 @@ fn spawn_rg_join_and_finalize_task( tokio::task::spawn(async move { let num_cols = column_writer_tasks.len(); let mut finalized_rg = Vec::with_capacity(num_cols); - for task in column_writer_tasks.into_iter() { + for task in column_writer_tasks { let writer = task .await .map_err(|e| ParquetError::General(e.to_string()))??; @@ -865,7 +865,7 @@ fn spawn_column_parallel_row_group_writer( let mut col_writer_tasks = Vec::with_capacity(num_columns); let mut col_array_channels = Vec::with_capacity(num_columns); - for mut col_writer in col_writers.into_iter() { + for mut col_writer in col_writers { let (send_array, mut receive_array) = tokio::sync::mpsc::channel::(max_buffer_size); col_array_channels.push(send_array); @@ -1135,7 +1135,7 @@ async fn test_multi_threaded_encrypted_writing_deprecated() { // Wait for all column writers to finish writing let mut finalized_rg = Vec::with_capacity(num_columns); - for task in col_writer_tasks.into_iter() { + for task in col_writer_tasks { finalized_rg.push(task.await.unwrap().unwrap().close().unwrap()); } From c5801f732c35e3cf1e20fb0e3b4dc7bd49995b53 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 4 Aug 2026 23:12:53 +0200 Subject: [PATCH 05/13] Enable `clippy::manual_is_variant_and` lint Replaces `.map(f).unwrap_or_default()` with `.is_some_and(f)`, applied with `cargo clippy --fix`. The one negated case is spelled `is_none_or` instead, matching the style already used elsewhere. --- Cargo.toml | 1 + arrow-array/src/array/fixed_size_list_array.rs | 3 +-- arrow-array/src/array/mod.rs | 2 +- arrow-array/src/array/struct_array.rs | 2 +- arrow-array/src/iterator.rs | 5 +---- arrow-cast/src/cast/string.rs | 4 ++-- arrow-data/src/equal/variable_size.rs | 4 ++-- arrow-json/src/reader/struct_array.rs | 3 +-- arrow-json/src/writer/mod.rs | 6 +----- arrow-schema/src/field.rs | 2 +- arrow-schema/src/schema.rs | 2 +- arrow-string/src/binary_like.rs | 2 +- arrow-string/src/like.rs | 2 +- 13 files changed, 15 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d51d26c7f4f0..780325187e2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -202,6 +202,7 @@ lossy_float_literal = "warn" macro_use_imports = "warn" manual_instant_elapsed = "warn" manual_is_power_of_two = "warn" +manual_is_variant_and = "warn" manual_midpoint = "warn" manual_string_new = "warn" match_wild_err_arm = "warn" diff --git a/arrow-array/src/array/fixed_size_list_array.rs b/arrow-array/src/array/fixed_size_list_array.rs index a6255482be6d..9cecc309971d 100644 --- a/arrow-array/src/array/fixed_size_list_array.rs +++ b/arrow-array/src/array/fixed_size_list_array.rs @@ -290,8 +290,7 @@ impl FixedSizeListArray { let nulls_valid = field.is_nullable() || nulls .as_ref() - .map(|n| n.expand(size as _).contains(&a)) - .unwrap_or_default() + .is_some_and(|n| n.expand(size as _).contains(&a)) || (nulls.is_none() && a.null_count() == 0); if !nulls_valid { diff --git a/arrow-array/src/array/mod.rs b/arrow-array/src/array/mod.rs index cf1e0b85a026..8a5e476846ee 100644 --- a/arrow-array/src/array/mod.rs +++ b/arrow-array/src/array/mod.rs @@ -266,7 +266,7 @@ pub unsafe trait Array: std::fmt::Debug + Send + Sync { /// assert_eq!(array.is_null(0), false); /// ``` fn is_null(&self, index: usize) -> bool { - self.nulls().map(|n| n.is_null(index)).unwrap_or_default() + self.nulls().is_some_and(|n| n.is_null(index)) } /// Returns whether the element at `index` is *not* null, the diff --git a/arrow-array/src/array/struct_array.rs b/arrow-array/src/array/struct_array.rs index bf7dc934dcf0..126a3ff4b208 100644 --- a/arrow-array/src/array/struct_array.rs +++ b/arrow-array/src/array/struct_array.rs @@ -168,7 +168,7 @@ impl StructArray { if !f.is_nullable() && let Some(a) = a.logical_nulls() - && !nulls.as_ref().map(|n| n.contains(&a)).unwrap_or_default() + && nulls.as_ref().is_none_or(|n| !n.contains(&a)) && a.null_count() > 0 { return Err(ArrowError::InvalidArgumentError(format!( diff --git a/arrow-array/src/iterator.rs b/arrow-array/src/iterator.rs index 156e296cf151..d954c9ce2f0c 100644 --- a/arrow-array/src/iterator.rs +++ b/arrow-array/src/iterator.rs @@ -67,10 +67,7 @@ impl ArrayIter { #[inline] fn is_null(&self, idx: usize) -> bool { - self.logical_nulls - .as_ref() - .map(|x| x.is_null(idx)) - .unwrap_or_default() + self.logical_nulls.as_ref().is_some_and(|x| x.is_null(idx)) } } diff --git a/arrow-cast/src/cast/string.rs b/arrow-cast/src/cast/string.rs index 86712e15f931..3c1933519631 100644 --- a/arrow-cast/src/cast/string.rs +++ b/arrow-cast/src/cast/string.rs @@ -26,7 +26,7 @@ pub(crate) fn value_to_string( let formatter = ArrayFormatter::try_new(array, &options.format_options)?; let nulls = array.nulls(); for i in 0..array.len() { - match nulls.map(|x| x.is_null(i)).unwrap_or_default() { + match nulls.is_some_and(|x| x.is_null(i)) { true => builder.append_null(), false => { formatter.value(i).write(&mut builder)?; @@ -49,7 +49,7 @@ pub(crate) fn value_to_string_view( // TODO: replace with write to builder after https://github.com/apache/arrow-rs/issues/6373 let mut buffer = String::new(); for i in 0..array.len() { - match nulls.map(|x| x.is_null(i)).unwrap_or_default() { + match nulls.is_some_and(|x| x.is_null(i)) { true => builder.append_null(), false => { // write to buffer first and then copy into target array diff --git a/arrow-data/src/equal/variable_size.rs b/arrow-data/src/equal/variable_size.rs index 10aeafd7e9a3..d80faaf2ca1b 100644 --- a/arrow-data/src/equal/variable_size.rs +++ b/arrow-data/src/equal/variable_size.rs @@ -81,8 +81,8 @@ pub(super) fn variable_sized_equal( let rhs_pos = rhs_start + i; // the null bits can still be `None`, indicating that the value is valid. - let lhs_is_null = lhs.nulls().map(|v| v.is_null(lhs_pos)).unwrap_or_default(); - let rhs_is_null = rhs.nulls().map(|v| v.is_null(rhs_pos)).unwrap_or_default(); + let lhs_is_null = lhs.nulls().is_some_and(|v| v.is_null(lhs_pos)); + let rhs_is_null = rhs.nulls().is_some_and(|v| v.is_null(rhs_pos)); lhs_is_null || (lhs_is_null == rhs_is_null) diff --git a/arrow-json/src/reader/struct_array.rs b/arrow-json/src/reader/struct_array.rs index d310618e109a..75bb02781be9 100644 --- a/arrow-json/src/reader/struct_array.rs +++ b/arrow-json/src/reader/struct_array.rs @@ -248,8 +248,7 @@ impl ArrayDecoder for StructArrayDecoder { // Sanity check assert_eq!(c.len(), pos.len()); if let Some(a) = c.nulls() { - let nulls_valid = - f.is_nullable() || nulls.as_ref().map(|n| n.contains(a)).unwrap_or_default(); + let nulls_valid = f.is_nullable() || nulls.as_ref().is_some_and(|n| n.contains(a)); if !nulls_valid { return Err(ArrowError::JsonError(format!( diff --git a/arrow-json/src/writer/mod.rs b/arrow-json/src/writer/mod.rs index 341779afedca..b39d8a150d24 100644 --- a/arrow-json/src/writer/mod.rs +++ b/arrow-json/src/writer/mod.rs @@ -2603,11 +2603,7 @@ mod tests { // 1. You can use information from Field to determine how to do the encoding. // 2. For dictionary arrays the Field is always the outer field but the array may be the keys or values array // and thus the data type of `field` may not match the data type of `array`. - let padded = field - .metadata() - .get("padded") - .map(|v| v == "true") - .unwrap_or_default(); + let padded = field.metadata().get("padded").is_some_and(|v| v == "true"); match (array.data_type(), padded) { (DataType::Int32, true) => { let array = array.as_primitive::(); diff --git a/arrow-schema/src/field.rs b/arrow-schema/src/field.rs index bf7358a101b5..66874f66723c 100644 --- a/arrow-schema/src/field.rs +++ b/arrow-schema/src/field.rs @@ -927,7 +927,7 @@ impl Field { && (self.nullable || !other.nullable) // make sure self.metadata is a superset of other.metadata && other.metadata.iter().all(|(k, v1)| { - self.metadata.get(k).map(|v2| v1 == v2).unwrap_or_default() + self.metadata.get(k).is_some_and(|v2| v1 == v2) }) } diff --git a/arrow-schema/src/schema.rs b/arrow-schema/src/schema.rs index 3964591eb22d..54e513635b9f 100644 --- a/arrow-schema/src/schema.rs +++ b/arrow-schema/src/schema.rs @@ -507,7 +507,7 @@ impl Schema { && other .metadata .iter() - .all(|(k, v1)| self.metadata.get(k).map(|v2| v1 == v2).unwrap_or_default()) + .all(|(k, v1)| self.metadata.get(k).is_some_and(|v2| v1 == v2)) } } diff --git a/arrow-string/src/binary_like.rs b/arrow-string/src/binary_like.rs index a66400aa786f..3759ff85737a 100644 --- a/arrow-string/src/binary_like.rs +++ b/arrow-string/src/binary_like.rs @@ -132,7 +132,7 @@ fn vectored_iter<'a, T: BinaryArrayType<'a> + 'a>( let nulls = a_v.nulls(); let keys = a_v.normalized_keys(); keys.into_iter().enumerate().map(move |(idx, key)| { - if nulls.map(|n| n.is_null(idx)).unwrap_or_default() || a.is_null(key) { + if nulls.is_some_and(|n| n.is_null(idx)) || a.is_null(key) { return None; } Some(a.value(key)) diff --git a/arrow-string/src/like.rs b/arrow-string/src/like.rs index e9077d4b090d..7c1e2e44742f 100644 --- a/arrow-string/src/like.rs +++ b/arrow-string/src/like.rs @@ -374,7 +374,7 @@ fn vectored_iter<'a, T: StringArrayType<'a> + 'a>( let nulls = a_v.nulls(); let keys = a_v.normalized_keys(); keys.into_iter().enumerate().map(move |(idx, key)| { - if nulls.map(|n| n.is_null(idx)).unwrap_or_default() || a.is_null(key) { + if nulls.is_some_and(|n| n.is_null(idx)) || a.is_null(key) { return None; } Some(a.value(key)) From 335f0e86000117aa0190c2150a18b142cdca5c91 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 4 Aug 2026 23:15:32 +0200 Subject: [PATCH 06/13] Enable `clippy::equatable_if_let` lint Rewrites `if let Pat = x` on unit-like patterns as `x == Pat` or `matches!`, applied with `cargo clippy --fix`. The `tokenizer.next()` cases still call `next()` exactly once, so nothing changes about consumption. --- Cargo.toml | 1 + arrow-avro/src/codec.rs | 2 +- arrow-json/src/reader/schema.rs | 5 +- arrow-schema/src/ffi.rs | 2 +- parquet-variant/src/utils.rs | 2 +- parquet/src/file/serialized_reader.rs | 2 +- parquet/src/record/triplet.rs | 6 +- parquet/src/schema/parser.rs | 101 +++++++++++++------------- 8 files changed, 61 insertions(+), 60 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 780325187e2e..2959cd2c48b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,6 +168,7 @@ doc_comment_double_space_linebreaks = "warn" doc_include_without_cfg = "warn" doc_link_with_quotes = "warn" empty_enum_variants_with_brackets = "warn" +equatable_if_let = "warn" exit = "warn" expl_impl_clone_on_copy = "warn" explicit_deref_methods = "warn" diff --git a/arrow-avro/src/codec.rs b/arrow-avro/src/codec.rs index 5618539c50f6..ec6224ed1ecc 100644 --- a/arrow-avro/src/codec.rs +++ b/arrow-avro/src/codec.rs @@ -600,7 +600,7 @@ impl AvroField { /// converted to use `Utf8View` instead of `Utf8`. pub(crate) fn with_utf8view(&self) -> Self { let mut field = self.clone(); - if let Codec::Utf8 = field.data_type.codec { + if field.data_type.codec == Codec::Utf8 { field.data_type.codec = Codec::Utf8View; } field diff --git a/arrow-json/src/reader/schema.rs b/arrow-json/src/reader/schema.rs index 524e6b2aa560..ce6bedf6983a 100644 --- a/arrow-json/src/reader/schema.rs +++ b/arrow-json/src/reader/schema.rs @@ -388,7 +388,10 @@ fn collect_field_types_from_object( set_object_scalar_field_type(field_types, k, DataType::Utf8)?; } Value::Object(inner_map) => { - if let InferredType::Any = field_types.get(k).unwrap_or(&InferredType::Any) { + if matches!( + field_types.get(k).unwrap_or(&InferredType::Any), + InferredType::Any + ) { field_types.insert(k.to_string(), InferredType::Object(HashMap::new())); } match field_types.get_mut(k).unwrap() { diff --git a/arrow-schema/src/ffi.rs b/arrow-schema/src/ffi.rs index 3f6fcd0f2c9b..2279d2d50f14 100644 --- a/arrow-schema/src/ffi.rs +++ b/arrow-schema/src/ffi.rs @@ -813,7 +813,7 @@ impl TryFrom<&Field> for FFI_ArrowSchema { Flags::empty() }; - if let Some(true) = field.dict_is_ordered() { + if field.dict_is_ordered() == Some(true) { flags |= Flags::DICTIONARY_ORDERED; } diff --git a/parquet-variant/src/utils.rs b/parquet-variant/src/utils.rs index 33f65c4e2b00..b73d7fa63994 100644 --- a/parquet-variant/src/utils.rs +++ b/parquet-variant/src/utils.rs @@ -187,7 +187,7 @@ pub(crate) fn parse_path(s: &str) -> Result>, ArrowEr }; let bytes = s.as_bytes(); - if let Some(b'.') = bytes.first() { + if matches!(bytes.first(), Some(b'.')) { return Err(ArrowError::ParseError("Unexpected leading '.'".into())); } diff --git a/parquet/src/file/serialized_reader.rs b/parquet/src/file/serialized_reader.rs index b52aac367bf9..4141971170af 100644 --- a/parquet/src/file/serialized_reader.rs +++ b/parquet/src/file/serialized_reader.rs @@ -2332,7 +2332,7 @@ mod tests { //col11->timestamp_col: INT96 UNCOMPRESSED DO:0 FPO:490093 SZ:111948/111948/1.00 VC:7300 ENC:BIT_PACKED,RLE,PLAIN ST:[num_nulls: 0, min/max not defined] //Notice: min_max values for each page for this col not exits. assert!(!&column_index[0][10].is_sorted()); - if let ColumnIndexMetaData::NONE = &column_index[0][10] { + if matches!(&column_index[0][10], ColumnIndexMetaData::NONE) { assert_eq!(row_group_offset_indexes[10].page_locations.len(), 974); } else { unreachable!() diff --git a/parquet/src/record/triplet.rs b/parquet/src/record/triplet.rs index b4d39bbbd9c9..db3088c71574 100644 --- a/parquet/src/record/triplet.rs +++ b/parquet/src/record/triplet.rs @@ -555,7 +555,7 @@ mod tests { assert_eq!(iter.max_def_level(), descr.max_def_level()); assert_eq!(iter.max_rep_level(), descr.max_rep_level()); - while let Ok(true) = iter.read_next() { + while matches!(iter.read_next(), Ok(true)) { assert!(iter.has_next()); if !iter.is_null() { values.push(iter.current_value().unwrap()); @@ -589,7 +589,7 @@ mod tests { #[test] fn test_current_def_level_safe_after_exhaustion() { let mut iter = open_triplet_iter("nulls.snappy.parquet", &["b_struct", "b_c_int"], 256); - while let Ok(true) = iter.read_next() {} + while matches!(iter.read_next(), Ok(true)) {} assert!(!iter.has_next()); assert_eq!(iter.current_def_level(), 0); } @@ -601,7 +601,7 @@ mod tests { &["a", "list", "element", "list", "element", "list", "element"], 256, ); - while let Ok(true) = iter.read_next() {} + while matches!(iter.read_next(), Ok(true)) {} assert!(!iter.has_next()); assert_eq!(iter.current_rep_level(), 0); } diff --git a/parquet/src/schema/parser.rs b/parquet/src/schema/parser.rs index 071962aa4ed8..c6a79a82027c 100644 --- a/parquet/src/schema/parser.rs +++ b/parquet/src/schema/parser.rs @@ -245,7 +245,7 @@ impl Parser<'_> { .ok_or_else(|| general_err!("Expected name, found None"))?; // Parse logical or converted type if exists - let (logical_type, converted_type) = if let Some("(") = self.tokenizer.next() { + let (logical_type, converted_type) = if self.tokenizer.next() == Some("(") { let tpe = self .tokenizer .next() @@ -269,7 +269,7 @@ impl Parser<'_> { }; // Parse optional id - let id = if let Some("=") = self.tokenizer.next() { + let id = if self.tokenizer.next() == Some("=") { self.tokenizer.next().and_then(|v| v.parse::().ok()) } else { self.tokenizer.backtrack(); @@ -311,8 +311,7 @@ impl Parser<'_> { .ok_or_else(|| general_err!("Expected name, found None"))?; // Parse converted type - let (logical_type, converted_type, precision, scale) = if let Some("(") = - self.tokenizer.next() + let (logical_type, converted_type, precision, scale) = if self.tokenizer.next() == Some("(") { let (mut logical, mut converted) = self .tokenizer @@ -337,13 +336,13 @@ impl Parser<'_> { if let Some(tpe) = &logical { match tpe { LogicalType::Decimal { .. } => { - if let Some("(") = self.tokenizer.next() { + if self.tokenizer.next() == Some("(") { precision = parse_i32( self.tokenizer.next(), "Expected precision, found None", "Failed to parse precision for DECIMAL type", )?; - if let Some(",") = self.tokenizer.next() { + if self.tokenizer.next() == Some(",") { scale = parse_i32( self.tokenizer.next(), "Expected scale, found None", @@ -358,13 +357,13 @@ impl Parser<'_> { } } LogicalType::Time { .. } => { - if let Some("(") = self.tokenizer.next() { + if self.tokenizer.next() == Some("(") { let unit = parse_timeunit( self.tokenizer.next(), "Invalid timeunit found", "Failed to parse timeunit for TIME type", )?; - if let Some(",") = self.tokenizer.next() { + if self.tokenizer.next() == Some(",") { let is_adjusted_to_u_t_c = parse_bool( self.tokenizer.next(), "Invalid boolean found", @@ -380,13 +379,13 @@ impl Parser<'_> { } } LogicalType::Timestamp { .. } => { - if let Some("(") = self.tokenizer.next() { + if self.tokenizer.next() == Some("(") { let unit = parse_timeunit( self.tokenizer.next(), "Invalid timeunit found", "Failed to parse timeunit for TIMESTAMP type", )?; - if let Some(",") = self.tokenizer.next() { + if self.tokenizer.next() == Some(",") { let is_adjusted_to_u_t_c = parse_bool( self.tokenizer.next(), "Invalid boolean found", @@ -401,57 +400,55 @@ impl Parser<'_> { } } } - LogicalType::Integer { .. } => { - if let Some("(") = self.tokenizer.next() { - let bit_width = parse_i32( - self.tokenizer.next(), - "Invalid bit_width found", - "Failed to parse bit_width for INTEGER type", - )? as i8; - match physical_type { - PhysicalType::INT32 => match bit_width { - 8 | 16 | 32 => {} - _ => { - return Err(general_err!( - "Incorrect bit width {} for INT32", - bit_width - )); - } - }, - PhysicalType::INT64 => { - if bit_width != 64 { - return Err(general_err!( - "Incorrect bit width {} for INT64", - bit_width - )); - } - } + LogicalType::Integer { .. } if self.tokenizer.next() == Some("(") => { + let bit_width = parse_i32( + self.tokenizer.next(), + "Invalid bit_width found", + "Failed to parse bit_width for INTEGER type", + )? as i8; + match physical_type { + PhysicalType::INT32 => match bit_width { + 8 | 16 | 32 => {} _ => { return Err(general_err!( - "Logical type Integer cannot be used with physical type {}", - physical_type + "Incorrect bit width {} for INT32", + bit_width + )); + } + }, + PhysicalType::INT64 => { + if bit_width != 64 { + return Err(general_err!( + "Incorrect bit width {} for INT64", + bit_width )); } } - if let Some(",") = self.tokenizer.next() { - let is_signed = parse_bool( - self.tokenizer.next(), - "Invalid boolean found", - "Failed to parse is_signed for INTEGER type", - )?; - assert_token(self.tokenizer.next(), ")")?; - logical = Some(LogicalType::integer(bit_width, is_signed)); - converted = ConvertedType::from(logical.clone()); - } else { - // Invalid token for unit - self.tokenizer.backtrack(); + _ => { + return Err(general_err!( + "Logical type Integer cannot be used with physical type {}", + physical_type + )); } } + if self.tokenizer.next() == Some(",") { + let is_signed = parse_bool( + self.tokenizer.next(), + "Invalid boolean found", + "Failed to parse is_signed for INTEGER type", + )?; + assert_token(self.tokenizer.next(), ")")?; + logical = Some(LogicalType::integer(bit_width, is_signed)); + converted = ConvertedType::from(logical.clone()); + } else { + // Invalid token for unit + self.tokenizer.backtrack(); + } } _ => {} } } else if converted == ConvertedType::DECIMAL { - if let Some("(") = self.tokenizer.next() { + if self.tokenizer.next() == Some("(") { // Parse precision precision = parse_i32( self.tokenizer.next(), @@ -460,7 +457,7 @@ impl Parser<'_> { )?; // Parse scale - scale = if let Some(",") = self.tokenizer.next() { + scale = if self.tokenizer.next() == Some(",") { parse_i32( self.tokenizer.next(), "Expected scale, found None", @@ -486,7 +483,7 @@ impl Parser<'_> { }; // Parse optional id - let id = if let Some("=") = self.tokenizer.next() { + let id = if self.tokenizer.next() == Some("=") { self.tokenizer.next().and_then(|v| v.parse::().ok()) } else { self.tokenizer.backtrack(); From 6baa557224ef3af52ac17c42f0cd44308305cb8a Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 4 Aug 2026 23:18:50 +0200 Subject: [PATCH 07/13] Enable `clippy::needless_raw_string_hashes` lint Drops `#` from raw strings that contain no quotes, applied with `cargo clippy --fix`. Strings that do contain a `"` keep their hashes. --- Cargo.toml | 1 + arrow-cast/src/cast/mod.rs | 4 ++-- arrow-csv/src/writer.rs | 8 ++++---- arrow-schema/src/datatype_parse.rs | 6 +++--- parquet-variant-compute/src/variant_get.rs | 4 ++-- parquet/src/arrow/arrow_writer/levels.rs | 8 ++++---- parquet/src/arrow/arrow_writer/mod.rs | 4 ++-- parquet/src/compression.rs | 4 ++-- parquet/src/file/metadata/push_decoder.rs | 12 ++++++------ parquet/tests/geospatial.rs | 4 ++-- 10 files changed, 28 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2959cd2c48b5..2f87326f6612 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -210,6 +210,7 @@ match_wild_err_arm = "warn" mismatching_type_param_order = "warn" mut_mut = "warn" mutex_integer = "warn" +needless_raw_string_hashes = "warn" negative_feature_names = "warn" non_zero_suggestions = "warn" nonstandard_macro_braces = "warn" diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs index 85c32b948e26..d4a7235dddd8 100644 --- a/arrow-cast/src/cast/mod.rs +++ b/arrow-cast/src/cast/mod.rs @@ -5859,12 +5859,12 @@ mod tests { test_unsafe_string_to_interval_err!( vec![Some("2 months 31 days 1 second")], IntervalUnit::YearMonth, - r#"Cast error: Cannot cast 2 months 31 days 1 second to IntervalYearMonth. Only year and month fields are allowed."# + r"Cast error: Cannot cast 2 months 31 days 1 second to IntervalYearMonth. Only year and month fields are allowed." ); test_unsafe_string_to_interval_err!( vec![Some("1 day 1.5 milliseconds")], IntervalUnit::DayTime, - r#"Cast error: Cannot cast 1 day 1.5 milliseconds to IntervalDayTime because the nanos part isn't multiple of milliseconds"# + r"Cast error: Cannot cast 1 day 1.5 milliseconds to IntervalDayTime because the nanos part isn't multiple of milliseconds" ); // overflow diff --git a/arrow-csv/src/writer.rs b/arrow-csv/src/writer.rs index 5236775b68ee..af413c889d86 100644 --- a/arrow-csv/src/writer.rs +++ b/arrow-csv/src/writer.rs @@ -739,14 +739,14 @@ mod tests { let mut buffer: Vec = vec![]; file.read_to_end(&mut buffer).unwrap(); - let expected = r#"c1,c2,c3,c4,c5,c6,c7 + let expected = r"c1,c2,c3,c4,c5,c6,c7 Lorem ipsum dolor sit amet,123.564532,3,true,,00:20:34,cupcakes consectetur adipiscing elit,,2,false,2019-04-18T10:54:47.378,06:51:20,cupcakes sed do eiusmod tempor,-556132.25,1,,2019-04-18T02:45:55.555,23:46:03,foo Lorem ipsum dolor sit amet,123.564532,3,true,,00:20:34,cupcakes consectetur adipiscing elit,,2,false,2019-04-18T10:54:47.378,06:51:20,cupcakes sed do eiusmod tempor,-556132.25,1,,2019-04-18T02:45:55.555,23:46:03,foo -"#; +"; assert_eq!(expected, str::from_utf8(&buffer).unwrap()); } @@ -800,7 +800,7 @@ sed do eiusmod tempor,-556132.25,1,,2019-04-18T02:45:55.555,23:46:03,foo let mut buffer: Vec = vec![]; file.read_to_end(&mut buffer).unwrap(); - let expected = r#"c1,c2,c3,c4 + let expected = r"c1,c2,c3,c4 -3.335724,-3.335724,-3.335724,-3.335724 2.179404,2.179404,2.179404,2.179404 ,,, @@ -809,7 +809,7 @@ sed do eiusmod tempor,-556132.25,1,,2019-04-18T02:45:55.555,23:46:03,foo 2.179404,2.179404,2.179404,2.179404 ,,, 0.290472,0.290472,0.290472,0.290472 -"#; +"; assert_eq!(expected, str::from_utf8(&buffer).unwrap()); } diff --git a/arrow-schema/src/datatype_parse.rs b/arrow-schema/src/datatype_parse.rs index cc4dbf44ad66..9439d8ea2188 100644 --- a/arrow-schema/src/datatype_parse.rs +++ b/arrow-schema/src/datatype_parse.rs @@ -1429,7 +1429,7 @@ mod test { ), ])), ), - (r#"Struct()"#, Struct(Fields::empty())), + (r"Struct()", Struct(Fields::empty())), ( "FixedSizeList(4, Int64)", FixedSizeList(Arc::new(Field::new_list_field(Int64, true)), 4), @@ -1461,12 +1461,12 @@ mod test { ("", "Error finding next token"), ("null", "Unsupported type 'null'"), ("Nu", "Unsupported type 'Nu'"), - (r#"Timestamp(ns, +00:00)"#, "Error unknown token: +00"), + (r"Timestamp(ns, +00:00)", "Error unknown token: +00"), ( r#"Timestamp(ns, "+00:00)"#, r#"Unterminated string at: "+00:00)"#, ), - (r#"Timestamp(ns, "")"#, r#"empty strings aren't allowed"#), + (r#"Timestamp(ns, "")"#, r"empty strings aren't allowed"), ( r#"Timestamp(ns, "+00:00"")"#, r#"Parser error: Unterminated string at: ")"#, diff --git a/parquet-variant-compute/src/variant_get.rs b/parquet-variant-compute/src/variant_get.rs index 04a2690b1e1e..7528a5c8269c 100644 --- a/parquet-variant-compute/src/variant_get.rs +++ b/parquet-variant-compute/src/variant_get.rs @@ -4862,7 +4862,7 @@ mod test { use arrow::datatypes::Int64Type; let string_array: ArrayRef = Arc::new(StringArray::from(vec![ - r#"[[1, 2], [3]]"#, + r"[[1, 2], [3]]", r#"[[4], "not a list", [5, 6]]"#, ])); let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap()); @@ -4940,7 +4940,7 @@ mod test { #[test] fn test_variant_get_list_like_unsafe_cast_preserves_null_elements() { - let string_array: ArrayRef = Arc::new(StringArray::from(vec![r#"[1, null, 3]"#])); + let string_array: ArrayRef = Arc::new(StringArray::from(vec![r"[1, null, 3]"])); let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap()); let cast_options = CastOptions { safe: false, diff --git a/parquet/src/arrow/arrow_writer/levels.rs b/parquet/src/arrow/arrow_writer/levels.rs index aad7c1a4051f..0ce3fac49538 100644 --- a/parquet/src/arrow/arrow_writer/levels.rs +++ b/parquet/src/arrow/arrow_writer/levels.rs @@ -2164,10 +2164,10 @@ mod tests { let expected = vec![ String::new(), String::new(), - r#"[]"#.to_string(), - r#"[{list: [3, ], integers: }]"#.to_string(), - r#"[, {list: , integers: 5}]"#.to_string(), - r#"[]"#.to_string(), + r"[]".to_string(), + r"[{list: [3, ], integers: }]".to_string(), + r"[, {list: , integers: 5}]".to_string(), + r"[]".to_string(), ]; let actual: Vec<_> = (0..6) diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index a1fb21ec2759..9ed5195c6ca4 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -4830,7 +4830,7 @@ mod tests { // Verify data is as expected - let expected = r#" + let expected = r" +-------------------------------------------------------------------------------------------------------+ | struct_b | +-------------------------------------------------------------------------------------------------------+ @@ -4842,7 +4842,7 @@ mod tests { | {list: [{leaf_a: 6, leaf_b: }, {leaf_a: 7, leaf_b: }, {leaf_a: 8, leaf_b: }, {leaf_a: 9, leaf_b: 1}]} | | {list: [{leaf_a: 10, leaf_b: }]} | +-------------------------------------------------------------------------------------------------------+ - "#.trim().split('\n').map(|x| x.trim()).collect::>().join("\n"); + ".trim().split('\n').map(|x| x.trim()).collect::>().join("\n"); let actual = pretty_format_batches(batches).unwrap().to_string(); assert_eq!(actual, expected); diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index 45b2b7edf95a..3116570426c7 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -24,7 +24,7 @@ // therefore actually run as a doc test) rather than to the `use` statement below. #![cfg_attr( feature = "experimental", - doc = r##" + doc = r" # Example ```no_run @@ -47,7 +47,7 @@ codec.decompress(&compressed[..], &mut output, None).unwrap(); assert_eq!(output, data); ``` -"## +" )] use crate::basic::Compression as CodecType; use crate::errors::{ParquetError, Result}; diff --git a/parquet/src/file/metadata/push_decoder.rs b/parquet/src/file/metadata/push_decoder.rs index de812b3e87e9..c53ec3722a6c 100644 --- a/parquet/src/file/metadata/push_decoder.rs +++ b/parquet/src/file/metadata/push_decoder.rs @@ -50,7 +50,7 @@ use std::sync::Arc; /// #[cfg_attr( feature = "arrow", - doc = r##" + doc = r#" ```rust # use std::ops::Range; # use bytes::Bytes; @@ -98,7 +98,7 @@ loop { } # } ``` -"## +"# )] /// /// # Example with "prefetching" @@ -122,7 +122,7 @@ loop { /// for other reasons. #[cfg_attr( feature = "arrow", - doc = r##" + doc = r#" ```rust # use std::ops::Range; # use bytes::Bytes; @@ -160,7 +160,7 @@ decoder.push_ranges(vec![0..file_len], vec![prefetched_bytes]).unwrap(); } # } ``` -"## +"# )] /// /// # Example using [`AsyncRead`] @@ -172,7 +172,7 @@ decoder.push_ranges(vec![0..file_len], vec![prefetched_bytes]).unwrap(); /// decoder. #[cfg_attr( feature = "arrow", - doc = r##" + doc = r#" ```rust # use std::ops::Range; # use bytes::Bytes; @@ -215,7 +215,7 @@ async fn decode_metadata( } } ``` -"## +"# )] /// [`AsyncRead`]: tokio::io::AsyncRead #[derive(Debug)] diff --git a/parquet/tests/geospatial.rs b/parquet/tests/geospatial.rs index 388b5c003d0e..4bc6a7decc55 100644 --- a/parquet/tests/geospatial.rs +++ b/parquet/tests/geospatial.rs @@ -437,7 +437,7 @@ mod test { // Geometry with default CRS (defaults to OGC:CRS84 per Parquet spec) (LogicalType::geometry(None), r#"{"crs":"OGC:CRS84"}"#), // Geometry with srid:0 should result in an unset (omitted) CRS - (LogicalType::geometry(Some("srid:0".to_string())), r#"{}"#), + (LogicalType::geometry(Some("srid:0".to_string())), r"{}"), // Geometry with custom CRSes (authority:code and partial projjson) ( LogicalType::geometry(Some("EPSG:4267".to_string())), @@ -538,7 +538,7 @@ mod test { // Test cases: (extension metadata JSON, expected LogicalType) let test_cases = [ // Geometry with no CRS should be GEOMETRY(srid:0) - (r#"{}"#, LogicalType::geometry(Some("srid:0".to_string()))), + (r"{}", LogicalType::geometry(Some("srid:0".to_string()))), // Geometry with string CRS ( r#"{"crs":"EPSG:4267"}"#, From 0fc32a58131b978d1c1aa19a98020c3174e45790 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 4 Aug 2026 23:21:53 +0200 Subject: [PATCH 08/13] Enable `clippy::ignored_unit_patterns` lint Uses `()` instead of `_` where the matched type is unit, applied with `cargo clippy --fix`. --- Cargo.toml | 1 + arrow-avro/src/reader/mod.rs | 2 +- arrow-cast/src/cast/decimal.rs | 8 +++++--- arrow-cast/src/cast/mod.rs | 6 +++--- arrow-cast/src/display.rs | 4 ++-- arrow-ipc/src/reader.rs | 2 +- arrow-schema/src/extension/canonical/bool8.rs | 2 +- .../src/extension/canonical/timestamp_with_offset.rs | 2 +- arrow-schema/src/extension/canonical/uuid.rs | 2 +- parquet-variant-compute/src/variant_to_arrow.rs | 2 +- parquet/benches/row_group_index_reader.rs | 2 +- parquet/src/arrow/schema/virtual_type.rs | 4 ++-- parquet/src/compression.rs | 6 +++--- parquet/src/file/metadata/reader.rs | 2 +- parquet/src/parquet_thrift.rs | 12 ++++++------ parquet/tests/encryption/encryption_async.rs | 2 +- 16 files changed, 31 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2f87326f6612..4b75274281f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -179,6 +179,7 @@ float_cmp_const = "warn" fn_params_excessive_bools = "warn" fn_to_numeric_cast_any = "warn" format_push_string = "warn" +ignored_unit_patterns = "warn" imprecise_flops = "warn" inconsistent_struct_constructor = "warn" index_refutable_slice = "warn" diff --git a/arrow-avro/src/reader/mod.rs b/arrow-avro/src/reader/mod.rs index 2767a514152c..82ea9e6fd672 100644 --- a/arrow-avro/src/reader/mod.rs +++ b/arrow-avro/src/reader/mod.rs @@ -4771,7 +4771,7 @@ mod test { { let idx = schema.index_of("array_of_union").unwrap(); let dt = schema.field(idx).data_type().clone(); - let (item_field, _) = match &dt { + let (item_field, ()) = match &dt { DataType::List(f) => (f.clone(), ()), other => panic!("array_of_union must be List, got {other:?}"), }; diff --git a/arrow-cast/src/cast/decimal.rs b/arrow-cast/src/cast/decimal.rs index 9d1465567e0d..a6497332d728 100644 --- a/arrow-cast/src/cast/decimal.rs +++ b/arrow-cast/src/cast/decimal.rs @@ -370,7 +370,7 @@ where let error = cast_decimal_to_decimal_error::(output_precision, output_scale); array.try_unary(|x| { f_fallible(x).ok_or_else(|| error(x)).and_then(|v| { - O::validate_decimal_precision(v, output_precision, output_scale).map(|_| v) + O::validate_decimal_precision(v, output_precision, output_scale).map(|()| v) }) })? }; @@ -671,7 +671,9 @@ where T::DATA_TYPE, )) }) - .and_then(|v| T::validate_decimal_precision(v, precision, scale).map(|_| v)) + .and_then(|v| { + T::validate_decimal_precision(v, precision, scale).map(|()| v) + }) }) .transpose() }) @@ -801,7 +803,7 @@ where v )) }) - .and_then(|v| D::validate_decimal_precision(v, precision, scale).map(|_| v)) + .and_then(|v| D::validate_decimal_precision(v, precision, scale).map(|()| v)) })? .with_precision_and_scale(precision, scale) .map(|a| Arc::new(a) as ArrayRef) diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs index d4a7235dddd8..c7229ec3b58a 100644 --- a/arrow-cast/src/cast/mod.rs +++ b/arrow-cast/src/cast/mod.rs @@ -390,7 +390,7 @@ where false => array.try_unary::<_, D, _>(|v| { v.as_() .div_checked(scale_factor) - .and_then(|v| D::validate_decimal_precision(v, precision, scale).map(|_| v)) + .and_then(|v| D::validate_decimal_precision(v, precision, scale).map(|()| v)) })?, } } else { @@ -404,7 +404,7 @@ where false => array.try_unary::<_, D, _>(|v| { v.as_() .mul_checked(scale_factor) - .and_then(|v| D::validate_decimal_precision(v, precision, scale).map(|_| v)) + .and_then(|v| D::validate_decimal_precision(v, precision, scale).map(|()| v)) })?, } }; @@ -2704,7 +2704,7 @@ fn cast_binary_to_fixed_size_binary( builder.append_null(); } else { match builder.append_value(array.value(i)) { - Ok(_) => {} + Ok(()) => {} Err(e) => match cast_options.safe { true => builder.append_null(), false => return Err(e), diff --git a/arrow-cast/src/display.rs b/arrow-cast/src/display.rs index bacaef46d765..5705a455c938 100644 --- a/arrow-cast/src/display.rs +++ b/arrow-cast/src/display.rs @@ -419,7 +419,7 @@ impl ValueFormatter<'_> { /// will return an error on formatting issue pub fn write(&self, s: &mut dyn Write) -> Result<(), ArrowError> { match self.formatter.format.write(self.idx, s) { - Ok(_) => Ok(()), + Ok(()) => Ok(()), Err(FormatError::Arrow(e)) => Err(e), Err(FormatError::Format(_)) => Err(ArrowError::CastError("Format error".to_string())), } @@ -614,7 +614,7 @@ impl<'a, T: DisplayIndex> DisplayIndexState<'a> for T { Ok(()) } - fn write(&self, _: &Self::State, idx: usize, f: &mut dyn Write) -> FormatResult { + fn write(&self, (): &Self::State, idx: usize, f: &mut dyn Write) -> FormatResult { DisplayIndex::write(self, idx, f) } } diff --git a/arrow-ipc/src/reader.rs b/arrow-ipc/src/reader.rs index 46b6ac61c2c4..fba9e18d77d8 100644 --- a/arrow-ipc/src/reader.rs +++ b/arrow-ipc/src/reader.rs @@ -1861,7 +1861,7 @@ impl MessageReader { pub fn read_meta_len(&mut self) -> Result, ArrowError> { let mut meta_len: [u8; 4] = [0; 4]; match self.reader.read_exact(&mut meta_len) { - Ok(_) => {} + Ok(()) => {} Err(e) => { return if e.kind() == std::io::ErrorKind::UnexpectedEof { // Handle EOF without the "0xFFFFFFFF 0x00000000" diff --git a/arrow-schema/src/extension/canonical/bool8.rs b/arrow-schema/src/extension/canonical/bool8.rs index 17eeb240ac29..75df61a632fd 100644 --- a/arrow-schema/src/extension/canonical/bool8.rs +++ b/arrow-schema/src/extension/canonical/bool8.rs @@ -66,7 +66,7 @@ impl ExtensionType for Bool8 { } fn try_new(data_type: &DataType, _metadata: Self::Metadata) -> Result { - Self.supports_data_type(data_type).map(|_| Self) + Self.supports_data_type(data_type).map(|()| Self) } fn validate(data_type: &DataType, _metadata: Self::Metadata) -> Result<(), ArrowError> { diff --git a/arrow-schema/src/extension/canonical/timestamp_with_offset.rs b/arrow-schema/src/extension/canonical/timestamp_with_offset.rs index 84b49564aee6..e40a21ad6336 100644 --- a/arrow-schema/src/extension/canonical/timestamp_with_offset.rs +++ b/arrow-schema/src/extension/canonical/timestamp_with_offset.rs @@ -137,7 +137,7 @@ impl ExtensionType for TimestampWithOffset { } fn try_new(data_type: &DataType, _metadata: Self::Metadata) -> Result { - Self.supports_data_type(data_type).map(|_| Self) + Self.supports_data_type(data_type).map(|()| Self) } fn validate(data_type: &DataType, _metadata: Self::Metadata) -> Result<(), ArrowError> { diff --git a/arrow-schema/src/extension/canonical/uuid.rs b/arrow-schema/src/extension/canonical/uuid.rs index 16e7de438092..345fe0397bbe 100644 --- a/arrow-schema/src/extension/canonical/uuid.rs +++ b/arrow-schema/src/extension/canonical/uuid.rs @@ -75,7 +75,7 @@ impl ExtensionType for Uuid { } fn try_new(data_type: &DataType, _metadata: Self::Metadata) -> Result { - Self.supports_data_type(data_type).map(|_| Self) + Self.supports_data_type(data_type).map(|()| Self) } fn validate(data_type: &DataType, _metadata: Self::Metadata) -> Result<(), ArrowError> { diff --git a/parquet-variant-compute/src/variant_to_arrow.rs b/parquet-variant-compute/src/variant_to_arrow.rs index d7c61b7653af..4c4ac367fb15 100644 --- a/parquet-variant-compute/src/variant_to_arrow.rs +++ b/parquet-variant-compute/src/variant_to_arrow.rs @@ -1419,7 +1419,7 @@ struct FakeNullBuilder { } impl FakeNullBuilder { - fn append_value(&mut self, _: ()) { + fn append_value(&mut self, (): ()) { self.item_count += 1; } diff --git a/parquet/benches/row_group_index_reader.rs b/parquet/benches/row_group_index_reader.rs index 1fadfb5d4b7c..4c7968ae97f4 100644 --- a/parquet/benches/row_group_index_reader.rs +++ b/parquet/benches/row_group_index_reader.rs @@ -74,7 +74,7 @@ impl ExtensionType for RowGroupIndex { data_type: &ArrowDataType, _metadata: Self::Metadata, ) -> Result { - RowGroupIndex.supports_data_type(data_type).map(|_| Self) + RowGroupIndex.supports_data_type(data_type).map(|()| Self) } } diff --git a/parquet/src/arrow/schema/virtual_type.rs b/parquet/src/arrow/schema/virtual_type.rs index dc9e191e8f4b..7acdc0c2c003 100644 --- a/parquet/src/arrow/schema/virtual_type.rs +++ b/parquet/src/arrow/schema/virtual_type.rs @@ -67,7 +67,7 @@ impl ExtensionType for RowGroupIndex { } fn try_new(data_type: &DataType, _metadata: Self::Metadata) -> Result { - Self.supports_data_type(data_type).map(|_| Self) + Self.supports_data_type(data_type).map(|()| Self) } fn validate(data_type: &DataType, _metadata: Self::Metadata) -> Result<(), ArrowError> { @@ -115,7 +115,7 @@ impl ExtensionType for RowNumber { } fn try_new(data_type: &DataType, _metadata: Self::Metadata) -> Result { - Self.supports_data_type(data_type).map(|_| Self) + Self.supports_data_type(data_type).map(|()| Self) } fn validate(data_type: &DataType, _metadata: Self::Metadata) -> Result<(), ArrowError> { diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index 3116570426c7..cb1620e3fe4d 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -350,7 +350,7 @@ impl GzipLevel { /// /// Compression levels must be valid (i.e. be acceptable for [`flate2::Compression`]). pub fn try_new(level: u32) -> Result { - Self::is_valid_level(level).map(|_| Self(level)) + Self::is_valid_level(level).map(|()| Self(level)) } /// Returns the compression level. @@ -432,7 +432,7 @@ impl BrotliLevel { /// /// Compression levels must be valid. pub fn try_new(level: u32) -> Result { - Self::is_valid_level(level).map(|_| Self(level)) + Self::is_valid_level(level).map(|()| Self(level)) } /// Returns the compression level. @@ -588,7 +588,7 @@ impl ZstdLevel { /// /// Compression levels must be valid (i.e. be acceptable for [`zstd::compression_level_range`]). pub fn try_new(level: i32) -> Result { - Self::is_valid_level(level).map(|_| Self(level)) + Self::is_valid_level(level).map(|()| Self(level)) } /// Returns the compression level. diff --git a/parquet/src/file/metadata/reader.rs b/parquet/src/file/metadata/reader.rs index 78414ffdcbda..43bd339930f8 100644 --- a/parquet/src/file/metadata/reader.rs +++ b/parquet/src/file/metadata/reader.rs @@ -930,7 +930,7 @@ mod tests { let mut bytes = bytes_for_range(452505..len); loop { match reader.try_parse_sized(&bytes, len) { - Ok(_) => break, + Ok(()) => break, Err(ParquetError::NeedMoreData(needed)) => { bytes = bytes_for_range(len - needed as u64..len); if reader.has_metadata() { diff --git a/parquet/src/parquet_thrift.rs b/parquet/src/parquet_thrift.rs index 65c7eae5e07c..a3da8574119d 100644 --- a/parquet/src/parquet_thrift.rs +++ b/parquet/src/parquet_thrift.rs @@ -499,11 +499,11 @@ pub(crate) trait ThriftCompactInputProtocol<'a> { // boolean field has no data FieldType::BooleanFalse | FieldType::BooleanTrue => Ok(()), FieldType::Byte => self.read_i8().map(|_| ()), - FieldType::I16 => self.skip_vlq().map(|_| ()), - FieldType::I32 => self.skip_vlq().map(|_| ()), - FieldType::I64 => self.skip_vlq().map(|_| ()), - FieldType::Double => self.skip_bytes(8).map(|_| ()), - FieldType::Binary => self.skip_binary().map(|_| ()), + FieldType::I16 => self.skip_vlq(), + FieldType::I32 => self.skip_vlq(), + FieldType::I64 => self.skip_vlq(), + FieldType::Double => self.skip_bytes(8), + FieldType::Binary => self.skip_binary(), // see https://github.com/apache/thrift/blob/master/doc/specs/thrift-compact-protocol.md#struct FieldType::Struct => { loop { @@ -541,7 +541,7 @@ pub(crate) trait ThriftCompactInputProtocol<'a> { Ok(()) } // see https://github.com/apache/thrift/blob/master/doc/specs/thrift-compact-protocol.md#universal-unique-identifier-encoding - FieldType::Uuid => self.skip_bytes(16).map(|_| ()), + FieldType::Uuid => self.skip_bytes(16), _ => Err(ThriftProtocolError::SkipUnsupportedType(field_type)), } } diff --git a/parquet/tests/encryption/encryption_async.rs b/parquet/tests/encryption/encryption_async.rs index ea64f0bd90db..82569cc0ac35 100644 --- a/parquet/tests/encryption/encryption_async.rs +++ b/parquet/tests/encryption/encryption_async.rs @@ -111,7 +111,7 @@ async fn test_misspecified_encryption_keys() { let decryption_properties = builder.build().unwrap(); match verify_encryption_test_file_read_async(&mut file, decryption_properties).await { - Ok(_) => { + Ok(()) => { panic!("did not get expected error") } Err(e) => { From 88c01c6789f76f3d67dcbca68c27fe50e0d3b580 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 4 Aug 2026 23:26:37 +0200 Subject: [PATCH 09/13] Enable `clippy::unnested_or_patterns` lint Nests or-patterns, applied with `cargo clippy --fix`. Each group of collapsed arms already shared a body, so match order and reachability are unchanged. --- Cargo.toml | 1 + arrow-array/src/ffi.rs | 65 ++++++++++++--------------- arrow-avro/src/reader/record.rs | 3 +- arrow-avro/src/writer/encoder.rs | 2 +- arrow-cast/src/cast/mod.rs | 17 +++---- arrow-json/src/reader/schema.rs | 5 +-- arrow-json/src/reader/tape.rs | 2 +- parquet/src/arrow/schema/complex.rs | 8 ++-- parquet/src/column/writer/mod.rs | 2 +- parquet/src/geospatial/accumulator.rs | 2 +- parquet/src/schema/types.rs | 2 +- 11 files changed, 48 insertions(+), 61 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4b75274281f9..535caae8d9ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -249,6 +249,7 @@ unnecessary_literal_bound = "warn" unnecessary_safety_doc = "warn" unnecessary_self_imports = "warn" unnecessary_struct_initialization = "warn" +unnested_or_patterns = "warn" unused_async = "warn" unused_peekable = "warn" unused_rounding = "warn" diff --git a/arrow-array/src/ffi.rs b/arrow-array/src/ffi.rs index 970419c633b1..4e132b4cc416 100644 --- a/arrow-array/src/ffi.rs +++ b/arrow-array/src/ffi.rs @@ -144,7 +144,7 @@ fn bit_width(data_type: &DataType, i: usize) -> Result { let child_bit_width = bit_width(f.data_type(), 1)?; child_bit_width * (*num_elems as usize) } - (DataType::FixedSizeBinary(_), _) | (DataType::FixedSizeList(_, _), _) => { + (DataType::FixedSizeBinary(_) | DataType::FixedSizeList(_, _), _) => { return Err(ArrowError::CDataInterface(format!( "The datatype \"{data_type}\" expects 2 buffers, but requested {i}. Please verify that the C data interface is correctly implemented." ))); @@ -152,34 +152,29 @@ fn bit_width(data_type: &DataType, i: usize) -> Result { // Variable-size list and map have one i32 buffer. // Variable-sized binaries: have two buffers. // "small": first buffer is i32, second is in bytes - (DataType::Utf8, 1) - | (DataType::Binary, 1) - | (DataType::List(_), 1) - | (DataType::Map(_, _), 1) => i32::BITS as _, - (DataType::Utf8, 2) | (DataType::Binary, 2) => u8::BITS as _, + (DataType::Utf8 | DataType::Binary | DataType::List(_) | DataType::Map(_, _), 1) => { + i32::BITS as _ + } + (DataType::Utf8 | DataType::Binary, 2) => u8::BITS as _, // List views have two i32 buffers, offsets and sizes - (DataType::ListView(_), 1) | (DataType::ListView(_), 2) => i32::BITS as _, + (DataType::ListView(_), 1 | 2) => i32::BITS as _, // Large list views have two i64 buffers, offsets and sizes - (DataType::LargeListView(_), 1) | (DataType::LargeListView(_), 2) => i64::BITS as _, - (DataType::List(_), _) | (DataType::Map(_, _), _) => { + (DataType::LargeListView(_), 1 | 2) => i64::BITS as _, + (DataType::List(_) | DataType::Map(_, _), _) => { return Err(ArrowError::CDataInterface(format!( "The datatype \"{data_type}\" expects 2 buffers, but requested {i}. Please verify that the C data interface is correctly implemented." ))); } - (DataType::Utf8, _) | (DataType::Binary, _) => { + (DataType::Utf8 | DataType::Binary, _) => { return Err(ArrowError::CDataInterface(format!( "The datatype \"{data_type}\" expects 3 buffers, but requested {i}. Please verify that the C data interface is correctly implemented." ))); } // Variable-sized binaries: have two buffers. // LargeUtf8: first buffer is i64, second is in bytes - (DataType::LargeUtf8, 1) | (DataType::LargeBinary, 1) | (DataType::LargeList(_), 1) => { - i64::BITS as _ - } - (DataType::LargeUtf8, 2) | (DataType::LargeBinary, 2) | (DataType::LargeList(_), 2) => { - u8::BITS as _ - } - (DataType::LargeUtf8, _) | (DataType::LargeBinary, _) | (DataType::LargeList(_), _) => { + (DataType::LargeUtf8 | DataType::LargeBinary | DataType::LargeList(_), 1) => i64::BITS as _, + (DataType::LargeUtf8 | DataType::LargeBinary | DataType::LargeList(_), 2) => u8::BITS as _, + (DataType::LargeUtf8 | DataType::LargeBinary | DataType::LargeList(_), _) => { return Err(ArrowError::CDataInterface(format!( "The datatype \"{data_type}\" expects 3 buffers, but requested {i}. Please verify that the C data interface is correctly implemented." ))); @@ -187,8 +182,8 @@ fn bit_width(data_type: &DataType, i: usize) -> Result { // Variable-sized views: have 3 or more buffers. // Buffer 1 are the u128 views // Buffers 2...N-1 are u8 byte buffers - (DataType::Utf8View, 1) | (DataType::BinaryView, 1) => u128::BITS as _, - (DataType::Utf8View, _) | (DataType::BinaryView, _) => u8::BITS as _, + (DataType::Utf8View | DataType::BinaryView, 1) => u128::BITS as _, + (DataType::Utf8View | DataType::BinaryView, _) => u8::BITS as _, // type ids. UnionArray doesn't have null bitmap so buffer index begins with 0. (DataType::Union(_, _), 0) => i8::BITS as _, // Only DenseUnion has 2nd buffer @@ -456,27 +451,27 @@ impl ImportedArrowArray<'_> { // Inner type is not important for buffer length. Ok(match (&data_type, i) { - (DataType::Utf8, 1) - | (DataType::LargeUtf8, 1) - | (DataType::Binary, 1) - | (DataType::LargeBinary, 1) - | (DataType::List(_), 1) - | (DataType::LargeList(_), 1) - | (DataType::Map(_, _), 1) => { + ( + DataType::Utf8 + | DataType::LargeUtf8 + | DataType::Binary + | DataType::LargeBinary + | DataType::List(_) + | DataType::LargeList(_) + | DataType::Map(_, _), + 1, + ) => { // the len of the offset buffer (buffer 1) equals length + 1 let bits = bit_width(data_type, i)?; debug_assert_eq!(bits % 8, 0); (length + 1) * (bits / 8) } - (DataType::ListView(_), 1) - | (DataType::ListView(_), 2) - | (DataType::LargeListView(_), 1) - | (DataType::LargeListView(_), 2) => { + (DataType::ListView(_) | DataType::LargeListView(_), 1 | 2) => { let bits = bit_width(data_type, i)?; debug_assert_eq!(bits % 8, 0); length * (bits / 8) } - (DataType::Utf8, 2) | (DataType::Binary, 2) => { + (DataType::Utf8 | DataType::Binary, 2) => { if self.array.is_empty() { return Ok(0); } @@ -490,7 +485,7 @@ impl ImportedArrowArray<'_> { // get last offset (unsafe { *offset_buffer.add(len / size_of::() - 1) }) as usize } - (DataType::LargeUtf8, 2) | (DataType::LargeBinary, 2) => { + (DataType::LargeUtf8 | DataType::LargeBinary, 2) => { if self.array.is_empty() { return Ok(0); } @@ -508,10 +503,8 @@ impl ImportedArrowArray<'_> { // Buffer 1 is the views buffer, which stores 1 u128 per length of the array. // Buffers 2..N-1 are the buffers holding the byte data. Their lengths are variable. // Buffer N is of length (N - 2) and stores i64 containing the lengths of buffers 2..N-1 - (DataType::Utf8View, 1) | (DataType::BinaryView, 1) => { - std::mem::size_of::() * length - } - (DataType::Utf8View, i) | (DataType::BinaryView, i) => { + (DataType::Utf8View | DataType::BinaryView, 1) => std::mem::size_of::() * length, + (DataType::Utf8View | DataType::BinaryView, i) => { variadic_buffer_lengths[i - 2] as usize } // buffer len of primitive types diff --git a/arrow-avro/src/reader/record.rs b/arrow-avro/src/reader/record.rs index b4619f196aaa..9f97a800a015 100644 --- a/arrow-avro/src/reader/record.rs +++ b/arrow-avro/src/reader/record.rs @@ -324,8 +324,7 @@ impl Decoder { (Codec::Float64, Some(Promotion::FloatToDouble)) => { Self::Float32ToFloat64(Vec::with_capacity(DEFAULT_CAPACITY)) } - (Codec::Utf8, Some(Promotion::BytesToString)) - | (Codec::Utf8View, Some(Promotion::BytesToString)) => Self::BytesToString( + (Codec::Utf8 | Codec::Utf8View, Some(Promotion::BytesToString)) => Self::BytesToString( OffsetBufferBuilder::new(DEFAULT_CAPACITY), Vec::with_capacity(DEFAULT_CAPACITY), ), diff --git a/arrow-avro/src/writer/encoder.rs b/arrow-avro/src/writer/encoder.rs index e88337cd6d47..4d1140677c46 100644 --- a/arrow-avro/src/writer/encoder.rs +++ b/arrow-avro/src/writer/encoder.rs @@ -1044,7 +1044,7 @@ impl FieldPlan { { matches!( arrow_field.extension_type_name(), - Some("arrow.uuid") | Some("uuid") + Some("arrow.uuid" | "uuid") ) } #[cfg(not(feature = "canonical_extension_types"))] diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs index c7229ec3b58a..d848898f7ec6 100644 --- a/arrow-cast/src/cast/mod.rs +++ b/arrow-cast/src/cast/mod.rs @@ -269,14 +269,9 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool { | LargeUtf8 | Date32 | Date64 - | Time32(Second) - | Time32(Millisecond) - | Time64(Microsecond) - | Time64(Nanosecond) - | Timestamp(Second, _) - | Timestamp(Millisecond, _) - | Timestamp(Microsecond, _) - | Timestamp(Nanosecond, _) + | Time32(Second | Millisecond) + | Time64(Microsecond | Nanosecond) + | Timestamp(Second | Millisecond | Microsecond | Nanosecond, _) | Interval(_) | BinaryView, ) => true, @@ -320,10 +315,8 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool { Timestamp(_, _) | Date32 | Date64 - | Time32(Second) - | Time32(Millisecond) - | Time64(Microsecond) - | Time64(Nanosecond), + | Time32(Second | Millisecond) + | Time64(Microsecond | Nanosecond), ) => true, (_, Duration(_)) if from_type.is_numeric() => true, (Duration(_), _) if to_type.is_numeric() => true, diff --git a/arrow-json/src/reader/schema.rs b/arrow-json/src/reader/schema.rs index ce6bedf6983a..f9f70da1f03c 100644 --- a/arrow-json/src/reader/schema.rs +++ b/arrow-json/src/reader/schema.rs @@ -94,9 +94,8 @@ fn coerce_data_type(dt: Vec<&DataType>) -> DataType { (DataType::Null, o) | (o, DataType::Null) => o, (DataType::Boolean, DataType::Boolean) => DataType::Boolean, (DataType::Int64, DataType::Int64) => DataType::Int64, - (DataType::Float64, DataType::Float64) - | (DataType::Float64, DataType::Int64) - | (DataType::Int64, DataType::Float64) => DataType::Float64, + (DataType::Float64 | DataType::Int64, DataType::Float64) + | (DataType::Float64, DataType::Int64) => DataType::Float64, (DataType::List(l), DataType::List(r)) => { list_type_of(coerce_data_type(vec![l.data_type(), r.data_type()])) } diff --git a/arrow-json/src/reader/tape.rs b/arrow-json/src/reader/tape.rs index 683e172d5dce..32f40024bfc2 100644 --- a/arrow-json/src/reader/tape.rs +++ b/arrow-json/src/reader/tape.rs @@ -413,7 +413,7 @@ impl TapeDecoder { iter.skip_whitespace(); *state = match next!(iter) { b'"' => DecoderState::String, - b @ b'-' | b @ b'0'..=b'9' => { + b @ (b'-' | b'0'..=b'9') => { self.bytes.push(b); DecoderState::Number } diff --git a/parquet/src/arrow/schema/complex.rs b/parquet/src/arrow/schema/complex.rs index 99dc3d4dc762..9277c8e193df 100644 --- a/parquet/src/arrow/schema/complex.rs +++ b/parquet/src/arrow/schema/complex.rs @@ -85,9 +85,11 @@ impl ParquetField { list_data_type: Option, ) -> Result { let arrow_field = match &list_data_type { - Some(DataType::List(field_hint)) - | Some(DataType::LargeList(field_hint)) - | Some(DataType::FixedSizeList(field_hint, _)) => Some(field_hint.as_ref()), + Some( + DataType::List(field_hint) + | DataType::LargeList(field_hint) + | DataType::FixedSizeList(field_hint, _), + ) => Some(field_hint.as_ref()), Some(_) => { return Err(general_err!( "Internal error: should be validated earlier that list_data_type is only a type of list" diff --git a/parquet/src/column/writer/mod.rs b/parquet/src/column/writer/mod.rs index 314440f15f3c..c98469cf7cec 100644 --- a/parquet/src/column/writer/mod.rs +++ b/parquet/src/column/writer/mod.rs @@ -1186,7 +1186,7 @@ impl<'a, E: ColumnValueEncoder> GenericColumnWriter<'a, E> { Type::FIXED_LEN_BYTE_ARRAY if !matches!( self.descr.logical_type_ref(), - Some(&LogicalType::Decimal { .. }) | Some(&LogicalType::Float16) + Some(&LogicalType::Decimal { .. } | &LogicalType::Float16) ) => { true diff --git a/parquet/src/geospatial/accumulator.rs b/parquet/src/geospatial/accumulator.rs index 3aad1060e05c..c204db94fa66 100644 --- a/parquet/src/geospatial/accumulator.rs +++ b/parquet/src/geospatial/accumulator.rs @@ -34,7 +34,7 @@ pub fn try_new_geo_stats_accumulator( ) -> Option> { if !matches!( descr.logical_type_ref(), - Some(LogicalType::Geometry { .. }) | Some(LogicalType::Geography { .. }) + Some(LogicalType::Geometry { .. } | LogicalType::Geography { .. }) ) { return None; } diff --git a/parquet/src/schema/types.rs b/parquet/src/schema/types.rs index f81ff64ddc62..16b2eddfb07d 100644 --- a/parquet/src/schema/types.rs +++ b/parquet/src/schema/types.rs @@ -356,7 +356,7 @@ impl<'a> PrimitiveTypeBuilder<'a> { } // Check that logical type and physical type are compatible match (logical_type, self.physical_type) { - (LogicalType::Map, _) | (LogicalType::List, _) => { + (LogicalType::Map | LogicalType::List, _) => { return Err(general_err!( "{:?} cannot be applied to a primitive type for field '{}'", logical_type, From 4f94bbc3b94f795d09c1bd8f686c5d22abc8c2ce Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 5 Aug 2026 17:59:18 +0200 Subject: [PATCH 10/13] Prefer `==` over `matches!` where the type allows it Two of the `matches!` calls introduced by `equatable_if_let` read better as equality comparisons. The remaining ones stay: `InferredType` has no `PartialEq`, and `ParquetError` deliberately does not implement it (#4469). --- parquet-variant/src/utils.rs | 2 +- parquet/src/file/serialized_reader.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/parquet-variant/src/utils.rs b/parquet-variant/src/utils.rs index b73d7fa63994..b2e2f654e06f 100644 --- a/parquet-variant/src/utils.rs +++ b/parquet-variant/src/utils.rs @@ -187,7 +187,7 @@ pub(crate) fn parse_path(s: &str) -> Result>, ArrowEr }; let bytes = s.as_bytes(); - if matches!(bytes.first(), Some(b'.')) { + if bytes.first() == Some(&b'.') { return Err(ArrowError::ParseError("Unexpected leading '.'".into())); } diff --git a/parquet/src/file/serialized_reader.rs b/parquet/src/file/serialized_reader.rs index 4141971170af..fe9a5c04863c 100644 --- a/parquet/src/file/serialized_reader.rs +++ b/parquet/src/file/serialized_reader.rs @@ -2332,7 +2332,7 @@ mod tests { //col11->timestamp_col: INT96 UNCOMPRESSED DO:0 FPO:490093 SZ:111948/111948/1.00 VC:7300 ENC:BIT_PACKED,RLE,PLAIN ST:[num_nulls: 0, min/max not defined] //Notice: min_max values for each page for this col not exits. assert!(!&column_index[0][10].is_sorted()); - if matches!(&column_index[0][10], ColumnIndexMetaData::NONE) { + if column_index[0][10] == ColumnIndexMetaData::NONE { assert_eq!(row_group_offset_indexes[10].page_locations.len(), 974); } else { unreachable!() From def787b8fa3b6e5cad379ce54dac763a1aceae9e Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 5 Aug 2026 18:11:53 +0200 Subject: [PATCH 11/13] Drop the `r` prefix from raw strings that need no escaping Ten plain data strings left over from the `needless_raw_string_hashes` commit. Raw strings are kept where they still earn their prefix: regex and LIKE-pattern tables, and multi-line blocks that would otherwise need `\n`. --- arrow-cast/src/cast/mod.rs | 4 ++-- parquet-variant-compute/src/variant_get.rs | 4 ++-- parquet/src/arrow/arrow_writer/levels.rs | 8 ++++---- parquet/tests/geospatial.rs | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs index d848898f7ec6..725fa15738d2 100644 --- a/arrow-cast/src/cast/mod.rs +++ b/arrow-cast/src/cast/mod.rs @@ -5852,12 +5852,12 @@ mod tests { test_unsafe_string_to_interval_err!( vec![Some("2 months 31 days 1 second")], IntervalUnit::YearMonth, - r"Cast error: Cannot cast 2 months 31 days 1 second to IntervalYearMonth. Only year and month fields are allowed." + "Cast error: Cannot cast 2 months 31 days 1 second to IntervalYearMonth. Only year and month fields are allowed." ); test_unsafe_string_to_interval_err!( vec![Some("1 day 1.5 milliseconds")], IntervalUnit::DayTime, - r"Cast error: Cannot cast 1 day 1.5 milliseconds to IntervalDayTime because the nanos part isn't multiple of milliseconds" + "Cast error: Cannot cast 1 day 1.5 milliseconds to IntervalDayTime because the nanos part isn't multiple of milliseconds" ); // overflow diff --git a/parquet-variant-compute/src/variant_get.rs b/parquet-variant-compute/src/variant_get.rs index 7528a5c8269c..7150992160fe 100644 --- a/parquet-variant-compute/src/variant_get.rs +++ b/parquet-variant-compute/src/variant_get.rs @@ -4862,7 +4862,7 @@ mod test { use arrow::datatypes::Int64Type; let string_array: ArrayRef = Arc::new(StringArray::from(vec![ - r"[[1, 2], [3]]", + "[[1, 2], [3]]", r#"[[4], "not a list", [5, 6]]"#, ])); let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap()); @@ -4940,7 +4940,7 @@ mod test { #[test] fn test_variant_get_list_like_unsafe_cast_preserves_null_elements() { - let string_array: ArrayRef = Arc::new(StringArray::from(vec![r"[1, null, 3]"])); + let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, null, 3]"])); let variant_array = ArrayRef::from(json_to_variant(&string_array).unwrap()); let cast_options = CastOptions { safe: false, diff --git a/parquet/src/arrow/arrow_writer/levels.rs b/parquet/src/arrow/arrow_writer/levels.rs index 0ce3fac49538..40417ef73c1d 100644 --- a/parquet/src/arrow/arrow_writer/levels.rs +++ b/parquet/src/arrow/arrow_writer/levels.rs @@ -2164,10 +2164,10 @@ mod tests { let expected = vec![ String::new(), String::new(), - r"[]".to_string(), - r"[{list: [3, ], integers: }]".to_string(), - r"[, {list: , integers: 5}]".to_string(), - r"[]".to_string(), + "[]".to_string(), + "[{list: [3, ], integers: }]".to_string(), + "[, {list: , integers: 5}]".to_string(), + "[]".to_string(), ]; let actual: Vec<_> = (0..6) diff --git a/parquet/tests/geospatial.rs b/parquet/tests/geospatial.rs index 4bc6a7decc55..28f4121283a1 100644 --- a/parquet/tests/geospatial.rs +++ b/parquet/tests/geospatial.rs @@ -437,7 +437,7 @@ mod test { // Geometry with default CRS (defaults to OGC:CRS84 per Parquet spec) (LogicalType::geometry(None), r#"{"crs":"OGC:CRS84"}"#), // Geometry with srid:0 should result in an unset (omitted) CRS - (LogicalType::geometry(Some("srid:0".to_string())), r"{}"), + (LogicalType::geometry(Some("srid:0".to_string())), "{}"), // Geometry with custom CRSes (authority:code and partial projjson) ( LogicalType::geometry(Some("EPSG:4267".to_string())), @@ -538,7 +538,7 @@ mod test { // Test cases: (extension metadata JSON, expected LogicalType) let test_cases = [ // Geometry with no CRS should be GEOMETRY(srid:0) - (r"{}", LogicalType::geometry(Some("srid:0".to_string()))), + ("{}", LogicalType::geometry(Some("srid:0".to_string()))), // Geometry with string CRS ( r#"{"crs":"EPSG:4267"}"#, From a50db5b48f14b49c91b1fa8fbb12f7a1ddcc9191 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 5 Aug 2026 18:27:06 +0200 Subject: [PATCH 12/13] Opt `arrow-cmp` into the workspace lints `arrow-cmp` was added after the workspace lints landed, so it was the only member without `[lints] workspace = true`. No fixes were needed: the crate is already clean under the full lint set. Co-Authored-By: Claude Opus 5 (1M context) --- arrow-cmp/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arrow-cmp/Cargo.toml b/arrow-cmp/Cargo.toml index bbeadb22abb6..5a66ab341915 100644 --- a/arrow-cmp/Cargo.toml +++ b/arrow-cmp/Cargo.toml @@ -42,3 +42,6 @@ arrow-schema = { workspace = true } [dev-dependencies] half = { version = "2.1", default-features = false, features = ["num-traits"] } + +[lints] +workspace = true From 8d53be98eea07d282cf235e231993f0c552be29c Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 6 Aug 2026 08:57:59 +0200 Subject: [PATCH 13/13] Apply suggestion from @Jefffrey Co-authored-by: Jeffrey Vo --- arrow-avro/src/reader/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arrow-avro/src/reader/mod.rs b/arrow-avro/src/reader/mod.rs index 82ea9e6fd672..b8d84d5e53b6 100644 --- a/arrow-avro/src/reader/mod.rs +++ b/arrow-avro/src/reader/mod.rs @@ -4771,8 +4771,8 @@ mod test { { let idx = schema.index_of("array_of_union").unwrap(); let dt = schema.field(idx).data_type().clone(); - let (item_field, ()) = match &dt { - DataType::List(f) => (f.clone(), ()), + let item_field = match &dt { + DataType::List(f) => f.clone(), other => panic!("array_of_union must be List, got {other:?}"), }; let (uf, _) = match item_field.data_type() {