Skip to content

Shake your foundation: make, don't panic & derive..#142

Open
cds-amal wants to merge 10 commits intomasterfrom
stack/pr1-foundation
Open

Shake your foundation: make, don't panic & derive..#142
cds-amal wants to merge 10 commits intomasterfrom
stack/pr1-foundation

Conversation

@cds-amal
Copy link
Collaborator

This PR introduces independent improvements that lays the groundwork for robust multi-nightly
support. Each one stands alone, but together they establish the tooling and
resilience the rest of the stack builds on.

  • feat(make): self-documenting help target and modernized Makefile. make help
    now extracts target descriptions via an awk one-liner, instead of complicated
    make shellery. Also adds standalone fmt, clippy, stdlib-smir, and build-info
    targets. The Makefile establishes its final structure here (including stubs
    for golden file management and UI testing that become functional in later
    PRs); we write the API we desire and make it real in subsequent PRs.

  • fix(ty_visitor): catch rustc panics during layout computation. Some types
    (notably dyn Trait in certain positions) cause rustc's layout engine to panic
    rather than returning Err. Turns out catch_unwind is the only viable option
    here; rustc doesn't surface these as recoverable errors. We wrap ty.layout(),
    record panicked types, and report them in a summary instead of taking the
    whole run down with them.

  • fix(cargo_stable_mir_json): derive toolchain lib path dynamically. The helper
    binary hardcoded the library path, which broke every time the nightly
    directory name changed (i.e., on every nightly bump; not ideal). Now resolves
    it at runtime from the active toolchain.

  • refactor: derive rustc commit from toolchain, drop [metadata] section.
    rust-toolchain.toml carried a [metadata] rustc-commit = ... field that had to
    be updated by hand on every bump. The UI test scripts now derive the commit
    hash from the Rust release manifest instead, which means one fewer thing to
    forget, yay! Also inlines format args across the codebase to satisfy
    clippy::uninlined_format_args.

Test plan

  • make help prints a formatted target list
  • cargo build succeeds on the pinned nightly
  • make clippy and make fmt work as standalone targets
  • cargo run -- -Zno-codegen tests/integration/programs/enum.rs produces
    output (exercises the ty_visitor panic catch on types with tricky layouts)

Add a 'make help' target with awk-based extraction of target
descriptions. Also adds standalone 'fmt', 'clippy', 'stdlib-smir',
'build-info', and nightly administration targets.

Uses the final Makefile structure: targets for golden file management,
UI testing, and nightly lifecycle are included but depend on scripts
added in later commits.
Some types (e.g., dyn Trait in certain positions) cause rustc's layout
computation to panic rather than returning an error. Wrap layout calls
in catch_unwind so the type visitor can continue; panicked types are
recorded and reported in a summary rather than crashing the whole run.
Instead of hardcoding the library path, resolve it from the active
nightly toolchain at runtime. This avoids breakage when the toolchain
directory name changes.
@cds-amal cds-amal requested a review from a team March 10, 2026 23:59
Drop the [metadata] section from rust-toolchain.toml; the UI test
scripts now derive the rustc commit hash directly from the nightly
date via the Rust manifest. Also fixes clippy uninlined_format_args
warnings.
@cds-amal cds-amal force-pushed the stack/pr1-foundation branch from d14cc18 to 21a3ddd Compare March 11, 2026 00:04
The receipt-driven integration-test target requires receipts (PR 2) and
per-nightly golden directories (PR 3). Revert to master's flat-file
version so CI passes on the foundation PR.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR reduces hardcoded nightly metadata and makes tooling derive the active Rust nightly/commit dynamically, while also hardening the Stable MIR type collection against rustc-internal layout panics.

