Switch from Arc/RwLock to Rc/RefCell for CodeContextMenu (#22035)

`CodeContextMenu` is always accessed on one thread, so only `Rc`s and
`Rc<RefCell<_>>` are needed. There should be tiny performance benefits
from this. The main benefit of this is that when seeing code accessing a
`RwLock` it would be reasonable to wonder whether it will block. The
only potential downside is the potential for panics due to overlapping
borrows of the RefCells. I think this is an acceptable risk because most
errors of this nature will be local or will be caught by clippy via the
check for holding a RefCell reference over an `await`.

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2024-12-16 01:50:21 -07:00 committed by GitHub
parent 7b721efe2c
commit a94afbc062
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 108 additions and 93 deletions

View file

@ -1,4 +1,5 @@
use std::{cell::Cell, cmp::Reverse, ops::Range, sync::Arc};
use std::cell::RefCell;
use std::{cell::Cell, cmp::Reverse, ops::Range, rc::Rc};
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
@ -11,7 +12,6 @@ use language::{CodeLabel, Documentation};
use lsp::LanguageServerId;
use multi_buffer::{Anchor, ExcerptId};
use ordered_float::OrderedFloat;
use parking_lot::RwLock;
use project::{CodeAction, Completion, TaskSourceKind};
use task::ResolvedTask;
use ui::{
@ -137,9 +137,9 @@ pub struct CompletionsMenu {
sort_completions: bool,
pub initial_position: Anchor,
pub buffer: Model<Buffer>,
pub completions: Arc<RwLock<Box<[Completion]>>>,
match_candidates: Arc<[StringMatchCandidate]>,
pub matches: Arc<[StringMatch]>,
pub completions: Rc<RefCell<Box<[Completion]>>>,
match_candidates: Rc<[StringMatchCandidate]>,
pub matches: Rc<[StringMatch]>,
pub selected_item: usize,
scroll_handle: UniformListScrollHandle,
resolve_completions: bool,
@ -169,7 +169,7 @@ impl CompletionsMenu {
initial_position,
buffer,
show_completion_documentation,
completions: Arc::new(RwLock::new(completions)),
completions: RefCell::new(completions).into(),
match_candidates,
matches: Vec::new().into(),
selected_item: 0,
@ -223,7 +223,7 @@ impl CompletionsMenu {
sort_completions,
initial_position: selection.start,
buffer,
completions: Arc::new(RwLock::new(completions)),
completions: RefCell::new(completions).into(),
match_candidates,
matches,
selected_item: 0,
@ -329,13 +329,13 @@ impl CompletionsMenu {
workspace: Option<WeakView<Workspace>>,
cx: &mut ViewContext<Editor>,
) -> AnyElement {
let completions = self.completions.borrow_mut();
let show_completion_documentation = self.show_completion_documentation;
let widest_completion_ix = self
.matches
.iter()
.enumerate()
.max_by_key(|(_, mat)| {
let completions = self.completions.read();
let completion = &completions[mat.candidate_id];
let documentation = &completion.documentation;
@ -350,14 +350,12 @@ impl CompletionsMenu {
})
.map(|(ix, _)| ix);
let completions = self.completions.clone();
let matches = self.matches.clone();
let selected_item = self.selected_item;
let style = style.clone();
let multiline_docs = if show_completion_documentation {
let mat = &self.matches[selected_item];
match &self.completions.read()[mat.candidate_id].documentation {
match &completions[mat.candidate_id].documentation {
Some(Documentation::MultiLinePlainText(text)) => {
Some(div().child(SharedString::from(text.clone())))
}
@ -401,13 +399,16 @@ impl CompletionsMenu {
.occlude()
});
drop(completions);
let completions = self.completions.clone();
let matches = self.matches.clone();
let list = uniform_list(
cx.view().clone(),
"completions",
matches.len(),
move |_editor, range, cx| {
let start_ix = range.start;
let completions_guard = completions.read();
let completions_guard = completions.borrow_mut();
matches[range]
.iter()
@ -548,7 +549,7 @@ impl CompletionsMenu {
}
}
let completions = self.completions.read();
let completions = self.completions.borrow_mut();
if self.sort_completions {
matches.sort_unstable_by_key(|mat| {
// We do want to strike a balance here between what the language server tells us
@ -611,13 +612,13 @@ impl CompletionsMenu {
pub struct AvailableCodeAction {
pub excerpt_id: ExcerptId,
pub action: CodeAction,
pub provider: Arc<dyn CodeActionProvider>,
pub provider: Rc<dyn CodeActionProvider>,
}
#[derive(Clone)]
pub struct CodeActionContents {
pub tasks: Option<Arc<ResolvedTasks>>,
pub actions: Option<Arc<[AvailableCodeAction]>>,
pub tasks: Option<Rc<ResolvedTasks>>,
pub actions: Option<Rc<[AvailableCodeAction]>>,
}
impl CodeActionContents {
@ -702,7 +703,7 @@ pub enum CodeActionsItem {
CodeAction {
excerpt_id: ExcerptId,
action: CodeAction,
provider: Arc<dyn CodeActionProvider>,
provider: Rc<dyn CodeActionProvider>,
},
}