From 3ce89e257d20c34795d0577ea4ba0e0be194c0db Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:54:49 +0000 Subject: [PATCH 1/3] Use the actual StableCrateId for the incr comp session dir Previously only --crate-type would be taken into account, not #![crate_type]. --- compiler/rustc_incremental/src/persist/fs.rs | 20 +++++++------------ .../rustc_incremental/src/persist/load.rs | 11 +++++++--- compiler/rustc_interface/src/passes.rs | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 975bf1d18622a..f73cc4d43e8c5 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -116,8 +116,6 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_data_structures::{base_n, flock}; use rustc_fs_util::{LinkOrCopy, link_or_copy, try_canonicalize}; use rustc_middle::bug; -use rustc_session::config::CrateType; -use rustc_session::output::collect_crate_types; use rustc_session::{Session, StableCrateId}; use rustc_span::Symbol; use tracing::debug; @@ -212,7 +210,11 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu /// The garbage collection will take care of it. /// /// [`rustc_interface::queries::dep_graph`]: ../../rustc_interface/struct.Queries.html#structfield.dep_graph -pub(crate) fn prepare_session_directory(sess: &Session, crate_name: Symbol) { +pub(crate) fn prepare_session_directory( + sess: &Session, + crate_name: Symbol, + stable_crate_id: StableCrateId, +) { if sess.opts.incremental.is_none() { return; } @@ -222,7 +224,7 @@ pub(crate) fn prepare_session_directory(sess: &Session, crate_name: Symbol) { debug!("prepare_session_directory"); // {incr-comp-dir}/{crate-name-and-disambiguator} - let crate_dir = crate_path(sess, crate_name); + let crate_dir = crate_path(sess, crate_name, stable_crate_id); debug!("crate-dir: {}", crate_dir.display()); create_dir(sess, &crate_dir, "crate"); @@ -595,17 +597,9 @@ fn string_to_timestamp(s: &str) -> Result { Ok(UNIX_EPOCH + duration) } -fn crate_path(sess: &Session, crate_name: Symbol) -> PathBuf { +fn crate_path(sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId) -> PathBuf { let incr_dir = sess.opts.incremental.as_ref().unwrap().clone(); - let crate_types = collect_crate_types(sess, &[]); - let stable_crate_id = StableCrateId::new( - crate_name, - crate_types.contains(&CrateType::Executable), - sess.opts.cg.metadata.clone(), - sess.cfg_version, - ); - let crate_name = format!("{crate_name}-{}", stable_crate_id.as_u64().to_base_fixed_len(CASE_INSENSITIVE)); incr_dir.join(crate_name) diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 0e646b136c452..1b2a283a1a0d1 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -10,8 +10,8 @@ use rustc_middle::dep_graph::{DepGraph, DepsType, SerializedDepGraph, WorkProduc use rustc_middle::query::on_disk_cache::OnDiskCache; use rustc_serialize::Decodable; use rustc_serialize::opaque::MemDecoder; -use rustc_session::Session; use rustc_session::config::IncrementalStateAssertion; +use rustc_session::{Session, StableCrateId}; use rustc_span::Symbol; use tracing::{debug, warn}; @@ -208,9 +208,14 @@ pub fn load_query_result_cache(sess: &Session) -> Option { /// Setups the dependency graph by loading an existing graph from disk and set up streaming of a /// new graph to an incremental session directory. -pub fn setup_dep_graph(sess: &Session, crate_name: Symbol, deps: &DepsType) -> DepGraph { +pub fn setup_dep_graph( + sess: &Session, + crate_name: Symbol, + stable_crate_id: StableCrateId, + deps: &DepsType, +) -> DepGraph { // `load_dep_graph` can only be called after `prepare_session_directory`. - prepare_session_directory(sess, crate_name); + prepare_session_directory(sess, crate_name, stable_crate_id); let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess, deps)); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 03b8b61bbc0a8..08659f8511d5f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -936,7 +936,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let outputs = util::build_output_filenames(&pre_configured_attrs, sess); let dep_type = DepsType { dep_names: rustc_query_impl::dep_kind_names() }; - let dep_graph = setup_dep_graph(sess, crate_name, &dep_type); + let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id, &dep_type); let cstore = FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _); From b443a59ba80b92ba6ddd6c1cc5fedf07c53531a3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 27 Oct 2025 16:14:03 +0000 Subject: [PATCH 2/3] Allow codegen backends to indicate which crate types they support This way cargo will drop the unsupported crate types for crates that specify multiple crate types. --- .../rustc_codegen_ssa/src/traits/backend.rs | 14 +++++++++++++- compiler/rustc_driver_impl/src/lib.rs | 3 ++- compiler/rustc_interface/src/passes.rs | 6 +++++- compiler/rustc_interface/src/util.rs | 17 +++++++++++++++-- compiler/rustc_session/src/output.rs | 13 +++++++++++-- 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index ec53d9f53eb83..85bff45408140 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -10,7 +10,7 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; -use rustc_session::config::{self, OutputFilenames, PrintRequest}; +use rustc_session::config::{self, CrateType, OutputFilenames, PrintRequest}; use rustc_span::Symbol; use super::CodegenObject; @@ -62,6 +62,18 @@ pub trait CodegenBackend { } } + fn supported_crate_types(&self, _sess: &Session) -> Vec { + vec![ + CrateType::Executable, + CrateType::Dylib, + CrateType::Rlib, + CrateType::Staticlib, + CrateType::Cdylib, + CrateType::ProcMacro, + CrateType::Sdylib, + ] + } + fn print_passes(&self) {} fn print_version(&self) {} diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 9529ef2b99ad3..c926a7c742a0a 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -686,7 +686,8 @@ fn print_crate_info( }; let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess); let crate_name = passes::get_crate_name(sess, attrs); - let crate_types = collect_crate_types(sess, attrs); + let crate_types = + collect_crate_types(sess, &codegen_backend.supported_crate_types(sess), attrs); for &style in &crate_types { let fname = rustc_session::output::filename_for_input( sess, style, crate_name, &t_outputs, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 08659f8511d5f..6842b61f629e5 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -925,7 +925,11 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs); let crate_name = get_crate_name(sess, &pre_configured_attrs); - let crate_types = collect_crate_types(sess, &pre_configured_attrs); + let crate_types = collect_crate_types( + sess, + &compiler.codegen_backend.supported_crate_types(sess), + &pre_configured_attrs, + ); let stable_crate_id = StableCrateId::new( crate_name, crate_types.contains(&CrateType::Executable), diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index be2fd0787b98a..801c144c811a7 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -354,6 +354,14 @@ impl CodegenBackend for DummyCodegenBackend { "dummy" } + fn supported_crate_types(&self, _sess: &Session) -> Vec { + // This includes bin despite failing on the link step to ensure that you + // can still get the frontend handling for binaries. For all library + // like crate types cargo will fallback to rlib unless you specifically + // say that only a different crate type must be used. + vec![CrateType::Rlib, CrateType::Executable] + } + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { Box::new(CodegenResults { modules: vec![], @@ -380,12 +388,17 @@ impl CodegenBackend for DummyCodegenBackend { ) { // JUSTIFICATION: TyCtxt no longer available here #[allow(rustc::bad_opt_access)] - if sess.opts.crate_types.iter().any(|&crate_type| crate_type != CrateType::Rlib) { + if codegen_results + .crate_info + .crate_types + .iter() + .any(|&crate_type| crate_type != CrateType::Rlib) + { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] sess.dcx().fatal(format!( "crate type {} not supported by the dummy codegen backend", - sess.opts.crate_types[0], + codegen_results.crate_info.crate_types[0], )); } diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index cba70b5bd5d17..a48a4f649da1d 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -174,7 +174,11 @@ pub fn categorize_crate_type(s: Symbol) -> Option { Some(CRATE_TYPES.iter().find(|(key, _)| *key == s)?.1) } -pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec { +pub fn collect_crate_types( + session: &Session, + backend_crate_types: &[CrateType], + attrs: &[ast::Attribute], +) -> Vec { // If we're generating a test executable, then ignore all other output // styles at all other locations if session.opts.test { @@ -219,7 +223,12 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Date: Tue, 28 Oct 2025 14:15:19 +0000 Subject: [PATCH 3/3] Report correct unsupported crate type for the dummy codegen backend --- compiler/rustc_interface/src/util.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 801c144c811a7..5e9cb42365049 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -388,17 +388,16 @@ impl CodegenBackend for DummyCodegenBackend { ) { // JUSTIFICATION: TyCtxt no longer available here #[allow(rustc::bad_opt_access)] - if codegen_results + if let Some(&crate_type) = codegen_results .crate_info .crate_types .iter() - .any(|&crate_type| crate_type != CrateType::Rlib) + .find(|&&crate_type| crate_type != CrateType::Rlib) { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] sess.dcx().fatal(format!( - "crate type {} not supported by the dummy codegen backend", - codegen_results.crate_info.crate_types[0], + "crate type {crate_type} not supported by the dummy codegen backend" )); }