Skip to content

ci(windows): drop rustc's stale libwinpthread so C++ proc-macros load - #590

Merged
hedgar2017 merged 1 commit into
mainfrom
win-procmacro-winpthread
Jul 22, 2026
Merged

ci(windows): drop rustc's stale libwinpthread so C++ proc-macros load#590
hedgar2017 merged 1 commit into
mainfrom
win-procmacro-winpthread

Conversation

@nebasuke

@nebasuke nebasuke commented Jul 22, 2026

Copy link
Copy Markdown
Member

Workaround for #589 (the load-time sequel to #550).

Problem

Slang Tests → Windows is deterministically red on main since #557 merged (runs 29910202004, 29912409528):

error[E0463]: can't find crate for `melior_macro`
error: could not compile `melior` (lib) due to 1 previous error

The melior rev bump in #557 is the trigger, not the cause — it invalidated the cargo cache entry and forced the first fresh melior compile (= first proc-macro load) since the #550 shared-libstdc++ workaround landed. melior-macro's source is byte-identical across the two revs, and no good melior artifact can ever be cached while the load fails, so the leg stays red without this fix.

Root cause (confirmed by PE import/export analysis — full trail in #589)

melior-macro is a proc-macro that links LLVM C++ (via tblgen). Since the #550 workaround switched test builds to shared libstdc++, the built melior_macro.dll needs GCC 16's libstdc++-6.dll at load time.

rustc loads proc-macros via libloadingLoadLibraryExW(path, 0) → the default Windows DLL search order, in which the application directory — rustc's sysroot bin/ — beats PATH. The windows-gnu dist ships a stale libwinpthread-1.dll there, and GCC 16's libstdc++-6.dll imports three mingw-w64 v14 64-bit-time symbols the stale copy doesn't export:

GCC 16 libstdc++-6.dll imports from winpthread rust 1.97.1's bundled libwinpthread-1.dll
clock_gettime64 ❌ absent
nanosleep64 ❌ absent
pthread_cond_timedwait64 ❌ absent

The dependency chain fails to load and rustc surfaces it as the generic E0463: can't find crate. PATH-based fixes cannot work — the app dir always wins.

Fix

Delete the stale DLL from the sysroot bin/ in build-toolchain (next to the existing #550 workaround, same guards), so the dependency falls through to MSYS2's mingw-w64 v14 copy via PATH:

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, and std-*.dll all checked (they depend only on KERNEL32/msvcrt/ntdll/libgcc). rust-lld.exe does need it, but has its own copies under rustlib/<triple>/bin/ (rust-lang/rust#128876), untouched here. The libgcc half of the chain needs no intervention: all 14 symbols GCC 16's libstdc++ imports from libgcc_s_seh-1.dll are exported by rust's bundled copy. -f makes the step self-nooping (and deletable) once rust ships mingw-w64 ≥ v14.

Prior art — same class, same fix shape

An upstream report against rust-lang/rust is being filed in parallel (the bin/ copy is imported by nothing there and shadows newer runtimes during in-process loads); this workaround stays until a fixed toolchain reaches our pinned rust-toolchain.toml. The structural fix that makes it deletable on our side — getting tblgen out of macro-expansion time in the melior fork — is tracked in #589.

Verification

Verified in run 29923864614: the Windows leg passes — the cached GCC-16-linked melior_macro.dll (the exact artifact that failed on main) loads, melior compiles, and the slang suite runs green, with this one-file change as the only difference from the failing configuration. The run's overall red comes from solx-mlir :: conditional.sol failing on Linux ARM64 + macOS x86 — a pre-existing main breakage from #563, unrelated to this Windows-gated change; tracked in #591.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

Coverage Summary

Crate Line Coverage Function Coverage
solx 🟢 94.7% 🟡 68.0%
solx-benchmark-converter 🔴 0.0% 🔴 0.0%
solx-codegen-evm 🟢 88.8% 🟢 83.2%
solx-compiler-downloader 🔴 0.0% 🔴 0.0%
solx-core 🟢 96.6% 🟢 91.0%
solx-dev 🔴 2.4% 🔴 3.0%
solx-evm-assembly 🟡 70.6% 🟡 66.2%
solx-solc-test-adapter 🔴 1.7% 🔴 2.1%
solx-standard-json 🟢 95.4% 🟢 91.5%
solx-tester 🔴 38.2% 🔴 35.9%
solx-utils 🟢 84.4% 🟢 85.1%
solx-yul 🟡 78.9% 🟡 71.3%
Total 🟡 53.9% 🔴 47.1%

Codecov Report | HTML Report | Workflow Run

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts the Windows CI toolchain bootstrap to avoid a deterministic proc-macro load failure in Slang tests caused by rustc’s sysroot bin/ shadowing MSYS2’s newer MinGW runtime DLLs.

Changes:

  • Adds a Windows-only step in the shared build-toolchain composite action to remove rustc’s stale libwinpthread-1.dll from the sysroot bin/, allowing DLL resolution to fall through to MSYS2 via PATH.
  • Documents the rationale and why the step is expected to become a no-op once Rust ships a mingw-w64 v14+ bundled runtime.

@hedgar2017
hedgar2017 enabled auto-merge July 22, 2026 14:36
@nebasuke nebasuke removed the ci:slang Trigger slang unit tests on PR label Jul 22, 2026
rustc loads proc-macros via LoadLibraryExW with the default search
order, where the application directory - rustc's sysroot bin/ - beats
PATH. The windows-gnu dist ships a stale libwinpthread-1.dll there that
nothing in bin/ imports (verified: rustc.exe, rustdoc.exe,
rustc_driver-*.dll, std-*.dll depend only on KERNEL32/msvcrt/ntdll/
libgcc; rust-lld.exe has its own copies under rustlib/, untouched here).

Since the shared-libstdc++ workaround for #550, a freshly compiled
melior-macro (proc-macro linking LLVM C++ via tblgen) depends on GCC
16's libstdc++-6.dll at load time, which imports clock_gettime64,
nanosleep64 and pthread_cond_timedwait64 from mingw-w64 v14
winpthreads. The stale copy predates those exports, the dependency
chain fails to load, and rustc reports the generic E0463 "can't find
crate for melior_macro" - Slang Tests / Windows has been red on main
since the melior rev bump in #557 forced the first fresh melior build
(runs 29910202004, 29912409528).

Deleting the dead DLL lets the dependency fall through to MSYS2's copy
via PATH. Same-class prior art: rust-lang/rust#99534 (stale bundled
libgcc_s_dw2-1.dll vs MSYS2 gcc >= 11.3, fixed by a bundled-mingw
bump), ddnet/ddnet#10203, and a ruby-core report with the identical
delete-the-stale-DLL fix.
@nebasuke
nebasuke force-pushed the win-procmacro-winpthread branch from 9f2f747 to 72d4e32 Compare July 22, 2026 14:40
@hedgar2017
hedgar2017 added this pull request to the merge queue Jul 22, 2026
Merged via the queue into main with commit 66e29c9 Jul 22, 2026
45 checks passed
@hedgar2017
hedgar2017 deleted the win-procmacro-winpthread branch July 22, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants