Zed compiled on Fedora 44 x86_64 crashes with following error when opening a file that requires syntax highlighting: 2026-05-01T00:03:14+02:00 ERROR [crashes] thread 'main' panicked at /builddir/build/BUILD/zed-1.0.0-build/zed-1.0.0/crates/zed/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-c-api-impl-36.0.6/src/types/val.rs:40:14: unexpected kind: 129... Reproducible: Always Steps to Reproduce: 1. Install build dependencies: sudo dnf install rust cargo alsa-lib-devel fontconfig-devel wayland-devel libxkbcommon-x11-devel openssl-devel libzstd-devel perl-FindBin perl-IPC-Cmd perl-File-Compare perl-File-Copy perl-lib vulkan-loader libcurl-devel clang cmake 2. Download https://github.com/zed-industries/zed/archive/refs/tags/v1.0.0.tar.gz 3. Build and run cargo run --release 4. Run it 5. Open a file that requires syntax highlighting Actual Results: Zed panics Expected Results: Zed must not panic. Additional Information: This does not happen in Zed compiled on Fedora 43. It seems that the only difference is the version of LLVM used by rustc: Fedora 43 (Zed works): $ rustc -Vv rustc 1.95.0 (59807616e 2026-04-14) (Fedora 1.95.0-1.fc43) binary: rustc commit-hash: 59807616e1fa2540724bfbac14d7976d7e4a3860 commit-date: 2026-04-14 host: x86_64-unknown-linux-gnu release: 1.95.0 LLVM version: 21.1.8 Fedora 44 (Zed panics): $ rustc -Vv rustc 1.95.0 (59807616e 2026-04-14) (Fedora 1.95.0-1.fc44) binary: rustc commit-hash: 59807616e1fa2540724bfbac14d7976d7e4a3860 commit-date: 2026-04-14 host: x86_64-unknown-linux-gnu release: 1.95.0 LLVM version: 22.1.1 Also see https://github.com/zed-industries/zed/issues/54586#issuecomment-4301686401
I experimented a bit more and now it looks like this problem might be not related to rust at all. Zed stops panicking when compiled with CC=clang CXX=clang++. It looks like some C or C++ code from one of the dependencies is compiled with gcc by default and this somehow leads to a FFI problem. So maybe this is a gcc 16 bug instead.
Oh, completely forgot to add this: gcc version is x86_64 0:16.0.1-0.10.fc44.
The upstream Rust 1.95.0 build (i.e. from rustup) is also using LLVM 22 -- would you be willing to try that on both F43 and F44? That way the Rust toolchain is constant while only the GNU toolchain parts change.
> The upstream Rust 1.95.0 build (i.e. from rustup) is also using LLVM 22 -- would you be willing to try that on both F43 and F44? That way the Rust toolchain is constant while only the GNU toolchain parts change. I tried to compile Zed with upstream Rust 1.95.0 and 1.94.1 (which is specified in Zed's rust-toolchain.toml) on F44, and both resulting binaries was panicking in a same way unless I built with CC=clan CXX-clang++. Have not tried upstream Rust 1.95.0 on F43 yet.
Upstream 1.94.1 was still on LLVM 21, so that also seems to rule out LLVM versions being the root cause if that fails on F44.
I tried to build Zed 1.0.0 on Fedora 43 using upstream Rust 1.95.0 both with no special env, with `CC=gcc CXX=g++` and with `CC=clang CXX=clang++`. All three zed binaries worked as expected without panic. gcc-15.2.1-7.fc43.x86_64 clang-21.1.8-4.fc43.x86_64 llvm-libs-21.1.8-4.fc43.x86_64 $ rustc +stable -Vv rustc 1.95.0 (59807616e 2026-04-14) binary: rustc commit-hash: 59807616e1fa2540724bfbac14d7976d7e4a3860 commit-date: 2026-04-14 host: x86_64-unknown-linux-gnu release: 1.95.0 LLVM version: 22.1.2
Bet that is because clang and rustc when using LLVM backend violates the x86_64 psABI. See the paragraph starting at https://gitlab.com/x86-psABIs/x86-64-ABI/-/blob/master/x86-64-ABI/low-level-sys-info.tex?ref_type=heads#L717 "When a value of a type of class INTEGER is returned or passed in a register or on the stack, the excess bits that would not be present in the memory representation of the type (see basic-types) are unspecified. That is, the consumer side of those values needs to extend them or use short form instruction variants. As in the memory representation, for a value of type _Bool, the lowest 8 bits are significant, together forming the value 0 or 1." If you compile simple long foo (unsigned char x) { return x; } with gcc, you get the expected movzbl %dil, %eax ret but clang emits incorrect movl %edi, %eax retq I haven't verified this, but looking at https://docs.rs/crate/wasmtime-c-api-impl/36.0.6/source/src/types/val.rs#11 and https://docs.rs/crate/wasmtime-c-api-impl/36.0.6/source/src/types/val.rs#31 that looks likely to happen, it is a function with 8-bit argument and if it is called from something gcc compiled which doesn't guarantee all the padding bits (unspecified by psABI) are zero and the LLVM compiled Rust function doesn't extend it and compares as say 32-bit instead of 8-bit, then one would get a failure like that. See also https://github.com/llvm/llvm-project/issues/43573
See also https://github.com/llvm/llvm-project/issues/12579 , this has been reported already back in 2012...
(In reply to Jakub Jelinek from comment #7) > "When a value of a type of class INTEGER is returned or passed in a register > or on the stack, the excess bits that would not be present in the > memory representation of the type (see basic-types) are > unspecified. That is, the consumer side of those values needs > to extend them or use short form instruction variants. As in the > memory representation, for a value of type _Bool, the lowest 8 > bits are significant, together forming the value 0 or 1." I’m not familiar with compilers or ABIs, but I’m curious why the panic log correctly displays `129`. If this were indeed the root cause, wouldn't we expect the printed value to be incorrect as well? Furthermore, according to the LLVM issue, GCC is supposed to implement zero-extension on both sides, which theoretically should have prevented this. I took a quick look at the GCC 16 changelog but didn't spot any relevant changes.
I can't verify myself, the steps to reproduce aren't sufficient (I know very little about Rust, don't know what Zed is, how to run it, on what, ...). But guess you can test yourself, under debugger put a breakpoint on the into_valtype function (at its start ideally) and see what value is passed in %rdi register and what are the callers (backtrace) and which of them is built by gcc rather than rustc or clang. As for the printing, one thing is comparison which could be done using say 32-bit or 64-bit comparison (and thus compare also the padding bits in there), another is the actual printing of the value and that can be printing just the lowest 8 bits and not the rest.