Skip to content

Windows: freshly-built melior-macro proc-macro fails to load (E0463) — rustc's stale bundled libwinpthread-1.dll shadows MSYS2's GCC-16 runtime #589

Description

@nebasuke

Summary

main's Slang Tests → Windows leg has been deterministically red since #557 merged:

   Compiling melior-macro v0.19.5 (…melior?rev=52fa2611…)
   Compiling melior v0.26.9 (…melior?rev=52fa2611…)
error[E0463]: can't find crate for `melior_macro`
 --> …\melior\src\ir\attribute\attribute_like.rs:5:5
  |
5 | use melior_macro::attribute_check_functions;
error: could not compile `melior` (lib) due to 1 previous error

Windows-only; all other platforms pass. Failing runs: 29910202004 (#557 merge), 29912409528 (0.1.6 bump). This is the load-time sequel to #550's link-time problem: same "CI is one cache-fingerprint change from breaking" structure, and the fingerprint change (a melior rev bump) arrived first here.

Root cause (confirmed by PE import/export analysis, no Windows runner needed)

melior-macro is a proc-macro ([lib] proc-macro = true) that links LLVM C++ via tblgen (features = ["llvm21-0"]). Since the #550 workaround switched Windows test builds to shared libstdc++, the built melior_macro.dll depends on GCC 16's libstdc++-6.dll at load time.

rustc loads proc-macros via libloading::Library::new → LoadLibraryExW(path, 0) → the default Windows DLL search order: application directory (rustc's sysroot bin/) → System32 → cwd → PATH. The chain that fails:

  1. The x86_64-pc-windows-gnu rustc dist ships its own libgcc_s_seh-1.dll and libwinpthread-1.dll in the sysroot bin/ next to rustc.exe. The application directory beats PATH, so these stale copies win over MSYS2's /mingw64/bin for every dependency in the proc-macro's load chain.
  2. MSYS2 GCC 16's libstdc++-6.dll (mingw-w64-x86_64-gcc-libs-16.1.0-5) imports three 64-bit-time symbols from winpthread — clock_gettime64, nanosleep64, pthread_cond_timedwait64 (added in mingw-w64 v14).
  3. Rust 1.97.1's bundled libwinpthread-1.dll exports none of the three → LoadLibraryExW fails → rustc reports the generic E0463.
  4. The libgcc half is not broken: all 14 symbols GCC-16 libstdc++ imports from libgcc_s_seh-1.dll are exported by rust's bundled copy.

The melior rev bump (#557, 193e825 → 52fa2611) is the trigger, not the cause — melior-macro is byte-identical across the revs; the bump invalidated the cargo cache and forced the first fresh melior compile (= first proc-macro load) since the #550 workaround landed. Prior green history was the cache riding a melior built when the proc-macro still linked libstdc++ statically. Deterministic: no good melior artifact can be cached while the load fails.

A plain revert of the melior rev is not viable: #557's bytes_attr macro expands to StringAttribute::from_bytes(…), which only exists in the new rev — reverting breaks solx-mlir on every platform and wouldn't durably fix Windows.

Fix

Delete the stale DLL in build-toolchain (PR: #590), next to the existing #550 workaround:

rm -fv "$(rustc --print sysroot)/bin/libwinpthread-1.dll"

Verified safe: nothing in the sysroot bin/ imports winpthread (rustc.exe, rustdoc.exe, rustc_driver-*.dll, std-*.dll all checked); rust-lld.exe has its own copies under rustlib/<triple>/bin/ (rust-lang/rust#128876), untouched. The dependency then falls through to MSYS2's v14 copy via PATH. PATH-based fixes cannot work (app dir always wins), nor can copying into rustlib/.../bin/self-contained/ (not on the DLL search path).

Structural follow-ups

Prior art

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    buildToolchain, build and CI infrastructure

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions