chore: Bump Rust version to 1.86 (#28021)

Piotr Osiewicz created

Closes #ISSUE

Release Notes:

- N/A

Change summary

Dockerfile-collab                                 | 2 +-
crates/agent/src/active_thread.rs                 | 2 +-
crates/collab/src/rpc.rs                          | 2 +-
crates/file_finder/src/new_path_prompt.rs         | 6 +++---
crates/git/src/status.rs                          | 2 +-
crates/git_ui/src/picker_prompt.rs                | 5 +----
crates/gpui/src/key_dispatch.rs                   | 2 +-
crates/gpui/src/platform/mac/metal_renderer.rs    | 2 +-
crates/language/src/buffer.rs                     | 2 +-
crates/language/src/language_registry.rs          | 2 +-
crates/project_panel/src/project_panel.rs         | 2 +-
crates/prompt_store/src/prompts.rs                | 6 +++++-
crates/rope/src/chunk.rs                          | 2 +-
crates/vim/src/motion.rs                          | 2 +-
crates/vim/src/test/neovim_backed_test_context.rs | 4 ++--
crates/zed/src/zed/open_listener.rs               | 2 +-
rust-toolchain.toml                               | 2 +-
17 files changed, 24 insertions(+), 23 deletions(-)

Detailed changes

Dockerfile-collab 🔗

@@ -1,6 +1,6 @@
 # syntax = docker/dockerfile:1.2
 
-FROM rust:1.81-bookworm as builder
+FROM rust:1.86-bookworm as builder
 WORKDIR app
 COPY . .
 

crates/agent/src/active_thread.rs 🔗

@@ -1429,7 +1429,7 @@ impl ActiveThread {
                 .segments
                 .iter()
                 .enumerate()
-                .last()
+                .next_back()
                 .filter(|(_, segment)| matches!(segment, RenderedMessageSegment::Thinking { .. }))
                 .map(|(index, _)| index)
         } else {

crates/collab/src/rpc.rs 🔗

@@ -984,7 +984,7 @@ impl Server {
         }
     }
 
-    pub async fn snapshot<'a>(self: &'a Arc<Self>) -> ServerSnapshot<'a> {
+    pub async fn snapshot(self: &Arc<Self>) -> ServerSnapshot {
         ServerSnapshot {
             connection_pool: ConnectionPoolGuard {
                 guard: self.connection_pool.lock(),

crates/file_finder/src/new_path_prompt.rs 🔗

@@ -150,14 +150,14 @@ impl Match {
 
                     text.push_str(dir_indicator);
                     highlights.push((
-                        offset..offset + dir_indicator.bytes().len(),
+                        offset..offset + dir_indicator.len(),
                         HighlightStyle::color(Color::Muted.color(cx)),
                     ));
                 }
             } else {
                 text.push_str(dir_indicator);
                 highlights.push((
-                    offset..offset + dir_indicator.bytes().len(),
+                    offset..offset + dir_indicator.len(),
                     HighlightStyle::color(Color::Muted.color(cx)),
                 ))
             }
@@ -186,7 +186,7 @@ impl Match {
             if suffix.ends_with('/') {
                 text.push_str(dir_indicator);
                 highlights.push((
-                    offset..offset + dir_indicator.bytes().len(),
+                    offset..offset + dir_indicator.len(),
                     HighlightStyle::color(Color::Muted.color(cx)),
                 ));
             }

crates/git/src/status.rs 🔗

@@ -462,7 +462,7 @@ impl FromStr for GitStatus {
                 if path.ends_with('/') {
                     return None;
                 }
-                let status = entry[0..2].as_bytes().try_into().unwrap();
+                let status = entry.as_bytes()[0..2].try_into().unwrap();
                 let status = FileStatus::from_bytes(status).log_err()?;
                 let path = RepoPath(Path::new(path).into());
                 Some((path, status))

crates/git_ui/src/picker_prompt.rs 🔗

@@ -44,10 +44,7 @@ pub fn prompt(
             })
             .ok();
 
-        match rx.await {
-            Ok(selection) => Some(selection),
-            Err(_) => None, // User cancelled
-        }
+        (rx.await).ok()
     })
 }
 

crates/gpui/src/key_dispatch.rs 🔗

