rustc: Move crate_types from Session to GlobalCtxt

Removes a piece of mutable state.
Follow up to #114578.
This commit is contained in:
Vadim Petrochenkov 2023-08-08 18:28:20 +08:00
parent 8838c73e86
commit 0b89aac08d
26 changed files with 108 additions and 108 deletions

View file

@ -457,7 +457,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
// Don't hash unless necessary, because it's expensive. // Don't hash unless necessary, because it's expensive.
let opt_hir_hash = let opt_hir_hash =
if tcx.sess.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None }; if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
hir::Crate { owners, opt_hir_hash } hir::Crate { owners, opt_hir_hash }
} }
@ -648,7 +648,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let bodies = SortedMap::from_presorted_elements(bodies); let bodies = SortedMap::from_presorted_elements(bodies);
// Don't hash unless necessary, because it's expensive. // Don't hash unless necessary, because it's expensive.
let (opt_hash_including_bodies, attrs_hash) = if self.tcx.sess.needs_crate_hash() { let (opt_hash_including_bodies, attrs_hash) = if self.tcx.needs_crate_hash() {
self.tcx.with_stable_hashing_context(|mut hcx| { self.tcx.with_stable_hashing_context(|mut hcx| {
let mut stable_hasher = StableHasher::new(); let mut stable_hasher = StableHasher::new();
hcx.with_hir_bodies(node.def_id(), &bodies, |hcx| { hcx.with_hir_bodies(node.def_id(), &bodies, |hcx| {

View file

@ -98,7 +98,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
tcx.sess.fatal("JIT mode doesn't work with `cargo check`"); tcx.sess.fatal("JIT mode doesn't work with `cargo check`");
} }
if !tcx.sess.crate_types().contains(&rustc_session::config::CrateType::Executable) { if !tcx.crate_types().contains(&rustc_session::config::CrateType::Executable) {
tcx.sess.fatal("can't jit non-executable crate"); tcx.sess.fatal("can't jit non-executable crate");
} }

View file

@ -209,7 +209,7 @@ pub unsafe fn create_module<'ll>(
// PIE is potentially more effective than PIC, but can only be used in executables. // PIE is potentially more effective than PIC, but can only be used in executables.
// If all our outputs are executables, then we can relax PIC to PIE. // If all our outputs are executables, then we can relax PIC to PIE.
if reloc_model == RelocModel::Pie if reloc_model == RelocModel::Pie
|| sess.crate_types().iter().all(|ty| *ty == CrateType::Executable) || tcx.crate_types().iter().all(|ty| *ty == CrateType::Executable)
{ {
llvm::LLVMRustSetModulePIELevel(llmod); llvm::LLVMRustSetModulePIELevel(llmod);
} }

View file

@ -92,7 +92,7 @@ pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
// each rlib could produce a different set of visualizers that would be embedded // each rlib could produce a different set of visualizers that would be embedded
// in the `.debug_gdb_scripts` section. For that reason, we make sure that the // in the `.debug_gdb_scripts` section. For that reason, we make sure that the
// section is only emitted for leaf crates. // section is only emitted for leaf crates.
let embed_visualizers = cx.sess().crate_types().iter().any(|&crate_type| match crate_type { let embed_visualizers = cx.tcx.crate_types().iter().any(|&crate_type| match crate_type {
CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::Staticlib => { CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::Staticlib => {
// These are crate types for which we will embed pretty printers since they // These are crate types for which we will embed pretty printers since they
// are treated as leaf crates. // are treated as leaf crates.

View file

@ -111,7 +111,7 @@ impl CodegenCx<'_, '_> {
} }
// Symbols from executables can't really be imported any further. // Symbols from executables can't really be imported any further.
let all_exe = self.tcx.sess.crate_types().iter().all(|ty| *ty == CrateType::Executable); let all_exe = self.tcx.crate_types().iter().all(|ty| *ty == CrateType::Executable);
let is_declaration_for_linker = let is_declaration_for_linker =
is_declaration || linkage == llvm::Linkage::AvailableExternallyLinkage; is_declaration || linkage == llvm::Linkage::AvailableExternallyLinkage;
if all_exe && !is_declaration_for_linker { if all_exe && !is_declaration_for_linker {

View file

@ -69,7 +69,7 @@ pub fn link_binary<'a>(
let _timer = sess.timer("link_binary"); let _timer = sess.timer("link_binary");
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
let mut tempfiles_for_stdout_output: Vec<PathBuf> = Vec::new(); let mut tempfiles_for_stdout_output: Vec<PathBuf> = Vec::new();
for &crate_type in sess.crate_types().iter() { for &crate_type in &codegen_results.crate_info.crate_types {
// Ignore executable crates if we have -Z no-codegen, as they will error. // Ignore executable crates if we have -Z no-codegen, as they will error.
if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen()) if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen())
&& !output_metadata && !output_metadata

View file

@ -19,7 +19,7 @@ use rustc_session::config::{CrateType, OomStrategy};
use rustc_target::spec::SanitizerSet; use rustc_target::spec::SanitizerSet;
pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
crates_export_threshold(&tcx.sess.crate_types()) crates_export_threshold(tcx.crate_types())
} }
fn crate_export_threshold(crate_type: CrateType) -> SymbolExportLevel { fn crate_export_threshold(crate_type: CrateType) -> SymbolExportLevel {
@ -290,8 +290,8 @@ fn exported_symbols_provider_local(
})); }));
} }
if tcx.sess.crate_types().contains(&CrateType::Dylib) if tcx.crate_types().contains(&CrateType::Dylib)
|| tcx.sess.crate_types().contains(&CrateType::ProcMacro) || tcx.crate_types().contains(&CrateType::ProcMacro)
{ {
let symbol_name = metadata_symbol_name(tcx); let symbol_name = metadata_symbol_name(tcx);
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));

View file

@ -123,7 +123,7 @@ pub struct ModuleConfig {
impl ModuleConfig { impl ModuleConfig {
fn new( fn new(
kind: ModuleKind, kind: ModuleKind,
sess: &Session, tcx: TyCtxt<'_>,
no_builtins: bool, no_builtins: bool,
is_compiler_builtins: bool, is_compiler_builtins: bool,
) -> ModuleConfig { ) -> ModuleConfig {
@ -135,6 +135,7 @@ impl ModuleConfig {
}; };
} }
let sess = tcx.sess;
let opt_level_and_size = if_regular!(Some(sess.opts.optimize), None); let opt_level_and_size = if_regular!(Some(sess.opts.optimize), None);
let save_temps = sess.opts.cg.save_temps; let save_temps = sess.opts.cg.save_temps;
@ -166,7 +167,7 @@ impl ModuleConfig {
// `#![no_builtins]` is assumed to not participate in LTO and // `#![no_builtins]` is assumed to not participate in LTO and
// instead goes on to generate object code. // instead goes on to generate object code.
EmitObj::Bitcode EmitObj::Bitcode
} else if need_bitcode_in_object(sess) { } else if need_bitcode_in_object(tcx) {
EmitObj::ObjectCode(BitcodeSection::Full) EmitObj::ObjectCode(BitcodeSection::Full)
} else { } else {
EmitObj::ObjectCode(BitcodeSection::None) EmitObj::ObjectCode(BitcodeSection::None)
@ -414,9 +415,10 @@ pub struct CompiledModules {
pub allocator_module: Option<CompiledModule>, pub allocator_module: Option<CompiledModule>,
} }
fn need_bitcode_in_object(sess: &Session) -> bool { fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool {
let sess = tcx.sess;
let requested_for_rlib = sess.opts.cg.embed_bitcode let requested_for_rlib = sess.opts.cg.embed_bitcode
&& sess.crate_types().contains(&CrateType::Rlib) && tcx.crate_types().contains(&CrateType::Rlib)
&& sess.opts.output_types.contains_key(&OutputType::Exe); && sess.opts.output_types.contains_key(&OutputType::Exe);
let forced_by_target = sess.target.forces_embed_bitcode; let forced_by_target = sess.target.forces_embed_bitcode;
requested_for_rlib || forced_by_target requested_for_rlib || forced_by_target
@ -450,11 +452,11 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
let crate_info = CrateInfo::new(tcx, target_cpu); let crate_info = CrateInfo::new(tcx, target_cpu);
let regular_config = let regular_config =
ModuleConfig::new(ModuleKind::Regular, sess, no_builtins, is_compiler_builtins); ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins, is_compiler_builtins);
let metadata_config = let metadata_config =
ModuleConfig::new(ModuleKind::Metadata, sess, no_builtins, is_compiler_builtins); ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins, is_compiler_builtins);
let allocator_config = let allocator_config =
ModuleConfig::new(ModuleKind::Allocator, sess, no_builtins, is_compiler_builtins); ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins, is_compiler_builtins);
let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
let (codegen_worker_send, codegen_worker_receive) = channel(); let (codegen_worker_send, codegen_worker_receive) = channel();
@ -1092,7 +1094,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
}; };
let cgcx = CodegenContext::<B> { let cgcx = CodegenContext::<B> {
crate_types: sess.crate_types().to_vec(), crate_types: tcx.crate_types().to_vec(),
each_linked_rlib_for_lto, each_linked_rlib_for_lto,
lto: sess.lto(), lto: sess.lto(),
fewer_names: sess.fewer_names(), fewer_names: sess.fewer_names(),
@ -2063,7 +2065,7 @@ fn msvc_imps_needed(tcx: TyCtxt<'_>) -> bool {
); );
tcx.sess.target.is_like_windows && tcx.sess.target.is_like_windows &&
tcx.sess.crate_types().iter().any(|ct| *ct == CrateType::Rlib) && tcx.crate_types().iter().any(|ct| *ct == CrateType::Rlib) &&
// ThinLTO can't handle this workaround in all cases, so we don't // ThinLTO can't handle this workaround in all cases, so we don't
// emit the `__imp_` symbols. Instead we make them unnecessary by disallowing // emit the `__imp_` symbols. Instead we make them unnecessary by disallowing
// dynamic linking when linker plugin LTO is enabled. // dynamic linking when linker plugin LTO is enabled.

View file

@ -779,18 +779,13 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
impl CrateInfo { impl CrateInfo {
pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo { pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
let exported_symbols = tcx let crate_types = tcx.crate_types().to_vec();
.sess let exported_symbols = crate_types
.crate_types()
.iter() .iter()
.map(|&c| (c, crate::back::linker::exported_symbols(tcx, c))) .map(|&c| (c, crate::back::linker::exported_symbols(tcx, c)))
.collect(); .collect();
let linked_symbols = tcx let linked_symbols =
.sess crate_types.iter().map(|&c| (c, crate::back::linker::linked_symbols(tcx, c))).collect();
.crate_types()
.iter()
.map(|&c| (c, crate::back::linker::linked_symbols(tcx, c)))
.collect();
let local_crate_name = tcx.crate_name(LOCAL_CRATE); let local_crate_name = tcx.crate_name(LOCAL_CRATE);
let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
let subsystem = attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); let subsystem = attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
@ -829,6 +824,7 @@ impl CrateInfo {
let mut info = CrateInfo { let mut info = CrateInfo {
target_cpu, target_cpu,
crate_types,
exported_symbols, exported_symbols,
linked_symbols, linked_symbols,
local_crate_name, local_crate_name,
@ -916,7 +912,7 @@ impl CrateInfo {
}); });
} }
let embed_visualizers = tcx.sess.crate_types().iter().any(|&crate_type| match crate_type { let embed_visualizers = tcx.crate_types().iter().any(|&crate_type| match crate_type {
CrateType::Executable | CrateType::Dylib | CrateType::Cdylib => { CrateType::Executable | CrateType::Dylib | CrateType::Cdylib => {
// These are crate types for which we invoke the linker and can embed // These are crate types for which we invoke the linker and can embed
// NatVis visualizers. // NatVis visualizers.
@ -1013,7 +1009,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
match compute_per_cgu_lto_type( match compute_per_cgu_lto_type(
&tcx.sess.lto(), &tcx.sess.lto(),
&tcx.sess.opts, &tcx.sess.opts,
&tcx.sess.crate_types(), tcx.crate_types(),
ModuleKind::Regular, ModuleKind::Regular,
) { ) {
ComputedLtoType::No => CguReuse::PostLto, ComputedLtoType::No => CguReuse::PostLto,

View file

@ -150,6 +150,7 @@ impl From<&cstore::NativeLib> for NativeLib {
#[derive(Debug, Encodable, Decodable)] #[derive(Debug, Encodable, Decodable)]
pub struct CrateInfo { pub struct CrateInfo {
pub target_cpu: String, pub target_cpu: String,
pub crate_types: Vec<CrateType>,
pub exported_symbols: FxHashMap<CrateType, Vec<String>>, pub exported_symbols: FxHashMap<CrateType, Vec<String>>,
pub linked_symbols: FxHashMap<CrateType, Vec<(String, SymbolExportKind)>>, pub linked_symbols: FxHashMap<CrateType, Vec<(String, SymbolExportKind)>>,
pub local_crate_name: Symbol, pub local_crate_name: Symbol,

View file

@ -653,8 +653,6 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation { pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation {
if sess.opts.unstable_opts.link_only { if sess.opts.unstable_opts.link_only {
if let Input::File(file) = &sess.io.input { if let Input::File(file) = &sess.io.input {
// FIXME: #![crate_type] and #![crate_name] support not implemented yet
sess.init_crate_types(collect_crate_types(sess, &[]));
let outputs = compiler.build_output_filenames(sess, &[]); let outputs = compiler.build_output_filenames(sess, &[]);
let rlink_data = fs::read(file).unwrap_or_else(|err| { let rlink_data = fs::read(file).unwrap_or_else(|err| {
sess.emit_fatal(RlinkUnableToRead { err }); sess.emit_fatal(RlinkUnableToRead { err });

View file

@ -248,7 +248,7 @@ fn configure_and_expand(
rustc_ast_passes::ast_validation::check_crate(sess, &krate, resolver.lint_buffer()) rustc_ast_passes::ast_validation::check_crate(sess, &krate, resolver.lint_buffer())
}); });
let crate_types = sess.crate_types(); let crate_types = tcx.crate_types();
let is_executable_crate = crate_types.contains(&CrateType::Executable); let is_executable_crate = crate_types.contains(&CrateType::Executable);
let is_proc_macro_crate = crate_types.contains(&CrateType::ProcMacro); let is_proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
@ -340,11 +340,12 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
// Returns all the paths that correspond to generated files. // Returns all the paths that correspond to generated files.
fn generated_output_paths( fn generated_output_paths(
sess: &Session, tcx: TyCtxt<'_>,
outputs: &OutputFilenames, outputs: &OutputFilenames,
exact_name: bool, exact_name: bool,
crate_name: Symbol, crate_name: Symbol,
) -> Vec<PathBuf> { ) -> Vec<PathBuf> {
let sess = tcx.sess;
let mut out_filenames = Vec::new(); let mut out_filenames = Vec::new();
for output_type in sess.opts.output_types.keys() { for output_type in sess.opts.output_types.keys() {
let out_filename = outputs.path(*output_type); let out_filename = outputs.path(*output_type);
@ -353,7 +354,7 @@ fn generated_output_paths(
// If the filename has been overridden using `-o`, it will not be modified // If the filename has been overridden using `-o`, it will not be modified
// by appending `.rlib`, `.exe`, etc., so we can skip this transformation. // by appending `.rlib`, `.exe`, etc., so we can skip this transformation.
OutputType::Exe if !exact_name => { OutputType::Exe if !exact_name => {
for crate_type in sess.crate_types().iter() { for crate_type in tcx.crate_types().iter() {
let p = filename_for_input(sess, *crate_type, crate_name, outputs); let p = filename_for_input(sess, *crate_type, crate_name, outputs);
out_filenames.push(p.as_path().to_path_buf()); out_filenames.push(p.as_path().to_path_buf());
} }
@ -586,7 +587,7 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
let outputs = util::build_output_filenames(&krate.attrs, sess); let outputs = util::build_output_filenames(&krate.attrs, sess);
let output_paths = let output_paths =
generated_output_paths(sess, &outputs, sess.io.output_file.is_some(), crate_name); generated_output_paths(tcx, &outputs, sess.io.output_file.is_some(), crate_name);
// Ensure the source file isn't accidentally overwritten during compilation. // Ensure the source file isn't accidentally overwritten during compilation.
if let Some(ref input_path) = sess.io.input.opt_path() { if let Some(ref input_path) = sess.io.input.opt_path() {
@ -664,6 +665,7 @@ pub static DEFAULT_EXTERN_QUERY_PROVIDERS: LazyLock<ExternProviders> = LazyLock:
pub fn create_global_ctxt<'tcx>( pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler, compiler: &'tcx Compiler,
crate_types: Vec<CrateType>,
lint_store: Lrc<LintStore>, lint_store: Lrc<LintStore>,
dep_graph: DepGraph, dep_graph: DepGraph,
untracked: Untracked, untracked: Untracked,
@ -696,6 +698,7 @@ pub fn create_global_ctxt<'tcx>(
gcx_cell.get_or_init(move || { gcx_cell.get_or_init(move || {
TyCtxt::create_global_ctxt( TyCtxt::create_global_ctxt(
sess, sess,
crate_types,
lint_store, lint_store,
arena, arena,
hir_arena, hir_arena,

View file

@ -235,12 +235,12 @@ impl<'tcx> Queries<'tcx> {
let untracked = Untracked { cstore, source_span, definitions }; let untracked = Untracked { cstore, source_span, definitions };
// FIXME: Move these fields from session to tcx and make them immutable. // FIXME: Move these fields from session to tcx and make them immutable.
sess.init_crate_types(crate_types);
sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized"); sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized");
sess.init_features(rustc_expand::config::features(sess, &pre_configured_attrs)); sess.init_features(rustc_expand::config::features(sess, &pre_configured_attrs));
let qcx = passes::create_global_ctxt( let qcx = passes::create_global_ctxt(
self.compiler, self.compiler,
crate_types,
lint_store, lint_store,
self.dep_graph(dep_graph_future), self.dep_graph(dep_graph_future),
untracked, untracked,
@ -320,7 +320,7 @@ impl<'tcx> Queries<'tcx> {
let (crate_hash, prepare_outputs, dep_graph) = self.global_ctxt()?.enter(|tcx| { let (crate_hash, prepare_outputs, dep_graph) = self.global_ctxt()?.enter(|tcx| {
( (
if tcx.sess.needs_crate_hash() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None }, if tcx.needs_crate_hash() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None },
tcx.output_filenames(()).clone(), tcx.output_filenames(()).clone(),
tcx.dep_graph.clone(), tcx.dep_graph.clone(),
) )

View file

@ -545,7 +545,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
name, name,
// The all loop is because `--crate-type=rlib --crate-type=rlib` is // The all loop is because `--crate-type=rlib --crate-type=rlib` is
// legal and produces both inside this type. // legal and produces both inside this type.
self.sess.crate_types().iter().all(|c| *c == CrateType::Rlib), self.tcx.crate_types().iter().all(|c| *c == CrateType::Rlib),
hash, hash,
extra_filename, extra_filename,
false, // is_host false, // is_host
@ -689,7 +689,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
fn inject_panic_runtime(&mut self, krate: &ast::Crate) { fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
// If we're only compiling an rlib, then there's no need to select a // If we're only compiling an rlib, then there's no need to select a
// panic runtime, so we just skip this section entirely. // panic runtime, so we just skip this section entirely.
let any_non_rlib = self.sess.crate_types().iter().any(|ct| *ct != CrateType::Rlib); let any_non_rlib = self.tcx.crate_types().iter().any(|ct| *ct != CrateType::Rlib);
if !any_non_rlib { if !any_non_rlib {
info!("panic runtime injection skipped, only generating rlib"); info!("panic runtime injection skipped, only generating rlib");
return; return;
@ -818,7 +818,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
// At this point we've determined that we need an allocator. Let's see // At this point we've determined that we need an allocator. Let's see
// if our compilation session actually needs an allocator based on what // if our compilation session actually needs an allocator based on what
// we're emitting. // we're emitting.
let all_rlib = self.sess.crate_types().iter().all(|ct| matches!(*ct, CrateType::Rlib)); let all_rlib = self.tcx.crate_types().iter().all(|ct| matches!(*ct, CrateType::Rlib));
if all_rlib { if all_rlib {
return; return;
} }

View file

@ -66,8 +66,7 @@ use rustc_session::cstore::CrateDepKind;
use rustc_session::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic}; use rustc_session::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
pub(crate) fn calculate(tcx: TyCtxt<'_>) -> Dependencies { pub(crate) fn calculate(tcx: TyCtxt<'_>) -> Dependencies {
tcx.sess tcx.crate_types()
.crate_types()
.iter() .iter()
.map(|&ty| { .map(|&ty| {
let linkage = calculate_type(tcx, ty); let linkage = calculate_type(tcx, ty);

View file

@ -56,7 +56,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
// Always create a file at `metadata_filename`, even if we have nothing to write to it. // Always create a file at `metadata_filename`, even if we have nothing to write to it.
// This simplifies the creation of the output `out_filename` when requested. // This simplifies the creation of the output `out_filename` when requested.
let metadata_kind = tcx.sess.metadata_kind(); let metadata_kind = tcx.metadata_kind();
match metadata_kind { match metadata_kind {
MetadataKind::None => { MetadataKind::None => {
std::fs::File::create(&metadata_filename).unwrap_or_else(|err| { std::fs::File::create(&metadata_filename).unwrap_or_else(|err| {

View file

@ -52,10 +52,11 @@ fn find_bundled_library(
verbatim: Option<bool>, verbatim: Option<bool>,
kind: NativeLibKind, kind: NativeLibKind,
has_cfg: bool, has_cfg: bool,
sess: &Session, tcx: TyCtxt<'_>,
) -> Option<Symbol> { ) -> Option<Symbol> {
let sess = tcx.sess;
if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind
&& sess.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::Staticlib)) && tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::Staticlib))
&& (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true)) && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true))
{ {
let verbatim = verbatim.unwrap_or(false); let verbatim = verbatim.unwrap_or(false);
@ -364,7 +365,7 @@ impl<'tcx> Collector<'tcx> {
}; };
let kind = kind.unwrap_or(NativeLibKind::Unspecified); let kind = kind.unwrap_or(NativeLibKind::Unspecified);
let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), sess); let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), self.tcx);
self.libs.push(NativeLib { self.libs.push(NativeLib {
name, name,
filename, filename,
@ -442,9 +443,13 @@ impl<'tcx> Collector<'tcx> {
// Add if not found // Add if not found
let new_name: Option<&str> = passed_lib.new_name.as_deref(); let new_name: Option<&str> = passed_lib.new_name.as_deref();
let name = Symbol::intern(new_name.unwrap_or(&passed_lib.name)); let name = Symbol::intern(new_name.unwrap_or(&passed_lib.name));
let sess = self.tcx.sess; let filename = find_bundled_library(
let filename = name,
find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, false, sess); passed_lib.verbatim,
passed_lib.kind,
false,
self.tcx,
);
self.libs.push(NativeLib { self.libs.push(NativeLib {
name, name,
filename, filename,

View file

@ -1741,7 +1741,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} }
fn encode_proc_macros(&mut self) -> Option<ProcMacroData> { fn encode_proc_macros(&mut self) -> Option<ProcMacroData> {
let is_proc_macro = self.tcx.sess.crate_types().contains(&CrateType::ProcMacro); let is_proc_macro = self.tcx.crate_types().contains(&CrateType::ProcMacro);
if is_proc_macro { if is_proc_macro {
let tcx = self.tcx; let tcx = self.tcx;
let hir = tcx.hir(); let hir = tcx.hir();
@ -2204,7 +2204,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
source_file_cache, source_file_cache,
interpret_allocs: Default::default(), interpret_allocs: Default::default(),
required_source_files, required_source_files,
is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro), is_proc_macro: tcx.crate_types().contains(&CrateType::ProcMacro),
hygiene_ctxt: &hygiene_ctxt, hygiene_ctxt: &hygiene_ctxt,
symbol_table: Default::default(), symbol_table: Default::default(),
}; };

View file

@ -59,8 +59,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
use rustc_session::config::CrateType; use rustc_session::config::CrateType;
use rustc_session::cstore::{CrateStoreDyn, Untracked}; use rustc_session::cstore::{CrateStoreDyn, Untracked};
use rustc_session::lint::Lint; use rustc_session::lint::Lint;
use rustc_session::Limit; use rustc_session::{Limit, MetadataKind, Session};
use rustc_session::Session;
use rustc_span::def_id::{DefPathHash, StableCrateId}; use rustc_span::def_id::{DefPathHash, StableCrateId};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -527,6 +526,7 @@ pub struct GlobalCtxt<'tcx> {
interners: CtxtInterners<'tcx>, interners: CtxtInterners<'tcx>,
pub sess: &'tcx Session, pub sess: &'tcx Session,
crate_types: Vec<CrateType>,
/// This only ever stores a `LintStore` but we don't want a dependency on that type here. /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
/// ///
@ -687,6 +687,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// has a valid reference to the context, to allow formatting values that need it. /// has a valid reference to the context, to allow formatting values that need it.
pub fn create_global_ctxt( pub fn create_global_ctxt(
s: &'tcx Session, s: &'tcx Session,
crate_types: Vec<CrateType>,
lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>, lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>,
arena: &'tcx WorkerLocal<Arena<'tcx>>, arena: &'tcx WorkerLocal<Arena<'tcx>>,
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>, hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
@ -705,6 +706,7 @@ impl<'tcx> TyCtxt<'tcx> {
GlobalCtxt { GlobalCtxt {
sess: s, sess: s,
crate_types,
lint_store, lint_store,
arena, arena,
hir_arena, hir_arena,
@ -800,6 +802,43 @@ impl<'tcx> TyCtxt<'tcx> {
} }
} }
#[inline]
pub fn crate_types(self) -> &'tcx [CrateType] {
&self.crate_types
}
pub fn metadata_kind(self) -> MetadataKind {
self.crate_types()
.iter()
.map(|ty| match *ty {
CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => {
MetadataKind::None
}
CrateType::Rlib => MetadataKind::Uncompressed,
CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
})
.max()
.unwrap_or(MetadataKind::None)
}
pub fn needs_metadata(self) -> bool {
self.metadata_kind() != MetadataKind::None
}
pub fn needs_crate_hash(self) -> bool {
// Why is the crate hash needed for these configurations?
// - debug_assertions: for the "fingerprint the result" check in
// `rustc_query_system::query::plumbing::execute_job`.
// - incremental: for query lookups.
// - needs_metadata: for putting into crate metadata.
// - instrument_coverage: for putting into coverage data (see
// `hash_mir_source`).
cfg!(debug_assertions)
|| self.sess.opts.incremental.is_some()
|| self.needs_metadata()
|| self.sess.instrument_coverage()
}
#[inline] #[inline]
pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId { pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
if crate_num == LOCAL_CRATE { if crate_num == LOCAL_CRATE {
@ -986,7 +1025,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn local_crate_exports_generics(self) -> bool { pub fn local_crate_exports_generics(self) -> bool {
debug_assert!(self.sess.opts.share_generics()); debug_assert!(self.sess.opts.share_generics());
self.sess.crate_types().iter().any(|crate_type| { self.crate_types().iter().any(|crate_type| {
match crate_type { match crate_type {
CrateType::Executable CrateType::Executable
| CrateType::Staticlib | CrateType::Staticlib

View file

@ -31,7 +31,7 @@ struct EntryContext<'tcx> {
} }
fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
let any_exe = tcx.sess.crate_types().iter().any(|ty| *ty == CrateType::Executable); let any_exe = tcx.crate_types().iter().any(|ty| *ty == CrateType::Executable);
if !any_exe { if !any_exe {
// No need to find a main function. // No need to find a main function.
return None; return None;

View file

@ -364,10 +364,10 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet { fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet {
let effective_visibilities = &tcx.effective_visibilities(()); let effective_visibilities = &tcx.effective_visibilities(());
let any_library = let any_library = tcx
tcx.sess.crate_types().iter().any(|ty| { .crate_types()
*ty == CrateType::Rlib || *ty == CrateType::Dylib || *ty == CrateType::ProcMacro .iter()
}); .any(|ty| *ty == CrateType::Rlib || *ty == CrateType::Dylib || *ty == CrateType::ProcMacro);
let mut reachable_context = ReachableContext { let mut reachable_context = ReachableContext {
tcx, tcx,
maybe_typeck_results: None, maybe_typeck_results: None,

View file

@ -43,7 +43,7 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) { fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {
// We only need to check for the presence of weak lang items if we're // We only need to check for the presence of weak lang items if we're
// emitting something that's not an rlib. // emitting something that's not an rlib.
let needs_check = tcx.sess.crate_types().iter().any(|kind| match *kind { let needs_check = tcx.crate_types().iter().any(|kind| match *kind {
CrateType::Dylib CrateType::Dylib
| CrateType::ProcMacro | CrateType::ProcMacro
| CrateType::Cdylib | CrateType::Cdylib

View file

@ -4374,7 +4374,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
if let Some(res) = res if let Some(res) = res
&& let Some(def_id) = res.opt_def_id() && let Some(def_id) = res.opt_def_id()
&& !def_id.is_local() && !def_id.is_local()
&& self.r.tcx.sess.crate_types().contains(&CrateType::ProcMacro) && self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
&& matches!(self.r.tcx.sess.opts.resolve_doc_links, ResolveDocLinks::ExportedMetadata) { && matches!(self.r.tcx.sess.opts.resolve_doc_links, ResolveDocLinks::ExportedMetadata) {
// Encoding foreign def ids in proc macro crate metadata will ICE. // Encoding foreign def ids in proc macro crate metadata will ICE.
return None; return None;
@ -4389,7 +4389,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
match self.r.tcx.sess.opts.resolve_doc_links { match self.r.tcx.sess.opts.resolve_doc_links {
ResolveDocLinks::None => return, ResolveDocLinks::None => return,
ResolveDocLinks::ExportedMetadata ResolveDocLinks::ExportedMetadata
if !self.r.tcx.sess.crate_types().iter().copied().any(CrateType::has_metadata) if !self.r.tcx.crate_types().iter().copied().any(CrateType::has_metadata)
|| !maybe_exported.eval(self.r) => || !maybe_exported.eval(self.r) =>
{ {
return; return;
@ -4448,7 +4448,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
.into_iter() .into_iter()
.filter_map(|tr| { .filter_map(|tr| {
if !tr.def_id.is_local() if !tr.def_id.is_local()
&& self.r.tcx.sess.crate_types().contains(&CrateType::ProcMacro) && self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
&& matches!( && matches!(
self.r.tcx.sess.opts.resolve_doc_links, self.r.tcx.sess.opts.resolve_doc_links,
ResolveDocLinks::ExportedMetadata ResolveDocLinks::ExportedMetadata

View file

@ -152,7 +152,6 @@ pub struct Session {
/// Input, input file path and output file path to this compilation process. /// Input, input file path and output file path to this compilation process.
pub io: CompilerIO, pub io: CompilerIO,
crate_types: OnceCell<Vec<CrateType>>,
/// The `stable_crate_id` is constructed out of the crate name and all the /// The `stable_crate_id` is constructed out of the crate name and all the
/// `-C metadata` arguments passed to the compiler. Its value forms a unique /// `-C metadata` arguments passed to the compiler. Its value forms a unique
/// global identifier for the crate. It is used to allow multiple crates /// global identifier for the crate. It is used to allow multiple crates
@ -314,51 +313,11 @@ impl Session {
self.stable_crate_id.get().copied().unwrap() self.stable_crate_id.get().copied().unwrap()
} }
pub fn crate_types(&self) -> &[CrateType] {
self.crate_types.get().unwrap().as_slice()
}
/// Returns true if the crate is a testing one. /// Returns true if the crate is a testing one.
pub fn is_test_crate(&self) -> bool { pub fn is_test_crate(&self) -> bool {
self.opts.test self.opts.test
} }
pub fn needs_crate_hash(&self) -> bool {
// Why is the crate hash needed for these configurations?
// - debug_assertions: for the "fingerprint the result" check in
// `rustc_query_system::query::plumbing::execute_job`.
// - incremental: for query lookups.
// - needs_metadata: for putting into crate metadata.
// - instrument_coverage: for putting into coverage data (see
// `hash_mir_source`).
cfg!(debug_assertions)
|| self.opts.incremental.is_some()
|| self.needs_metadata()
|| self.instrument_coverage()
}
pub fn metadata_kind(&self) -> MetadataKind {
self.crate_types()
.iter()
.map(|ty| match *ty {
CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => {
MetadataKind::None
}
CrateType::Rlib => MetadataKind::Uncompressed,
CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
})
.max()
.unwrap_or(MetadataKind::None)
}
pub fn needs_metadata(&self) -> bool {
self.metadata_kind() != MetadataKind::None
}
pub fn init_crate_types(&self, crate_types: Vec<CrateType>) {
self.crate_types.set(crate_types).expect("`crate_types` was initialized twice")
}
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_span_warn<S: Into<MultiSpan>>( pub fn struct_span_warn<S: Into<MultiSpan>>(
@ -1516,7 +1475,6 @@ pub fn build_session(
parse_sess, parse_sess,
sysroot, sysroot,
io, io,
crate_types: OnceCell::new(),
stable_crate_id: OnceCell::new(), stable_crate_id: OnceCell::new(),
features: OnceCell::new(), features: OnceCell::new(),
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)), incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),

View file

@ -74,7 +74,6 @@ fn is_executable_or_proc_macro(cx: &LateContext<'_>) -> bool {
use rustc_session::config::CrateType; use rustc_session::config::CrateType;
cx.tcx cx.tcx
.sess
.crate_types() .crate_types()
.iter() .iter()
.any(|t: &CrateType| matches!(t, CrateType::Executable | CrateType::ProcMacro)) .any(|t: &CrateType| matches!(t, CrateType::Executable | CrateType::ProcMacro))

View file

@ -69,7 +69,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
} }
init_late_loggers(handler, tcx); init_late_loggers(handler, tcx);
if !tcx.sess.crate_types().contains(&CrateType::Executable) { if !tcx.crate_types().contains(&CrateType::Executable) {
tcx.sess.fatal("miri only makes sense on bin crates"); tcx.sess.fatal("miri only makes sense on bin crates");
} }