From 815c6f5141bd556c0c642e08f658a9f614142410 Mon Sep 17 00:00:00 2001 From: dybucc <149513579+dybucc@users.noreply.github.com> Date: Tue, 3 Mar 2026 05:28:12 +0100 Subject: [PATCH] Add small alloc and lookup optimizations (#49041) A vector was being instantiated when the callsite only required an iterable. Another part of the code was performing multiple `contains()` lookups on a vector, and now it does it on a hashed set. This change has required some extra modifications across the codebase, but the affected sites are minimal and have been adjusted without major issues. The changes include some `Hash` derived implementations, which were proposed in the original `lsp-types` in [[1]], and maybe could be merged into Zed's fork. I went ahead and used a newtype with a custom `Hash` implementation that simply called on the structure's public members' implementations of `Hash`. The next change includes the removal of a check of the request capabilities after having already checked the same thing in the call to `to_lsp_params_or_response()` right before. The result of the `match` expression should already have returned a `Task::ready()` if the above mentioned function failed in performing the check that was later repeated and now removed. Finally, in the `edits_from_lsp()` method, stable sorting was being performed when only unstable sorting would suffice. The method can only sort with respect to the key data, and not the satellite data, as the latter are the literal strings of the edit. It matters not which one of a sequence of overlapping edits (with same ranges that thus resolve the edits for equivalence) should come before the other. [1]: https://github.com/gluon-lang/lsp-types/pull/295/changes#diff-b1a35a68f14e696205874893c07fd24fdb88882b47c23cc0e0c80a30c7d53759R540 - [ ] Tests or screenshots needed? - [ ] Code Reviewed - [ ] Manual QA Release Notes: - Removed a vector allocation where the callsite only required an iterable. - Improved multiple lookup operations when deserializing LSP edit operations. - Removed a double-check of capabilities after requesting and thus determining LSP capabilities. - Replaced stable sorting with unstable sorting of edits returned by the LSP. --- crates/editor/src/editor.rs | 2 +- crates/project/src/lsp_command.rs | 2 +- crates/project/src/lsp_store.rs | 6 +----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index efc3cddcc8549df6d832e726c77f2dda600adaa4..28d96e721257eaad898408cafba67f9f991e4909 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -15365,7 +15365,7 @@ impl Editor { pub fn select_all(&mut self, _: &SelectAll, window: &mut Window, cx: &mut Context) { self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx); self.change_selections(SelectionEffects::no_scroll(), window, cx, |s| { - s.select_ranges(vec![Anchor::min()..Anchor::max()]); + s.select_ranges([Anchor::min()..Anchor::max()]); }); } diff --git a/crates/project/src/lsp_command.rs b/crates/project/src/lsp_command.rs index bd94378433d7a8d992b913258999a6004b8031f2..67edd6c13ca5a850a99f28dee849718d9e7ec9ae 100644 --- a/crates/project/src/lsp_command.rs +++ b/crates/project/src/lsp_command.rs @@ -533,7 +533,7 @@ impl LspCommand for PerformRename { .rename_provider .is_some_and(|capability| match capability { OneOf::Left(enabled) => enabled, - OneOf::Right(_options) => true, + OneOf::Right(_) => true, }) } diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 45111adf9eb45c3a2595ab557e1fbe986d041610..75f9702e12cf31ce4f555940d7d1918884bbc22a 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -3158,7 +3158,7 @@ impl LocalLspStore { .map(|edit| (range_from_lsp(edit.range), edit.new_text)) .collect::>(); - lsp_edits.sort_by_key(|(range, _)| (range.start, range.end)); + lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end)); let mut lsp_edits = lsp_edits.into_iter().peekable(); let mut edits = Vec::new(); @@ -5001,10 +5001,6 @@ impl LspStore { }; let status = request.status(); - if !request.check_capabilities(language_server.adapter_server_capabilities()) { - return Task::ready(Ok(Default::default())); - } - let request_timeout = ProjectSettings::get_global(cx) .global_lsp_settings .get_request_timeout();