Auto merge of #83610 - bjorn3:driver_cleanup, r=cjgillot
rustc_driver cleanup Best reviewed one commit at a time.
This commit is contained in:
commit
ac923d94f8
16 changed files with 168 additions and 224 deletions
|
@ -298,7 +298,7 @@ pub(crate) fn run_aot(
|
|||
metadata_module,
|
||||
metadata,
|
||||
windows_subsystem,
|
||||
linker_info: LinkerInfo::new(tcx),
|
||||
linker_info: LinkerInfo::new(tcx, crate::target_triple(tcx.sess).to_string()),
|
||||
crate_info: CrateInfo::new(tcx),
|
||||
},
|
||||
work_products,
|
||||
|
|
|
@ -218,13 +218,11 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
) -> Result<(), ErrorReported> {
|
||||
use rustc_codegen_ssa::back::link::link_binary;
|
||||
|
||||
let target_cpu = crate::target_triple(sess).to_string();
|
||||
link_binary::<crate::archive::ArArchiveBuilder<'_>>(
|
||||
sess,
|
||||
&codegen_results,
|
||||
outputs,
|
||||
&codegen_results.crate_name.as_str(),
|
||||
&target_cpu,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -4,12 +4,10 @@ use std::ffi::CString;
|
|||
|
||||
use cstr::cstr;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::ty::layout::HasTyCtxt;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::config::OptLevel;
|
||||
use rustc_session::Session;
|
||||
|
@ -355,35 +353,6 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
|
|||
}
|
||||
}
|
||||
|
||||
pub fn provide_both(providers: &mut Providers) {
|
||||
providers.wasm_import_module_map = |tcx, cnum| {
|
||||
// Build up a map from DefId to a `NativeLib` structure, where
|
||||
// `NativeLib` internally contains information about
|
||||
// `#[link(wasm_import_module = "...")]` for example.
|
||||
let native_libs = tcx.native_libraries(cnum);
|
||||
|
||||
let def_id_to_native_lib = native_libs
|
||||
.iter()
|
||||
.filter_map(|lib| lib.foreign_module.map(|id| (id, lib)))
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
|
||||
let mut ret = FxHashMap::default();
|
||||
for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
|
||||
let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module);
|
||||
let module = match module {
|
||||
Some(s) => s,
|
||||
None => continue,
|
||||
};
|
||||
ret.extend(lib.foreign_items.iter().map(|id| {
|
||||
assert_eq!(id.krate, cnum);
|
||||
(*id, module.to_string())
|
||||
}));
|
||||
}
|
||||
|
||||
ret
|
||||
};
|
||||
}
|
||||
|
||||
fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option<CString> {
|
||||
tcx.wasm_import_module_map(id.krate).get(&id).map(|s| CString::new(&s[..]).unwrap())
|
||||
}
|
||||
|
|
|
@ -254,13 +254,8 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
Box::new(metadata::LlvmMetadataLoader)
|
||||
}
|
||||
|
||||
fn provide(&self, providers: &mut ty::query::Providers) {
|
||||
attributes::provide_both(providers);
|
||||
}
|
||||
|
||||
fn provide_extern(&self, providers: &mut ty::query::Providers) {
|
||||
attributes::provide_both(providers);
|
||||
}
|
||||
fn provide(&self, _providers: &mut ty::query::Providers) {}
|
||||
fn provide_extern(&self, _providers: &mut ty::query::Providers) {}
|
||||
|
||||
fn codegen_crate<'tcx>(
|
||||
&self,
|
||||
|
@ -271,6 +266,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
Box::new(rustc_codegen_ssa::base::codegen_crate(
|
||||
LlvmCodegenBackend(()),
|
||||
tcx,
|
||||
crate::llvm_util::target_cpu(tcx.sess).to_string(),
|
||||
metadata,
|
||||
need_metadata_module,
|
||||
))
|
||||
|
@ -306,13 +302,11 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||
|
||||
// Run the linker on any artifacts that resulted from the LLVM run.
|
||||
// This should produce either a finished executable or library.
|
||||
let target_cpu = crate::llvm_util::target_cpu(sess);
|
||||
link_binary::<LlvmArchiveBuilder<'_>>(
|
||||
sess,
|
||||
&codegen_results,
|
||||
outputs,
|
||||
&codegen_results.crate_name.as_str(),
|
||||
target_cpu,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -50,7 +50,6 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
|||
codegen_results: &CodegenResults,
|
||||
outputs: &OutputFilenames,
|
||||
crate_name: &str,
|
||||
target_cpu: &str,
|
||||
) {
|
||||
let _timer = sess.timer("link_binary");
|
||||
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
|
||||
|
@ -100,7 +99,6 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
|||
&out_filename,
|
||||
codegen_results,
|
||||
path.as_ref(),
|
||||
target_cpu,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -532,7 +530,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
|
|||
out_filename: &Path,
|
||||
codegen_results: &CodegenResults,
|
||||
tmpdir: &Path,
|
||||
target_cpu: &str,
|
||||
) {
|
||||
info!("preparing {:?} to {:?}", crate_type, out_filename);
|
||||
let (linker_path, flavor) = linker_and_flavor(sess);
|
||||
|
@ -544,7 +541,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
|
|||
tmpdir,
|
||||
out_filename,
|
||||
codegen_results,
|
||||
target_cpu,
|
||||
);
|
||||
|
||||
linker::disable_localization(&mut cmd);
|
||||
|
@ -1609,14 +1605,13 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
|
|||
tmpdir: &Path,
|
||||
out_filename: &Path,
|
||||
codegen_results: &CodegenResults,
|
||||
target_cpu: &str,
|
||||
) -> Command {
|
||||
let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
|
||||
let base_cmd = get_linker(sess, path, flavor, crt_objects_fallback);
|
||||
// FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
|
||||
// to the linker args construction.
|
||||
assert!(base_cmd.get_args().is_empty() || sess.target.vendor == "uwp");
|
||||
let cmd = &mut *codegen_results.linker_info.to_linker(base_cmd, &sess, flavor, target_cpu);
|
||||
let cmd = &mut *codegen_results.linker_info.to_linker(base_cmd, &sess, flavor);
|
||||
let link_output_kind = link_output_kind(sess, crate_type);
|
||||
|
||||
// NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
|
||||
|
|
|
@ -37,12 +37,14 @@ pub fn disable_localization(linker: &mut Command) {
|
|||
/// need out of the shared crate context before we get rid of it.
|
||||
#[derive(Encodable, Decodable)]
|
||||
pub struct LinkerInfo {
|
||||
target_cpu: String,
|
||||
exports: FxHashMap<CrateType, Vec<String>>,
|
||||
}
|
||||
|
||||
impl LinkerInfo {
|
||||
pub fn new(tcx: TyCtxt<'_>) -> LinkerInfo {
|
||||
pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> LinkerInfo {
|
||||
LinkerInfo {
|
||||
target_cpu,
|
||||
exports: tcx
|
||||
.sess
|
||||
.crate_types()
|
||||
|
@ -57,38 +59,31 @@ impl LinkerInfo {
|
|||
cmd: Command,
|
||||
sess: &'a Session,
|
||||
flavor: LinkerFlavor,
|
||||
target_cpu: &'a str,
|
||||
) -> Box<dyn Linker + 'a> {
|
||||
match flavor {
|
||||
LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
|
||||
Box::new(MsvcLinker { cmd, sess, info: self }) as Box<dyn Linker>
|
||||
}
|
||||
LinkerFlavor::Em => Box::new(EmLinker { cmd, sess, info: self }) as Box<dyn Linker>,
|
||||
LinkerFlavor::Gcc => Box::new(GccLinker {
|
||||
cmd,
|
||||
sess,
|
||||
info: self,
|
||||
hinted_static: false,
|
||||
is_ld: false,
|
||||
target_cpu,
|
||||
}) as Box<dyn Linker>,
|
||||
LinkerFlavor::Gcc => {
|
||||
Box::new(GccLinker { cmd, sess, info: self, hinted_static: false, is_ld: false })
|
||||
as Box<dyn Linker>
|
||||
}
|
||||
|
||||
LinkerFlavor::Lld(LldFlavor::Ld)
|
||||
| LinkerFlavor::Lld(LldFlavor::Ld64)
|
||||
| LinkerFlavor::Ld => Box::new(GccLinker {
|
||||
cmd,
|
||||
sess,
|
||||
info: self,
|
||||
hinted_static: false,
|
||||
is_ld: true,
|
||||
target_cpu,
|
||||
}) as Box<dyn Linker>,
|
||||
| LinkerFlavor::Ld => {
|
||||
Box::new(GccLinker { cmd, sess, info: self, hinted_static: false, is_ld: true })
|
||||
as Box<dyn Linker>
|
||||
}
|
||||
|
||||
LinkerFlavor::Lld(LldFlavor::Wasm) => {
|
||||
Box::new(WasmLd::new(cmd, sess, self)) as Box<dyn Linker>
|
||||
}
|
||||
|
||||
LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
|
||||
LinkerFlavor::PtxLinker => {
|
||||
Box::new(PtxLinker { cmd, sess, info: self }) as Box<dyn Linker>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +152,6 @@ pub struct GccLinker<'a> {
|
|||
hinted_static: bool, // Keeps track of the current hinting mode.
|
||||
// Link as ld
|
||||
is_ld: bool,
|
||||
target_cpu: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> GccLinker<'a> {
|
||||
|
@ -229,8 +223,7 @@ impl<'a> GccLinker<'a> {
|
|||
};
|
||||
|
||||
self.linker_arg(&format!("-plugin-opt={}", opt_level));
|
||||
let target_cpu = self.target_cpu;
|
||||
self.linker_arg(&format!("-plugin-opt=mcpu={}", target_cpu));
|
||||
self.linker_arg(&format!("-plugin-opt=mcpu={}", self.info.target_cpu));
|
||||
}
|
||||
|
||||
fn build_dylib(&mut self, out_filename: &Path) {
|
||||
|
@ -1336,6 +1329,7 @@ fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
|
|||
pub struct PtxLinker<'a> {
|
||||
cmd: Command,
|
||||
sess: &'a Session,
|
||||
info: &'a LinkerInfo,
|
||||
}
|
||||
|
||||
impl<'a> Linker for PtxLinker<'a> {
|
||||
|
@ -1381,10 +1375,7 @@ impl<'a> Linker for PtxLinker<'a> {
|
|||
|
||||
fn finalize(&mut self) {
|
||||
// Provide the linker with fallback to internal `target-cpu`.
|
||||
self.cmd.arg("--fallback-arch").arg(match self.sess.opts.cg.target_cpu {
|
||||
Some(ref s) => s,
|
||||
None => &self.sess.target.cpu,
|
||||
});
|
||||
self.cmd.arg("--fallback-arch").arg(&self.info.target_cpu);
|
||||
}
|
||||
|
||||
fn link_dylib(&mut self, _lib: Symbol, _verbatim: bool, _as_needed: bool) {
|
||||
|
|
|
@ -370,11 +370,13 @@ pub fn provide(providers: &mut Providers) {
|
|||
providers.upstream_monomorphizations = upstream_monomorphizations_provider;
|
||||
providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
|
||||
providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;
|
||||
providers.wasm_import_module_map = wasm_import_module_map;
|
||||
}
|
||||
|
||||
pub fn provide_extern(providers: &mut Providers) {
|
||||
providers.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
|
||||
providers.upstream_monomorphizations_for = upstream_monomorphizations_for_provider;
|
||||
providers.wasm_import_module_map = wasm_import_module_map;
|
||||
}
|
||||
|
||||
fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel {
|
||||
|
@ -442,3 +444,30 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
|
|||
ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, String> {
|
||||
// Build up a map from DefId to a `NativeLib` structure, where
|
||||
// `NativeLib` internally contains information about
|
||||
// `#[link(wasm_import_module = "...")]` for example.
|
||||
let native_libs = tcx.native_libraries(cnum);
|
||||
|
||||
let def_id_to_native_lib = native_libs
|
||||
.iter()
|
||||
.filter_map(|lib| lib.foreign_module.map(|id| (id, lib)))
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
|
||||
let mut ret = FxHashMap::default();
|
||||
for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
|
||||
let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module);
|
||||
let module = match module {
|
||||
Some(s) => s,
|
||||
None => continue,
|
||||
};
|
||||
ret.extend(lib.foreign_items.iter().map(|id| {
|
||||
assert_eq!(id.krate, cnum);
|
||||
(*id, module.to_string())
|
||||
}));
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
|
|
@ -419,6 +419,7 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
|
|||
pub fn start_async_codegen<B: ExtraBackendMethods>(
|
||||
backend: B,
|
||||
tcx: TyCtxt<'_>,
|
||||
target_cpu: String,
|
||||
metadata: EncodedMetadata,
|
||||
total_cgus: usize,
|
||||
) -> OngoingCodegen<B> {
|
||||
|
@ -441,7 +442,7 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
|
|||
subsystem.to_string()
|
||||
});
|
||||
|
||||
let linker_info = LinkerInfo::new(tcx);
|
||||
let linker_info = LinkerInfo::new(tcx, target_cpu);
|
||||
let crate_info = CrateInfo::new(tcx);
|
||||
|
||||
let regular_config =
|
||||
|
|
|
@ -467,12 +467,13 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
pub fn codegen_crate<B: ExtraBackendMethods>(
|
||||
backend: B,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
target_cpu: String,
|
||||
metadata: EncodedMetadata,
|
||||
need_metadata_module: bool,
|
||||
) -> OngoingCodegen<B> {
|
||||
// Skip crate items and just output metadata in -Z no-codegen mode.
|
||||
if tcx.sess.opts.debugging_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() {
|
||||
let ongoing_codegen = start_async_codegen(backend, tcx, metadata, 1);
|
||||
let ongoing_codegen = start_async_codegen(backend, tcx, target_cpu, metadata, 1);
|
||||
|
||||
ongoing_codegen.codegen_finished(tcx);
|
||||
|
||||
|
@ -498,7 +499,8 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
|||
}
|
||||
}
|
||||
|
||||
let ongoing_codegen = start_async_codegen(backend.clone(), tcx, metadata, codegen_units.len());
|
||||
let ongoing_codegen =
|
||||
start_async_codegen(backend.clone(), tcx, target_cpu, metadata, codegen_units.len());
|
||||
let ongoing_codegen = AbortCodegenOnDrop::<B>(Some(ongoing_codegen));
|
||||
|
||||
// Codegen an allocator shim, if necessary.
|
||||
|
|
|
@ -35,7 +35,7 @@ use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, Tr
|
|||
use rustc_session::getopts;
|
||||
use rustc_session::lint::{Lint, LintId};
|
||||
use rustc_session::{config, DiagnosticOutput, Session};
|
||||
use rustc_session::{early_error, early_warn};
|
||||
use rustc_session::{early_error, early_error_no_abort, early_warn};
|
||||
use rustc_span::source_map::{FileLoader, FileName};
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
|
@ -133,6 +133,7 @@ pub fn diagnostics_registry() -> Registry {
|
|||
Registry::new(&rustc_error_codes::DIAGNOSTICS)
|
||||
}
|
||||
|
||||
/// This is the primary entry point for rustc.
|
||||
pub struct RunCompiler<'a, 'b> {
|
||||
at_args: &'a [String],
|
||||
callbacks: &'b mut (dyn Callbacks + Send),
|
||||
|
@ -146,6 +147,9 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
|
|||
pub fn new(at_args: &'a [String], callbacks: &'b mut (dyn Callbacks + Send)) -> Self {
|
||||
Self { at_args, callbacks, file_loader: None, emitter: None, make_codegen_backend: None }
|
||||
}
|
||||
|
||||
/// Set a custom codegen backend.
|
||||
///
|
||||
/// Used by cg_clif.
|
||||
pub fn set_make_codegen_backend(
|
||||
&mut self,
|
||||
|
@ -156,11 +160,17 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
|
|||
self.make_codegen_backend = make_codegen_backend;
|
||||
self
|
||||
}
|
||||
|
||||
/// Emit diagnostics to the specified location.
|
||||
///
|
||||
/// Used by RLS.
|
||||
pub fn set_emitter(&mut self, emitter: Option<Box<dyn Write + Send>>) -> &mut Self {
|
||||
self.emitter = emitter;
|
||||
self
|
||||
}
|
||||
|
||||
/// Load files from sources other than the file system.
|
||||
///
|
||||
/// Used by RLS.
|
||||
pub fn set_file_loader(
|
||||
&mut self,
|
||||
|
@ -169,6 +179,8 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
|
|||
self.file_loader = file_loader;
|
||||
self
|
||||
}
|
||||
|
||||
/// Parse args and run the compiler.
|
||||
pub fn run(self) -> interface::Result<()> {
|
||||
run_compiler(
|
||||
self.at_args,
|
||||
|
@ -179,8 +191,6 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
|
|||
)
|
||||
}
|
||||
}
|
||||
// Parse args and run the compiler. This is the primary entry point for rustc.
|
||||
// The FileLoader provides a way to load files from sources other than the file system.
|
||||
fn run_compiler(
|
||||
at_args: &[String],
|
||||
callbacks: &mut (dyn Callbacks + Send),
|
||||
|
@ -199,46 +209,43 @@ fn run_compiler(
|
|||
};
|
||||
|
||||
let sopts = config::build_session_options(&matches);
|
||||
let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg"));
|
||||
|
||||
// We wrap `make_codegen_backend` in another `Option` such that `dummy_config` can take
|
||||
// ownership of it when necessary, while also allowing the non-dummy config to take ownership
|
||||
// when `dummy_config` is not used.
|
||||
let mut make_codegen_backend = Some(make_codegen_backend);
|
||||
|
||||
let mut dummy_config = |sopts, cfg, diagnostic_output| {
|
||||
let mut config = interface::Config {
|
||||
opts: sopts,
|
||||
crate_cfg: cfg,
|
||||
input: Input::File(PathBuf::new()),
|
||||
input_path: None,
|
||||
output_file: None,
|
||||
output_dir: None,
|
||||
file_loader: None,
|
||||
diagnostic_output,
|
||||
stderr: None,
|
||||
lint_caps: Default::default(),
|
||||
parse_sess_created: None,
|
||||
register_lints: None,
|
||||
override_queries: None,
|
||||
make_codegen_backend: make_codegen_backend.take().unwrap(),
|
||||
registry: diagnostics_registry(),
|
||||
};
|
||||
callbacks.config(&mut config);
|
||||
config
|
||||
};
|
||||
|
||||
if let Some(ref code) = matches.opt_str("explain") {
|
||||
handle_explain(diagnostics_registry(), code, sopts.error_format);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg"));
|
||||
let (odir, ofile) = make_output(&matches);
|
||||
let (input, input_file_path, input_err) = match make_input(&matches.free) {
|
||||
Some(v) => v,
|
||||
None => match matches.free.len() {
|
||||
let mut config = interface::Config {
|
||||
opts: sopts,
|
||||
crate_cfg: cfg,
|
||||
input: Input::File(PathBuf::new()),
|
||||
input_path: None,
|
||||
output_file: ofile,
|
||||
output_dir: odir,
|
||||
file_loader,
|
||||
diagnostic_output,
|
||||
stderr: None,
|
||||
lint_caps: Default::default(),
|
||||
parse_sess_created: None,
|
||||
register_lints: None,
|
||||
override_queries: None,
|
||||
make_codegen_backend,
|
||||
registry: diagnostics_registry(),
|
||||
};
|
||||
|
||||
match make_input(config.opts.error_format, &matches.free) {
|
||||
Err(ErrorReported) => return Err(ErrorReported),
|
||||
Ok(Some((input, input_file_path))) => {
|
||||
config.input = input;
|
||||
config.input_path = input_file_path;
|
||||
|
||||
callbacks.config(&mut config);
|
||||
}
|
||||
Ok(None) => match matches.free.len() {
|
||||
0 => {
|
||||
let config = dummy_config(sopts, cfg, diagnostic_output);
|
||||
callbacks.config(&mut config);
|
||||
interface::run_compiler(config, |compiler| {
|
||||
let sopts = &compiler.session().opts;
|
||||
if sopts.describe_lints {
|
||||
|
@ -260,8 +267,8 @@ fn run_compiler(
|
|||
&***compiler.codegen_backend(),
|
||||
compiler.session(),
|
||||
None,
|
||||
&odir,
|
||||
&ofile,
|
||||
&compiler.output_dir(),
|
||||
&compiler.output_file(),
|
||||
);
|
||||
|
||||
if should_stop == Compilation::Stop {
|
||||
|
@ -273,7 +280,7 @@ fn run_compiler(
|
|||
}
|
||||
1 => panic!("make_input should have provided valid inputs"),
|
||||
_ => early_error(
|
||||
sopts.error_format,
|
||||
config.opts.error_format,
|
||||
&format!(
|
||||
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
|
||||
matches.free[0], matches.free[1],
|
||||
|
@ -282,35 +289,6 @@ fn run_compiler(
|
|||
},
|
||||
};
|
||||
|
||||
if let Some(err) = input_err {
|
||||
// Immediately stop compilation if there was an issue reading
|
||||
// the input (for example if the input stream is not UTF-8).
|
||||
interface::run_compiler(dummy_config(sopts, cfg, diagnostic_output), |compiler| {
|
||||
compiler.session().err(&err.to_string());
|
||||
});
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
|
||||
let mut config = interface::Config {
|
||||
opts: sopts,
|
||||
crate_cfg: cfg,
|
||||
input,
|
||||
input_path: input_file_path,
|
||||
output_file: ofile,
|
||||
output_dir: odir,
|
||||
file_loader,
|
||||
diagnostic_output,
|
||||
stderr: None,
|
||||
lint_caps: Default::default(),
|
||||
parse_sess_created: None,
|
||||
register_lints: None,
|
||||
override_queries: None,
|
||||
make_codegen_backend: make_codegen_backend.unwrap(),
|
||||
registry: diagnostics_registry(),
|
||||
};
|
||||
|
||||
callbacks.config(&mut config);
|
||||
|
||||
interface::run_compiler(config, |compiler| {
|
||||
let sess = compiler.session();
|
||||
let should_stop = RustcDefaultCalls::print_crate_info(
|
||||
|
@ -324,7 +302,6 @@ fn run_compiler(
|
|||
RustcDefaultCalls::list_metadata(
|
||||
sess,
|
||||
&*compiler.codegen_backend().metadata_loader(),
|
||||
&matches,
|
||||
compiler.input(),
|
||||
)
|
||||
})
|
||||
|
@ -411,11 +388,10 @@ fn run_compiler(
|
|||
return early_exit();
|
||||
}
|
||||
|
||||
if sess.opts.debugging_opts.save_analysis {
|
||||
let crate_name = queries.crate_name()?.peek().clone();
|
||||
queries.global_ctxt()?.peek_mut().enter(|tcx| {
|
||||
let result = tcx.analysis(LOCAL_CRATE);
|
||||
|
||||
queries.global_ctxt()?.peek_mut().enter(|tcx| {
|
||||
let result = tcx.analysis(LOCAL_CRATE);
|
||||
if sess.opts.debugging_opts.save_analysis {
|
||||
let crate_name = queries.crate_name()?.peek().clone();
|
||||
sess.time("save_analysis", || {
|
||||
save::process_crate(
|
||||
tcx,
|
||||
|
@ -428,12 +404,9 @@ fn run_compiler(
|
|||
),
|
||||
)
|
||||
});
|
||||
|
||||
result
|
||||
})?;
|
||||
}
|
||||
|
||||
queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?;
|
||||
}
|
||||
result
|
||||
})?;
|
||||
|
||||
if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
|
||||
return early_exit();
|
||||
|
@ -490,19 +463,23 @@ fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>)
|
|||
}
|
||||
|
||||
// Extract input (string or file and optional path) from matches.
|
||||
fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option<io::Error>)> {
|
||||
fn make_input(
|
||||
error_format: ErrorOutputType,
|
||||
free_matches: &[String],
|
||||
) -> Result<Option<(Input, Option<PathBuf>)>, ErrorReported> {
|
||||
if free_matches.len() == 1 {
|
||||
let ifile = &free_matches[0];
|
||||
if ifile == "-" {
|
||||
let mut src = String::new();
|
||||
let err = if io::stdin().read_to_string(&mut src).is_err() {
|
||||
Some(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
if io::stdin().read_to_string(&mut src).is_err() {
|
||||
// Immediately stop compilation if there was an issue reading
|
||||
// the input (for example if the input stream is not UTF-8).
|
||||
early_error_no_abort(
|
||||
error_format,
|
||||
"couldn't read from stdin, as it did not contain valid UTF-8",
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
);
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
|
||||
let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect(
|
||||
"when UNSTABLE_RUSTDOC_TEST_PATH is set \
|
||||
|
@ -511,14 +488,15 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option
|
|||
let line = isize::from_str_radix(&line, 10)
|
||||
.expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
|
||||
let file_name = FileName::doc_test_source_code(PathBuf::from(path), line);
|
||||
return Some((Input::Str { name: file_name, input: src }, None, err));
|
||||
Ok(Some((Input::Str { name: file_name, input: src }, None)))
|
||||
} else {
|
||||
Ok(Some((Input::Str { name: FileName::anon_source_code(&src), input: src }, None)))
|
||||
}
|
||||
Some((Input::Str { name: FileName::anon_source_code(&src), input: src }, None, err))
|
||||
} else {
|
||||
Some((Input::File(PathBuf::from(ifile)), Some(PathBuf::from(ifile)), None))
|
||||
Ok(Some((Input::File(PathBuf::from(ifile)), Some(PathBuf::from(ifile)))))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -619,28 +597,24 @@ fn show_content_with_pager(content: &str) {
|
|||
}
|
||||
|
||||
impl RustcDefaultCalls {
|
||||
fn process_rlink(sess: &Session, compiler: &interface::Compiler) -> Result<(), ErrorReported> {
|
||||
if let Input::File(file) = compiler.input() {
|
||||
// FIXME: #![crate_type] and #![crate_name] support not implemented yet
|
||||
let attrs = vec![];
|
||||
sess.init_crate_types(collect_crate_types(sess, &attrs));
|
||||
let outputs = compiler.build_output_filenames(&sess, &attrs);
|
||||
let rlink_data = fs::read_to_string(file).unwrap_or_else(|err| {
|
||||
sess.fatal(&format!("failed to read rlink file: {}", err));
|
||||
});
|
||||
let codegen_results: CodegenResults = json::decode(&rlink_data).unwrap_or_else(|err| {
|
||||
sess.fatal(&format!("failed to decode rlink: {}", err));
|
||||
});
|
||||
compiler.codegen_backend().link(&sess, codegen_results, &outputs)
|
||||
} else {
|
||||
sess.fatal("rlink must be a file")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation {
|
||||
if sess.opts.debugging_opts.link_only {
|
||||
let result = RustcDefaultCalls::process_rlink(sess, compiler);
|
||||
abort_on_err(result, sess);
|
||||
if let Input::File(file) = compiler.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 rlink_data = fs::read_to_string(file).unwrap_or_else(|err| {
|
||||
sess.fatal(&format!("failed to read rlink file: {}", err));
|
||||
});
|
||||
let codegen_results: CodegenResults =
|
||||
json::decode(&rlink_data).unwrap_or_else(|err| {
|
||||
sess.fatal(&format!("failed to decode rlink: {}", err));
|
||||
});
|
||||
let result = compiler.codegen_backend().link(&sess, codegen_results, &outputs);
|
||||
abort_on_err(result, sess);
|
||||
} else {
|
||||
sess.fatal("rlink must be a file")
|
||||
}
|
||||
Compilation::Stop
|
||||
} else {
|
||||
Compilation::Continue
|
||||
|
@ -650,11 +624,9 @@ impl RustcDefaultCalls {
|
|||
pub fn list_metadata(
|
||||
sess: &Session,
|
||||
metadata_loader: &dyn MetadataLoader,
|
||||
matches: &getopts::Matches,
|
||||
input: &Input,
|
||||
) -> Compilation {
|
||||
let r = matches.opt_strs("Z");
|
||||
if r.iter().any(|s| *s == "ls") {
|
||||
if sess.opts.debugging_opts.ls {
|
||||
match *input {
|
||||
Input::File(ref ifile) => {
|
||||
let path = &(*ifile);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Code to save/load the dep-graph from files.
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::definitions::Definitions;
|
||||
use rustc_hir::definitions::DefPathTable;
|
||||
use rustc_middle::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
|
||||
use rustc_middle::ty::query::OnDiskCache;
|
||||
use rustc_serialize::opaque::Decoder;
|
||||
|
@ -198,7 +198,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
|
|||
/// creating an empty cache if it could not be loaded.
|
||||
pub fn load_query_result_cache<'a>(
|
||||
sess: &'a Session,
|
||||
definitions: &Definitions,
|
||||
def_path_table: &DefPathTable,
|
||||
) -> Option<OnDiskCache<'a>> {
|
||||
if sess.opts.incremental.is_none() {
|
||||
return None;
|
||||
|
@ -212,7 +212,7 @@ pub fn load_query_result_cache<'a>(
|
|||
sess.is_nightly_build(),
|
||||
) {
|
||||
LoadResult::Ok { data: (bytes, start_pos) } => {
|
||||
Some(OnDiskCache::new(sess, bytes, start_pos, definitions))
|
||||
Some(OnDiskCache::new(sess, bytes, start_pos, def_path_table))
|
||||
}
|
||||
_ => Some(OnDiskCache::new_empty(sess.source_map())),
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use rustc_data_structures::{box_region_allow_access, declare_box_region_type, pa
|
|||
use rustc_errors::{ErrorReported, PResult};
|
||||
use rustc_expand::base::ExtCtxt;
|
||||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::Definitions;
|
||||
use rustc_hir::Crate;
|
||||
use rustc_lint::LintStore;
|
||||
use rustc_metadata::creader::CStore;
|
||||
|
@ -51,7 +50,7 @@ use std::io::{self, BufWriter, Write};
|
|||
use std::lazy::SyncLazy;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::{env, fs, iter, mem};
|
||||
use std::{env, fs, iter};
|
||||
|
||||
pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
|
||||
let krate = sess.time("parse_crate", || match input {
|
||||
|
@ -761,7 +760,7 @@ pub fn create_global_ctxt<'tcx>(
|
|||
lint_store: Lrc<LintStore>,
|
||||
krate: &'tcx Crate<'tcx>,
|
||||
dep_graph: DepGraph,
|
||||
mut resolver_outputs: ResolverOutputs,
|
||||
resolver_outputs: ResolverOutputs,
|
||||
outputs: OutputFilenames,
|
||||
crate_name: &str,
|
||||
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
|
||||
|
@ -769,12 +768,10 @@ pub fn create_global_ctxt<'tcx>(
|
|||
arena: &'tcx WorkerLocal<Arena<'tcx>>,
|
||||
) -> QueryContext<'tcx> {
|
||||
let sess = &compiler.session();
|
||||
let defs: &'tcx Definitions = arena.alloc(mem::replace(
|
||||
&mut resolver_outputs.definitions,
|
||||
Definitions::new(crate_name, sess.local_crate_disambiguator()),
|
||||
));
|
||||
|
||||
let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess, defs);
|
||||
let def_path_table = resolver_outputs.definitions.def_path_table();
|
||||
let query_result_on_disk_cache =
|
||||
rustc_incremental::load_query_result_cache(sess, def_path_table);
|
||||
|
||||
let codegen_backend = compiler.codegen_backend();
|
||||
let mut local_providers = *DEFAULT_QUERY_PROVIDERS;
|
||||
|
@ -798,7 +795,6 @@ pub fn create_global_ctxt<'tcx>(
|
|||
arena,
|
||||
resolver_outputs,
|
||||
krate,
|
||||
defs,
|
||||
dep_graph,
|
||||
query_result_on_disk_cache,
|
||||
queries.as_dyn(),
|
||||
|
|
|
@ -973,7 +973,7 @@ pub struct GlobalCtxt<'tcx> {
|
|||
export_map: ExportMap<LocalDefId>,
|
||||
|
||||
pub(crate) untracked_crate: &'tcx hir::Crate<'tcx>,
|
||||
pub(crate) definitions: &'tcx Definitions,
|
||||
pub(crate) definitions: Definitions,
|
||||
|
||||
/// This provides access to the incremental compilation on-disk cache for query results.
|
||||
/// Do not access this directly. It is only meant to be used by
|
||||
|
@ -1130,7 +1130,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
arena: &'tcx WorkerLocal<Arena<'tcx>>,
|
||||
resolutions: ty::ResolverOutputs,
|
||||
krate: &'tcx hir::Crate<'tcx>,
|
||||
definitions: &'tcx Definitions,
|
||||
dep_graph: DepGraph,
|
||||
on_disk_cache: Option<query::OnDiskCache<'tcx>>,
|
||||
queries: &'tcx dyn query::QueryEngine<'tcx>,
|
||||
|
@ -1172,7 +1171,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
glob_map: resolutions.glob_map,
|
||||
extern_prelude: resolutions.extern_prelude,
|
||||
untracked_crate: krate,
|
||||
definitions,
|
||||
definitions: resolutions.definitions,
|
||||
on_disk_cache,
|
||||
queries,
|
||||
query_caches: query::QueryCaches::default(),
|
||||
|
@ -1329,14 +1328,14 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
|
||||
let krate = self.gcx.untracked_crate;
|
||||
|
||||
StableHashingContext::new(self.sess, krate, self.definitions, &*self.cstore)
|
||||
StableHashingContext::new(self.sess, krate, &self.definitions, &*self.cstore)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> {
|
||||
let krate = self.gcx.untracked_crate;
|
||||
|
||||
StableHashingContext::ignore_spans(self.sess, krate, self.definitions, &*self.cstore)
|
||||
StableHashingContext::ignore_spans(self.sess, krate, &self.definitions, &*self.cstore)
|
||||
}
|
||||
|
||||
pub fn serialize_query_result_cache(self, encoder: &mut FileEncoder) -> FileEncodeResult {
|
||||
|
|
|
@ -10,8 +10,7 @@ use rustc_data_structures::thin_vec::ThinVec;
|
|||
use rustc_data_structures::unhash::UnhashMap;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::DefPathHash;
|
||||
use rustc_hir::definitions::Definitions;
|
||||
use rustc_hir::definitions::{DefPathHash, DefPathTable};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_query_system::dep_graph::DepContext;
|
||||
use rustc_query_system::query::QueryContext;
|
||||
|
@ -167,22 +166,13 @@ crate struct RawDefId {
|
|||
pub index: u32,
|
||||
}
|
||||
|
||||
fn make_local_def_path_hash_map(definitions: &Definitions) -> UnhashMap<DefPathHash, LocalDefId> {
|
||||
UnhashMap::from_iter(
|
||||
definitions
|
||||
.def_path_table()
|
||||
.all_def_path_hashes_and_def_ids(LOCAL_CRATE)
|
||||
.map(|(hash, def_id)| (hash, def_id.as_local().unwrap())),
|
||||
)
|
||||
}
|
||||
|
||||
impl<'sess> OnDiskCache<'sess> {
|
||||
/// Creates a new `OnDiskCache` instance from the serialized data in `data`.
|
||||
pub fn new(
|
||||
sess: &'sess Session,
|
||||
data: Vec<u8>,
|
||||
start_pos: usize,
|
||||
definitions: &Definitions,
|
||||
def_path_table: &DefPathTable,
|
||||
) -> Self {
|
||||
debug_assert!(sess.opts.incremental.is_some());
|
||||
|
||||
|
@ -220,7 +210,11 @@ impl<'sess> OnDiskCache<'sess> {
|
|||
hygiene_context: Default::default(),
|
||||
foreign_def_path_hashes: footer.foreign_def_path_hashes,
|
||||
latest_foreign_def_path_hashes: Default::default(),
|
||||
local_def_path_hash_to_def_id: make_local_def_path_hash_map(definitions),
|
||||
local_def_path_hash_to_def_id: UnhashMap::from_iter(
|
||||
def_path_table
|
||||
.all_def_path_hashes_and_def_ids(LOCAL_CRATE)
|
||||
.map(|(hash, def_id)| (hash, def_id.as_local().unwrap())),
|
||||
),
|
||||
def_path_hash_to_def_id_cache: Default::default(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1528,7 +1528,7 @@ pub enum IncrCompSession {
|
|||
InvalidBecauseOfErrors { session_directory: PathBuf },
|
||||
}
|
||||
|
||||
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
|
||||
pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) {
|
||||
let emitter: Box<dyn Emitter + sync::Send> = match output {
|
||||
config::ErrorOutputType::HumanReadable(kind) => {
|
||||
let (short, color_config) = kind.unzip();
|
||||
|
@ -1540,6 +1540,10 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
|
|||
};
|
||||
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
|
||||
handler.struct_fatal(msg).emit();
|
||||
}
|
||||
|
||||
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
|
||||
early_error_no_abort(output, msg);
|
||||
rustc_errors::FatalError.raise();
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ impl CodegenBackend for TheBackend {
|
|||
metadata_module: None,
|
||||
metadata,
|
||||
windows_subsystem: None,
|
||||
linker_info: LinkerInfo::new(tcx),
|
||||
linker_info: LinkerInfo::new(tcx, "fake_target_cpu".to_string()),
|
||||
crate_info: CrateInfo::new(tcx),
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue