2014-11-27 14:57:47 +00:00
|
|
|
//! The Rust compiler.
|
|
|
|
//!
|
|
|
|
//! # Note
|
|
|
|
//!
|
|
|
|
//! This API is completely unstable and subject to change.
|
|
|
|
|
2020-09-23 19:51:56 +00:00
|
|
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
2022-12-12 05:42:45 +00:00
|
|
|
#![feature(lazy_cell)]
|
2022-11-09 08:52:59 +00:00
|
|
|
#![feature(decl_macro)]
|
2018-03-03 05:19:15 +00:00
|
|
|
#![recursion_limit = "256"]
|
2022-02-23 13:06:22 +00:00
|
|
|
#![allow(rustc::potential_query_instability)]
|
2022-08-22 21:43:09 +00:00
|
|
|
#![deny(rustc::untranslatable_diagnostic)]
|
|
|
|
#![deny(rustc::diagnostic_outside_of_impl)]
|
2018-03-03 05:19:15 +00:00
|
|
|
|
2015-11-10 20:48:44 +00:00
|
|
|
#[macro_use]
|
2020-08-14 06:05:01 +00:00
|
|
|
extern crate tracing;
|
2015-01-01 04:43:46 +00:00
|
|
|
|
2019-07-16 17:08:32 +00:00
|
|
|
pub extern crate rustc_plugin_impl as plugin;
|
|
|
|
|
2020-04-27 17:56:11 +00:00
|
|
|
use rustc_ast as ast;
|
2022-08-25 16:05:23 +00:00
|
|
|
use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults};
|
2023-02-06 05:32:34 +00:00
|
|
|
use rustc_data_structures::profiling::{
|
|
|
|
get_resident_set_size, print_time_passes_entry, TimePassesFormat,
|
|
|
|
};
|
2018-12-08 19:30:23 +00:00
|
|
|
use rustc_data_structures::sync::SeqCst;
|
2020-03-31 19:18:30 +00:00
|
|
|
use rustc_errors::registry::{InvalidErrorCode, Registry};
|
2022-10-13 09:13:02 +00:00
|
|
|
use rustc_errors::{
|
2023-04-29 11:29:07 +00:00
|
|
|
DiagnosticMessage, ErrorGuaranteed, Handler, PResult, SubdiagnosticMessage, TerminalUrl,
|
2022-10-13 09:13:02 +00:00
|
|
|
};
|
2020-10-10 18:27:52 +00:00
|
|
|
use rustc_feature::find_gated_cfg;
|
2023-04-16 12:33:00 +00:00
|
|
|
use rustc_fluent_macro::fluent_messages;
|
2021-05-29 13:14:05 +00:00
|
|
|
use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
|
2019-11-30 09:16:19 +00:00
|
|
|
use rustc_interface::{interface, Queries};
|
2020-01-09 06:52:01 +00:00
|
|
|
use rustc_lint::LintStore;
|
2016-10-20 04:31:14 +00:00
|
|
|
use rustc_metadata::locator;
|
2022-07-06 12:44:47 +00:00
|
|
|
use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
|
2020-09-02 07:40:56 +00:00
|
|
|
use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths};
|
2020-11-14 02:02:03 +00:00
|
|
|
use rustc_session::cstore::MetadataLoader;
|
2023-03-31 10:59:13 +00:00
|
|
|
use rustc_session::getopts::{self, Matches};
|
2020-03-11 11:49:08 +00:00
|
|
|
use rustc_session::lint::{Lint, LintId};
|
2022-10-12 23:23:23 +00:00
|
|
|
use rustc_session::{config, Session};
|
2021-03-28 16:36:53 +00:00
|
|
|
use rustc_session::{early_error, early_error_no_abort, early_warn};
|
2020-03-12 23:07:58 +00:00
|
|
|
use rustc_span::source_map::{FileLoader, FileName};
|
|
|
|
use rustc_span::symbol::sym;
|
2021-06-03 15:45:09 +00:00
|
|
|
use rustc_target::json::ToJson;
|
2023-03-09 13:52:45 +00:00
|
|
|
use rustc_target::spec::{Target, TargetTriple};
|
2016-04-07 21:36:35 +00:00
|
|
|
|
2018-01-22 15:29:24 +00:00
|
|
|
use std::cmp::max;
|
2023-03-09 13:52:45 +00:00
|
|
|
use std::collections::BTreeMap;
|
2015-01-27 20:20:58 +00:00
|
|
|
use std::env;
|
2017-05-29 21:13:09 +00:00
|
|
|
use std::ffi::OsString;
|
2020-01-23 10:48:48 +00:00
|
|
|
use std::fs;
|
2022-10-16 13:55:18 +00:00
|
|
|
use std::io::{self, IsTerminal, Read, Write};
|
2018-12-08 19:30:23 +00:00
|
|
|
use std::panic::{self, catch_unwind};
|
2018-12-08 19:30:23 +00:00
|
|
|
use std::path::PathBuf;
|
2017-05-29 21:13:09 +00:00
|
|
|
use std::process::{self, Command, Stdio};
|
2015-03-11 22:24:14 +00:00
|
|
|
use std::str;
|
2023-04-29 11:29:07 +00:00
|
|
|
use std::sync::OnceLock;
|
2019-06-25 03:52:07 +00:00
|
|
|
use std::time::Instant;
|
2014-05-06 11:38:01 +00:00
|
|
|
|
2023-04-25 00:04:26 +00:00
|
|
|
// This import blocks the use of panicking `print` and `println` in all the code
|
|
|
|
// below. Please use `safe_print` and `safe_println` to avoid ICE when
|
|
|
|
// encountering an I/O error during print.
|
|
|
|
#[allow(unused_imports)]
|
|
|
|
use std::{compile_error as print, compile_error as println};
|
|
|
|
|
2021-02-18 15:15:24 +00:00
|
|
|
pub mod args;
|
2014-08-11 10:59:35 +00:00
|
|
|
pub mod pretty;
|
2023-04-25 00:04:26 +00:00
|
|
|
#[macro_use]
|
|
|
|
mod print;
|
2022-08-22 21:43:09 +00:00
|
|
|
mod session_diagnostics;
|
|
|
|
|
2022-08-25 16:05:23 +00:00
|
|
|
use crate::session_diagnostics::{
|
|
|
|
RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch,
|
|
|
|
RLinkWrongFileType, RlinkNotAFile, RlinkUnableToRead,
|
|
|
|
};
|
2017-10-30 17:42:21 +00:00
|
|
|
|
2023-03-02 23:18:38 +00:00
|
|
|
fluent_messages! { "../messages.ftl" }
|
2022-10-13 09:13:02 +00:00
|
|
|
|
|
|
|
pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
|
|
|
|
// tidy-alphabetical-start
|
|
|
|
crate::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_ast_passes::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_attr::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_borrowck::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_const_eval::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_error_messages::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_expand::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_incremental::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_infer::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_interface::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_lint::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_metadata::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_middle::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE,
|
2023-04-30 01:20:53 +00:00
|
|
|
rustc_mir_transform::DEFAULT_LOCALE_RESOURCE,
|
2022-10-13 09:13:02 +00:00
|
|
|
rustc_monomorphize::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_parse::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_passes::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_plugin_impl::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_privacy::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_query_system::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_resolve::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_session::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_symbol_mangling::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_trait_selection::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
rustc_ty_utils::DEFAULT_LOCALE_RESOURCE,
|
|
|
|
// tidy-alphabetical-end
|
|
|
|
];
|
|
|
|
|
2018-07-09 18:01:10 +00:00
|
|
|
/// Exit status code used for successful compilation and help output.
|
2018-12-08 19:30:23 +00:00
|
|
|
pub const EXIT_SUCCESS: i32 = 0;
|
2018-07-09 18:01:10 +00:00
|
|
|
|
2019-06-25 03:52:07 +00:00
|
|
|
/// Exit status code used for compilation failures and invalid flags.
|
2018-12-08 19:30:23 +00:00
|
|
|
pub const EXIT_FAILURE: i32 = 1;
|
2018-07-09 18:01:10 +00:00
|
|
|
|
2023-04-29 11:29:07 +00:00
|
|
|
pub const DEFAULT_BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/issues/new\
|
2020-07-04 16:41:21 +00:00
|
|
|
?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md";
|
2018-10-12 12:24:38 +00:00
|
|
|
|
2021-12-27 04:32:17 +00:00
|
|
|
const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["-Z", "-C", "--crate-type"];
|
2018-10-12 12:24:38 +00:00
|
|
|
|
|
|
|
const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"];
|
|
|
|
|
|
|
|
const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"];
|
2018-02-16 11:10:06 +00:00
|
|
|
|
2022-01-23 18:34:26 +00:00
|
|
|
pub fn abort_on_err<T>(result: Result<T, ErrorGuaranteed>, sess: &Session) -> T {
|
2016-01-21 00:19:20 +00:00
|
|
|
match result {
|
2018-12-08 19:30:23 +00:00
|
|
|
Err(..) => {
|
2017-07-02 13:09:09 +00:00
|
|
|
sess.abort_if_errors();
|
|
|
|
panic!("error reported but abort_if_errors didn't abort???");
|
|
|
|
}
|
2016-01-21 00:19:20 +00:00
|
|
|
Ok(x) => x,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-08 19:30:23 +00:00
|
|
|
pub trait Callbacks {
|
|
|
|
/// Called before creating the compiler instance
|
|
|
|
fn config(&mut self, _config: &mut interface::Config) {}
|
2019-07-14 18:29:20 +00:00
|
|
|
/// Called after parsing. Return value instructs the compiler whether to
|
|
|
|
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
2019-11-30 09:16:19 +00:00
|
|
|
fn after_parsing<'tcx>(
|
|
|
|
&mut self,
|
|
|
|
_compiler: &interface::Compiler,
|
|
|
|
_queries: &'tcx Queries<'tcx>,
|
|
|
|
) -> Compilation {
|
2019-07-14 18:29:20 +00:00
|
|
|
Compilation::Continue
|
2018-12-08 19:30:23 +00:00
|
|
|
}
|
2019-07-14 18:29:20 +00:00
|
|
|
/// Called after expansion. Return value instructs the compiler whether to
|
|
|
|
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
2019-11-30 09:16:19 +00:00
|
|
|
fn after_expansion<'tcx>(
|
|
|
|
&mut self,
|
|
|
|
_compiler: &interface::Compiler,
|
|
|
|
_queries: &'tcx Queries<'tcx>,
|
|
|
|
) -> Compilation {
|
2019-07-14 18:29:20 +00:00
|
|
|
Compilation::Continue
|
2019-07-14 18:24:48 +00:00
|
|
|
}
|
2019-07-14 18:29:20 +00:00
|
|
|
/// Called after analysis. Return value instructs the compiler whether to
|
|
|
|
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
2019-11-30 09:16:19 +00:00
|
|
|
fn after_analysis<'tcx>(
|
|
|
|
&mut self,
|
|
|
|
_compiler: &interface::Compiler,
|
|
|
|
_queries: &'tcx Queries<'tcx>,
|
|
|
|
) -> Compilation {
|
2019-07-14 18:29:20 +00:00
|
|
|
Compilation::Continue
|
2018-07-09 18:01:10 +00:00
|
|
|
}
|
2014-05-06 11:38:01 +00:00
|
|
|
}
|
|
|
|
|
2019-06-25 03:52:07 +00:00
|
|
|
#[derive(Default)]
|
|
|
|
pub struct TimePassesCallbacks {
|
2023-02-06 05:32:34 +00:00
|
|
|
time_passes: Option<TimePassesFormat>,
|
2019-06-25 03:52:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Callbacks for TimePassesCallbacks {
|
Remove `-Ztime` option.
The compiler currently has `-Ztime` and `-Ztime-passes`. I've used
`-Ztime-passes` for years but only recently learned about `-Ztime`.
What's the difference? Let's look at the `-Zhelp` output:
```
-Z time=val -- measure time of rustc processes (default: no)
-Z time-passes=val -- measure time of each rustc pass (default: no)
```
The `-Ztime-passes` description is clear, but the `-Ztime` one is less so.
Sounds like it measures the time for the entire process?
No. The real difference is that `-Ztime-passes` prints out info about passes,
and `-Ztime` does the same, but only for a subset of those passes. More
specifically, there is a distinction in the profiling code between a "verbose
generic activity" and an "extra verbose generic activity". `-Ztime-passes`
prints both kinds, while `-Ztime` only prints the first one. (It took me
a close reading of the source code to determine this difference.)
In practice this distinction has low value. Perhaps in the past the "extra
verbose" output was more voluminous, but now that we only print stats for a
pass if it exceeds 5ms or alters the RSS, `-Ztime-passes` is less spammy. Also,
a lot of the "extra verbose" cases are for individual lint passes, and you need
to also use `-Zno-interleave-lints` to see those anyway.
Therefore, this commit removes `-Ztime` and the associated machinery. One thing
to note is that the existing "extra verbose" activities all have an extra
string argument, so the commit adds the ability to accept an extra argument to
the "verbose" activities.
2022-10-06 03:51:45 +00:00
|
|
|
// JUSTIFICATION: the session doesn't exist at this point.
|
|
|
|
#[allow(rustc::bad_opt_access)]
|
2019-06-25 03:52:07 +00:00
|
|
|
fn config(&mut self, config: &mut interface::Config) {
|
2022-10-06 03:13:12 +00:00
|
|
|
// If a --print=... option has been given, we don't print the "total"
|
|
|
|
// time because it will mess up the --print output. See #64339.
|
Remove `-Ztime` option.
The compiler currently has `-Ztime` and `-Ztime-passes`. I've used
`-Ztime-passes` for years but only recently learned about `-Ztime`.
What's the difference? Let's look at the `-Zhelp` output:
```
-Z time=val -- measure time of rustc processes (default: no)
-Z time-passes=val -- measure time of each rustc pass (default: no)
```
The `-Ztime-passes` description is clear, but the `-Ztime` one is less so.
Sounds like it measures the time for the entire process?
No. The real difference is that `-Ztime-passes` prints out info about passes,
and `-Ztime` does the same, but only for a subset of those passes. More
specifically, there is a distinction in the profiling code between a "verbose
generic activity" and an "extra verbose generic activity". `-Ztime-passes`
prints both kinds, while `-Ztime` only prints the first one. (It took me
a close reading of the source code to determine this difference.)
In practice this distinction has low value. Perhaps in the past the "extra
verbose" output was more voluminous, but now that we only print stats for a
pass if it exceeds 5ms or alters the RSS, `-Ztime-passes` is less spammy. Also,
a lot of the "extra verbose" cases are for individual lint passes, and you need
to also use `-Zno-interleave-lints` to see those anyway.
Therefore, this commit removes `-Ztime` and the associated machinery. One thing
to note is that the existing "extra verbose" activities all have an extra
string argument, so the commit adds the ability to accept an extra argument to
the "verbose" activities.
2022-10-06 03:51:45 +00:00
|
|
|
//
|
2023-02-06 05:32:34 +00:00
|
|
|
self.time_passes = (config.opts.prints.is_empty() && config.opts.unstable_opts.time_passes)
|
|
|
|
.then(|| config.opts.unstable_opts.time_passes_format);
|
2020-09-03 06:30:51 +00:00
|
|
|
config.opts.trimmed_def_paths = TrimmedDefPaths::GoodPath;
|
2019-06-25 03:52:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-15 18:41:50 +00:00
|
|
|
pub fn diagnostics_registry() -> Registry {
|
2021-09-30 17:38:50 +00:00
|
|
|
Registry::new(rustc_error_codes::DIAGNOSTICS)
|
2019-11-15 18:41:50 +00:00
|
|
|
}
|
|
|
|
|
2021-03-28 16:48:52 +00:00
|
|
|
/// This is the primary entry point for rustc.
|
2020-10-07 12:09:59 +00:00
|
|
|
pub struct RunCompiler<'a, 'b> {
|
|
|
|
at_args: &'a [String],
|
|
|
|
callbacks: &'b mut (dyn Callbacks + Send),
|
|
|
|
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
|
|
|
|
make_codegen_backend:
|
|
|
|
Option<Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'b> RunCompiler<'a, 'b> {
|
|
|
|
pub fn new(at_args: &'a [String], callbacks: &'b mut (dyn Callbacks + Send)) -> Self {
|
2022-10-12 23:23:23 +00:00
|
|
|
Self { at_args, callbacks, file_loader: None, make_codegen_backend: None }
|
2020-10-07 12:09:59 +00:00
|
|
|
}
|
2021-03-28 16:48:52 +00:00
|
|
|
|
|
|
|
/// Set a custom codegen backend.
|
|
|
|
///
|
2022-10-12 23:23:23 +00:00
|
|
|
/// Has no uses within this repository, but is used by bjorn3 for "the
|
|
|
|
/// hotswapping branch of cg_clif" for "setting the codegen backend from a
|
|
|
|
/// custom driver where the custom codegen backend has arbitrary data."
|
|
|
|
/// (See #102759.)
|
2020-10-07 12:09:59 +00:00
|
|
|
pub fn set_make_codegen_backend(
|
|
|
|
&mut self,
|
|
|
|
make_codegen_backend: Option<
|
|
|
|
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
|
|
|
|
>,
|
|
|
|
) -> &mut Self {
|
|
|
|
self.make_codegen_backend = make_codegen_backend;
|
|
|
|
self
|
|
|
|
}
|
2021-03-28 16:48:52 +00:00
|
|
|
|
|
|
|
/// Load files from sources other than the file system.
|
|
|
|
///
|
2022-10-12 23:23:23 +00:00
|
|
|
/// Has no uses within this repository, but may be used in the future by
|
|
|
|
/// bjorn3 for "hooking rust-analyzer's VFS into rustc at some point for
|
|
|
|
/// running rustc without having to save". (See #102759.)
|
2020-10-07 12:09:59 +00:00
|
|
|
pub fn set_file_loader(
|
|
|
|
&mut self,
|
|
|
|
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
|
|
|
|
) -> &mut Self {
|
|
|
|
self.file_loader = file_loader;
|
|
|
|
self
|
|
|
|
}
|
2021-03-28 16:48:52 +00:00
|
|
|
|
|
|
|
/// Parse args and run the compiler.
|
2020-10-07 12:09:59 +00:00
|
|
|
pub fn run(self) -> interface::Result<()> {
|
2022-10-12 23:23:23 +00:00
|
|
|
run_compiler(self.at_args, self.callbacks, self.file_loader, self.make_codegen_backend)
|
2020-10-07 12:09:59 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-09 23:50:14 +00:00
|
|
|
|
2020-10-07 12:09:59 +00:00
|
|
|
fn run_compiler(
|
2019-08-20 02:02:12 +00:00
|
|
|
at_args: &[String],
|
2018-12-08 19:30:23 +00:00
|
|
|
callbacks: &mut (dyn Callbacks + Send),
|
|
|
|
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
|
2020-09-08 11:44:41 +00:00
|
|
|
make_codegen_backend: Option<
|
|
|
|
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
|
|
|
|
>,
|
2018-12-08 19:30:23 +00:00
|
|
|
) -> interface::Result<()> {
|
2023-03-13 17:28:59 +00:00
|
|
|
// Throw away the first argument, the name of the binary.
|
|
|
|
// In case of at_args being empty, as might be the case by
|
|
|
|
// passing empty argument array to execve under some platforms,
|
|
|
|
// just use an empty slice.
|
|
|
|
//
|
|
|
|
// This situation was possible before due to arg_expand_all being
|
|
|
|
// called before removing the argument, enabling a crash by calling
|
|
|
|
// the compiler with @empty_file as argv[0] and no more arguments.
|
|
|
|
let at_args = at_args.get(1..).unwrap_or_default();
|
|
|
|
|
2021-02-18 15:15:24 +00:00
|
|
|
let args = args::arg_expand_all(at_args);
|
|
|
|
|
2022-02-18 23:48:49 +00:00
|
|
|
let Some(matches) = handle_options(&args) else { return Ok(()) };
|
2018-04-25 22:49:52 +00:00
|
|
|
|
2019-10-11 21:30:58 +00:00
|
|
|
let sopts = config::build_session_options(&matches);
|
2014-07-01 16:39:41 +00:00
|
|
|
|
2023-04-07 13:20:26 +00:00
|
|
|
// Set parallel mode before thread pool creation, which will create `Lock`s.
|
|
|
|
interface::set_thread_safe_mode(&sopts.unstable_opts);
|
2023-03-03 02:14:57 +00:00
|
|
|
|
2018-12-08 19:30:23 +00:00
|
|
|
if let Some(ref code) = matches.opt_str("explain") {
|
2019-11-15 18:41:50 +00:00
|
|
|
handle_explain(diagnostics_registry(), code, sopts.error_format);
|
2018-12-08 19:30:23 +00:00
|
|
|
return Ok(());
|
|
|
|
}
|
2015-01-30 08:44:27 +00:00
|
|
|
|
2021-03-28 16:36:53 +00:00
|
|
|
let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg"));
|
2021-09-29 00:39:30 +00:00
|
|
|
let check_cfg = interface::parse_check_cfg(matches.opt_strs("check-cfg"));
|
2015-01-30 08:44:27 +00:00
|
|
|
let (odir, ofile) = make_output(&matches);
|
2021-03-28 16:36:53 +00:00
|
|
|
let mut config = interface::Config {
|
|
|
|
opts: sopts,
|
|
|
|
crate_cfg: cfg,
|
2021-09-29 00:39:30 +00:00
|
|
|
crate_check_cfg: check_cfg,
|
2021-03-28 16:36:53 +00:00
|
|
|
input: Input::File(PathBuf::new()),
|
|
|
|
output_file: ofile,
|
|
|
|
output_dir: odir,
|
|
|
|
file_loader,
|
2022-10-13 09:13:02 +00:00
|
|
|
locale_resources: DEFAULT_LOCALE_RESOURCES,
|
2021-03-28 16:36:53 +00:00
|
|
|
lint_caps: Default::default(),
|
|
|
|
parse_sess_created: None,
|
|
|
|
register_lints: None,
|
|
|
|
override_queries: None,
|
|
|
|
make_codegen_backend,
|
|
|
|
registry: diagnostics_registry(),
|
|
|
|
};
|
|
|
|
|
2021-05-02 15:57:04 +00:00
|
|
|
match make_input(config.opts.error_format, &matches.free) {
|
2022-01-23 00:49:12 +00:00
|
|
|
Err(reported) => return Err(reported),
|
2022-12-06 18:56:28 +00:00
|
|
|
Ok(Some(input)) => {
|
2021-03-28 16:36:53 +00:00
|
|
|
config.input = input;
|
|
|
|
|
|
|
|
callbacks.config(&mut config);
|
|
|
|
}
|
2021-05-02 15:57:04 +00:00
|
|
|
Ok(None) => match matches.free.len() {
|
2018-12-08 19:30:23 +00:00
|
|
|
0 => {
|
2021-03-28 16:36:53 +00:00
|
|
|
callbacks.config(&mut config);
|
2018-12-08 19:30:23 +00:00
|
|
|
interface::run_compiler(config, |compiler| {
|
|
|
|
let sopts = &compiler.session().opts;
|
|
|
|
if sopts.describe_lints {
|
2022-11-25 03:42:43 +00:00
|
|
|
let mut lint_store =
|
|
|
|
rustc_lint::new_lint_store(compiler.session().enable_internal_lints());
|
2020-10-07 13:35:21 +00:00
|
|
|
let registered_lints =
|
|
|
|
if let Some(register_lints) = compiler.register_lints() {
|
|
|
|
register_lints(compiler.session(), &mut lint_store);
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
};
|
|
|
|
describe_lints(compiler.session(), &lint_store, registered_lints);
|
2019-12-22 22:42:04 +00:00
|
|
|
return;
|
|
|
|
}
|
2022-12-07 09:24:00 +00:00
|
|
|
let should_stop =
|
|
|
|
print_crate_info(&***compiler.codegen_backend(), compiler.session(), false);
|
2014-05-06 11:38:01 +00:00
|
|
|
|
2018-12-08 19:30:23 +00:00
|
|
|
if should_stop == Compilation::Stop {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
early_error(sopts.error_format, "no input filename given")
|
|
|
|
});
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
1 => panic!("make_input should have provided valid inputs"),
|
|
|
|
_ => early_error(
|
2021-03-28 16:36:53 +00:00
|
|
|
config.opts.error_format,
|
2023-05-16 06:04:03 +00:00
|
|
|
format!(
|
2018-12-08 19:30:23 +00:00
|
|
|
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
|
2018-01-31 00:59:20 +00:00
|
|
|
matches.free[0], matches.free[1],
|
2019-12-22 22:42:04 +00:00
|
|
|
),
|
|
|
|
),
|
2018-12-08 19:30:23 +00:00
|
|
|
},
|
|
|
|
};
|
2017-10-30 17:42:21 +00:00
|
|
|
|
2018-12-08 19:30:23 +00:00
|
|
|
interface::run_compiler(config, |compiler| {
|
|
|
|
let sess = compiler.session();
|
2022-12-07 09:24:00 +00:00
|
|
|
let should_stop = print_crate_info(&***compiler.codegen_backend(), sess, true)
|
|
|
|
.and_then(|| list_metadata(sess, &*compiler.codegen_backend().metadata_loader()))
|
|
|
|
.and_then(|| try_process_rlink(sess, compiler));
|
2018-12-08 19:30:23 +00:00
|
|
|
|
|
|
|
if should_stop == Compilation::Stop {
|
|
|
|
return sess.compile_status();
|
|
|
|
}
|
|
|
|
|
2019-11-24 15:32:57 +00:00
|
|
|
let linker = compiler.enter(|queries| {
|
2019-11-25 16:29:32 +00:00
|
|
|
let early_exit = || sess.compile_status().map(|_| None);
|
2019-11-24 14:59:22 +00:00
|
|
|
queries.parse()?;
|
|
|
|
|
|
|
|
if let Some(ppm) = &sess.opts.pretty {
|
|
|
|
if ppm.needs_ast_map() {
|
2022-12-12 10:48:02 +00:00
|
|
|
queries.global_ctxt()?.enter(|tcx| {
|
2023-03-06 10:56:53 +00:00
|
|
|
tcx.ensure().early_lint_checks(());
|
2022-12-07 11:55:29 +00:00
|
|
|
pretty::print_after_hir_lowering(tcx, *ppm);
|
2019-11-24 14:59:22 +00:00
|
|
|
Ok(())
|
|
|
|
})?;
|
|
|
|
} else {
|
2022-12-12 10:48:02 +00:00
|
|
|
let krate = queries.parse()?.steal();
|
2022-12-07 09:24:00 +00:00
|
|
|
pretty::print_after_parsing(sess, &krate, *ppm);
|
2019-11-24 14:59:22 +00:00
|
|
|
}
|
2020-06-20 00:06:49 +00:00
|
|
|
trace!("finished pretty-printing");
|
2019-11-25 16:29:32 +00:00
|
|
|
return early_exit();
|
2018-12-08 19:30:23 +00:00
|
|
|
}
|
2016-10-27 06:36:56 +00:00
|
|
|
|
2019-11-30 09:16:19 +00:00
|
|
|
if callbacks.after_parsing(compiler, queries) == Compilation::Stop {
|
2019-11-25 16:29:32 +00:00
|
|
|
return early_exit();
|
2019-11-24 14:59:22 +00:00
|
|
|
}
|
2014-05-06 11:38:01 +00:00
|
|
|
|
2022-07-06 12:44:47 +00:00
|
|
|
if sess.opts.unstable_opts.parse_only || sess.opts.unstable_opts.show_span.is_some() {
|
2019-11-25 16:29:32 +00:00
|
|
|
return early_exit();
|
2019-11-24 14:59:22 +00:00
|
|
|
}
|
2018-03-15 09:09:20 +00:00
|
|
|
|
2019-11-24 14:59:22 +00:00
|
|
|
{
|
2022-12-12 10:48:02 +00:00
|
|
|
let plugins = queries.register_plugins()?;
|
2023-03-14 12:53:04 +00:00
|
|
|
let (.., lint_store) = &*plugins.borrow();
|
2018-03-15 09:09:20 +00:00
|
|
|
|
2019-11-24 14:59:22 +00:00
|
|
|
// Lint plugins are registered; now we can process command line flags.
|
|
|
|
if sess.opts.describe_lints {
|
2021-09-30 17:38:50 +00:00
|
|
|
describe_lints(sess, lint_store, true);
|
2019-11-25 16:29:32 +00:00
|
|
|
return early_exit();
|
2019-11-24 14:59:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-06 21:11:03 +00:00
|
|
|
// Make sure name resolution and macro expansion is run.
|
2022-10-17 13:11:26 +00:00
|
|
|
queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering(()));
|
2023-02-06 21:11:03 +00:00
|
|
|
|
2019-11-30 09:16:19 +00:00
|
|
|
if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
|
2019-11-25 16:29:32 +00:00
|
|
|
return early_exit();
|
2019-10-09 13:53:13 +00:00
|
|
|
}
|
2018-03-15 09:09:20 +00:00
|
|
|
|
2023-01-19 14:12:29 +00:00
|
|
|
// Make sure the `output_filenames` query is run for its side
|
|
|
|
// effects of writing the dep-info and reporting errors.
|
2023-02-06 21:11:03 +00:00
|
|
|
queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(()));
|
2023-01-23 10:25:51 +00:00
|
|
|
|
2019-11-24 14:59:22 +00:00
|
|
|
if sess.opts.output_types.contains_key(&OutputType::DepInfo)
|
|
|
|
&& sess.opts.output_types.len() == 1
|
|
|
|
{
|
2019-11-25 16:29:32 +00:00
|
|
|
return early_exit();
|
2019-11-24 14:59:22 +00:00
|
|
|
}
|
2019-07-14 18:24:48 +00:00
|
|
|
|
2022-07-06 12:44:47 +00:00
|
|
|
if sess.opts.unstable_opts.no_analysis {
|
2019-11-25 16:29:32 +00:00
|
|
|
return early_exit();
|
2019-11-24 14:59:22 +00:00
|
|
|
}
|
2018-03-15 09:09:20 +00:00
|
|
|
|
2022-09-15 01:29:12 +00:00
|
|
|
queries.global_ctxt()?.enter(|tcx| tcx.analysis(()))?;
|
2019-03-10 16:03:05 +00:00
|
|
|
|
2019-11-30 09:16:19 +00:00
|
|
|
if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
|
2019-11-25 16:29:32 +00:00
|
|
|
return early_exit();
|
2019-11-24 14:59:22 +00:00
|
|
|
}
|
2018-12-08 19:30:23 +00:00
|
|
|
|
2019-11-24 14:59:22 +00:00
|
|
|
queries.ongoing_codegen()?;
|
2019-03-10 16:03:05 +00:00
|
|
|
|
2022-07-06 12:44:47 +00:00
|
|
|
if sess.opts.unstable_opts.print_type_sizes {
|
2019-11-24 14:59:22 +00:00
|
|
|
sess.code_stats.print_type_sizes();
|
|
|
|
}
|
2018-12-08 19:30:23 +00:00
|
|
|
|
2019-11-24 15:32:57 +00:00
|
|
|
let linker = queries.linker()?;
|
|
|
|
Ok(Some(linker))
|
2019-11-24 14:59:22 +00:00
|
|
|
})?;
|
2018-12-08 19:30:23 +00:00
|
|
|
|
2019-11-24 15:32:57 +00:00
|
|
|
if let Some(linker) = linker {
|
2020-01-09 02:48:00 +00:00
|
|
|
let _timer = sess.timer("link");
|
2019-11-24 15:32:57 +00:00
|
|
|
linker.link()?
|
|
|
|
}
|
|
|
|
|
2022-07-06 12:44:47 +00:00
|
|
|
if sess.opts.unstable_opts.perf_stats {
|
2018-12-08 19:30:23 +00:00
|
|
|
sess.print_perf_stats();
|
|
|
|
}
|
|
|
|
|
2022-07-06 12:44:47 +00:00
|
|
|
if sess.opts.unstable_opts.print_fuel.is_some() {
|
2018-12-08 19:30:23 +00:00
|
|
|
eprintln!(
|
|
|
|
"Fuel used by {}: {}",
|
2022-07-06 12:44:47 +00:00
|
|
|
sess.opts.unstable_opts.print_fuel.as_ref().unwrap(),
|
2018-12-08 19:30:23 +00:00
|
|
|
sess.print_fuel.load(SeqCst)
|
|
|
|
);
|
|
|
|
}
|
2019-02-10 22:23:00 +00:00
|
|
|
|
2018-12-08 19:30:23 +00:00
|
|
|
Ok(())
|
|
|
|
})
|
2015-01-11 02:03:34 +00:00
|
|
|
}
|
|
|
|
|
2015-01-30 08:44:27 +00:00
|
|
|
// Extract output directory and file from matches.
|
2015-02-27 05:00:43 +00:00
|
|
|
fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>) {
|
2015-03-18 16:14:54 +00:00
|
|
|
let odir = matches.opt_str("out-dir").map(|o| PathBuf::from(&o));
|
|
|
|
let ofile = matches.opt_str("o").map(|o| PathBuf::from(&o));
|
2015-01-30 08:44:27 +00:00
|
|
|
(odir, ofile)
|
|
|
|
}
|
2015-01-11 02:03:34 +00:00
|
|
|
|
2015-01-30 08:44:27 +00:00
|
|
|
// Extract input (string or file and optional path) from matches.
|
2021-05-02 15:57:04 +00:00
|
|
|
fn make_input(
|
|
|
|
error_format: ErrorOutputType,
|
|
|
|
free_matches: &[String],
|
2022-12-06 18:56:28 +00:00
|
|
|
) -> Result<Option<Input>, ErrorGuaranteed> {
|
2015-01-30 08:44:27 +00:00
|
|
|
if free_matches.len() == 1 {
|
2017-03-24 08:31:26 +00:00
|
|
|
let ifile = &free_matches[0];
|
2015-01-30 08:44:27 +00:00
|
|
|
if ifile == "-" {
|
2015-03-11 22:24:14 +00:00
|
|
|
let mut src = String::new();
|
2021-05-02 15:57:04 +00:00
|
|
|
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).
|
2022-01-23 00:49:12 +00:00
|
|
|
let reported = early_error_no_abort(
|
2021-05-02 15:57:04 +00:00
|
|
|
error_format,
|
2018-01-31 00:59:20 +00:00
|
|
|
"couldn't read from stdin, as it did not contain valid UTF-8",
|
2021-05-02 15:57:04 +00:00
|
|
|
);
|
2022-01-23 00:49:12 +00:00
|
|
|
return Err(reported);
|
2021-05-02 15:57:04 +00:00
|
|
|
}
|
2019-08-27 06:07:56 +00:00
|
|
|
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 \
|
|
|
|
UNSTABLE_RUSTDOC_TEST_LINE also needs to be set",
|
|
|
|
);
|
|
|
|
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);
|
2022-12-06 18:56:28 +00:00
|
|
|
Ok(Some(Input::Str { name: file_name, input: src }))
|
2021-05-02 15:57:04 +00:00
|
|
|
} else {
|
2022-12-06 18:56:28 +00:00
|
|
|
Ok(Some(Input::Str { name: FileName::anon_source_code(&src), input: src }))
|
2019-08-27 06:07:56 +00:00
|
|
|
}
|
2015-01-30 08:44:27 +00:00
|
|
|
} else {
|
2022-12-06 18:56:28 +00:00
|
|
|
Ok(Some(Input::File(PathBuf::from(ifile))))
|
2015-01-30 08:44:27 +00:00
|
|
|
}
|
|
|
|
} else {
|
2021-05-02 15:57:04 +00:00
|
|
|
Ok(None)
|
2015-01-11 02:03:34 +00:00
|
|
|
}
|
2015-01-30 08:44:27 +00:00
|
|
|
}
|
2015-01-11 02:03:34 +00:00
|
|
|
|
2021-05-29 12:53:09 +00:00
|
|
|
/// Whether to stop or continue compilation.
|
2015-03-30 13:38:44 +00:00
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
2015-02-03 00:40:52 +00:00
|
|
|
pub enum Compilation {
|
|
|
|
Stop,
|
|
|
|
Continue,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Compilation {
|
|
|
|
pub fn and_then<F: FnOnce() -> Compilation>(self, next: F) -> Compilation {
|
|
|
|
match self {
|
|
|
|
Compilation::Stop => Compilation::Stop,
|
2015-11-10 20:48:44 +00:00
|
|
|
Compilation::Continue => next(),
|
2015-02-03 00:40:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-15 18:41:50 +00:00
|
|
|
fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
|
2021-06-22 01:11:53 +00:00
|
|
|
let upper_cased_code = code.to_ascii_uppercase();
|
2022-12-19 09:31:55 +00:00
|
|
|
let normalised =
|
|
|
|
if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") };
|
2020-02-28 22:32:09 +00:00
|
|
|
match registry.try_find_description(&normalised) {
|
2023-02-25 07:14:10 +00:00
|
|
|
Ok(description) => {
|
2017-06-20 07:53:03 +00:00
|
|
|
let mut is_in_code_block = false;
|
2017-05-29 21:13:09 +00:00
|
|
|
let mut text = String::new();
|
2016-02-08 20:53:05 +00:00
|
|
|
// Slice off the leading newline and print.
|
2019-11-13 19:54:43 +00:00
|
|
|
for line in description.lines() {
|
2017-06-20 07:53:03 +00:00
|
|
|
let indent_level =
|
|
|
|
line.find(|c: char| !c.is_whitespace()).unwrap_or_else(|| line.len());
|
|
|
|
let dedented_line = &line[indent_level..];
|
|
|
|
if dedented_line.starts_with("```") {
|
|
|
|
is_in_code_block = !is_in_code_block;
|
2019-11-13 19:54:43 +00:00
|
|
|
text.push_str(&line[..(indent_level + 3)]);
|
2017-06-20 07:53:03 +00:00
|
|
|
} else if is_in_code_block && dedented_line.starts_with("# ") {
|
|
|
|
continue;
|
2016-05-01 16:13:36 +00:00
|
|
|
} else {
|
2017-05-29 21:13:09 +00:00
|
|
|
text.push_str(line);
|
2017-06-20 07:53:03 +00:00
|
|
|
}
|
2017-06-29 14:57:54 +00:00
|
|
|
text.push('\n');
|
2017-06-20 07:53:03 +00:00
|
|
|
}
|
2022-10-16 13:55:18 +00:00
|
|
|
if io::stdout().is_terminal() {
|
2017-07-02 20:27:10 +00:00
|
|
|
show_content_with_pager(&text);
|
|
|
|
} else {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_print!("{text}");
|
2017-07-02 20:27:10 +00:00
|
|
|
}
|
2016-02-08 20:53:05 +00:00
|
|
|
}
|
2020-02-28 22:32:09 +00:00
|
|
|
Err(InvalidErrorCode) => {
|
2023-05-16 06:04:03 +00:00
|
|
|
early_error(output, format!("{code} is not a valid error code"));
|
2020-02-28 22:32:09 +00:00
|
|
|
}
|
2016-02-08 20:53:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-30 11:59:07 +00:00
|
|
|
fn show_content_with_pager(content: &str) {
|
2017-06-29 14:57:54 +00:00
|
|
|
let pager_name = env::var_os("PAGER").unwrap_or_else(|| {
|
2022-08-23 16:48:46 +00:00
|
|
|
if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") }
|
2017-05-29 21:13:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
let mut fallback_to_println = false;
|
|
|
|
|
|
|
|
match Command::new(pager_name).stdin(Stdio::piped()).spawn() {
|
|
|
|
Ok(mut pager) => {
|
2017-08-01 12:03:03 +00:00
|
|
|
if let Some(pipe) = pager.stdin.as_mut() {
|
2017-05-29 21:13:09 +00:00
|
|
|
if pipe.write_all(content.as_bytes()).is_err() {
|
|
|
|
fallback_to_println = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if pager.wait().is_err() {
|
|
|
|
fallback_to_println = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(_) => {
|
|
|
|
fallback_to_println = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If pager fails for whatever reason, we should still print the content
|
|
|
|
// to standard output
|
|
|
|
if fallback_to_println {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_print!("{content}");
|
2017-05-29 21:13:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-25 10:49:29 +00:00
|
|
|
pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation {
|
2022-07-06 12:44:47 +00:00
|
|
|
if sess.opts.unstable_opts.link_only {
|
2022-12-07 09:24:00 +00:00
|
|
|
if let Input::File(file) = &sess.io.input {
|
2021-06-25 10:49:29 +00:00
|
|
|
// 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(file).unwrap_or_else(|err| {
|
2022-08-24 12:12:39 +00:00
|
|
|
sess.emit_fatal(RlinkUnableToRead { err });
|
2021-06-25 10:49:29 +00:00
|
|
|
});
|
2023-05-08 09:12:38 +00:00
|
|
|
let codegen_results = match CodegenResults::deserialize_rlink(sess, rlink_data) {
|
2022-04-02 15:26:39 +00:00
|
|
|
Ok(codegen) => codegen,
|
2022-08-24 17:15:44 +00:00
|
|
|
Err(err) => {
|
2022-08-25 16:05:23 +00:00
|
|
|
match err {
|
|
|
|
CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType),
|
|
|
|
CodegenErrors::EmptyVersionNumber => {
|
|
|
|
sess.emit_fatal(RLinkEmptyVersionNumber)
|
|
|
|
}
|
|
|
|
CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => {
|
|
|
|
sess.emit_fatal(RLinkEncodingVersionMismatch {
|
|
|
|
version_array,
|
|
|
|
rlink_version,
|
|
|
|
})
|
|
|
|
}
|
2023-05-08 09:12:38 +00:00
|
|
|
CodegenErrors::RustcVersionMismatch { rustc_version } => {
|
2022-08-25 16:05:23 +00:00
|
|
|
sess.emit_fatal(RLinkRustcVersionMismatch {
|
|
|
|
rustc_version,
|
2023-05-08 09:12:38 +00:00
|
|
|
current_version: sess.cfg_version,
|
2022-08-25 16:05:23 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
};
|
2022-04-02 15:26:39 +00:00
|
|
|
}
|
|
|
|
};
|
2021-06-25 10:49:29 +00:00
|
|
|
let result = compiler.codegen_backend().link(sess, codegen_results, &outputs);
|
|
|
|
abort_on_err(result, sess);
|
2020-01-23 10:48:48 +00:00
|
|
|
} else {
|
2022-08-23 16:48:46 +00:00
|
|
|
sess.emit_fatal(RlinkNotAFile {})
|
2020-01-23 10:48:48 +00:00
|
|
|
}
|
2021-06-25 10:49:29 +00:00
|
|
|
Compilation::Stop
|
|
|
|
} else {
|
|
|
|
Compilation::Continue
|
2020-01-23 10:48:48 +00:00
|
|
|
}
|
2021-06-25 10:49:29 +00:00
|
|
|
}
|
2020-01-23 10:48:48 +00:00
|
|
|
|
2022-12-07 09:24:00 +00:00
|
|
|
pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Compilation {
|
2022-07-06 12:44:47 +00:00
|
|
|
if sess.opts.unstable_opts.ls {
|
2022-12-07 09:24:00 +00:00
|
|
|
match sess.io.input {
|
2021-06-25 10:49:29 +00:00
|
|
|
Input::File(ref ifile) => {
|
|
|
|
let path = &(*ifile);
|
|
|
|
let mut v = Vec::new();
|
|
|
|
locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v).unwrap();
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{}", String::from_utf8(v).unwrap());
|
2021-06-25 10:49:29 +00:00
|
|
|
}
|
|
|
|
Input::Str { .. } => {
|
|
|
|
early_error(ErrorOutputType::default(), "cannot list metadata for stdin");
|
2015-01-30 08:44:27 +00:00
|
|
|
}
|
|
|
|
}
|
2021-06-25 10:49:29 +00:00
|
|
|
return Compilation::Stop;
|
2015-01-30 08:44:27 +00:00
|
|
|
}
|
|
|
|
|
2021-06-25 10:49:29 +00:00
|
|
|
Compilation::Continue
|
|
|
|
}
|
2015-01-30 08:44:27 +00:00
|
|
|
|
2021-06-25 10:49:29 +00:00
|
|
|
fn print_crate_info(
|
|
|
|
codegen_backend: &dyn CodegenBackend,
|
|
|
|
sess: &Session,
|
2022-12-07 08:42:21 +00:00
|
|
|
parse_attrs: bool,
|
2021-06-25 10:49:29 +00:00
|
|
|
) -> Compilation {
|
|
|
|
use rustc_session::config::PrintRequest::*;
|
|
|
|
// NativeStaticLibs and LinkArgs are special - printed during linking
|
|
|
|
// (empty iterator returns true)
|
|
|
|
if sess.opts.prints.iter().all(|&p| p == NativeStaticLibs || p == LinkArgs) {
|
|
|
|
return Compilation::Continue;
|
|
|
|
}
|
|
|
|
|
2022-12-07 08:42:21 +00:00
|
|
|
let attrs = if parse_attrs {
|
2022-12-07 09:24:00 +00:00
|
|
|
let result = parse_crate_attrs(sess);
|
2022-12-07 08:42:21 +00:00
|
|
|
match result {
|
|
|
|
Ok(attrs) => Some(attrs),
|
|
|
|
Err(mut parse_error) => {
|
|
|
|
parse_error.emit();
|
|
|
|
return Compilation::Stop;
|
2016-02-19 13:43:13 +00:00
|
|
|
}
|
2021-06-25 10:49:29 +00:00
|
|
|
}
|
2022-12-07 08:42:21 +00:00
|
|
|
} else {
|
|
|
|
None
|
2021-06-25 10:49:29 +00:00
|
|
|
};
|
|
|
|
for req in &sess.opts.prints {
|
|
|
|
match *req {
|
|
|
|
TargetList => {
|
2022-12-25 15:42:35 +00:00
|
|
|
let mut targets = rustc_target::spec::TARGETS.to_vec();
|
2021-06-25 10:49:29 +00:00
|
|
|
targets.sort_unstable();
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{}", targets.join("\n"));
|
2021-06-25 10:49:29 +00:00
|
|
|
}
|
2023-04-25 00:04:26 +00:00
|
|
|
Sysroot => safe_println!("{}", sess.sysroot.display()),
|
|
|
|
TargetLibdir => safe_println!("{}", sess.target_tlib_path.dir.display()),
|
2021-06-03 15:45:09 +00:00
|
|
|
TargetSpec => {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
|
2021-06-03 15:45:09 +00:00
|
|
|
}
|
2023-03-09 13:52:45 +00:00
|
|
|
AllTargetSpecs => {
|
|
|
|
let mut targets = BTreeMap::new();
|
|
|
|
for name in rustc_target::spec::TARGETS {
|
|
|
|
let triple = TargetTriple::from_triple(name);
|
|
|
|
let target = Target::expect_builtin(&triple);
|
|
|
|
targets.insert(name, target.to_json());
|
|
|
|
}
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{}", serde_json::to_string_pretty(&targets).unwrap());
|
2023-03-09 13:52:45 +00:00
|
|
|
}
|
2021-06-25 10:49:29 +00:00
|
|
|
FileNames | CrateName => {
|
2023-02-10 08:01:50 +00:00
|
|
|
let Some(attrs) = attrs.as_ref() else {
|
|
|
|
// no crate attributes, print out an error and exit
|
|
|
|
return Compilation::Continue;
|
|
|
|
};
|
2022-12-07 09:24:00 +00:00
|
|
|
let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess);
|
|
|
|
let id = rustc_session::output::find_crate_name(sess, attrs);
|
2021-06-25 10:49:29 +00:00
|
|
|
if *req == PrintRequest::CrateName {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{id}");
|
2021-06-25 10:49:29 +00:00
|
|
|
continue;
|
2015-01-30 08:44:27 +00:00
|
|
|
}
|
2021-06-25 10:49:29 +00:00
|
|
|
let crate_types = collect_crate_types(sess, attrs);
|
|
|
|
for &style in &crate_types {
|
|
|
|
let fname =
|
2022-12-06 12:46:10 +00:00
|
|
|
rustc_session::output::filename_for_input(sess, style, id, &t_outputs);
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{}", fname.file_name().unwrap().to_string_lossy());
|
2016-01-25 19:36:18 +00:00
|
|
|
}
|
2021-06-25 10:49:29 +00:00
|
|
|
}
|
|
|
|
Cfg => {
|
|
|
|
let mut cfgs = sess
|
|
|
|
.parse_sess
|
|
|
|
.config
|
|
|
|
.iter()
|
|
|
|
.filter_map(|&(name, value)| {
|
|
|
|
// Note that crt-static is a specially recognized cfg
|
|
|
|
// directive that's printed out here as part of
|
|
|
|
// rust-lang/rust#37406, but in general the
|
|
|
|
// `target_feature` cfg is gated under
|
|
|
|
// rust-lang/rust#29717. For now this is just
|
|
|
|
// specifically allowing the crt-static cfg and that's
|
|
|
|
// it, this is intended to get into Cargo and then go
|
|
|
|
// through to build scripts.
|
|
|
|
if (name != sym::target_feature || value != Some(sym::crt_dash_static))
|
|
|
|
&& !sess.is_nightly_build()
|
|
|
|
&& find_gated_cfg(|cfg_sym| cfg_sym == name).is_some()
|
|
|
|
{
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(value) = value {
|
2022-12-19 09:31:55 +00:00
|
|
|
Some(format!("{name}=\"{value}\""))
|
2021-06-25 10:49:29 +00:00
|
|
|
} else {
|
|
|
|
Some(name.to_string())
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect::<Vec<String>>();
|
|
|
|
|
|
|
|
cfgs.sort();
|
|
|
|
for cfg in cfgs {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{cfg}");
|
2017-04-30 18:33:25 +00:00
|
|
|
}
|
2015-01-30 08:44:27 +00:00
|
|
|
}
|
2022-09-08 13:37:15 +00:00
|
|
|
CallingConventions => {
|
|
|
|
let mut calling_conventions = rustc_target::spec::abi::all_names();
|
|
|
|
calling_conventions.sort_unstable();
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{}", calling_conventions.join("\n"));
|
2022-09-08 13:37:15 +00:00
|
|
|
}
|
2021-06-25 10:49:29 +00:00
|
|
|
RelocationModels
|
|
|
|
| CodeModels
|
|
|
|
| TlsModels
|
|
|
|
| TargetCPUs
|
|
|
|
| StackProtectorStrategies
|
|
|
|
| TargetFeatures => {
|
|
|
|
codegen_backend.print(*req, sess);
|
|
|
|
}
|
|
|
|
// Any output here interferes with Cargo's parsing of other printed output
|
|
|
|
NativeStaticLibs => {}
|
|
|
|
LinkArgs => {}
|
2022-11-07 14:21:35 +00:00
|
|
|
SplitDebuginfo => {
|
|
|
|
use rustc_target::spec::SplitDebuginfo::{Off, Packed, Unpacked};
|
|
|
|
|
|
|
|
for split in &[Off, Packed, Unpacked] {
|
|
|
|
let stable = sess.target.options.supported_split_debuginfo.contains(split);
|
|
|
|
let unstable_ok = sess.unstable_options();
|
|
|
|
if stable || unstable_ok {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{split}");
|
2022-11-07 14:21:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-12-06 05:15:16 +00:00
|
|
|
DeploymentTarget => {
|
|
|
|
use rustc_target::spec::current_apple_deployment_target;
|
|
|
|
|
|
|
|
if sess.target.is_like_osx {
|
|
|
|
safe_println!(
|
|
|
|
"deployment_target={}",
|
|
|
|
current_apple_deployment_target(&sess.target)
|
|
|
|
.expect("unknown Apple target OS")
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
early_error(
|
|
|
|
ErrorOutputType::default(),
|
|
|
|
"only Apple targets currently support deployment version info",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2015-01-30 08:44:27 +00:00
|
|
|
}
|
Preliminary feature staging
This partially implements the feature staging described in the
[release channel RFC][rc]. It does not yet fully conform to the RFC as
written, but does accomplish its goals sufficiently for the 1.0 alpha
release.
It has three primary user-visible effects:
* On the nightly channel, use of unstable APIs generates a warning.
* On the beta channel, use of unstable APIs generates a warning.
* On the beta channel, use of feature gates generates a warning.
Code that does not trigger these warnings is considered 'stable',
modulo pre-1.0 bugs.
Disabling the warnings for unstable APIs continues to be done in the
existing (i.e. old) style, via `#[allow(...)]`, not that specified in
the RFC. I deem this marginally acceptable since any code that must do
this is not using the stable dialect of Rust.
Use of feature gates is itself gated with the new 'unstable_features'
lint, on nightly set to 'allow', and on beta 'warn'.
The attribute scheme used here corresponds to an older version of the
RFC, with the `#[staged_api]` crate attribute toggling the staging
behavior of the stability attributes, but the user impact is only
in-tree so I'm not concerned about having to make design changes later
(and I may ultimately prefer the scheme here after all, with the
`#[staged_api]` crate attribute).
Since the Rust codebase itself makes use of unstable features the
compiler and build system to a midly elaborate dance to allow it to
bootstrap while disobeying these lints (which would otherwise be
errors because Rust builds with `-D warnings`).
This patch includes one significant hack that causes a
regression. Because the `format_args!` macro emits calls to unstable
APIs it would trigger the lint. I added a hack to the lint to make it
not trigger, but this in turn causes arguments to `println!` not to be
checked for feature gates. I don't presently understand macro
expansion well enough to fix. This is bug #20661.
Closes #16678
[rc]: https://github.com/rust-lang/rfcs/blob/master/text/0507-release-channels.md
2015-01-06 14:26:08 +00:00
|
|
|
}
|
2021-06-25 10:49:29 +00:00
|
|
|
Compilation::Stop
|
Preliminary feature staging
This partially implements the feature staging described in the
[release channel RFC][rc]. It does not yet fully conform to the RFC as
written, but does accomplish its goals sufficiently for the 1.0 alpha
release.
It has three primary user-visible effects:
* On the nightly channel, use of unstable APIs generates a warning.
* On the beta channel, use of unstable APIs generates a warning.
* On the beta channel, use of feature gates generates a warning.
Code that does not trigger these warnings is considered 'stable',
modulo pre-1.0 bugs.
Disabling the warnings for unstable APIs continues to be done in the
existing (i.e. old) style, via `#[allow(...)]`, not that specified in
the RFC. I deem this marginally acceptable since any code that must do
this is not using the stable dialect of Rust.
Use of feature gates is itself gated with the new 'unstable_features'
lint, on nightly set to 'allow', and on beta 'warn'.
The attribute scheme used here corresponds to an older version of the
RFC, with the `#[staged_api]` crate attribute toggling the staging
behavior of the stability attributes, but the user impact is only
in-tree so I'm not concerned about having to make design changes later
(and I may ultimately prefer the scheme here after all, with the
`#[staged_api]` crate attribute).
Since the Rust codebase itself makes use of unstable features the
compiler and build system to a midly elaborate dance to allow it to
bootstrap while disobeying these lints (which would otherwise be
errors because Rust builds with `-D warnings`).
This patch includes one significant hack that causes a
regression. Because the `format_args!` macro emits calls to unstable
APIs it would trigger the lint. I added a hack to the lint to make it
not trigger, but this in turn causes arguments to `println!` not to be
checked for feature gates. I don't presently understand macro
expansion well enough to fix. This is bug #20661.
Closes #16678
[rc]: https://github.com/rust-lang/rfcs/blob/master/text/0507-release-channels.md
2015-01-06 14:26:08 +00:00
|
|
|
}
|
|
|
|
|
2015-06-26 17:32:27 +00:00
|
|
|
/// Prints version information
|
2022-11-09 08:52:59 +00:00
|
|
|
///
|
|
|
|
/// NOTE: this is a macro to support drivers built at a different time than the main `rustc_driver` crate.
|
|
|
|
pub macro version($binary: literal, $matches: expr) {
|
|
|
|
fn unw(x: Option<&str>) -> &str {
|
|
|
|
x.unwrap_or("unknown")
|
|
|
|
}
|
|
|
|
$crate::version_at_macro_invocation(
|
|
|
|
$binary,
|
|
|
|
$matches,
|
|
|
|
unw(option_env!("CFG_VERSION")),
|
|
|
|
unw(option_env!("CFG_VER_HASH")),
|
|
|
|
unw(option_env!("CFG_VER_DATE")),
|
|
|
|
unw(option_env!("CFG_RELEASE")),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)] // use the macro instead
|
|
|
|
pub fn version_at_macro_invocation(
|
|
|
|
binary: &str,
|
|
|
|
matches: &getopts::Matches,
|
|
|
|
version: &str,
|
|
|
|
commit_hash: &str,
|
|
|
|
commit_date: &str,
|
|
|
|
release: &str,
|
|
|
|
) {
|
2014-12-16 00:03:39 +00:00
|
|
|
let verbose = matches.opt_present("verbose");
|
2014-05-19 03:37:07 +00:00
|
|
|
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("{binary} {version}");
|
2018-10-12 12:36:10 +00:00
|
|
|
|
2014-05-19 03:37:07 +00:00
|
|
|
if verbose {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("binary: {binary}");
|
|
|
|
safe_println!("commit-hash: {commit_hash}");
|
|
|
|
safe_println!("commit-date: {commit_date}");
|
|
|
|
safe_println!("host: {}", config::host_triple());
|
|
|
|
safe_println!("release: {release}");
|
2021-05-29 14:36:17 +00:00
|
|
|
|
|
|
|
let debug_flags = matches.opt_strs("Z");
|
2021-07-29 09:54:39 +00:00
|
|
|
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
|
2021-05-29 14:36:17 +00:00
|
|
|
get_codegen_backend(&None, backend_name).print_version();
|
2014-05-19 03:37:07 +00:00
|
|
|
}
|
2014-05-06 11:38:01 +00:00
|
|
|
}
|
|
|
|
|
2020-10-10 18:27:52 +00:00
|
|
|
fn usage(verbose: bool, include_unstable_options: bool, nightly_build: bool) {
|
2014-12-17 13:42:50 +00:00
|
|
|
let groups = if verbose { config::rustc_optgroups() } else { config::rustc_short_optgroups() };
|
2017-06-08 21:20:55 +00:00
|
|
|
let mut options = getopts::Options::new();
|
|
|
|
for option in groups.iter().filter(|x| include_unstable_options || x.is_stable()) {
|
|
|
|
(option.apply)(&mut options);
|
|
|
|
}
|
2018-10-12 12:14:03 +00:00
|
|
|
let message = "Usage: rustc [OPTIONS] INPUT";
|
2020-10-10 18:27:52 +00:00
|
|
|
let nightly_help = if nightly_build {
|
2019-04-10 10:10:25 +00:00
|
|
|
"\n -Z help Print unstable compiler options"
|
2017-07-30 09:17:22 +00:00
|
|
|
} else {
|
|
|
|
""
|
|
|
|
};
|
|
|
|
let verbose_help = if verbose {
|
2014-12-16 00:03:39 +00:00
|
|
|
""
|
|
|
|
} else {
|
|
|
|
"\n --help -v Print the full set of options rustc accepts"
|
|
|
|
};
|
2021-02-18 15:10:28 +00:00
|
|
|
let at_path = if verbose {
|
2019-07-30 22:57:10 +00:00
|
|
|
" @path Read newline separated options from `path`\n"
|
|
|
|
} else {
|
|
|
|
""
|
|
|
|
};
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!(
|
2019-07-30 22:57:10 +00:00
|
|
|
"{options}{at_path}\nAdditional help:
|
2014-05-06 11:38:01 +00:00
|
|
|
-C help Print codegen options
|
2015-11-10 20:48:44 +00:00
|
|
|
-W help \
|
2019-08-01 18:06:52 +00:00
|
|
|
Print 'lint' options and default settings{nightly}{verbose}\n",
|
|
|
|
options = options.usage(message),
|
2019-07-30 22:57:10 +00:00
|
|
|
at_path = at_path,
|
2019-08-01 18:06:52 +00:00
|
|
|
nightly = nightly_help,
|
|
|
|
verbose = verbose_help
|
|
|
|
);
|
2014-05-06 11:38:01 +00:00
|
|
|
}
|
|
|
|
|
2018-03-06 05:01:30 +00:00
|
|
|
fn print_wall_help() {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!(
|
2018-03-06 05:01:30 +00:00
|
|
|
"
|
2018-03-13 01:26:51 +00:00
|
|
|
The flag `-Wall` does not exist in `rustc`. Most useful lints are enabled by
|
|
|
|
default. Use `rustc -W help` to see all available lints. It's more common to put
|
|
|
|
warning settings in the crate root using `#![warn(LINT_NAME)]` instead of using
|
2018-03-06 05:01:30 +00:00
|
|
|
the command line flag directly.
|
|
|
|
"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-04-06 01:09:43 +00:00
|
|
|
/// Write to stdout lint command options, together with a list of all available lints
|
|
|
|
pub fn describe_lints(sess: &Session, lint_store: &LintStore, loaded_plugins: bool) {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!(
|
2014-05-06 11:38:01 +00:00
|
|
|
"
|
|
|
|
Available lint options:
|
|
|
|
-W <foo> Warn about <foo>
|
2015-11-10 20:48:44 +00:00
|
|
|
-A <foo> \
|
|
|
|
Allow <foo>
|
2014-05-06 11:38:01 +00:00
|
|
|
-D <foo> Deny <foo>
|
2015-11-10 20:48:44 +00:00
|
|
|
-F <foo> Forbid <foo> \
|
2017-03-12 10:12:05 +00:00
|
|
|
(deny <foo> and all attempts to override)
|
2014-06-10 21:03:19 +00:00
|
|
|
|
2014-05-06 11:38:01 +00:00
|
|
|
"
|
|
|
|
);
|
|
|
|
|
2019-10-07 20:52:53 +00:00
|
|
|
fn sort_lints(sess: &Session, mut lints: Vec<&'static Lint>) -> Vec<&'static Lint> {
|
2018-03-30 09:54:14 +00:00
|
|
|
// The sort doesn't case-fold but it's doubtful we care.
|
2019-11-12 17:09:20 +00:00
|
|
|
lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess.edition()), x.name));
|
2014-10-30 01:21:37 +00:00
|
|
|
lints
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sort_lint_groups(
|
2020-01-09 06:52:01 +00:00
|
|
|
lints: Vec<(&'static str, Vec<LintId>, bool)>,
|
|
|
|
) -> Vec<(&'static str, Vec<LintId>)> {
|
2014-10-30 01:21:37 +00:00
|
|
|
let mut lints: Vec<_> = lints.into_iter().map(|(x, y, _)| (x, y)).collect();
|
2018-04-01 04:52:45 +00:00
|
|
|
lints.sort_by_key(|l| l.0);
|
2014-10-30 01:21:37 +00:00
|
|
|
lints
|
|
|
|
}
|
|
|
|
|
2014-12-30 18:51:18 +00:00
|
|
|
let (plugin, builtin): (Vec<_>, _) =
|
2019-10-07 20:52:53 +00:00
|
|
|
lint_store.get_lints().iter().cloned().partition(|&lint| lint.is_plugin);
|
2018-02-23 00:51:42 +00:00
|
|
|
let plugin = sort_lints(sess, plugin);
|
|
|
|
let builtin = sort_lints(sess, builtin);
|
2014-06-10 21:03:19 +00:00
|
|
|
|
2014-12-30 18:51:18 +00:00
|
|
|
let (plugin_groups, builtin_groups): (Vec<_>, _) =
|
2022-01-05 12:02:16 +00:00
|
|
|
lint_store.get_lint_groups().partition(|&(.., p)| p);
|
2014-07-21 03:27:59 +00:00
|
|
|
let plugin_groups = sort_lint_groups(plugin_groups);
|
|
|
|
let builtin_groups = sort_lint_groups(builtin_groups);
|
|
|
|
|
2015-11-10 20:48:44 +00:00
|
|
|
let max_name_len =
|
|
|
|
plugin.iter().chain(&builtin).map(|&s| s.name.chars().count()).max().unwrap_or(0);
|
2015-02-01 17:44:15 +00:00
|
|
|
let padded = |x: &str| {
|
2018-04-01 04:48:15 +00:00
|
|
|
let mut s = " ".repeat(max_name_len - x.chars().count());
|
2014-10-15 06:05:01 +00:00
|
|
|
s.push_str(x);
|
|
|
|
s
|
2014-06-04 21:35:58 +00:00
|
|
|
};
|
2014-05-06 11:38:01 +00:00
|
|
|
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("Lint checks provided by rustc:\n");
|
2014-06-04 21:35:58 +00:00
|
|
|
|
2015-02-01 17:44:15 +00:00
|
|
|
let print_lints = |lints: Vec<&Lint>| {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!(" {} {:7.7} {}", padded("name"), "default", "meaning");
|
|
|
|
safe_println!(" {} {:7.7} {}", padded("----"), "-------", "-------");
|
2015-02-01 01:03:04 +00:00
|
|
|
for lint in lints {
|
2021-12-13 21:58:58 +00:00
|
|
|
let name = lint.name_lower().replace('_', "-");
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!(
|
2021-03-22 19:57:52 +00:00
|
|
|
" {} {:7.7} {}",
|
|
|
|
padded(&name),
|
|
|
|
lint.default_level(sess.edition()).as_str(),
|
|
|
|
lint.desc
|
|
|
|
);
|
2014-06-10 21:03:19 +00:00
|
|
|
}
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("\n");
|
2014-06-10 21:03:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
print_lints(builtin);
|
|
|
|
|
2016-01-06 06:42:19 +00:00
|
|
|
let max_name_len = max(
|
|
|
|
"warnings".len(),
|
|
|
|
plugin_groups
|
|
|
|
.iter()
|
|
|
|
.chain(&builtin_groups)
|
|
|
|
.map(|&(s, _)| s.chars().count())
|
|
|
|
.max()
|
|
|
|
.unwrap_or(0),
|
|
|
|
);
|
2016-01-04 16:54:30 +00:00
|
|
|
|
2015-02-01 17:44:15 +00:00
|
|
|
let padded = |x: &str| {
|
2018-04-01 04:48:15 +00:00
|
|
|
let mut s = " ".repeat(max_name_len - x.chars().count());
|
2014-10-15 06:05:01 +00:00
|
|
|
s.push_str(x);
|
|
|
|
s
|
2014-07-21 03:27:59 +00:00
|
|
|
};
|
|
|
|
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("Lint groups provided by rustc:\n");
|
2014-07-21 03:27:59 +00:00
|
|
|
|
2022-07-02 05:54:05 +00:00
|
|
|
let print_lint_groups = |lints: Vec<(&'static str, Vec<LintId>)>, all_warnings| {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!(" {} sub-lints", padded("name"));
|
|
|
|
safe_println!(" {} ---------", padded("----"));
|
2022-07-02 05:54:05 +00:00
|
|
|
|
|
|
|
if all_warnings {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!(" {} all lints that are set to issue warnings", padded("warnings"));
|
2022-07-02 05:54:05 +00:00
|
|
|
}
|
|
|
|
|
2015-02-01 01:03:04 +00:00
|
|
|
for (name, to) in lints {
|
2021-12-13 21:58:58 +00:00
|
|
|
let name = name.to_lowercase().replace('_', "-");
|
2015-11-10 20:48:44 +00:00
|
|
|
let desc = to
|
|
|
|
.into_iter()
|
2021-12-13 21:58:58 +00:00
|
|
|
.map(|x| x.to_string().replace('_', "-"))
|
2015-11-10 20:48:44 +00:00
|
|
|
.collect::<Vec<String>>()
|
|
|
|
.join(", ");
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!(" {} {}", padded(&name), desc);
|
2014-06-19 00:26:14 +00:00
|
|
|
}
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("\n");
|
2014-07-21 03:27:59 +00:00
|
|
|
};
|
|
|
|
|
2022-07-02 05:54:05 +00:00
|
|
|
print_lint_groups(builtin_groups, true);
|
2014-07-21 03:27:59 +00:00
|
|
|
|
|
|
|
match (loaded_plugins, plugin.len(), plugin_groups.len()) {
|
|
|
|
(false, 0, _) | (false, _, 0) => {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("Lint tools like Clippy can provide additional lints and lint groups.");
|
2014-07-21 03:27:59 +00:00
|
|
|
}
|
2016-08-26 16:23:42 +00:00
|
|
|
(false, ..) => panic!("didn't load lint plugins but got them anyway!"),
|
2023-04-25 00:04:26 +00:00
|
|
|
(true, 0, 0) => safe_println!("This crate does not load any lint plugins or lint groups."),
|
2014-07-21 03:27:59 +00:00
|
|
|
(true, l, g) => {
|
|
|
|
if l > 0 {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("Lint checks provided by plugins loaded by this crate:\n");
|
2014-07-21 03:27:59 +00:00
|
|
|
print_lints(plugin);
|
|
|
|
}
|
|
|
|
if g > 0 {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("Lint groups provided by plugins loaded by this crate:\n");
|
2022-07-02 05:54:05 +00:00
|
|
|
print_lint_groups(plugin_groups, false);
|
2014-07-21 03:27:59 +00:00
|
|
|
}
|
2014-06-19 00:26:14 +00:00
|
|
|
}
|
|
|
|
}
|
2014-05-06 11:38:01 +00:00
|
|
|
}
|
|
|
|
|
2023-03-31 10:59:13 +00:00
|
|
|
/// Show help for flag categories shared between rustdoc and rustc.
|
|
|
|
///
|
|
|
|
/// Returns whether a help option was printed.
|
|
|
|
pub fn describe_flag_categories(matches: &Matches) -> bool {
|
|
|
|
// Handle the special case of -Wall.
|
|
|
|
let wall = matches.opt_strs("W");
|
|
|
|
if wall.iter().any(|x| *x == "all") {
|
|
|
|
print_wall_help();
|
|
|
|
rustc_errors::FatalError.raise();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't handle -W help here, because we might first load plugins.
|
|
|
|
let debug_flags = matches.opt_strs("Z");
|
|
|
|
if debug_flags.iter().any(|x| *x == "help") {
|
|
|
|
describe_debug_flags();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
let cg_flags = matches.opt_strs("C");
|
|
|
|
if cg_flags.iter().any(|x| *x == "help") {
|
|
|
|
describe_codegen_flags();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if cg_flags.iter().any(|x| *x == "no-stack-check") {
|
|
|
|
early_warn(
|
|
|
|
ErrorOutputType::default(),
|
|
|
|
"the --no-stack-check flag is deprecated and does nothing",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if cg_flags.iter().any(|x| *x == "passes=list") {
|
|
|
|
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
|
|
|
|
get_codegen_backend(&None, backend_name).print_passes();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2014-05-06 11:38:01 +00:00
|
|
|
fn describe_debug_flags() {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("\nAvailable options:\n");
|
2022-07-06 12:44:47 +00:00
|
|
|
print_flag_list("-Z", config::Z_OPTIONS);
|
2014-05-06 11:38:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn describe_codegen_flags() {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!("\nAvailable codegen options:\n");
|
2015-11-07 13:00:55 +00:00
|
|
|
print_flag_list("-C", config::CG_OPTIONS);
|
|
|
|
}
|
|
|
|
|
2023-03-31 10:59:13 +00:00
|
|
|
fn print_flag_list<T>(
|
2015-11-07 13:00:55 +00:00
|
|
|
cmdline_opt: &str,
|
2020-04-03 03:15:10 +00:00
|
|
|
flag_list: &[(&'static str, T, &'static str, &'static str)],
|
2015-11-07 13:00:55 +00:00
|
|
|
) {
|
2020-04-03 03:15:10 +00:00
|
|
|
let max_len = flag_list.iter().map(|&(name, _, _, _)| name.chars().count()).max().unwrap_or(0);
|
2015-11-07 13:00:55 +00:00
|
|
|
|
2020-04-03 03:15:10 +00:00
|
|
|
for &(name, _, _, desc) in flag_list {
|
2023-04-25 00:04:26 +00:00
|
|
|
safe_println!(
|
2020-04-03 03:15:10 +00:00
|
|
|
" {} {:>width$}=val -- {}",
|
2015-11-10 20:48:44 +00:00
|
|
|
cmdline_opt,
|
2021-12-13 21:58:58 +00:00
|
|
|
name.replace('_', "-"),
|
2015-11-10 20:48:44 +00:00
|
|
|
desc,
|
2020-04-03 03:15:10 +00:00
|
|
|
width = max_len
|
2015-11-10 20:48:44 +00:00
|
|
|
);
|
2014-05-06 11:38:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-09 04:00:52 +00:00
|
|
|
/// Process command line options. Emits messages as appropriate. If compilation
|
2016-02-20 06:03:54 +00:00
|
|
|
/// should continue, returns a getopts::Matches object parsed from args,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// otherwise returns `None`.
|
2016-02-20 06:03:54 +00:00
|
|
|
///
|
2017-01-22 07:45:06 +00:00
|
|
|
/// The compiler's handling of options is a little complicated as it ties into
|
2019-08-09 23:25:34 +00:00
|
|
|
/// our stability story. The current intention of each compiler option is to
|
|
|
|
/// have one of two modes:
|
2016-02-20 06:03:54 +00:00
|
|
|
///
|
|
|
|
/// 1. An option is stable and can be used everywhere.
|
2019-08-09 23:25:34 +00:00
|
|
|
/// 2. An option is unstable, and can only be used on nightly.
|
2016-02-20 06:03:54 +00:00
|
|
|
///
|
|
|
|
/// Like unstable library and language features, however, unstable options have
|
|
|
|
/// always required a form of "opt in" to indicate that you're using them. This
|
|
|
|
/// provides the easy ability to scan a code base to check to see if anything
|
|
|
|
/// unstable is being used. Currently, this "opt in" is the `-Z` "zed" flag.
|
|
|
|
///
|
|
|
|
/// All options behind `-Z` are considered unstable by default. Other top-level
|
|
|
|
/// options can also be considered unstable, and they were unlocked through the
|
|
|
|
/// `-Z unstable-options` flag. Note that `-Z` remains to be the root of
|
|
|
|
/// instability in both cases, though.
|
|
|
|
///
|
|
|
|
/// So with all that in mind, the comments below have some more detail about the
|
|
|
|
/// contortions done here to get things to work out correctly.
|
2016-03-20 03:37:13 +00:00
|
|
|
pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
2014-05-15 04:39:11 +00:00
|
|
|
if args.is_empty() {
|
2014-12-17 13:42:50 +00:00
|
|
|
// user did not write `-v` nor `-Z unstable-options`, so do not
|
|
|
|
// include that extra information.
|
2020-10-10 18:27:52 +00:00
|
|
|
let nightly_build =
|
|
|
|
rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build();
|
|
|
|
usage(false, false, nightly_build);
|
2014-05-15 04:39:11 +00:00
|
|
|
return None;
|
|
|
|
}
|
2014-05-06 11:38:01 +00:00
|
|
|
|
2016-02-20 06:03:54 +00:00
|
|
|
// Parse with *all* options defined in the compiler, we don't worry about
|
|
|
|
// option stability here we just want to parse as much as possible.
|
2017-06-08 21:20:55 +00:00
|
|
|
let mut options = getopts::Options::new();
|
|
|
|
for option in config::rustc_optgroups() {
|
|
|
|
(option.apply)(&mut options);
|
|
|
|
}
|
2021-06-27 23:15:16 +00:00
|
|
|
let matches = options.parse(args).unwrap_or_else(|e| {
|
|
|
|
let msg = match e {
|
|
|
|
getopts::Fail::UnrecognizedOption(ref opt) => CG_OPTIONS
|
|
|
|
.iter()
|
|
|
|
.map(|&(name, ..)| ('C', name))
|
2022-07-06 12:44:47 +00:00
|
|
|
.chain(Z_OPTIONS.iter().map(|&(name, ..)| ('Z', name)))
|
2021-12-13 21:58:58 +00:00
|
|
|
.find(|&(_, name)| *opt == name.replace('_', "-"))
|
2022-12-19 09:31:55 +00:00
|
|
|
.map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
|
2021-06-27 23:15:16 +00:00
|
|
|
_ => None,
|
|
|
|
};
|
2023-05-16 06:04:03 +00:00
|
|
|
early_error(ErrorOutputType::default(), msg.unwrap_or_else(|| e.to_string()));
|
2021-06-27 23:15:16 +00:00
|
|
|
});
|
2015-03-11 08:42:00 +00:00
|
|
|
|
2016-02-20 06:03:54 +00:00
|
|
|
// For all options we just parsed, we check a few aspects:
|
|
|
|
//
|
|
|
|
// * If the option is stable, we're all good
|
|
|
|
// * If the option wasn't passed, we're all good
|
|
|
|
// * If `-Z unstable-options` wasn't passed (and we're not a -Z option
|
|
|
|
// ourselves), then we require the `-Z unstable-options` flag to unlock
|
|
|
|
// this option that was passed.
|
|
|
|
// * If we're a nightly compiler, then unstable options are now unlocked, so
|
|
|
|
// we're good to go.
|
2019-08-09 23:25:34 +00:00
|
|
|
// * Otherwise, if we're an unstable option then we generate an error
|
2016-02-20 06:03:54 +00:00
|
|
|
// (unstable option being used on stable)
|
2016-03-15 08:09:29 +00:00
|
|
|
nightly_options::check_nightly_options(&matches, &config::rustc_optgroups());
|
2014-12-17 13:42:50 +00:00
|
|
|
|
2014-05-06 11:38:01 +00:00
|
|
|
if matches.opt_present("h") || matches.opt_present("help") {
|
2019-08-09 23:25:34 +00:00
|
|
|
// Only show unstable options in --help if we accept unstable options.
|
2020-10-10 18:27:52 +00:00
|
|
|
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
|
|
|
|
let nightly_build = nightly_options::match_is_nightly_build(&matches);
|
|
|
|
usage(matches.opt_present("verbose"), unstable_enabled, nightly_build);
|
2014-05-06 11:38:01 +00:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2023-03-31 10:59:13 +00:00
|
|
|
if describe_flag_categories(&matches) {
|
2014-05-06 11:38:01 +00:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2014-05-19 03:37:07 +00:00
|
|
|
if matches.opt_present("version") {
|
2022-11-09 08:52:59 +00:00
|
|
|
version!("rustc", &matches);
|
2014-12-16 00:03:39 +00:00
|
|
|
return None;
|
2014-05-06 11:38:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Some(matches)
|
|
|
|
}
|
|
|
|
|
2022-12-07 09:24:00 +00:00
|
|
|
fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
|
|
|
|
match &sess.io.input {
|
2019-10-15 20:48:13 +00:00
|
|
|
Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess),
|
|
|
|
Input::Str { name, input } => rustc_parse::parse_crate_attrs_from_source_str(
|
|
|
|
name.clone(),
|
|
|
|
input.clone(),
|
|
|
|
&sess.parse_sess,
|
|
|
|
),
|
2016-02-13 17:05:16 +00:00
|
|
|
}
|
2014-05-06 11:38:01 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Gets a list of extra command-line flags provided by the user, as strings.
|
2018-02-16 11:10:06 +00:00
|
|
|
///
|
|
|
|
/// This function is used during ICEs to show more information useful for
|
|
|
|
/// debugging, since some ICEs only happens with non-default compiler flags
|
|
|
|
/// (and the users don't always report them).
|
|
|
|
fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
|
2021-12-27 04:32:17 +00:00
|
|
|
let mut args = env::args_os().map(|arg| arg.to_string_lossy().to_string()).peekable();
|
2018-02-16 11:10:06 +00:00
|
|
|
|
|
|
|
let mut result = Vec::new();
|
|
|
|
let mut excluded_cargo_defaults = false;
|
2021-12-27 04:32:17 +00:00
|
|
|
while let Some(arg) = args.next() {
|
|
|
|
if let Some(a) = ICE_REPORT_COMPILER_FLAGS.iter().find(|a| arg.starts_with(*a)) {
|
|
|
|
let content = if arg.len() == a.len() {
|
2022-09-08 23:08:53 +00:00
|
|
|
// A space-separated option, like `-C incremental=foo` or `--crate-type rlib`
|
2021-12-27 04:32:17 +00:00
|
|
|
match args.next() {
|
|
|
|
Some(arg) => arg.to_string(),
|
|
|
|
None => continue,
|
|
|
|
}
|
|
|
|
} else if arg.get(a.len()..a.len() + 1) == Some("=") {
|
2022-09-08 23:08:53 +00:00
|
|
|
// An equals option, like `--crate-type=rlib`
|
2021-12-27 04:32:17 +00:00
|
|
|
arg[a.len() + 1..].to_string()
|
2018-02-16 11:10:06 +00:00
|
|
|
} else {
|
2022-09-08 23:08:53 +00:00
|
|
|
// A non-space option, like `-Cincremental=foo`
|
2021-12-27 04:32:17 +00:00
|
|
|
arg[a.len()..].to_string()
|
|
|
|
};
|
2022-09-08 23:08:53 +00:00
|
|
|
let option = content.split_once('=').map(|s| s.0).unwrap_or(&content);
|
|
|
|
if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| option == *exc) {
|
2018-02-16 11:10:06 +00:00
|
|
|
excluded_cargo_defaults = true;
|
2021-12-27 04:32:17 +00:00
|
|
|
} else {
|
|
|
|
result.push(a.to_string());
|
2022-09-08 23:08:53 +00:00
|
|
|
match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) {
|
2022-12-19 09:31:55 +00:00
|
|
|
Some(s) => result.push(format!("{s}=[REDACTED]")),
|
2021-12-27 04:32:17 +00:00
|
|
|
None => result.push(content),
|
|
|
|
}
|
2018-02-16 11:10:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-23 16:48:46 +00:00
|
|
|
if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None }
|
2018-02-16 11:10:06 +00:00
|
|
|
}
|
|
|
|
|
2019-05-06 11:47:58 +00:00
|
|
|
/// Runs a closure and catches unwinds triggered by fatal errors.
|
2014-05-06 11:38:01 +00:00
|
|
|
///
|
2019-05-10 15:44:25 +00:00
|
|
|
/// The compiler currently unwinds with a special sentinel value to abort
|
2019-05-06 11:47:58 +00:00
|
|
|
/// compilation on fatal errors. This function catches that sentinel and turns
|
|
|
|
/// the panic into a `Result` instead.
|
2022-01-23 18:34:26 +00:00
|
|
|
pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorGuaranteed> {
|
2018-12-08 19:30:23 +00:00
|
|
|
catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| {
|
2020-01-09 10:18:47 +00:00
|
|
|
if value.is::<rustc_errors::FatalErrorMarker>() {
|
2023-05-05 17:31:54 +00:00
|
|
|
#[allow(deprecated)]
|
2022-01-23 00:49:12 +00:00
|
|
|
ErrorGuaranteed::unchecked_claim_error_was_emitted()
|
2018-07-09 18:01:10 +00:00
|
|
|
} else {
|
2019-05-06 11:47:58 +00:00
|
|
|
panic::resume_unwind(value);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2014-05-06 11:38:01 +00:00
|
|
|
|
2020-05-10 21:36:41 +00:00
|
|
|
/// Variant of `catch_fatal_errors` for the `interface::Result` return type
|
|
|
|
/// that also computes the exit code.
|
|
|
|
pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
|
|
|
|
let result = catch_fatal_errors(f).and_then(|result| result);
|
|
|
|
match result {
|
|
|
|
Ok(()) => EXIT_SUCCESS,
|
|
|
|
Err(_) => EXIT_FAILURE,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-29 11:29:07 +00:00
|
|
|
/// Stores the default panic hook, from before [`install_ice_hook`] was called.
|
|
|
|
static DEFAULT_HOOK: OnceLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> =
|
|
|
|
OnceLock::new();
|
|
|
|
|
|
|
|
/// Installs a panic hook that will print the ICE message on unexpected panics.
|
|
|
|
///
|
|
|
|
/// The hook is intended to be useable even by external tools. You can pass a custom
|
|
|
|
/// `bug_report_url`, or report arbitrary info in `extra_info`. Note that `extra_info` is called in
|
|
|
|
/// a context where *the thread is currently panicking*, so it must not panic or the process will
|
|
|
|
/// abort.
|
|
|
|
///
|
|
|
|
/// If you have no extra info to report, pass the empty closure `|_| ()` as the argument to
|
|
|
|
/// extra_info.
|
|
|
|
///
|
|
|
|
/// A custom rustc driver can skip calling this to set up a custom ICE hook.
|
|
|
|
pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) {
|
|
|
|
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce
|
|
|
|
// full backtraces. When a compiler ICE happens, we want to gather
|
|
|
|
// as much information as possible to present in the issue opened
|
|
|
|
// by the user. Compiler developers and other rustc users can
|
|
|
|
// opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE"
|
|
|
|
// (e.g. `RUST_BACKTRACE=1`)
|
|
|
|
if std::env::var("RUST_BACKTRACE").is_err() {
|
|
|
|
std::env::set_var("RUST_BACKTRACE", "full");
|
|
|
|
}
|
2022-08-02 00:08:13 +00:00
|
|
|
|
2023-04-29 11:29:07 +00:00
|
|
|
let default_hook = DEFAULT_HOOK.get_or_init(panic::take_hook);
|
2021-05-24 16:47:16 +00:00
|
|
|
|
2023-04-29 11:29:07 +00:00
|
|
|
panic::set_hook(Box::new(move |info| {
|
|
|
|
// If the error was caused by a broken pipe then this is not a bug.
|
|
|
|
// Write the error and return immediately. See #98700.
|
|
|
|
#[cfg(windows)]
|
|
|
|
if let Some(msg) = info.payload().downcast_ref::<String>() {
|
|
|
|
if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") {
|
2023-05-15 16:42:44 +00:00
|
|
|
// the error code is already going to be reported when the panic unwinds up the stack
|
Use `Cow` in `{D,Subd}iagnosticMessage`.
Each of `{D,Subd}iagnosticMessage::{Str,Eager}` has a comment:
```
// FIXME(davidtwco): can a `Cow<'static, str>` be used here?
```
This commit answers that question in the affirmative. It's not the most
compelling change ever, but it might be worth merging.
This requires changing the `impl<'a> From<&'a str>` impls to `impl
From<&'static str>`, which involves a bunch of knock-on changes that
require/result in call sites being a little more precise about exactly
what kind of string they use to create errors, and not just `&str`. This
will result in fewer unnecessary allocations, though this will not have
any notable perf effects given that these are error paths.
Note that I was lazy within Clippy, using `to_string` in a few places to
preserve the existing string imprecision. I could have used `impl
Into<{D,Subd}iagnosticMessage>` in various places as is done in the
compiler, but that would have required changes to *many* call sites
(mostly changing `&format("...")` to `format!("...")`) which didn't seem
worthwhile.
2023-05-04 00:55:21 +00:00
|
|
|
let _ = early_error_no_abort(ErrorOutputType::default(), msg.clone());
|
2023-04-29 11:29:07 +00:00
|
|
|
return;
|
Make `sess.bug` much less noisy
Before:
```
Compiling core v0.0.0 (C:\Users\Joshua Nelson\src\rust2\library\core)
error: internal compiler error: no warnings or errors encountered even though `delayed_good_path_bugs` issued
error: internal compiler error: oops
|
= note: delayed at 0: std::backtrace_rs::backtrace::trace_unsynchronized
1: std::backtrace::Backtrace::disabled
2: std::backtrace::Backtrace::force_capture
3: <rustc_errors::Handler>::delay_good_path_bug::<&str>
4: <rustc_interface::passes::QueryContext>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}::{closure#2}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
5: RINvMs2_NtCsiwHPejSviHg_15rustc_interface7queriesNtNtB8_9interface8Compiler5enterNCNCNvCs7PhwInflpyf_12rustc_driver12run_compilers_0s0_0INtNtCslM5znELOk5i_4core6result6ResultINtNtB2f_6option6OptionNtB6_6LinkerENtCshthk7JDUYGg_12rustc_errors15ErrorGuarante
6: RINvCs6uSsza6NDuD_10rustc_span15with_source_mapINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_errors15ErrorGuaranteedENCNCINvNtCsiwHPejSviHg_15rustc_interface9interface12run_compilerBJ_NCNvCs7PhwInflpyf_12rustc_driver12run_compilers_0E00EB
7: RINvMs_Cs9yvsqs6YnUZ_10scoped_tlsINtB5_9ScopedKeyNtCs6uSsza6NDuD_10rustc_span14SessionGlobalsE3setNCINvNtCsiwHPejSviHg_15rustc_interface9interface12run_compilerINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_errors15ErrorGuaranteedENCNvCs7P
8: RINvNtNtCs5xszGlR5JQw_3std10sys_common9backtrace28___rust_begin_short_backtraceNCNCINvNtCsiwHPejSviHg_15rustc_interface4util31run_in_thread_pool_with_globalsNCINvNtB1o_9interface12run_compilerINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_
9: RINvNtCs5xszGlR5JQw_3std9panicking3tryINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_errors15ErrorGuaranteedEINtNtNtBF_5panic11unwind_safe16AssertUnwindSafeNCNCINvMNtB4_6threadNtB2S_7Builder16spawn_unchecked_NCNCINvNtCsiwHPejSviHg_15rustc_
10: <std::thread::Builder>::spawn_scoped::<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<(), rustc_driver::run_compiler::{closure#0}>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
11: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
12: std::sys::windows::thread::Thread::new
13: BaseThreadInitThunk
14: RtlUserThreadStart
thread 'rustc' panicked at 'Box<dyn Any>', compiler\rustc_errors\src\lib.rs:1610:13
stack backtrace:
0: 0x7fffbe935a15 - std::backtrace_rs::backtrace::trace_unsynchronized::h2a29ea0a35c1f799
1: 0x7fffbe968811 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h5e4ca8af47bfbcc0
2: 0x7fffbe98aeab - core::fmt::write::h152a9de2569e7dc7
3: 0x7fffbe961059 - std::io::Write::write_fmt::h2452e19093defac4
4: 0x7fffbe96866b - std::sys_common::backtrace::print::h550d034f7b77d60a
5: 0x7fffbe93be1b - std::panicking::default_hook::h3969ead74039b801
6: 0x7fffbe93bbad - std::panicking::default_hook::h3969ead74039b801
7: 0x7fffa5f0abe3 - rustc_driver[5b2ae43fbecaf219]::handle_options
8: 0x7fffbe93c25b - std::panicking::rust_panic_with_hook::h32bbe3ce24999160
9: 0x7fffa82baee5 - std[4086331e48bff2f6]::sys_common::backtrace::__rust_end_short_backtrace::<std[4086331e48bff2f6]::panicking::begin_panic<&str>::{closure#0}, !>
10: 0x7fffa82bae89 - std[4086331e48bff2f6]::sys_common::backtrace::__rust_end_short_backtrace::<std[4086331e48bff2f6]::panicking::begin_panic<rustc_errors[cb829533098ec0fe]::ExplicitBug>::{closure#0}, !>
11: 0x7fffa867ed89 - std[4086331e48bff2f6]::panicking::begin_panic::<rustc_errors[cb829533098ec0fe]::ExplicitBug>
12: 0x7fffa8298de9 - <alloc[284c8fe3a98c29c4]::string::String as core[fda266aeadfb153a]::fmt::Write>::write_fmt
13: 0x7fffa829b7e2 - <rustc_errors[cb829533098ec0fe]::HandlerInner>::flush_delayed::<core[fda266aeadfb153a]::iter::adapters::map::Map<alloc[284c8fe3a98c29c4]::vec::into_iter::IntoIter<rustc_errors[cb829533098ec0fe]::DelayedDiagnostic>, <rustc_errors[cb829533098ec0fe]::DelayedDiagnostic>::decorate>, &str>
14: 0x7fffa8288638 - <rustc_errors[cb829533098ec0fe]::HandlerInner as core[fda266aeadfb153a]::ops::drop::Drop>::drop
15: 0x7fffa5eb90e1 - core[fda266aeadfb153a]::ptr::drop_in_place::<rustc_errors[cb829533098ec0fe]::Handler>
16: 0x7fffa5ebe9fd - core[fda266aeadfb153a]::ptr::drop_in_place::<rustc_session[e703468b2407e34a]::cgu_reuse_tracker::CguReuseTracker>
17: 0x7fffa5ec0d7c - core[fda266aeadfb153a]::ptr::drop_in_place::<rustc_session[e703468b2407e34a]::session::Session>
18: 0x7fffa5ebe41c - core[fda266aeadfb153a]::ptr::drop_in_place::<rustc_interface[d7cd35f07e7e6ecc]::interface::Compiler>
19: 0x7fffa5eea05f - RINvCs6uSsza6NDuD_10rustc_span15with_source_mapINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_errors15ErrorGuaranteedENCNCINvNtCsiwHPejSviHg_15rustc_interface9interface12run_compilerBJ_NCNvCs7PhwInflpyf_12rustc_driver12run_compilers_0E00EB
20: 0x7fffa5edbe3a - RINvMs_Cs9yvsqs6YnUZ_10scoped_tlsINtB5_9ScopedKeyNtCs6uSsza6NDuD_10rustc_span14SessionGlobalsE3setNCINvNtCsiwHPejSviHg_15rustc_interface9interface12run_compilerINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_errors15ErrorGuaranteedENCNvCs7P
21: 0x7fffa5ef4ec9 - RINvNtNtCs5xszGlR5JQw_3std10sys_common9backtrace28___rust_begin_short_backtraceNCNCINvNtCsiwHPejSviHg_15rustc_interface4util31run_in_thread_pool_with_globalsNCINvNtB1o_9interface12run_compilerINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_
22: 0x7fffa5ee9935 - RINvNtCs5xszGlR5JQw_3std9panicking3tryINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_errors15ErrorGuaranteedEINtNtNtBF_5panic11unwind_safe16AssertUnwindSafeNCNCINvMNtB4_6threadNtB2S_7Builder16spawn_unchecked_NCNCINvNtCsiwHPejSviHg_15rustc_
23: 0x7fffa5f0d770 - <std[4086331e48bff2f6]::thread::Builder>::spawn_scoped::<rustc_interface[d7cd35f07e7e6ecc]::util::run_in_thread_pool_with_globals<rustc_interface[d7cd35f07e7e6ecc]::interface::run_compiler<(), rustc_driver[5b2ae43fbecaf219]::run_compiler::{closure#0}>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
24: 0x7fffbe95b35b - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hfcd927f7aebafa45
25: 0x7fffbe9331d3 - std::sys::windows::thread::Thread::new::hf8f4c920eaebd965
26: 0x7ff815877614 - BaseThreadInitThunk
27: 0x7ff8166e26a1 - RtlUserThreadStart
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
note: rustc 1.68.0-dev running on x86_64-pc-windows-msvc
note: compiler flags: --crate-type lib -C opt-level=3 -C embed-bitcode=no -C debuginfo=0 -Z unstable-options -C incremental=[REDACTED] -C symbol-mangling-version=legacy -Z unstable-options -Z unstable-options -Z macro-backtrace -C split-debuginfo=packed -C target-feature=+crt-static -C prefer-dynamic -C embed-bitcode=yes -Z crate-attr=doc(html_root_url="https://doc.rust-lang.org/nightly/") -Z binary-dep-depinfo -Z force-unstable-if-unmarked
note: some of the compiler flags provided by cargo are hidden
query stack during panic:
end of query stack
error: could not compile `core`
```
After:
```
Compiling core v0.0.0 (C:\Users\Joshua Nelson\src\rust2\library\core)
error: internal compiler error: no warnings or errors encountered even though `delayed_good_path_bugs` issued
error: internal compiler error: oops
|
= note: delayed at 0: std::backtrace_rs::backtrace::trace_unsynchronized
1: std::backtrace::Backtrace::disabled
2: std::backtrace::Backtrace::force_capture
3: <rustc_errors::Handler>::delay_good_path_bug::<&str>
4: <rustc_interface::passes::QueryContext>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}::{closure#2}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
5: RINvMs2_NtCsiwHPejSviHg_15rustc_interface7queriesNtNtB8_9interface8Compiler5enterNCNCNvCs7PhwInflpyf_12rustc_driver12run_compilers_0s0_0INtNtCslM5znELOk5i_4core6result6ResultINtNtB2f_6option6OptionNtB6_6LinkerENtCshthk7JDUYGg_12rustc_errors15ErrorGuarante
6: RINvCs6uSsza6NDuD_10rustc_span15with_source_mapINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_errors15ErrorGuaranteedENCNCINvNtCsiwHPejSviHg_15rustc_interface9interface12run_compilerBJ_NCNvCs7PhwInflpyf_12rustc_driver12run_compilers_0E00EB
7: RINvMs_Cs9yvsqs6YnUZ_10scoped_tlsINtB5_9ScopedKeyNtCs6uSsza6NDuD_10rustc_span14SessionGlobalsE3setNCINvNtCsiwHPejSviHg_15rustc_interface9interface12run_compilerINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_errors15ErrorGuaranteedENCNvCs7P
8: RINvNtNtCs5xszGlR5JQw_3std10sys_common9backtrace28___rust_begin_short_backtraceNCNCINvNtCsiwHPejSviHg_15rustc_interface4util31run_in_thread_pool_with_globalsNCINvNtB1o_9interface12run_compilerINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_
9: RINvNtCs5xszGlR5JQw_3std9panicking3tryINtNtCslM5znELOk5i_4core6result6ResultuNtCshthk7JDUYGg_12rustc_errors15ErrorGuaranteedEINtNtNtBF_5panic11unwind_safe16AssertUnwindSafeNCNCINvMNtB4_6threadNtB2S_7Builder16spawn_unchecked_NCNCINvNtCsiwHPejSviHg_15rustc_
10: <std::thread::Builder>::spawn_scoped::<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<(), rustc_driver::run_compiler::{closure#0}>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
11: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
12: std::sys::windows::thread::Thread::new
13: BaseThreadInitThunk
14: RtlUserThreadStart
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
note: rustc 1.68.0-dev running on x86_64-pc-windows-msvc
note: compiler flags: --crate-type lib -C opt-level=3 -C embed-bitcode=no -C debuginfo=0 -Z unstable-options -C incremental=[REDACTED] -C symbol-mangling-version=legacy -Z unstable-options -Z unstable-options -Z macro-backtrace -C split-debuginfo=packed -C target-feature=+crt-static -C prefer-dynamic -C embed-bitcode=yes -Z crate-attr=doc(html_root_url="https://doc.rust-lang.org/nightly/") -Z binary-dep-depinfo -Z force-unstable-if-unmarked
note: some of the compiler flags provided by cargo are hidden
query stack during panic:
end of query stack
error: could not compile `core`
```
2022-12-22 18:43:27 +00:00
|
|
|
}
|
2023-04-29 11:29:07 +00:00
|
|
|
};
|
2021-05-24 16:47:16 +00:00
|
|
|
|
2023-04-29 11:29:07 +00:00
|
|
|
// Invoke the default handler, which prints the actual panic message and optionally a backtrace
|
|
|
|
// Don't do this for delayed bugs, which already emit their own more useful backtrace.
|
|
|
|
if !info.payload().is::<rustc_errors::DelayedBugPanic>() {
|
|
|
|
(*default_hook)(info);
|
|
|
|
|
|
|
|
// Separate the output with an empty line
|
|
|
|
eprintln!();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Print the ICE message
|
|
|
|
report_ice(info, bug_report_url, extra_info);
|
|
|
|
}));
|
|
|
|
}
|
2018-02-16 11:10:06 +00:00
|
|
|
|
2021-05-24 16:47:16 +00:00
|
|
|
/// Prints the ICE message, including query stack, but without backtrace.
|
2019-07-26 21:31:02 +00:00
|
|
|
///
|
|
|
|
/// The message will point the user at `bug_report_url` to report the ICE.
|
|
|
|
///
|
|
|
|
/// When `install_ice_hook` is called, this function will be called as the panic
|
|
|
|
/// hook.
|
2023-04-29 11:29:07 +00:00
|
|
|
pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(&Handler)) {
|
2022-03-28 08:36:20 +00:00
|
|
|
let fallback_bundle =
|
2022-10-17 13:11:26 +00:00
|
|
|
rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
|
2020-01-09 10:18:47 +00:00
|
|
|
let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
|
|
|
|
rustc_errors::ColorConfig::Auto,
|
2019-05-06 11:47:58 +00:00
|
|
|
None,
|
2022-03-28 08:36:20 +00:00
|
|
|
None,
|
2022-03-26 07:27:43 +00:00
|
|
|
fallback_bundle,
|
2019-05-06 11:47:58 +00:00
|
|
|
false,
|
|
|
|
false,
|
|
|
|
None,
|
2019-09-07 13:57:11 +00:00
|
|
|
false,
|
2022-10-18 22:08:20 +00:00
|
|
|
false,
|
2023-02-09 10:16:00 +00:00
|
|
|
TerminalUrl::No,
|
2019-05-06 11:47:58 +00:00
|
|
|
));
|
2020-01-09 10:18:47 +00:00
|
|
|
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
|
2019-05-06 11:47:58 +00:00
|
|
|
|
|
|
|
// a .span_bug or .bug call has already printed what
|
|
|
|
// it wants to print.
|
2022-12-31 01:20:59 +00:00
|
|
|
if !info.payload().is::<rustc_errors::ExplicitBug>()
|
2022-12-31 01:56:59 +00:00
|
|
|
&& !info.payload().is::<rustc_errors::DelayedBugPanic>()
|
2022-12-31 01:20:59 +00:00
|
|
|
{
|
2023-02-07 19:17:24 +00:00
|
|
|
handler.emit_err(session_diagnostics::Ice);
|
2019-05-06 11:47:58 +00:00
|
|
|
}
|
2018-02-16 11:10:06 +00:00
|
|
|
|
2022-08-19 13:48:15 +00:00
|
|
|
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url });
|
|
|
|
handler.emit_note(session_diagnostics::IceVersion {
|
|
|
|
version: util::version_str!().unwrap_or("unknown_version"),
|
|
|
|
triple: config::host_triple(),
|
|
|
|
});
|
2018-02-16 11:10:06 +00:00
|
|
|
|
2019-05-06 11:47:58 +00:00
|
|
|
if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() {
|
2022-08-19 13:48:15 +00:00
|
|
|
handler.emit_note(session_diagnostics::IceFlags { flags: flags.join(" ") });
|
2019-05-06 11:47:58 +00:00
|
|
|
if excluded_cargo_defaults {
|
2022-08-19 13:48:15 +00:00
|
|
|
handler.emit_note(session_diagnostics::IceExcludeCargoDefaults);
|
2018-07-09 18:01:10 +00:00
|
|
|
}
|
2019-05-06 11:47:58 +00:00
|
|
|
}
|
|
|
|
|
2019-05-06 22:14:40 +00:00
|
|
|
// If backtraces are enabled, also print the query stack
|
2023-05-24 14:19:22 +00:00
|
|
|
let backtrace = env::var_os("RUST_BACKTRACE").is_some_and(|x| &x != "0");
|
2019-05-06 22:14:40 +00:00
|
|
|
|
2020-09-29 14:44:07 +00:00
|
|
|
let num_frames = if backtrace { None } else { Some(2) };
|
|
|
|
|
2020-04-08 18:47:36 +00:00
|
|
|
interface::try_print_query_stack(&handler, num_frames);
|
2019-05-06 22:14:40 +00:00
|
|
|
|
2023-04-29 11:29:07 +00:00
|
|
|
// We don't trust this callback not to panic itself, so run it at the end after we're sure we've
|
|
|
|
// printed all the relevant info.
|
|
|
|
extra_info(&handler);
|
|
|
|
|
2019-05-06 22:14:40 +00:00
|
|
|
#[cfg(windows)]
|
2023-01-15 18:43:15 +00:00
|
|
|
if env::var("RUSTC_BREAK_ON_ICE").is_ok() {
|
|
|
|
// Trigger a debugger if we crashed during bootstrap
|
|
|
|
unsafe { windows::Win32::System::Diagnostics::Debug::DebugBreak() };
|
2019-05-06 22:14:40 +00:00
|
|
|
}
|
2019-05-06 11:47:58 +00:00
|
|
|
}
|
|
|
|
|
2018-01-25 08:04:00 +00:00
|
|
|
/// This allows tools to enable rust logging without having to magically match rustc's
|
2020-08-14 06:05:01 +00:00
|
|
|
/// tracing crate version.
|
2018-01-25 08:04:00 +00:00
|
|
|
pub fn init_rustc_env_logger() {
|
2023-02-07 14:24:35 +00:00
|
|
|
init_env_logger("RUSTC_LOG");
|
2020-07-25 13:50:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// This allows tools to enable rust logging without having to magically match rustc's
|
2020-08-14 06:05:01 +00:00
|
|
|
/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var
|
2020-07-25 13:50:51 +00:00
|
|
|
/// other than `RUSTC_LOG`.
|
|
|
|
pub fn init_env_logger(env: &str) {
|
2022-01-04 00:32:52 +00:00
|
|
|
if let Err(error) = rustc_log::init_env_logger(env) {
|
2023-05-16 06:04:03 +00:00
|
|
|
early_error(ErrorOutputType::default(), error.to_string());
|
2022-01-04 00:32:52 +00:00
|
|
|
}
|
2018-01-25 08:04:00 +00:00
|
|
|
}
|
|
|
|
|
2021-07-02 00:20:04 +00:00
|
|
|
#[cfg(all(unix, any(target_env = "gnu", target_os = "macos")))]
|
|
|
|
mod signal_handler {
|
|
|
|
extern "C" {
|
|
|
|
fn backtrace_symbols_fd(
|
|
|
|
buffer: *const *mut libc::c_void,
|
|
|
|
size: libc::c_int,
|
|
|
|
fd: libc::c_int,
|
|
|
|
);
|
|
|
|
}
|
2020-12-19 08:50:33 +00:00
|
|
|
|
2021-07-02 00:20:04 +00:00
|
|
|
extern "C" fn print_stack_trace(_: libc::c_int) {
|
|
|
|
const MAX_FRAMES: usize = 256;
|
|
|
|
static mut STACK_TRACE: [*mut libc::c_void; MAX_FRAMES] =
|
|
|
|
[std::ptr::null_mut(); MAX_FRAMES];
|
|
|
|
unsafe {
|
|
|
|
let depth = libc::backtrace(STACK_TRACE.as_mut_ptr(), MAX_FRAMES as i32);
|
|
|
|
if depth == 0 {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
backtrace_symbols_fd(STACK_TRACE.as_ptr(), depth, 2);
|
2020-12-19 08:50:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-27 11:15:06 +00:00
|
|
|
/// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
|
|
|
|
/// process, print a stack trace and then exit.
|
2021-07-02 00:20:04 +00:00
|
|
|
pub(super) fn install() {
|
|
|
|
unsafe {
|
|
|
|
const ALT_STACK_SIZE: usize = libc::MINSIGSTKSZ + 64 * 1024;
|
|
|
|
let mut alt_stack: libc::stack_t = std::mem::zeroed();
|
|
|
|
alt_stack.ss_sp =
|
|
|
|
std::alloc::alloc(std::alloc::Layout::from_size_align(ALT_STACK_SIZE, 1).unwrap())
|
|
|
|
as *mut libc::c_void;
|
|
|
|
alt_stack.ss_size = ALT_STACK_SIZE;
|
2021-09-30 17:38:50 +00:00
|
|
|
libc::sigaltstack(&alt_stack, std::ptr::null_mut());
|
2021-07-02 00:20:04 +00:00
|
|
|
|
|
|
|
let mut sa: libc::sigaction = std::mem::zeroed();
|
|
|
|
sa.sa_sigaction = print_stack_trace as libc::sighandler_t;
|
|
|
|
sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK;
|
|
|
|
libc::sigemptyset(&mut sa.sa_mask);
|
|
|
|
libc::sigaction(libc::SIGSEGV, &sa, std::ptr::null_mut());
|
|
|
|
}
|
2020-12-19 08:50:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-02 00:20:04 +00:00
|
|
|
#[cfg(not(all(unix, any(target_env = "gnu", target_os = "macos"))))]
|
|
|
|
mod signal_handler {
|
|
|
|
pub(super) fn install() {}
|
|
|
|
}
|
2020-12-19 08:50:33 +00:00
|
|
|
|
2020-05-10 22:11:42 +00:00
|
|
|
pub fn main() -> ! {
|
2021-01-25 20:56:21 +00:00
|
|
|
let start_time = Instant::now();
|
|
|
|
let start_rss = get_resident_set_size();
|
2023-02-07 14:24:35 +00:00
|
|
|
init_rustc_env_logger();
|
2021-07-02 00:20:04 +00:00
|
|
|
signal_handler::install();
|
2019-06-25 03:52:07 +00:00
|
|
|
let mut callbacks = TimePassesCallbacks::default();
|
2023-04-29 11:29:07 +00:00
|
|
|
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
|
2020-05-10 21:36:41 +00:00
|
|
|
let exit_code = catch_with_exit_code(|| {
|
2018-01-22 17:18:40 +00:00
|
|
|
let args = env::args_os()
|
|
|
|
.enumerate()
|
|
|
|
.map(|(i, arg)| {
|
|
|
|
arg.into_string().unwrap_or_else(|arg| {
|
2019-08-20 02:02:12 +00:00
|
|
|
early_error(
|
|
|
|
ErrorOutputType::default(),
|
2023-05-16 06:04:03 +00:00
|
|
|
format!("argument {i} is not valid Unicode: {arg:?}"),
|
2018-01-22 17:18:40 +00:00
|
|
|
)
|
|
|
|
})
|
2019-12-22 22:42:04 +00:00
|
|
|
})
|
2018-01-22 17:18:40 +00:00
|
|
|
.collect::<Vec<_>>();
|
2020-10-07 12:09:59 +00:00
|
|
|
RunCompiler::new(&args, &mut callbacks).run()
|
2020-05-10 21:36:41 +00:00
|
|
|
});
|
2021-01-25 20:56:21 +00:00
|
|
|
|
2023-02-06 05:32:34 +00:00
|
|
|
if let Some(format) = callbacks.time_passes {
|
2021-01-25 20:56:21 +00:00
|
|
|
let end_rss = get_resident_set_size();
|
2023-03-21 17:41:45 +00:00
|
|
|
print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss, format);
|
2021-01-25 20:56:21 +00:00
|
|
|
}
|
|
|
|
|
2020-05-10 22:11:42 +00:00
|
|
|
process::exit(exit_code)
|
2014-11-27 14:57:47 +00:00
|
|
|
}
|