@@ -488,7 +488,7 @@ impl DispatchTree {
             let (bindings, _) = self.bindings_for_input(&input[0..=last], dispatch_path);
             if !bindings.is_empty() {
                 to_replay.push(Replay {
-                    keystroke: input.drain(0..=last).last().unwrap(),
+                    keystroke: input.drain(0..=last).next_back().unwrap(),
                     bindings,
                 });
                 break;

crates/gpui/src/platform/mac/metal_renderer.rs 🔗

@@ -1211,7 +1211,7 @@ fn build_path_rasterization_pipeline_state(
 
 // Align to multiples of 256 make Metal happy.
 fn align_offset(offset: &mut usize) {
-    *offset = ((*offset + 255) / 256) * 256;
+    *offset = (*offset).div_ceil(256) * 256;
 }
 
 #[repr(C)]

crates/language/src/buffer.rs 🔗

@@ -2876,7 +2876,7 @@ impl BufferSnapshot {
             if let Some(range_to_truncate) = indent_ranges
                 .iter_mut()
                 .filter(|indent_range| indent_range.contains(&outdent_position))
-                .last()
+                .next_back()
             {
                 range_to_truncate.end = outdent_position;
             }

crates/language/src/language_registry.rs 🔗

@@ -680,7 +680,7 @@ impl LanguageRegistry {
         // `Path.extension()` returns None for files with a leading '.'
         // and no other extension which is not the desired behavior here,
         // as we want `.zshrc` to result in extension being `Some("zshrc")`
-        let extension = filename.and_then(|filename| filename.split('.').last());
+        let extension = filename.and_then(|filename| filename.split('.').next_back());
         let path_suffixes = [extension, filename, path.to_str()];
         let empty = GlobSet::empty();
 

crates/project_panel/src/project_panel.rs 🔗

@@ -3259,7 +3259,7 @@ impl ProjectPanel {
                                         .take(prefix_components)
                                         .collect::<PathBuf>();
                                     if let Some(last_component) =
-                                        Path::new(processing_filename).components().last()
+                                        Path::new(processing_filename).components().next_back()
                                     {
                                         new_path.push(last_component);
                                         previous_components.next();

crates/prompt_store/src/prompts.rs 🔗

@@ -241,7 +241,11 @@ impl PromptBuilder {
 
     fn register_built_in_templates(handlebars: &mut Handlebars) -> Result<()> {
         for path in Assets.list("prompts")? {
-            if let Some(id) = path.split('/').last().and_then(|s| s.strip_suffix(".hbs")) {
+            if let Some(id) = path
+                .split('/')
+                .next_back()
+                .and_then(|s| s.strip_suffix(".hbs"))
+            {
                 if let Some(prompt) = Assets.load(path.as_ref()).log_err().flatten() {
                     log::debug!("Registering built-in prompt template: {}", id);
                     let prompt = String::from_utf8_lossy(prompt.as_ref());

crates/rope/src/chunk.rs 🔗

@@ -906,7 +906,7 @@ mod tests {
             let first_line = text.split('\n').next().unwrap();
             assert_eq!(chunk.first_line_chars(), first_line.chars().count() as u32);
 
-            let last_line = text.split('\n').last().unwrap();
+            let last_line = text.split('\n').next_back().unwrap();
             assert_eq!(chunk.last_line_chars(), last_line.chars().count() as u32);
             assert_eq!(
                 chunk.last_line_len_utf16(),

crates/vim/src/motion.rs 🔗

@@ -2174,7 +2174,7 @@ fn matching(map: &DisplaySnapshot, display_point: DisplayPoint) -> DisplayPoint
 // https://neovim.io/doc/user/motion.html#N%25
 fn go_to_percentage(map: &DisplaySnapshot, point: DisplayPoint, count: usize) -> DisplayPoint {
     let total_lines = map.buffer_snapshot.max_point().row + 1;
-    let target_line = (count * total_lines as usize + 99) / 100;
+    let target_line = (count * total_lines as usize).div_ceil(100);
     let target_point = DisplayPoint::new(
         DisplayRow(target_line.saturating_sub(1) as u32),
         point.column(),

crates/vim/src/test/neovim_backed_test_context.rs 🔗

@@ -147,7 +147,7 @@ impl NeovimBackedTestContext {
             .name()
             .expect("thread is not named")
             .split(':')
-            .last()
+            .next_back()
             .unwrap()
             .to_string();
         Self {
@@ -171,7 +171,7 @@ impl NeovimBackedTestContext {
             .name()
             .expect("thread is not named")
             .split(':')
-            .last()
+            .next_back()
             .unwrap()
             .to_string();
         Self {

crates/zed/src/zed/open_listener.rs 🔗

@@ -103,7 +103,7 @@ impl OpenRequest {
         let mut parts = request_path.split('/');
         if parts.next() == Some("channel") {
             if let Some(slug) = parts.next() {
-                if let Some(id_str) = slug.split('-').last() {
+                if let Some(id_str) = slug.split('-').next_back() {
                     if let Ok(channel_id) = id_str.parse::<u64>() {
                         let Some(next) = parts.next() else {
                             self.join_channel = Some(channel_id);

rust-toolchain.toml 🔗

@@ -1,5 +1,5 @@
 [toolchain]
-channel = "1.85"
+channel = "1.86"
 profile = "minimal"
 components = [ "rustfmt", "clippy" ]
 targets = [