copilot: Remove an unwrap in URI parsing code (#32698)

Closes #32630

Release Notes:

- Fixed a potential crash when opening active modules in a debugger
session (with Copilot enabled).
This commit is contained in:
Piotr Osiewicz 2025-06-13 19:17:35 +02:00 committed by GitHub
parent cf129aa19d
commit e59fb2e16a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -26,6 +26,7 @@ use parking_lot::Mutex;
use request::StatusNotification; use request::StatusNotification;
use settings::SettingsStore; use settings::SettingsStore;
use sign_in::{reinstall_and_sign_in_within_workspace, sign_out_within_workspace}; use sign_in::{reinstall_and_sign_in_within_workspace, sign_out_within_workspace};
use std::collections::hash_map::Entry;
use std::{ use std::{
any::TypeId, any::TypeId,
env, env,
@ -731,42 +732,43 @@ impl Copilot {
return; return;
} }
registered_buffers let entry = registered_buffers.entry(buffer.entity_id());
.entry(buffer.entity_id()) if let Entry::Vacant(e) = entry {
.or_insert_with(|| { let Ok(uri) = uri_for_buffer(buffer, cx) else {
let uri: lsp::Url = uri_for_buffer(buffer, cx); return;
let language_id = id_for_language(buffer.read(cx).language()); };
let snapshot = buffer.read(cx).snapshot(); let language_id = id_for_language(buffer.read(cx).language());
server let snapshot = buffer.read(cx).snapshot();
.notify::<lsp::notification::DidOpenTextDocument>( server
&lsp::DidOpenTextDocumentParams { .notify::<lsp::notification::DidOpenTextDocument>(
text_document: lsp::TextDocumentItem { &lsp::DidOpenTextDocumentParams {
uri: uri.clone(), text_document: lsp::TextDocumentItem {
language_id: language_id.clone(), uri: uri.clone(),
version: 0, language_id: language_id.clone(),
text: snapshot.text(), version: 0,
}, text: snapshot.text(),
}, },
) },
.ok(); )
.ok();
RegisteredBuffer { e.insert(RegisteredBuffer {
uri, uri,
language_id, language_id,
snapshot, snapshot,
snapshot_version: 0, snapshot_version: 0,
pending_buffer_change: Task::ready(Some(())), pending_buffer_change: Task::ready(Some(())),
_subscriptions: [ _subscriptions: [
cx.subscribe(buffer, |this, buffer, event, cx| { cx.subscribe(buffer, |this, buffer, event, cx| {
this.handle_buffer_event(buffer, event, cx).log_err(); this.handle_buffer_event(buffer, event, cx).log_err();
}), }),
cx.observe_release(buffer, move |this, _buffer, _cx| { cx.observe_release(buffer, move |this, _buffer, _cx| {
this.buffers.remove(&weak_buffer); this.buffers.remove(&weak_buffer);
this.unregister_buffer(&weak_buffer); this.unregister_buffer(&weak_buffer);
}), }),
], ],
}
}); });
}
} }
} }
@ -798,7 +800,9 @@ impl Copilot {
language::BufferEvent::FileHandleChanged language::BufferEvent::FileHandleChanged
| language::BufferEvent::LanguageChanged => { | language::BufferEvent::LanguageChanged => {
let new_language_id = id_for_language(buffer.read(cx).language()); let new_language_id = id_for_language(buffer.read(cx).language());
let new_uri = uri_for_buffer(&buffer, cx); let Ok(new_uri) = uri_for_buffer(&buffer, cx) else {
return Ok(());
};
if new_uri != registered_buffer.uri if new_uri != registered_buffer.uri
|| new_language_id != registered_buffer.language_id || new_language_id != registered_buffer.language_id
{ {
@ -1068,11 +1072,13 @@ fn id_for_language(language: Option<&Arc<Language>>) -> String {
.unwrap_or_else(|| "plaintext".to_string()) .unwrap_or_else(|| "plaintext".to_string())
} }
fn uri_for_buffer(buffer: &Entity<Buffer>, cx: &App) -> lsp::Url { fn uri_for_buffer(buffer: &Entity<Buffer>, cx: &App) -> Result<lsp::Url, ()> {
if let Some(file) = buffer.read(cx).file().and_then(|file| file.as_local()) { if let Some(file) = buffer.read(cx).file().and_then(|file| file.as_local()) {
lsp::Url::from_file_path(file.abs_path(cx)).unwrap() lsp::Url::from_file_path(file.abs_path(cx))
} else { } else {
format!("buffer://{}", buffer.entity_id()).parse().unwrap() format!("buffer://{}", buffer.entity_id())
.parse()
.map_err(|_| ())
} }
} }