diff options
Diffstat (limited to 'compiler/rustc_interface/src')
| -rw-r--r-- | compiler/rustc_interface/src/callbacks.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/errors.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/interface.rs | 28 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/queries.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/tests.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/util.rs | 148 |
6 files changed, 91 insertions, 136 deletions
diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index f44ae705a3c..a27f73789cd 100644 --- a/compiler/rustc_interface/src/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs @@ -29,7 +29,7 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) { /// This is a callback from `rustc_errors` as it cannot access the implicit state /// in `rustc_middle` otherwise. It is used when diagnostic messages are /// emitted and stores them in the current query, if there is one. -fn track_diagnostic(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner)) { +fn track_diagnostic<R>(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R { tls::with_context_opt(|icx| { if let Some(icx) = icx { if let Some(diagnostics) = icx.diagnostics { @@ -38,11 +38,11 @@ fn track_diagnostic(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner)) { // Diagnostics are tracked, we can ignore the dependency. let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() }; - return tls::enter_context(&icx, move || (*f)(diagnostic)); + tls::enter_context(&icx, move || (*f)(diagnostic)) + } else { + // In any other case, invoke diagnostics anyway. + (*f)(diagnostic) } - - // In any other case, invoke diagnostics anyway. - (*f)(diagnostic); }) } diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs index a9ab2720d89..29294003b8f 100644 --- a/compiler/rustc_interface/src/errors.rs +++ b/compiler/rustc_interface/src/errors.rs @@ -1,7 +1,5 @@ use rustc_macros::Diagnostic; -use rustc_session::config::CrateType; use rustc_span::{Span, Symbol}; -use rustc_target::spec::TargetTriple; use std::io; use std::path::Path; @@ -91,13 +89,6 @@ pub struct FailedWritingFile<'a> { pub struct ProcMacroCratePanicAbort; #[derive(Diagnostic)] -#[diag(interface_unsupported_crate_type_for_target)] -pub struct UnsupportedCrateTypeForTarget<'a> { - pub crate_type: CrateType, - pub target_triple: &'a TargetTriple, -} - -#[derive(Diagnostic)] #[diag(interface_multiple_output_types_adaption)] pub struct MultipleOutputTypesAdaption; diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 284d965979e..8ba14d37982 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -16,7 +16,7 @@ use rustc_parse::maybe_new_parser_from_source_str; use rustc_query_impl::QueryCtxt; use rustc_query_system::query::print_query_stack; use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName}; -use rustc_session::filesearch::sysroot_candidates; +use rustc_session::filesearch::{self, sysroot_candidates}; use rustc_session::parse::ParseSess; use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session}; use rustc_span::source_map::FileLoader; @@ -339,14 +339,22 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se let early_dcx = EarlyDiagCtxt::new(config.opts.error_format); - let codegen_backend = if let Some(make_codegen_backend) = config.make_codegen_backend { - make_codegen_backend(&config.opts) - } else { - util::get_codegen_backend( + let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone()); + + let target = config::build_target_config(&early_dcx, &config.opts, &sysroot); + + let codegen_backend = match config.make_codegen_backend { + None => util::get_codegen_backend( &early_dcx, - &config.opts.maybe_sysroot, + &sysroot, config.opts.unstable_opts.codegen_backend.as_deref(), - ) + &target, + ), + Some(make_codegen_backend) => { + // N.B. `make_codegen_backend` takes precedence over + // `target.default_codegen_backend`, which is ignored in this case. + make_codegen_backend(&config.opts) + } }; let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); @@ -367,9 +375,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se let mut locale_resources = Vec::from(config.locale_resources); locale_resources.push(codegen_backend.locale_resource()); - // target_override is documented to be called before init(), so this is okay - let target_override = codegen_backend.target_override(&config.opts); - let mut sess = rustc_session::build_session( early_dcx, config.opts, @@ -384,7 +389,8 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se locale_resources, config.lint_caps, config.file_loader, - target_override, + target, + sysroot, util::rustc_version_str().unwrap_or("unknown"), config.ice_file, config.using_internal_features, diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index da11d090b74..ee677a092e2 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::{GlobalCtxt, TyCtxt}; use rustc_serialize::opaque::FileEncodeResult; use rustc_session::config::{self, CrateType, OutputFilenames, OutputType}; use rustc_session::cstore::Untracked; -use rustc_session::output::find_crate_name; +use rustc_session::output::{collect_crate_types, find_crate_name}; use rustc_session::Session; use rustc_span::symbol::sym; use std::any::Any; @@ -128,7 +128,7 @@ impl<'tcx> Queries<'tcx> { // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches. let crate_name = find_crate_name(sess, &pre_configured_attrs); - let crate_types = util::collect_crate_types(sess, &pre_configured_attrs); + let crate_types = collect_crate_types(sess, &pre_configured_attrs); let stable_crate_id = StableCrateId::new( crate_name, crate_types.contains(&CrateType::Executable), @@ -136,7 +136,7 @@ impl<'tcx> Queries<'tcx> { sess.cfg_version, ); let outputs = util::build_output_filenames(&pre_configured_attrs, sess); - let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?; + let dep_graph = setup_dep_graph(sess)?; let cstore = FreezeLock::new(Box::new(CStore::new( self.compiler.codegen_backend.metadata_loader(), @@ -321,6 +321,8 @@ impl Compiler { } self.sess.time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph)); + + gcx.enter(rustc_query_impl::query_key_hash_verify_all); } // The timer's lifetime spans the dropping of `queries`, which contains diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 4f15d1c1d3a..8a27e9a6453 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -4,16 +4,17 @@ use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::{ build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg, - CollapseMacroDebuginfo, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, - ExternLocation, Externs, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, - InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, - OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius, - ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, + CollapseMacroDebuginfo, CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, + ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, Input, + InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, + NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, + Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, + WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; -use rustc_session::{build_session, getopts, CompilerIO, EarlyDiagCtxt, Session}; +use rustc_session::{build_session, filesearch, getopts, CompilerIO, EarlyDiagCtxt, Session}; use rustc_span::edition::{Edition, DEFAULT_EDITION}; use rustc_span::symbol::sym; use rustc_span::{FileName, SourceFileHashAlgorithm}; @@ -37,6 +38,11 @@ fn mk_session(matches: getopts::Matches) -> (Session, Cfg) { output_file: None, temps_dir, }; + + let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone()); + + let target = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot); + let sess = build_session( early_dcx, sessopts, @@ -46,7 +52,8 @@ fn mk_session(matches: getopts::Matches) -> (Session, Cfg) { vec![], Default::default(), None, - None, + target, + sysroot, "", None, Arc::default(), @@ -685,7 +692,7 @@ fn test_unstable_options_tracking_hash() { untracked!(nll_facts, true); untracked!(no_analysis, true); untracked!(no_leak_check, true); - untracked!(no_parallel_llvm, true); + untracked!(no_parallel_backend, true); untracked!(parse_only, true); // `pre_link_arg` is omitted because it just forwards to `pre_link_args`. untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]); @@ -743,6 +750,7 @@ fn test_unstable_options_tracking_hash() { ); tracked!(codegen_backend, Some("abc".to_string())); tracked!(collapse_macro_debuginfo, CollapseMacroDebuginfo::Yes); + tracked!(coverage_options, CoverageOptions { branch: true }); tracked!(crate_attr, vec!["abc".to_string()]); tracked!(cross_crate_inline_threshold, InliningThreshold::Always); tracked!(debug_info_for_profiling, true); diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 23bd2dac57e..d09f8d7d7cf 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -7,20 +7,22 @@ use rustc_data_structures::sync; use rustc_metadata::{load_symbol_from_dylib, DylibError}; use rustc_parse::validate_attr; use rustc_session as session; -use rustc_session::config::{self, Cfg, CrateType, OutFileName, OutputFilenames, OutputTypes}; +use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes}; use rustc_session::filesearch::sysroot_candidates; use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer}; -use rustc_session::{filesearch, output, Session}; +use rustc_session::{filesearch, Session}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::sym; +use rustc_target::spec::Target; +use session::output::{categorize_crate_type, CRATE_TYPES}; use session::EarlyDiagCtxt; -use std::env; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::OnceLock; use std::thread; +use std::{env, iter}; /// Function pointer type that constructs a new CodegenBackend. pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>; @@ -46,12 +48,20 @@ pub fn add_configuration(cfg: &mut Cfg, sess: &mut Session, codegen_backend: &dy } } -const STACK_SIZE: usize = 8 * 1024 * 1024; - -fn get_stack_size() -> Option<usize> { - // FIXME: Hacks on hacks. If the env is trying to override the stack size - // then *don't* set it explicitly. - env::var_os("RUST_MIN_STACK").is_none().then_some(STACK_SIZE) +pub static STACK_SIZE: OnceLock<usize> = OnceLock::new(); +pub const DEFAULT_STACK_SIZE: usize = 8 * 1024 * 1024; + +fn init_stack_size() -> usize { + // Obey the environment setting or default + *STACK_SIZE.get_or_init(|| { + env::var_os("RUST_MIN_STACK") + .map(|os_str| os_str.to_string_lossy().into_owned()) + // ignore if it is set to nothing + .filter(|s| s.trim() != "") + .map(|s| s.trim().parse::<usize>().unwrap()) + // otherwise pick a consistent default + .unwrap_or(DEFAULT_STACK_SIZE) + }) } pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>( @@ -64,10 +74,7 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>( // the parallel compiler, in particular to ensure there is no accidental // sharing of data between the main thread and the compilation thread // (which might cause problems for the parallel compiler). - let mut builder = thread::Builder::new().name("rustc".to_string()); - if let Some(size) = get_stack_size() { - builder = builder.stack_size(size); - } + let builder = thread::Builder::new().name("rustc".to_string()).stack_size(init_stack_size()); // We build the session globals and run `f` on the spawned thread, because // `SessionGlobals` does not impl `Send` in the non-parallel compiler. @@ -118,7 +125,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>( }); } - let mut builder = rayon::ThreadPoolBuilder::new() + let builder = rayon::ThreadPoolBuilder::new() .thread_name(|_| "rustc".to_string()) .acquire_thread_handler(jobserver::acquire_thread) .release_thread_handler(jobserver::release_thread) @@ -142,10 +149,8 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>( on_panic.disable(); }) .unwrap(); - }); - if let Some(size) = get_stack_size() { - builder = builder.stack_size(size); - } + }) + .stack_size(init_stack_size()); // We create the session globals on the main thread, then create the thread // pool. Upon creation, each worker thread created gets a copy of the @@ -195,21 +200,25 @@ fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBacken /// A name of `None` indicates that the default backend should be used. pub fn get_codegen_backend( early_dcx: &EarlyDiagCtxt, - maybe_sysroot: &Option<PathBuf>, + sysroot: &Path, backend_name: Option<&str>, + target: &Target, ) -> Box<dyn CodegenBackend> { static LOAD: OnceLock<unsafe fn() -> Box<dyn CodegenBackend>> = OnceLock::new(); let load = LOAD.get_or_init(|| { - let default_codegen_backend = option_env!("CFG_DEFAULT_CODEGEN_BACKEND").unwrap_or("llvm"); + let backend = backend_name + .or(target.default_codegen_backend.as_deref()) + .or(option_env!("CFG_DEFAULT_CODEGEN_BACKEND")) + .unwrap_or("llvm"); - match backend_name.unwrap_or(default_codegen_backend) { + match backend { filename if filename.contains('.') => { load_backend_from_dylib(early_dcx, filename.as_ref()) } #[cfg(feature = "llvm")] "llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new, - backend_name => get_codegen_sysroot(early_dcx, maybe_sysroot, backend_name), + backend_name => get_codegen_sysroot(early_dcx, sysroot, backend_name), } }); @@ -244,7 +253,7 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> { #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable fn get_codegen_sysroot( early_dcx: &EarlyDiagCtxt, - maybe_sysroot: &Option<PathBuf>, + sysroot: &Path, backend_name: &str, ) -> MakeBackendFn { // For now we only allow this function to be called once as it'll dlopen a @@ -261,28 +270,28 @@ fn get_codegen_sysroot( let target = session::config::host_triple(); let sysroot_candidates = sysroot_candidates(); - let sysroot = maybe_sysroot - .iter() - .chain(sysroot_candidates.iter()) + let sysroot = iter::once(sysroot) + .chain(sysroot_candidates.iter().map(<_>::as_ref)) .map(|sysroot| { filesearch::make_target_lib_path(sysroot, target).with_file_name("codegen-backends") }) .find(|f| { info!("codegen backend candidate: {}", f.display()); f.exists() - }); - let sysroot = sysroot.unwrap_or_else(|| { - let candidates = sysroot_candidates - .iter() - .map(|p| p.display().to_string()) - .collect::<Vec<_>>() - .join("\n* "); - let err = format!( - "failed to find a `codegen-backends` folder \ + }) + .unwrap_or_else(|| { + let candidates = sysroot_candidates + .iter() + .map(|p| p.display().to_string()) + .collect::<Vec<_>>() + .join("\n* "); + let err = format!( + "failed to find a `codegen-backends` folder \ in the sysroot candidates:\n* {candidates}" - ); - early_dcx.early_fatal(err); - }); + ); + early_dcx.early_fatal(err); + }); + info!("probing {} for a codegen backend", sysroot.display()); let d = sysroot.read_dir().unwrap_or_else(|e| { @@ -394,67 +403,6 @@ pub(crate) fn check_attr_crate_type( } } -const CRATE_TYPES: &[(Symbol, CrateType)] = &[ - (sym::rlib, CrateType::Rlib), - (sym::dylib, CrateType::Dylib), - (sym::cdylib, CrateType::Cdylib), - (sym::lib, config::default_lib_output()), - (sym::staticlib, CrateType::Staticlib), - (sym::proc_dash_macro, CrateType::ProcMacro), - (sym::bin, CrateType::Executable), -]; - -fn categorize_crate_type(s: Symbol) -> Option<CrateType> { - Some(CRATE_TYPES.iter().find(|(key, _)| *key == s)?.1) -} - -pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<CrateType> { - // If we're generating a test executable, then ignore all other output - // styles at all other locations - if session.opts.test { - return vec![CrateType::Executable]; - } - - // Only check command line flags if present. If no types are specified by - // command line, then reuse the empty `base` Vec to hold the types that - // will be found in crate attributes. - // JUSTIFICATION: before wrapper fn is available - #[allow(rustc::bad_opt_access)] - let mut base = session.opts.crate_types.clone(); - if base.is_empty() { - let attr_types = attrs.iter().filter_map(|a| { - if a.has_name(sym::crate_type) - && let Some(s) = a.value_str() - { - categorize_crate_type(s) - } else { - None - } - }); - base.extend(attr_types); - if base.is_empty() { - base.push(output::default_output_for_target(session)); - } else { - base.sort(); - base.dedup(); - } - } - - base.retain(|crate_type| { - if output::invalid_output_for_target(session, *crate_type) { - session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget { - crate_type: *crate_type, - target_triple: &session.opts.target_triple, - }); - false - } else { - true - } - }); - - base -} - fn multiple_output_types_to_stdout( output_types: &OutputTypes, single_output_file_is_stdout: bool, |
