chore: Bump Rust to 1.87 (#30739)

Piotr Osiewicz created

Closes #ISSUE

Release Notes:

- N/A

Change summary

Cargo.toml                                                                             |  3 
Dockerfile-collab                                                                      |  2 
crates/agent/src/agent_configuration/configure_context_server_modal.rs                 |  1 
crates/assistant_tools/src/edit_agent/evals/fixtures/disable_cursor_blinking/before.rs |  2 
crates/collab/src/db.rs                                                                |  2 
crates/collab/src/main.rs                                                              |  1 
crates/collab/src/tests.rs                                                             |  4 
crates/debugger_ui/src/session/running/stack_frame_list.rs                             |  1 
crates/editor/src/code_context_menus.rs                                                |  2 
crates/editor/src/display_map/block_map.rs                                             |  1 
crates/editor/src/editor.rs                                                            |  6 
crates/editor/src/element.rs                                                           |  1 
crates/gpui/src/platform/linux/x11/clipboard.rs                                        |  2 
crates/language/src/language.rs                                                        |  4 
crates/outline_panel/src/outline_panel.rs                                              |  4 
crates/project/src/debugger/dap_store.rs                                               |  1 
crates/project/src/lsp_store.rs                                                        |  8 
crates/project/src/manifest_tree/path_trie.rs                                          |  2 
crates/project/src/project.rs                                                          |  4 
crates/project/src/task_store.rs                                                       |  2 
crates/project/src/terminals.rs                                                        |  2 
crates/project/src/worktree_store.rs                                                   |  2 
crates/project_panel/src/project_panel.rs                                              | 14 
crates/remote/src/ssh_session.rs                                                       |  2 
crates/repl/src/repl_editor.rs                                                         |  1 
crates/rpc/src/message_stream.rs                                                       |  1 
crates/task/src/debug_format.rs                                                        |  1 
rust-toolchain.toml                                                                    |  2 
28 files changed, 33 insertions(+), 45 deletions(-)

Detailed changes

Cargo.toml 🔗

@@ -788,6 +788,9 @@ let_underscore_future = "allow"
 # running afoul of the borrow checker.
 too_many_arguments = "allow"
 
+# We often have large enum variants yet we rarely actually bother with splitting them up.
+large_enum_variant = "allow"
+
 [workspace.metadata.cargo-machete]
 ignored = [
     "bindgen",

Dockerfile-collab 🔗

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

crates/collab/src/db.rs 🔗

@@ -543,7 +543,7 @@ pub struct MembershipUpdated {
 
 /// The result of setting a member's role.
 #[derive(Debug)]
-#[allow(clippy::large_enum_variant)]
+
 pub enum SetMemberRoleResult {
     InviteUpdated(Channel),
     MembershipUpdated(MembershipUpdated),

crates/collab/src/main.rs 🔗

@@ -36,6 +36,7 @@ use util::{ResultExt as _, maybe};
 const VERSION: &str = env!("CARGO_PKG_VERSION");
 const REVISION: Option<&'static str> = option_env!("GITHUB_SHA");
 
+#[expect(clippy::result_large_err)]
 #[tokio::main]
 async fn main() -> Result<()> {
     if let Err(error) = env::load_dotenv() {

crates/collab/src/tests.rs 🔗

@@ -36,8 +36,8 @@ fn room_participants(room: &Entity<Room>, cx: &mut TestAppContext) -> RoomPartic
     room.read_with(cx, |room, _| {
         let mut remote = room
             .remote_participants()
-            .iter()
-            .map(|(_, participant)| participant.user.github_login.clone())
+            .values()
+            .map(|participant| participant.user.github_login.clone())
             .collect::<Vec<_>>();
         let mut pending = room
             .pending_participants()

crates/editor/src/code_context_menus.rs 🔗

@@ -40,7 +40,6 @@ pub const MENU_ASIDE_X_PADDING: Pixels = px(16.);
 pub const MENU_ASIDE_MIN_WIDTH: Pixels = px(260.);
 pub const MENU_ASIDE_MAX_WIDTH: Pixels = px(500.);
 
-#[allow(clippy::large_enum_variant)]
 pub enum CodeContextMenu {
     Completions(CompletionsMenu),
     CodeActions(CodeActionsMenu),
@@ -928,7 +927,6 @@ impl CodeActionContents {
     }
 }
 
-#[allow(clippy::large_enum_variant)]
 #[derive(Clone)]
 pub enum CodeActionsItem {
     Task(TaskSourceKind, ResolvedTask),

crates/editor/src/editor.rs 🔗

@@ -1311,7 +1311,7 @@ pub struct ActiveDiagnosticGroup {
 }
 
 #[derive(Debug, PartialEq, Eq)]
-#[allow(clippy::large_enum_variant)]
+
 pub(crate) enum ActiveDiagnostic {
     None,
     All,
@@ -20278,8 +20278,8 @@ impl EditorSnapshot {
         let participant_indices = collaboration_hub.user_participant_indices(cx);
         let collaborators_by_peer_id = collaboration_hub.collaborators(cx);
         let collaborators_by_replica_id = collaborators_by_peer_id
-            .iter()
-            .map(|(_, collaborator)| (collaborator.replica_id, collaborator))
+            .values()
+            .map(|collaborator| (collaborator.replica_id, collaborator))
             .collect::<HashMap<_, _>>();
         self.buffer_snapshot
             .selections_in_range(range, false)

crates/editor/src/element.rs 🔗

@@ -6393,7 +6393,6 @@ pub(crate) struct LineWithInvisibles {
     font_size: Pixels,
 }
 
-#[allow(clippy::large_enum_variant)]
 enum LineFragment {
     Text(ShapedLine),
     Element {

crates/gpui/src/platform/linux/x11/clipboard.rs 🔗

@@ -983,7 +983,7 @@ impl Clipboard {
         // format that the contents can be converted to
         format_atoms[0..IMAGE_FORMAT_COUNT].copy_from_slice(&image_format_atoms);
         format_atoms[IMAGE_FORMAT_COUNT..].copy_from_slice(&text_format_atoms);
-        debug_assert!(!format_atoms.iter().any(|&a| a == atom_none));
+        debug_assert!(!format_atoms.contains(&atom_none));
 
         let result = self.inner.read(&format_atoms, selection)?;
 

crates/language/src/language.rs 🔗

@@ -1858,9 +1858,9 @@ impl LanguageScope {
     pub fn language_allowed(&self, name: &LanguageServerName) -> bool {
         let config = &self.language.config;
         let opt_in_servers = &config.scope_opt_in_language_servers;
-        if opt_in_servers.iter().any(|o| *o == *name) {
+        if opt_in_servers.contains(name) {
             if let Some(over) = self.config_override() {
-                over.opt_into_language_servers.iter().any(|o| *o == *name)
+                over.opt_into_language_servers.contains(name)
             } else {
                 false
             }

crates/outline_panel/src/outline_panel.rs 🔗

@@ -1620,7 +1620,7 @@ impl OutlinePanel {
                                     .get(&external_file.buffer_id)
                                     .into_iter()
                                     .flat_map(|excerpts| {
-                                        excerpts.iter().map(|(excerpt_id, _)| {
+                                        excerpts.keys().map(|excerpt_id| {
                                             CollapsedEntry::Excerpt(
                                                 external_file.buffer_id,
                                                 *excerpt_id,
@@ -1641,7 +1641,7 @@ impl OutlinePanel {
                             entries.extend(
                                 self.excerpts.get(&file.buffer_id).into_iter().flat_map(
                                     |excerpts| {
-                                        excerpts.iter().map(|(excerpt_id, _)| {
+                                        excerpts.keys().map(|excerpt_id| {
                                             CollapsedEntry::Excerpt(file.buffer_id, *excerpt_id)
                                         })
                                     },

crates/project/src/lsp_store.rs 🔗

@@ -3415,7 +3415,6 @@ pub struct RemoteLspStore {
     upstream_project_id: u64,
 }
 
-#[allow(clippy::large_enum_variant)]
 pub(crate) enum LspStoreMode {
     Local(LocalLspStore),   // ssh host and collab host
     Remote(RemoteLspStore), // collab guest
@@ -8806,9 +8805,10 @@ impl LspStore {
                     })
                 });
 
-            let is_unnecessary = diagnostic.tags.as_ref().map_or(false, |tags| {
-                tags.iter().any(|tag| *tag == DiagnosticTag::UNNECESSARY)
-            });
+            let is_unnecessary = diagnostic
+                .tags
+                .as_ref()
+                .map_or(false, |tags| tags.contains(&DiagnosticTag::UNNECESSARY));
 
             if is_supporting {
                 supporting_diagnostics.insert(

crates/project/src/manifest_tree/path_trie.rs 🔗

@@ -98,7 +98,7 @@ impl<Label: Ord + Clone> RootPathTrie<Label> {
             };
         }
         if !current.labels.is_empty() {
-            (callback)(&current.worktree_relative_path, &current.labels);
+            let _ = (callback)(&current.worktree_relative_path, &current.labels);
         }
     }
 

crates/project/src/project.rs 🔗

@@ -3653,7 +3653,7 @@ impl Project {
             let mut buffer_count = 0;
             let mut limit_reached = false;
             let query = Arc::new(query);
-            let mut chunks = matching_buffers_rx.ready_chunks(64);
+            let chunks = matching_buffers_rx.ready_chunks(64);
 
             // Now that we know what paths match the query, we will load at most
             // 64 buffers at a time to avoid overwhelming the main thread. For each
@@ -4392,7 +4392,7 @@ impl Project {
         envelope: TypedEnvelope<proto::LanguageServerPromptRequest>,
         mut cx: AsyncApp,
     ) -> Result<proto::LanguageServerPromptResponse> {
-        let (tx, mut rx) = smol::channel::bounded(1);
+        let (tx, rx) = smol::channel::bounded(1);
         let actions: Vec<_> = envelope
             .payload
             .actions

crates/project/src/task_store.rs 🔗

@@ -21,7 +21,7 @@ use crate::{
     worktree_store::WorktreeStore,
 };
 
-#[allow(clippy::large_enum_variant)] // platform-dependent warning
+// platform-dependent warning
 pub enum TaskStore {
     Functional(StoreState),
     Noop,

crates/project/src/terminals.rs 🔗

@@ -24,7 +24,7 @@ pub struct Terminals {
 }
 
 /// Terminals are opened either for the users shell, or to run a task.
-#[allow(clippy::large_enum_variant)]
+
 #[derive(Debug)]
 pub enum TerminalKind {
     /// Run a shell at the given path (or $HOME if None)

crates/project/src/worktree_store.rs 🔗

@@ -876,7 +876,7 @@ impl WorktreeStore {
 
     async fn filter_paths(
         fs: &Arc<dyn Fs>,
-        mut input: Receiver<MatchingEntry>,
+        input: Receiver<MatchingEntry>,
         query: &SearchQuery,
     ) -> Result<()> {
         let mut input = pin!(input);

crates/project_panel/src/project_panel.rs 🔗

@@ -2854,12 +2854,9 @@ impl ProjectPanel {
                 }
                 let precedes_new_entry = if let Some(new_entry_id) = new_entry_parent_id {
                     entry.id == new_entry_id || {
-                        self.ancestors.get(&entry.id).map_or(false, |entries| {
-                            entries
-                                .ancestors
-                                .iter()
-                                .any(|entry_id| *entry_id == new_entry_id)
-                        })
+                        self.ancestors
+                            .get(&entry.id)
+                            .map_or(false, |entries| entries.ancestors.contains(&new_entry_id))
                     }
                 } else {
                     false
@@ -3369,10 +3366,7 @@ impl ProjectPanel {
                                     .ancestors
                                     .get(&entry.id)
                                     .is_some_and(|auto_folded_dirs| {
-                                        auto_folded_dirs
-                                            .ancestors
-                                            .iter()
-                                            .any(|entry_id| *entry_id == edit_state.entry_id)
+                                        auto_folded_dirs.ancestors.contains(&edit_state.entry_id)
                                     })
                         };
 

crates/remote/src/ssh_session.rs 🔗

@@ -925,7 +925,7 @@ impl SshRemoteClient {
 
                             if missed_heartbeats != 0 {
                                 missed_heartbeats = 0;
-                                this.update(cx, |this, mut cx| {
+                                let _ =this.update(cx, |this, mut cx| {
                                     this.handle_heartbeat_result(missed_heartbeats, &mut cx)
                                 })?;
                             }

crates/repl/src/repl_editor.rs 🔗

@@ -170,7 +170,6 @@ pub fn run(
     anyhow::Ok(())
 }
 
-#[allow(clippy::large_enum_variant)]
 pub enum SessionSupport {
     ActiveSession(Entity<Session>),
     Inactive(KernelSpecification),

crates/rpc/src/message_stream.rs 🔗

@@ -20,7 +20,6 @@ pub struct MessageStream<S> {
     encoding_buffer: Vec<u8>,
 }
 
-#[allow(clippy::large_enum_variant)]
 #[derive(Debug)]
 pub enum Message {
     Envelope(Envelope),

crates/task/src/debug_format.rs 🔗

@@ -186,7 +186,6 @@ impl From<AttachRequest> for DebugRequest {
 
 #[derive(Deserialize, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)]
 #[serde(untagged)]
-#[allow(clippy::large_enum_variant)]
 pub enum BuildTaskDefinition {
     ByName(SharedString),
     Template {

rust-toolchain.toml 🔗

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