From 8836859e57e0210df963e2e890ee677c9cf21380 Mon Sep 17 00:00:00 2001 From: meh Date: Fri, 25 Sep 2026 00:05:31 +0700 Subject: [PATCH 1/4] Build the timing example without the `parallel` feature `cargo test` builds every example, and without `parallel` there is no `sync::set_parallel_executor`, so the default build's test run failed to compile. The two calls go through `hand_over`, which gives frontend the executor only when the feature is on; without it the example's pool still runs whole files side by side (`files`), each session serial. --- examples/parallel_timing.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/examples/parallel_timing.rs b/examples/parallel_timing.rs index 99972d31..de021c4d 100644 --- a/examples/parallel_timing.rs +++ b/examples/parallel_timing.rs @@ -353,6 +353,17 @@ fn pass_of(text: &str) -> &'static str { "other" } +/// Hand `executor` to frontend as the pool its stages run on. Only a build with the `parallel` +/// feature has stages to run there; without it every session is serial and the pool this +/// program built still runs whole files side by side (`files`). +fn hand_over(executor: nagoya::Executor) { + #[cfg(feature = "parallel")] + frontend::rustc_data_structures::sync::set_parallel_executor(executor) + .unwrap_or_else(|_| panic!("an executor was already set")); + #[cfg(not(feature = "parallel"))] + drop(executor); +} + fn catcher(f: &mut dyn FnMut()) -> Result<(), frontend::unwind_janky::Payload> { std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) } @@ -581,8 +592,7 @@ fn main() { let executor = runtime.executor().clone_handle(); // Kept for the life of the program: dropping a `Runtime` does not stop its workers. std::mem::forget(runtime); - frontend::rustc_data_structures::sync::set_parallel_executor(executor) - .unwrap_or_else(|_| panic!("an executor was already set")); + hand_over(executor); println!("pool: {workers} workers"); } let mut args = raw.into_iter(); @@ -618,8 +628,7 @@ fn main() { let pool = Arc::clone(runtime.pool()); let executor = runtime.executor().clone_handle(); std::mem::forget(runtime); - frontend::rustc_data_structures::sync::set_parallel_executor(executor) - .unwrap_or_else(|_| panic!("an executor was already set")); + hand_over(executor); let run = || -> (Vec, f64) { let slots: Arc>> = Arc::new((0..files.len()).map(|_| std::sync::OnceLock::new()).collect()); From bdceef4f6e2c3689b7a39b891e6c6d9d134ec2cf Mon Sep 17 00:00:00 2001 From: meh Date: Fri, 25 Sep 2026 00:33:39 +0700 Subject: [PATCH 2/4] Drop a comment paragraph a merge left in twice --- src/frontend_facts/mod.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/frontend_facts/mod.rs b/src/frontend_facts/mod.rs index 24c2dda7..eec5642b 100644 --- a/src/frontend_facts/mod.rs +++ b/src/frontend_facts/mod.rs @@ -524,16 +524,6 @@ fn extract_with(tcx: TyCtxt<'_>, bodies: bool) -> CrateFacts { // The second stage takes them after every other body, each after its owner's signature is // lowered (`lower_signature`), which is the state rustc checks them in. // - // In rustc's order, in two stages. The first takes every body rustc's own body loop - // (`rustc_hir_analysis::check_crate`) type-checks. That loop skips an anon const of the type - // system (an array length, a const generic argument): such a const's type is fed while the - // signature or body around it is lowered, and rustc lowers every signature before it checks - // any body. This walk does not run that crate-wide lowering (it would stop a `no_core` file - // on its first missing lang item), so checking those consts in index order reached one before - // its type was fed: core, which has no other error to stop at first, ended in delayed bugs. - // The second stage takes them after every other body, each after its owner's signature is - // lowered (`lower_signature`), which is the state rustc checks them in. - // // A body weighs its source at type checking's rate (`sync::cost::TYPECK`), which is what // most of its fact costs, so a small file's bodies run serially, as width one runs them. // The two stages above stay unweighted, cut by count: their items cost a path printed per From c3ddecebd18855531ebf5e5ff3eba1ad36057c9f Mon Sep 17 00:00:00 2001 From: meh Date: Fri, 25 Sep 2026 00:34:13 +0700 Subject: [PATCH 3/4] Release frontend_macros 0.3.0: `symbols!` emits the predefined table crates.io's 0.2.0 generates `Interner::with_extra_symbols`; the macro in this tree generates `PREDEFINED_SYMBOL_LIST`, the static table the interner is now built from at compile time. frontend 0.5.0 compiles only against the new output, and the generated items changed shape, so this is 0.3.0 and frontend requires it. --- Cargo.toml | 2 +- frontend_macros/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cd104222..fc159e05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,7 +82,7 @@ parallel = ["dep:nagoya"] nagoya = { git = "https://github.com/pathscale/nagoya", branch = "feat/stack-size", optional = true } # The two crates that could not be merged. `rustc_macros` is the historical name and the source # still says `rustc_macros::`, so it is aliased rather than renamed across ten thousand sites. -rustc_macros = { package = "frontend_macros", path = "frontend_macros", version = "0.2.0", optional = true } +rustc_macros = { package = "frontend_macros", path = "frontend_macros", version = "0.3.0", optional = true } frontend_diag_template = { path = "frontend_diag_template", version = "0.1.1" } # Not a module, deliberately. See `frontend_arena/Cargo.toml`. frontend_arena = { path = "frontend_arena", version = "0.2.0" } diff --git a/frontend_macros/Cargo.toml b/frontend_macros/Cargo.toml index 68d3af36..4dcbcaab 100644 --- a/frontend_macros/Cargo.toml +++ b/frontend_macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frontend_macros" -version = "0.2.0" +version = "0.3.0" edition = "2024" license = "Apache-2.0 OR MIT" description = "the derives and attribute macros the frontend crate is built from" From 44ff047fe9e0bc385f1caf5c7f097c4f9926ceed Mon Sep 17 00:00:00 2001 From: meh Date: Fri, 25 Sep 2026 00:34:13 +0700 Subject: [PATCH 4/4] Take nagoya 0.1.14 from crates.io instead of its git branch crates.io refuses a git dependency, and `Runtime::builder().stack_size` (what the `parallel` feature and the timing example build their pools with) is in nagoya 0.1.14. --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fc159e05..611ac8a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,8 +78,8 @@ parallel = ["dep:nagoya"] # nagoya's pool, for `parallel` only. `Runtime::builder().stack_size`, `Executor::{submit, pool}` # and `block_on` are what this crate calls. Default features, because `std` is the point: see the # `parallel` feature above. -# Moves to the crates.io release (`^0.1.14`) once nagoya publishes `Runtime::builder`. -nagoya = { git = "https://github.com/pathscale/nagoya", branch = "feat/stack-size", optional = true } +# `Runtime::builder` arrived in 0.1.14. +nagoya = { version = "^0.1.14", optional = true } # The two crates that could not be merged. `rustc_macros` is the historical name and the source # still says `rustc_macros::`, so it is aliased rather than renamed across ten thousand sites. rustc_macros = { package = "frontend_macros", path = "frontend_macros", version = "0.3.0", optional = true } @@ -137,7 +137,7 @@ unicode-width = "0.2.2" [dev-dependencies] # The timing example sizes its own nagoya pool (`--pool N`) and hands it over with # `sync::set_parallel_executor`, to measure scaling at pool sizes other than the default. -nagoya = { git = "https://github.com/pathscale/nagoya", branch = "feat/stack-size" } +nagoya = "^0.1.14" # The pool's idle policy for `--tuning` (`Builder::tuning` takes fanout's `Tuning`, which nagoya # does not re-export). ps-st3 = { version = "^0.6", default-features = false, features = ["fanout"] }