Title: Build fixes + macOS objc2 prep: gpui menus, tungstenite alignment, clippy cleanups
Overview
- Target: Build the
zedworkspace locally without errors. - Primary blocker:
jupyter-websocket-clientfailed to compile due to unresolved imports fromasync-tungsteniteand a follow‑on type mismatch caused by two differentasync-tungsteniteversions in the dependency graph. - Approach: Enable the correct feature on
async-tungstenitev0.31.0 required byjupyter-websocket-client, and isolate type identity by importing that version via an alias in thereplcrate where the websocket types are used. On macOS, standardize menus on raw Objective‑C, adopt icrate typed constants, and prepare for an objc2 migration.
Changes Since Last Update
-
Menus (platform.rs):
- Replaced Cocoa shims with raw Objective‑C for
NSMenu/NSMenuItem(create viaalloc/new/init+autorelease). - Added
add_menu_item(parent_menu, ...)that creates separator/action/submenu/system items and immediately adds them to the parent (correct retention and simpler lifetimes). - Rewired window/services menus with
setWindowsMenu:andsetServicesMenu:(msg_send!). - Removed the legacy
create_menu_itemhelper; no callers remain.
- Replaced Cocoa shims with raw Objective‑C for
-
objc2 dependency (Cargo):
- Made
objc2non‑optional on macOS and removed it from themacos-bladefeature set. - Enabled icrate features for NSMenu/NSMenuItem/NSStatusBar/NSScroller to support typed usage.
- Made
-
Other mac modules:
- status_item.rs: using icrate
NSSquareStatusItemLengthandNSViewLayerContentsRedrawDuringViewResize. - window_appearance.rs: switched to icrate
NSAppearanceName*and localized unsafe. - events.rs: localized unsafe blocks around typed getters; removed unnecessary casts.
- status_item.rs: using icrate
-
collab crate (clippy blockers):
- Removed conflicting manual
Nullableimpl in ids.rs; disambiguatedto_stringcalls in queries and tests to avoid trait collisions withsea_orm::Iden.
- Removed conflicting manual
Root Cause Analysis (build failures)
- Feature gating in
async-tungstenite0.31.0
jupyter-websocket-clientimportsasync_tungstenite::tokio, which is behind thetokio-runtimefeature inasync-tungstenitev0.31.0.- That feature wasn’t enabled in our graph, causing unresolved imports during compilation.
- Multiple
async-tungsteniteversions in the workspace
- The workspace depends on
async-tungstenitev0.29.1 (viaworkspace.dependencies). jupyter-websocket-clientdepends onasync-tungstenitev0.31.0.- When
replusedconnect_asyncand also consumed types produced byjupyter-websocket-client, we ended up with two differentWebSocketStreamtypes. Even if generics look the same, different crate versions yield distinct types, causing a mismatch.
Changes Implemented (build fixes)
- Alias
async-tungstenitev0.31.0 inreplwithtokio-runtimeenabled
- crates/repl/Cargo.toml:
async_tungstenite_031 = { package = "async-tungstenite", version = "0.31.0", default-features = false, features = ["tokio-runtime"] }
- Import the aliased crate in
repl
- crates/repl/src/kernels/remote_kernels.rs:
use async_tungstenite_031::tokio::connect_async;use async_tungstenite_031::tungstenite::{client::IntoClientRequest, http::HeaderValue};
Why this works
- Ensures
async_tungstenite::tokiois compiled in v0.31.0 by enablingtokio-runtime. - Aligns all websocket types used in
replwith those produced byjupyter-websocket-client(0.31.0), removing cross‑version type mismatches.
Validation
cargo check -p replpasses.cargo check -p zedpasses.cargo clippy -p gpui --all-targetsruns clean (shader cache on macOS may require elevated permissions).cargo clippy --workspace --all-targetsruns clean aftercollabfixes.
macOS objc2 Migration Prep
- Standardize raw Objective‑C messaging via
msg_sendin menus while adopting icrate typed constants where they bring clarity and safety. - Make
objc2unconditional on macOS to avoid feature mismatch; defer full typed migration to phased follow‑ups.
Planned Phases (high level)
- Phase 1 — Typed Menus: use
objc2::msg_send_id!,Retained<T>, typed setters; convert strings to icrateNSString. - Phase 2 — Typed NSString/Selectors: introduce a helper and replace remaining Cocoa
NSStringusage where practical. - Phase 3 — Beyond Menus: migrate services hooks, panels, pasteboard, and common NSApplication calls to objc2 typed APIs.
- Phase 4 — window.rs Sweep: re‑scan for typed replacements, confirm parity.
Risks and Mitigations
- Macro family mixing: avoid mixing
objcandobjc2macros within the same section; convert sections atomically and keep rawidinterop localized. - Retention/lifetimes: add items to parents immediately, prefer typed ownership where available.
- Rollback: current raw Objective‑C path is stable and can serve as fallback if needed.
Design Notes and Trade‑offs
- Minimal blast radius for build fixes: avoided a workspace‑wide
async-tungstenitebump; used a targeted alias to keep other crates stable. - Type identity: ensured websocket types come from a single crate version where the integration actually happens.
- Future: consider unifying
async-tungsteniteacross the workspace to 0.31.x after a dedicated validation sweep.
Follow‑ups / Backlog
- Unify
async-tungsteniteversions workspace‑wide; aligntokio-tungsteniteandtungsteniteaccordingly. - Continue objc2 typed migration across mac modules (services, panels, pasteboard, NSApplication).
- Replace remaining numeric constants with icrate typed constants where available.
- Optional: enforce single‑version policy via
cargo-deny(bans), add CI checks.
Files of Interest
- AGENTS.md: detailed narrative of the build fixes, macOS migration prep, validation steps, and plans.
- crates/repl/Cargo.toml: alias for
async-tungstenite0.31.0 withtokio-runtime. - crates/repl/src/kernels/remote_kernels.rs: imports updated to aliased 0.31.0 to match
jupyter-websocket-client. - macOS modules in
gpui: menus standardized on raw Objective‑C; icrate constants adopted; objc2 made unconditional.
Checklist
- cargo fmt
- cargo check -p gpui
- cargo clippy -p gpui --all-targets
- cargo clippy --workspace --all-targets
- Update AGENTS.md with scope, changes, and validation
Notes
- For shader compilation on macOS during clippy, elevated permissions may be needed due to shader cache writes.
ghPR text mirrors AGENTS.md for maximum reviewer context; future PRs can be shorter once objc2 migration stabilizes.