Use `u64` instead of `usize` in `ElementId` (#29493)

Michael Sloan created

Truncation to a 32 bit `usize` could cause two distinct IDs to be
considered the same element.

Release Notes:

- N/A

Change summary

crates/agent/src/context.rs                              |  5 -
crates/agent/src/context_picker.rs                       |  2 
crates/agent/src/context_picker/file_context_picker.rs   |  2 
crates/agent/src/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(-)

Detailed changes

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 {

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,

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,

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),
         ))
     }
 }

crates/editor/src/display_map/block_map.rs 🔗

@@ -65,7 +65,7 @@ pub struct CustomBlockId(pub usize);
 
 impl From<CustomBlockId> for ElementId {
     fn from(val: CustomBlockId) -> Self {
-        ElementId::Integer(val.0)
+        val.0.into()
     }
 }
 

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<std::path::Path>),
 }
 
+impl ElementId {
+    /// Constructs an `ElementId::NamedInteger` from a name and `usize`.
+    pub fn named_usize(name: impl Into<SharedString>, 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<SharedString> for ElementId {
 
 impl From<usize> for ElementId {
     fn from(id: usize) -> Self {
-        ElementId::Integer(id)
+        ElementId::Integer(id as u64)
     }
 }
 
 impl From<i32> 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<Uuid> 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())
     }
 }
 

crates/markdown/src/markdown.rs 🔗

@@ -1167,7 +1167,7 @@ fn render_copy_code_block_button(
     markdown: Entity<Markdown>,
     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(),

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;