Changes:

  • Removed rust-toolchain.toml metadata for rustc-commit and derived the rustc commit from rustc -vV in UI tooling and CI.
  • Added panic-catching around ty.layout() to avoid crashing when rustc panics during layout computation, and surfaced a warning summary.
  • Expanded/organized Makefile targets (help, UI test utilities, nightly management, stdlib smir artifact generation) and improved portability in some scripts.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/ui/ensure_rustc_commit.sh Derives rustc commit from rustc -vV and fetches missing commits before checkout/worktree creation.
src/printer/ty_visitor.rs Catches rustc panics during layout computation and records them for later reporting.
src/printer/collect.rs Emits a warning summary when layout panics were encountered during collection.
src/printer/schema.rs Modernizes an assert message using captured formatting.
src/printer/items.rs Simplifies debug formatting with captured formatting syntax.
src/bin/cargo_stable_mir_json.rs Derives toolchain library path via rustc --print sysroot instead of hardcoded nightly paths.
rust-toolchain.toml Removes the [metadata] rustc-commit field.
Makefile Adds help/quality/test/nightly/stdlib targets and improves structure/portability.
.github/workflows/test.yml Reads nightly channel from rust-toolchain.toml and derives rustc commit dynamically for UI tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

TIL (thanks Copilot!), the previous approach temporarily replaced the
process-wide panic hook with a no-op to suppress backtraces from caught
layout panics. Turns out that's a thread-safety footgun: rustc's own
worker threads could panic while the no-op hook is installed, silently
swallowing unrelated diagnostics. The hook swap was also racy with
anything else that calls set_hook concurrently.

catch_unwind is what actually keeps the process alive; the hook swap was
purely cosmetic (suppressing stderr noise). Dropped it entirely and
accepted the default backtrace output for caught panics. The end-of-run
LayoutPanic summary still reports everything it did before. My research
surfaced a way to suppress the stderr noise that I decided was too much
for a little noise, but I'm including here for completeness.

Set teh hook once at startup (not per-call) to a hook that checks a
thread-local flag:

```rust
thread_local! {
  static SUPPRESS_PANIC_OUTPUT: Cell<bool> = const { Cell::new(false) };
}

// Called once, e.g. in driver setup:
std::panic::set_hook(Box::new(|info| {
  SUPPRESS_PANIC_OUTPUT.with(|flag| {
      if !flag.get() {
          eprintln!("{info}");
      }
  });
}));

// Then in try_layout_shape, just toggle the flag:
SUPPRESS_PANIC_OUTPUT.with(|f| f.set(true));
let result = catch_unwind(AssertUnwindSafe(|| ty.layout()...));
SUPPRESS_PANIC_OUTPUT.with(|f| f.set(false));

This is thread-safe (thread-local, not global), no race conditions, no
risk of swallowing other threads' panics, and our collected LayoutPanic
report at teh end works exactly as before.
If this script is sourced from a working directory outside the repo
tree, rustup won't find rust-toolchain.toml and may select whatever
default toolchain happens to be active, giving us the wrong commit
hash. We now derive the repo root from BASH_SOURCE (two levels up from
the script's own directory) and cd there before invoking rustc, so the
toolchain selection stays correct regardless of the caller's CWD.
TOOLCHAIN_NAME defaults to empty in the Makefile, which meant
make clean would always run rustup toolchain uninstall "" and fail.
Now we only attempt the uninstall when the variable is actually set.
The workflow was downloading yq from GitHub releases without any
integrity check (a supply-chain risk, however small, on CI runners).
We now download the upstream checksums file alongside the binary and
verify the SHA256 before installing.

While we're at it, the identical 8-line install block was copy-pasted
across all three jobs. Extracted into .github/scripts/install-yq.sh
so there's exactly one place to update the version or change the
verification logic.
The checksums file from mikefarah/yq uses a custom multi-hash-per-line
format that isn't compatible with sha256sum -c (which expects GNU
coreutils format). Switched to checksums-bsd, which uses the standard
BSD-style "SHA256 (file) = hash" layout; a small sed converts that to
GNU format for verification.
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.

2 participants