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_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..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), @@ -936,7 +940,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 _); diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index be2fd0787b98a..5e9cb42365049 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,16 @@ 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 let Some(&crate_type) = codegen_results + .crate_info + .crate_types + .iter() + .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", - sess.opts.crate_types[0], + "crate type {crate_type} not supported by the dummy codegen backend" )); } 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