diff --git a/crates/pi-ast/src/ops.rs b/crates/pi-ast/src/ops.rs index 2149f52cd..bf80b7266 100644 --- a/crates/pi-ast/src/ops.rs +++ b/crates/pi-ast/src/ops.rs @@ -200,7 +200,7 @@ fn quote_bare_metavars(pattern: &str) -> String { } /// Byte index of the end of the UTF-8 character starting at `index`. -fn next_char_boundary(bytes: &[u8], index: usize) -> usize { +const fn next_char_boundary(bytes: &[u8], index: usize) -> usize { let mut end = index + 1; while end < bytes.len() && (bytes[end] & 0b1100_0000) == 0b1000_0000 { end += 1; diff --git a/crates/pi-natives/src/grep.rs b/crates/pi-natives/src/grep.rs index eb9e8f915..ff022ced8 100644 --- a/crates/pi-natives/src/grep.rs +++ b/crates/pi-natives/src/grep.rs @@ -814,7 +814,7 @@ pub(crate) struct GrepConfig { /// Check if `bytes[start]` (which must be `b'{'`) begins a valid repetition /// quantifier: `{N}`, `{N,}`, or `{N,M}` where N and M are decimal digits. /// Returns the byte index of the closing `}` if valid. -fn find_valid_repetition(bytes: &[u8], start: usize) -> Option { +const fn find_valid_repetition(bytes: &[u8], start: usize) -> Option { let len = bytes.len(); let mut i = start + 1; // Must start with at least one digit. @@ -847,7 +847,7 @@ fn find_valid_repetition(bytes: &[u8], start: usize) -> Option { None } -fn find_braced_escape_end(bytes: &[u8], start: usize) -> Option { +const fn find_braced_escape_end(bytes: &[u8], start: usize) -> Option { let mut i = start + 1; while i < bytes.len() { if bytes[i] == b'}' { diff --git a/crates/pi-natives/src/keys.rs b/crates/pi-natives/src/keys.rs index d62110182..3f97fb245 100644 --- a/crates/pi-natives/src/keys.rs +++ b/crates/pi-natives/src/keys.rs @@ -323,9 +323,7 @@ pub fn matches_kitty_sequence( && base == expected_codepoint { let cp = parsed.codepoint; - let is_ascii_letter = u8::try_from(cp) - .ok() - .is_some_and(|b| b.is_ascii_alphabetic()); + let is_ascii_letter = u8::try_from(cp).is_ok_and(|b| b.is_ascii_alphabetic()); let is_known_symbol = is_symbol_key(cp); if !is_ascii_letter && !is_known_symbol { return true; @@ -637,9 +635,7 @@ fn matches_key_inner(bytes: &[u8], key_id: &str, kitty_protocol_active: bool) -> if let Some(base) = parsed_base && base == codepoint { - let is_ascii_letter = u8::try_from(parsed_codepoint) - .ok() - .is_some_and(|b| b.is_ascii_alphabetic()); + let is_ascii_letter = u8::try_from(parsed_codepoint).is_ok_and(|b| b.is_ascii_alphabetic()); let is_known_symbol = is_symbol_key(parsed_codepoint); if !is_ascii_letter && !is_known_symbol { return true; @@ -1389,9 +1385,7 @@ fn format_kitty_key(parsed: &ParsedKittySequence) -> Option> { text_codepoint } else { let cp = parsed.codepoint; - let is_ascii_letter = u8::try_from(cp) - .ok() - .is_some_and(|b| b.is_ascii_alphabetic()); + let is_ascii_letter = u8::try_from(cp).is_ok_and(|b| b.is_ascii_alphabetic()); let is_known_symbol = is_symbol_key(cp); if is_ascii_letter || is_known_symbol { cp diff --git a/crates/pi-natives/src/snapcompact.rs b/crates/pi-natives/src/snapcompact.rs index fa47c573e..800281e1a 100644 --- a/crates/pi-natives/src/snapcompact.rs +++ b/crates/pi-natives/src/snapcompact.rs @@ -410,7 +410,7 @@ fn fill_repeat_bands_rgb(pixels: &mut [u8], width: usize, height: usize, grid: & for copy in 1..grid.repeat { let band_top = (row * grid.repeat + copy) * grid.cell_h; for y in band_top..(band_top + grid.cell_h).min(height) { - for px in pixels[y * width * 3..(y + 1) * width * 3].chunks_exact_mut(3) { + for px in pixels[y * width * 3..(y + 1) * width * 3].as_chunks_mut::<3>().0 { px.copy_from_slice(&band); } } @@ -1302,7 +1302,7 @@ fn render_snapcompact_png_sync( render_bitmap(&text, src_w, src_h, font, &native, black_ink) }; let mut rgb = vec![0f32; src_w * src_h * 3]; - for (dst, &idx) in rgb.chunks_exact_mut(3).zip(&indexed) { + for (dst, &idx) in rgb.as_chunks_mut::<3>().0.iter_mut().zip(&indexed) { let [r, g, b] = PALETTE[idx as usize]; dst[0] = f32::from(r); dst[1] = f32::from(g); diff --git a/crates/pi-natives/src/text.rs b/crates/pi-natives/src/text.rs index 25da9cab1..cfcf8a185 100644 --- a/crates/pi-natives/src/text.rs +++ b/crates/pi-natives/src/text.rs @@ -405,7 +405,7 @@ fn ansi_seq_len_u16(data: &[u16], pos: usize) -> Option { } #[inline] -fn is_sgr_u16(seq: &[u16]) -> bool { +const fn is_sgr_u16(seq: &[u16]) -> bool { seq.len() >= 3 && seq[1] == b'[' as u16 && *seq.last().unwrap() == b'm' as u16 } diff --git a/crates/pi-shell/src/minimizer/filters/cargo.rs b/crates/pi-shell/src/minimizer/filters/cargo.rs index 71bf9dd02..b72fb73ce 100644 --- a/crates/pi-shell/src/minimizer/filters/cargo.rs +++ b/crates/pi-shell/src/minimizer/filters/cargo.rs @@ -745,7 +745,7 @@ mod tests { // Two separate groups, not merged let unused_pos = out.find("unused_variables").unwrap(); let clone_pos = out.find("clippy::redundant_clone").unwrap(); - assert!(unused_pos != clone_pos); + assert_ne!(unused_pos, clone_pos); } #[test] diff --git a/crates/pi-shell/src/minimizer/filters/go.rs b/crates/pi-shell/src/minimizer/filters/go.rs index 05b32bf5b..cd8ab928e 100644 --- a/crates/pi-shell/src/minimizer/filters/go.rs +++ b/crates/pi-shell/src/minimizer/filters/go.rs @@ -315,12 +315,12 @@ fn summarize_golangci_json(line: &str) -> Option { .get("Pos") .and_then(|pos| pos.get("Line")) .and_then(serde_json::Value::as_u64) - .map_or(0, |value| value); + .unwrap_or(0); let col_no = issue .get("Pos") .and_then(|pos| pos.get("Column")) .and_then(serde_json::Value::as_u64) - .map_or(0, |value| value); + .unwrap_or(0); let linter = issue .get("FromLinter") .and_then(|v| v.as_str()) diff --git a/crates/vendor/brush-builtins/src/complete.rs b/crates/vendor/brush-builtins/src/complete.rs index c837fded5..4445da13f 100644 --- a/crates/vendor/brush-builtins/src/complete.rs +++ b/crates/vendor/brush-builtins/src/complete.rs @@ -189,7 +189,7 @@ impl CommonCompleteCommandArgs { actions } - fn has_completion_spec(&self) -> bool { + const fn has_completion_spec(&self) -> bool { !self.options.is_empty() || !self.actions.is_empty() || self.glob_pattern.is_some() diff --git a/crates/vendor/brush-builtins/src/history.rs b/crates/vendor/brush-builtins/src/history.rs index e4aad4611..1bfc2dbd4 100644 --- a/crates/vendor/brush-builtins/src/history.rs +++ b/crates/vendor/brush-builtins/src/history.rs @@ -200,15 +200,12 @@ fn expand_history_args( let mut result = ExecutionResult::success(); for arg in args { - match expand_history_arg(history, arg) { - Ok(expanded) => { - writeln!(stdout, "{expanded}")?; - }, - Err(()) => { - writeln!(stderr, "history: {arg}: history expansion failed")?; - result = ExecutionResult::general_error(); - }, - } + if let Ok(expanded) = expand_history_arg(history, arg) { + writeln!(stdout, "{expanded}")?; + } else { + writeln!(stderr, "history: {arg}: history expansion failed")?; + result = ExecutionResult::general_error(); + } } Ok(result) diff --git a/crates/vendor/brush-builtins/src/mapfile.rs b/crates/vendor/brush-builtins/src/mapfile.rs index 779f60104..d9446b204 100644 --- a/crates/vendor/brush-builtins/src/mapfile.rs +++ b/crates/vendor/brush-builtins/src/mapfile.rs @@ -158,7 +158,7 @@ impl MapFileCommand { let array_index = self.origin.unwrap_or(0) + i64::try_from(entry_count)?; if let Some(callback) = &self.callback - && (entry_count + 1) % callback_group_size == 0 + && (entry_count + 1).is_multiple_of(callback_group_size) { let result = run_callback(callback, array_index, &line_str, context).await?; if !result.is_normal_flow() { diff --git a/crates/vendor/brush-builtins/src/trap.rs b/crates/vendor/brush-builtins/src/trap.rs index bfd5e170d..20a44dea6 100644 --- a/crates/vendor/brush-builtins/src/trap.rs +++ b/crates/vendor/brush-builtins/src/trap.rs @@ -78,7 +78,7 @@ impl TrapCommand { signal_type: TrapSignal, ) -> Result<(), brush_core::Error> { if let Some(handler) = context.shell.traps().get_handler(signal_type) { - writeln!(context.stdout(), "trap -- '{}' {signal_type}", &handler.command)?; + writeln!(context.stdout(), "trap -- '{}' {signal_type}", handler.command)?; } Ok(()) } diff --git a/crates/vendor/brush-builtins/src/umask.rs b/crates/vendor/brush-builtins/src/umask.rs index dff7552ae..e0bf12203 100644 --- a/crates/vendor/brush-builtins/src/umask.rs +++ b/crates/vendor/brush-builtins/src/umask.rs @@ -179,7 +179,7 @@ mod tests { use super::*; fn parse(mode: &str, current_umask: u32) -> u32 { - parse_symbolic_umask(mode, current_umask).unwrap() as u32 + u32::from(parse_symbolic_umask(mode, current_umask).unwrap()) } #[test] diff --git a/crates/vendor/brush-core/src/commands.rs b/crates/vendor/brush-core/src/commands.rs index 6362096f8..068c97d8e 100644 --- a/crates/vendor/brush-core/src/commands.rs +++ b/crates/vendor/brush-core/src/commands.rs @@ -1018,7 +1018,7 @@ pub enum ChildSessionAction { /// `child_stdin_is_terminal` arm before pipeline membership would ever matter. /// /// Foregrounding remains gated on `new_pg && child_stdin_is_terminal`. -pub fn child_session_action( +pub const fn child_session_action( new_pg: bool, child_stdin_is_terminal: bool, _in_pipeline_group: bool, diff --git a/crates/vendor/brush-core/src/completion.rs b/crates/vendor/brush-core/src/completion.rs index 690e04edc..fdd13db1a 100644 --- a/crates/vendor/brush-core/src/completion.rs +++ b/crates/vendor/brush-core/src/completion.rs @@ -1286,10 +1286,9 @@ fn try_get_variable_completions( return None; } (prefix, true) - } else if let Some(prefix) = token.strip_prefix('$') { - (prefix, false) } else { - return None; + let prefix = token.strip_prefix('$')?; + (prefix, false) }; // If there's a path separator, this is a path like $HOME/foo, not a variable to diff --git a/crates/vendor/brush-core/src/history.rs b/crates/vendor/brush-core/src/history.rs index 9a850baa1..7ff44df07 100644 --- a/crates/vendor/brush-core/src/history.rs +++ b/crates/vendor/brush-core/src/history.rs @@ -465,7 +465,8 @@ impl<'a> Iterator for Search<'a> { fn next(&mut self) -> Option { loop { - if let Some(index) = self.next_index { + { + let index = self.next_index?; // Make sure we haven't hit the end of the history. if index >= self.history.items.len() { return None; @@ -494,8 +495,6 @@ impl<'a> Iterator for Search<'a> { return Some(item); } } - } else { - return None; } } } diff --git a/crates/vendor/brush-core/src/interp.rs b/crates/vendor/brush-core/src/interp.rs index f92da46c6..c8ab3e092 100644 --- a/crates/vendor/brush-core/src/interp.rs +++ b/crates/vendor/brush-core/src/interp.rs @@ -133,7 +133,7 @@ impl ExecutionParameters { } /// Disables external-command output marking for this execution branch. - pub fn disable_command_output_marking(&mut self) { + pub const fn disable_command_output_marking(&mut self) { self.command_output_disabled = true; } @@ -1181,7 +1181,7 @@ impl Execute for ast::CaseClauseCommand { // switched on, but that's not it. if shell.options().print_commands_and_arguments { shell - .trace_command(params, std::format!("case {} in", &self.value)) + .trace_command(params, std::format!("case {} in", self.value)) .await; } diff --git a/crates/vendor/brush-core/src/sys/fs.rs b/crates/vendor/brush-core/src/sys/fs.rs index 092ebda8e..21f8ce517 100644 --- a/crates/vendor/brush-core/src/sys/fs.rs +++ b/crates/vendor/brush-core/src/sys/fs.rs @@ -5,8 +5,8 @@ use std::{ path::{Path, PathBuf}, }; -/// Normalizes shell-facing path aliases before std::fs sees them. -pub fn normalize_shell_path(path: &Path) -> Cow<'_, Path> { +/// Normalizes shell-facing path aliases before `std::fs` sees them. +pub const fn normalize_shell_path(path: &Path) -> Cow<'_, Path> { #[cfg(windows)] { translate_unix_drive_path(path).map_or(Cow::Borrowed(path), Cow::Owned) @@ -18,7 +18,7 @@ pub fn normalize_shell_path(path: &Path) -> Cow<'_, Path> { } /// Returns a Windows drive root for a shell pattern that starts with an MSYS/WSL drive alias. -pub fn pattern_drive_alias_root( +pub const fn pattern_drive_alias_root( starts_with_forward_slash: bool, first: &str, second: Option<&str>, @@ -72,7 +72,7 @@ fn drive_root_path(drive: u8) -> PathBuf { } #[cfg(any(windows, test))] -fn is_ascii_drive_component(value: &str) -> bool { +const fn is_ascii_drive_component(value: &str) -> bool { value.len() == 1 && value.as_bytes()[0].is_ascii_alphabetic() } @@ -122,6 +122,42 @@ const fn is_path_separator(byte: u8) -> bool { byte == b'/' || byte == b'\\' } +pub use super::platform::fs::*; + +/// Extension trait for path-related filesystem operations. +pub trait PathExt { + /// Returns true if the path exists and is readable by the current user. + fn readable(&self) -> bool; + /// Returns true if the path exists and is writable by the current user. + fn writable(&self) -> bool; + /// Returns true if the path exists and is executable by the current user. + /// + /// On Windows, this returns true if *either* the path itself is a file with + /// a `PATHEXT` extension *or* appending some `PATHEXT` extension resolves + /// to an existing file. To recover the actual on-disk path in the + /// latter case, use [`resolve_executable`] which takes ownership + /// and avoids copies on platforms where no resolution is needed. + fn executable(&self) -> bool; + + /// Returns true if the path exists and is a block device. + fn exists_and_is_block_device(&self) -> bool; + /// Returns true if the path exists and is a character device. + fn exists_and_is_char_device(&self) -> bool; + /// Returns true if the path exists and is a FIFO (named pipe). + fn exists_and_is_fifo(&self) -> bool; + /// Returns true if the path exists and is a socket. + fn exists_and_is_socket(&self) -> bool; + /// Returns true if the path exists and has the setgid bit set. + fn exists_and_is_setgid(&self) -> bool; + /// Returns true if the path exists and has the setuid bit set. + fn exists_and_is_setuid(&self) -> bool; + /// Returns true if the path exists and has the sticky bit set. + fn exists_and_is_sticky_bit(&self) -> bool; + + /// Returns the device ID and inode number for the path. + fn get_device_and_inode(&self) -> Result<(u64, u64), crate::error::Error>; +} + #[cfg(test)] mod tests { use super::*; @@ -183,39 +219,3 @@ mod tests { assert_eq!(translate_unix_drive_path(Path::new("\\mnt\\d\\logs")).as_deref(), None); } } - -pub use super::platform::fs::*; - -/// Extension trait for path-related filesystem operations. -pub trait PathExt { - /// Returns true if the path exists and is readable by the current user. - fn readable(&self) -> bool; - /// Returns true if the path exists and is writable by the current user. - fn writable(&self) -> bool; - /// Returns true if the path exists and is executable by the current user. - /// - /// On Windows, this returns true if *either* the path itself is a file with - /// a `PATHEXT` extension *or* appending some `PATHEXT` extension resolves - /// to an existing file. To recover the actual on-disk path in the - /// latter case, use [`resolve_executable`] which takes ownership - /// and avoids copies on platforms where no resolution is needed. - fn executable(&self) -> bool; - - /// Returns true if the path exists and is a block device. - fn exists_and_is_block_device(&self) -> bool; - /// Returns true if the path exists and is a character device. - fn exists_and_is_char_device(&self) -> bool; - /// Returns true if the path exists and is a FIFO (named pipe). - fn exists_and_is_fifo(&self) -> bool; - /// Returns true if the path exists and is a socket. - fn exists_and_is_socket(&self) -> bool; - /// Returns true if the path exists and has the setgid bit set. - fn exists_and_is_setgid(&self) -> bool; - /// Returns true if the path exists and has the setuid bit set. - fn exists_and_is_setuid(&self) -> bool; - /// Returns true if the path exists and has the sticky bit set. - fn exists_and_is_sticky_bit(&self) -> bool; - - /// Returns the device ID and inode number for the path. - fn get_device_and_inode(&self) -> Result<(u64, u64), crate::error::Error>; -} diff --git a/crates/vendor/uu-find/src/find/matchers/exec.rs b/crates/vendor/uu-find/src/find/matchers/exec.rs index a207412b5..c7d0cc5b6 100644 --- a/crates/vendor/uu-find/src/find/matchers/exec.rs +++ b/crates/vendor/uu-find/src/find/matchers/exec.rs @@ -198,7 +198,7 @@ impl Matcher for MultiExecMatcher { writeln!( &mut stderr(), "Cannot fit a single argument {}: {}", - &path_to_file.to_string_lossy(), + path_to_file.to_string_lossy(), e ) .unwrap(); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 302c0cd54..12599ed66 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2026-04-29" +channel = "nightly-2026-07-28" components = ["rustfmt", "clippy", "rust-analyzer"] targets = ["x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"]