From 60ec55b1799d5d898921a230464ae361bfae85d9 Mon Sep 17 00:00:00 2001 From: Michael Sloan Date: Sat, 26 Apr 2025 20:31:25 -0600 Subject: [PATCH] Use `u64` instead of `usize` in `ElementId` (#29493) Truncation to a 32 bit `usize` could cause two distinct IDs to be considered the same element. Release Notes: - N/A --- crates/agent/src/context.rs | 5 ++-- crates/agent/src/context_picker.rs | 2 +- .../src/context_picker/file_context_picker.rs | 2 +- .../context_picker/symbol_context_picker.rs | 5 +--- crates/editor/src/display_map/block_map.rs | 2 +- crates/editor/src/display_map/fold_map.rs | 2 +- crates/gpui/src/window.rs | 25 ++++++++++++------- crates/markdown/src/markdown.rs | 2 +- crates/zeta/src/onboarding_modal.rs | 2 +- 9 files changed, 25 insertions(+), 22 deletions(-) diff --git a/crates/agent/src/context.rs b/crates/agent/src/context.rs index c9101c5615..ceed361159 100644 --- a/crates/agent/src/context.rs +++ b/crates/agent/src/context.rs @@ -1,5 +1,4 @@ use std::hash::{Hash, Hasher}; -use std::usize; use std::{ops::Range, path::Path, sync::Arc}; use collections::HashSet; @@ -85,7 +84,7 @@ impl AgentContext { /// ID created at time of context add, for use in ElementId. This is not the stable identity of a /// context, instead that's handled by the `PartialEq` and `Hash` impls of `AgentContextKey`. #[derive(Debug, Copy, Clone)] -pub struct ContextId(usize); +pub struct ContextId(u64); impl ContextId { pub fn zero() -> Self { @@ -93,7 +92,7 @@ impl ContextId { } fn for_lookup() -> Self { - ContextId(usize::MAX) + ContextId(u64::MAX) } pub fn post_inc(&mut self) -> Self { diff --git a/crates/agent/src/context_picker.rs b/crates/agent/src/context_picker.rs index 752f8a0af2..e8adb03ef3 100644 --- a/crates/agent/src/context_picker.rs +++ b/crates/agent/src/context_picker.rs @@ -388,7 +388,7 @@ impl ContextPicker { ContextMenuItem::custom_entry( move |_window, cx| { render_file_context_entry( - ElementId::NamedInteger("ctx-recent".into(), ix), + ElementId::named_usize("ctx-recent", ix), worktree_id, &path, &path_prefix, diff --git a/crates/agent/src/context_picker/file_context_picker.rs b/crates/agent/src/context_picker/file_context_picker.rs index 1dbd209850..a6b25e882e 100644 --- a/crates/agent/src/context_picker/file_context_picker.rs +++ b/crates/agent/src/context_picker/file_context_picker.rs @@ -169,7 +169,7 @@ impl PickerDelegate for FileContextPickerDelegate { .inset(true) .toggle_state(selected) .child(render_file_context_entry( - ElementId::NamedInteger("file-ctx-picker".into(), ix), + ElementId::named_usize("file-ctx-picker", ix), WorktreeId::from_usize(mat.worktree_id), &mat.path, &mat.path_prefix, diff --git a/crates/agent/src/context_picker/symbol_context_picker.rs b/crates/agent/src/context_picker/symbol_context_picker.rs index bc70c237a4..dfe915a94b 100644 --- a/crates/agent/src/context_picker/symbol_context_picker.rs +++ b/crates/agent/src/context_picker/symbol_context_picker.rs @@ -171,10 +171,7 @@ impl PickerDelegate for SymbolContextPickerDelegate { let mat = &self.matches[ix]; Some(ListItem::new(ix).inset(true).toggle_state(selected).child( - render_symbol_context_entry( - ElementId::NamedInteger("symbol-ctx-picker".into(), ix), - mat, - ), + render_symbol_context_entry(ElementId::named_usize("symbol-ctx-picker", ix), mat), )) } } diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 39bc41b9dc..5a6e0109c2 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -65,7 +65,7 @@ pub struct CustomBlockId(pub usize); impl From for ElementId { fn from(val: CustomBlockId) -> Self { - ElementId::Integer(val.0) + val.0.into() } } diff --git a/crates/editor/src/display_map/fold_map.rs b/crates/editor/src/display_map/fold_map.rs index a8b5d135fc..8281b7642c 100644 --- a/crates/editor/src/display_map/fold_map.rs +++ b/crates/editor/src/display_map/fold_map.rs @@ -1065,7 +1065,7 @@ pub struct FoldId(usize); impl From for ElementId { fn from(val: FoldId) -> Self { - ElementId::Integer(val.0) + val.0.into() } } diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 2bbb984e50..c9af06f7cc 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -4046,7 +4046,7 @@ pub enum ElementId { /// The ID of a View element View(EntityId), /// An integer ID. - Integer(usize), + Integer(u64), /// A string based ID. Name(SharedString), /// A UUID. @@ -4054,11 +4054,18 @@ pub enum ElementId { /// An ID that's equated with a focus handle. FocusHandle(FocusId), /// A combination of a name and an integer. - NamedInteger(SharedString, usize), + NamedInteger(SharedString, u64), /// A path Path(Arc), } +impl ElementId { + /// Constructs an `ElementId::NamedInteger` from a name and `usize`. + pub fn named_usize(name: impl Into, integer: usize) -> ElementId { + Self::NamedInteger(name.into(), integer as u64) + } +} + impl Display for ElementId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -4089,13 +4096,13 @@ impl TryInto for ElementId { impl From for ElementId { fn from(id: usize) -> Self { - ElementId::Integer(id) + ElementId::Integer(id as u64) } } impl From for ElementId { fn from(id: i32) -> Self { - Self::Integer(id as usize) + Self::Integer(id as u64) } } @@ -4125,25 +4132,25 @@ impl<'a> From<&'a FocusHandle> for ElementId { impl From<(&'static str, EntityId)> for ElementId { fn from((name, id): (&'static str, EntityId)) -> Self { - ElementId::NamedInteger(name.into(), id.as_u64() as usize) + ElementId::NamedInteger(name.into(), id.as_u64()) } } impl From<(&'static str, usize)> for ElementId { fn from((name, id): (&'static str, usize)) -> Self { - ElementId::NamedInteger(name.into(), id) + ElementId::NamedInteger(name.into(), id as u64) } } impl From<(SharedString, usize)> for ElementId { fn from((name, id): (SharedString, usize)) -> Self { - ElementId::NamedInteger(name, id) + ElementId::NamedInteger(name, id as u64) } } impl From<(&'static str, u64)> for ElementId { fn from((name, id): (&'static str, u64)) -> Self { - ElementId::NamedInteger(name.into(), id as usize) + ElementId::NamedInteger(name.into(), id) } } @@ -4155,7 +4162,7 @@ impl From for ElementId { impl From<(&'static str, u32)> for ElementId { fn from((name, id): (&'static str, u32)) -> Self { - ElementId::NamedInteger(name.into(), id as usize) + ElementId::NamedInteger(name.into(), id.into()) } } diff --git a/crates/markdown/src/markdown.rs b/crates/markdown/src/markdown.rs index 52376fe232..134a19a65b 100644 --- a/crates/markdown/src/markdown.rs +++ b/crates/markdown/src/markdown.rs @@ -1167,7 +1167,7 @@ fn render_copy_code_block_button( markdown: Entity, cx: &App, ) -> impl IntoElement { - let id = ElementId::NamedInteger("copy-markdown-code".into(), id); + let id = ElementId::named_usize("copy-markdown-code", id); let was_copied = markdown.read(cx).copied_code_blocks.contains(&id); IconButton::new( id.clone(), diff --git a/crates/zeta/src/onboarding_modal.rs b/crates/zeta/src/onboarding_modal.rs index abd409dd78..682e5f282f 100644 --- a/crates/zeta/src/onboarding_modal.rs +++ b/crates/zeta/src/onboarding_modal.rs @@ -254,7 +254,7 @@ impl Render for ZedPredictModal { .text_color(text_color) .child("tab") .with_animation( - ElementId::Integer(n), + n, Animation::new(Duration::from_secs(2)).repeat(), move |tab, delta| { let delta = (delta - 0.15 * n as f32) / 0.7;