Auto merge of #113105 - matthiaskrgr:rollup-rci0uym, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #112207 (Add trustzone and virtualization target features for aarch32.) - #112454 (Make compiletest aware of targets without dynamic linking) - #112628 (Allow comparing `Box`es with different allocators) - #112692 (Provide more context for `rustc +nightly -Zunstable-options` on stable) - #112972 (Make `UnwindAction::Continue` explicit in MIR dump) - #113020 (Add tests impl via obj unless denied) - #113084 (Simplify some conditions) - #113103 (Normalize types when applying uninhabited predicate.) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
6b46c996e1
212 changed files with 1041 additions and 936 deletions
|
@ -623,13 +623,12 @@ impl<'a> AstValidator<'a> {
|
|||
fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId) {
|
||||
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
|
||||
// call site which do not have a macro backtrace. See #61963.
|
||||
let is_macro_callsite = self
|
||||
if self
|
||||
.session
|
||||
.source_map()
|
||||
.span_to_snippet(span)
|
||||
.map(|snippet| snippet.starts_with("#["))
|
||||
.unwrap_or(true);
|
||||
if !is_macro_callsite {
|
||||
.is_ok_and(|snippet| !snippet.starts_with("#["))
|
||||
{
|
||||
self.lint_buffer.buffer_lint_with_diagnostic(
|
||||
MISSING_ABI,
|
||||
id,
|
||||
|
|
|
@ -225,10 +225,10 @@ pub(crate) fn write_ir_file(
|
|||
let res = std::fs::File::create(clif_file_name).and_then(|mut file| write(&mut file));
|
||||
if let Err(err) = res {
|
||||
// Using early_warn as no Session is available here
|
||||
rustc_session::early_warn(
|
||||
let handler = rustc_session::EarlyErrorHandler::new(
|
||||
rustc_session::config::ErrorOutputType::default(),
|
||||
format!("error writing ir file: {}", err),
|
||||
);
|
||||
handler.early_warn(format!("error writing ir file: {}", err));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
|
|||
// #[target_feature].
|
||||
("thumb-mode", Some(sym::arm_target_feature)),
|
||||
("thumb2", Some(sym::arm_target_feature)),
|
||||
("trustzone", Some(sym::arm_target_feature)),
|
||||
("v5te", Some(sym::arm_target_feature)),
|
||||
("v6", Some(sym::arm_target_feature)),
|
||||
("v6k", Some(sym::arm_target_feature)),
|
||||
|
@ -53,6 +54,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
|
|||
("vfp2", Some(sym::arm_target_feature)),
|
||||
("vfp3", Some(sym::arm_target_feature)),
|
||||
("vfp4", Some(sym::arm_target_feature)),
|
||||
("virtualization", Some(sym::arm_target_feature)),
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ use std::fmt;
|
|||
use std::fs;
|
||||
use std::io;
|
||||
|
||||
use rustc_session::EarlyErrorHandler;
|
||||
|
||||
fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
|
||||
if let Some(path) = arg.strip_prefix('@') {
|
||||
let file = match fs::read_to_string(path) {
|
||||
|
@ -21,15 +23,12 @@ fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
|
|||
/// **Note:** This function doesn't interpret argument 0 in any special way.
|
||||
/// If this function is intended to be used with command line arguments,
|
||||
/// `argv[0]` must be removed prior to calling it manually.
|
||||
pub fn arg_expand_all(at_args: &[String]) -> Vec<String> {
|
||||
pub fn arg_expand_all(handler: &EarlyErrorHandler, at_args: &[String]) -> Vec<String> {
|
||||
let mut args = Vec::new();
|
||||
for arg in at_args {
|
||||
match arg_expand(arg.clone()) {
|
||||
Ok(arg) => args.extend(arg),
|
||||
Err(err) => rustc_session::early_error(
|
||||
rustc_session::config::ErrorOutputType::default(),
|
||||
format!("Failed to load argument file: {err}"),
|
||||
),
|
||||
Err(err) => handler.early_error(format!("Failed to load argument file: {err}")),
|
||||
}
|
||||
}
|
||||
args
|
||||
|
|
|
@ -40,8 +40,7 @@ use rustc_session::config::{
|
|||
use rustc_session::cstore::MetadataLoader;
|
||||
use rustc_session::getopts::{self, Matches};
|
||||
use rustc_session::lint::{Lint, LintId};
|
||||
use rustc_session::{config, Session};
|
||||
use rustc_session::{early_error, early_error_no_abort, early_warn};
|
||||
use rustc_session::{config, EarlyErrorHandler, Session};
|
||||
use rustc_span::source_map::{FileLoader, FileName};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_target::json::ToJson;
|
||||
|
@ -174,6 +173,7 @@ pub trait Callbacks {
|
|||
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
||||
fn after_analysis<'tcx>(
|
||||
&mut self,
|
||||
_handler: &EarlyErrorHandler,
|
||||
_compiler: &interface::Compiler,
|
||||
_queries: &'tcx Queries<'tcx>,
|
||||
) -> Compilation {
|
||||
|
@ -260,6 +260,8 @@ fn run_compiler(
|
|||
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
|
||||
>,
|
||||
) -> interface::Result<()> {
|
||||
let mut early_error_handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
|
||||
// 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,
|
||||
|
@ -270,22 +272,22 @@ fn run_compiler(
|
|||
// the compiler with @empty_file as argv[0] and no more arguments.
|
||||
let at_args = at_args.get(1..).unwrap_or_default();
|
||||
|
||||
let args = args::arg_expand_all(at_args);
|
||||
let args = args::arg_expand_all(&early_error_handler, at_args);
|
||||
|
||||
let Some(matches) = handle_options(&args) else { return Ok(()) };
|
||||
let Some(matches) = handle_options(&early_error_handler, &args) else { return Ok(()) };
|
||||
|
||||
let sopts = config::build_session_options(&matches);
|
||||
let sopts = config::build_session_options(&mut early_error_handler, &matches);
|
||||
|
||||
// Set parallel mode before thread pool creation, which will create `Lock`s.
|
||||
interface::set_thread_safe_mode(&sopts.unstable_opts);
|
||||
|
||||
if let Some(ref code) = matches.opt_str("explain") {
|
||||
handle_explain(diagnostics_registry(), code, sopts.error_format);
|
||||
handle_explain(&early_error_handler, diagnostics_registry(), code);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg"));
|
||||
let check_cfg = interface::parse_check_cfg(matches.opt_strs("check-cfg"));
|
||||
let cfg = interface::parse_cfgspecs(&early_error_handler, matches.opt_strs("cfg"));
|
||||
let check_cfg = interface::parse_check_cfg(&early_error_handler, matches.opt_strs("check-cfg"));
|
||||
let (odir, ofile) = make_output(&matches);
|
||||
let mut config = interface::Config {
|
||||
opts: sopts,
|
||||
|
@ -304,7 +306,7 @@ fn run_compiler(
|
|||
registry: diagnostics_registry(),
|
||||
};
|
||||
|
||||
match make_input(config.opts.error_format, &matches.free) {
|
||||
match make_input(&early_error_handler, &matches.free) {
|
||||
Err(reported) => return Err(reported),
|
||||
Ok(Some(input)) => {
|
||||
config.input = input;
|
||||
|
@ -314,8 +316,13 @@ fn run_compiler(
|
|||
Ok(None) => match matches.free.len() {
|
||||
0 => {
|
||||
callbacks.config(&mut config);
|
||||
|
||||
early_error_handler.abort_if_errors();
|
||||
|
||||
interface::run_compiler(config, |compiler| {
|
||||
let sopts = &compiler.session().opts;
|
||||
let handler = EarlyErrorHandler::new(sopts.error_format);
|
||||
|
||||
if sopts.describe_lints {
|
||||
let mut lint_store =
|
||||
rustc_lint::new_lint_store(compiler.session().enable_internal_lints());
|
||||
|
@ -329,31 +336,38 @@ fn run_compiler(
|
|||
describe_lints(compiler.session(), &lint_store, registered_lints);
|
||||
return;
|
||||
}
|
||||
let should_stop =
|
||||
print_crate_info(&**compiler.codegen_backend(), compiler.session(), false);
|
||||
let should_stop = print_crate_info(
|
||||
&handler,
|
||||
&**compiler.codegen_backend(),
|
||||
compiler.session(),
|
||||
false,
|
||||
);
|
||||
|
||||
if should_stop == Compilation::Stop {
|
||||
return;
|
||||
}
|
||||
early_error(sopts.error_format, "no input filename given")
|
||||
handler.early_error("no input filename given")
|
||||
});
|
||||
return Ok(());
|
||||
}
|
||||
1 => panic!("make_input should have provided valid inputs"),
|
||||
_ => early_error(
|
||||
config.opts.error_format,
|
||||
format!(
|
||||
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
|
||||
matches.free[0], matches.free[1],
|
||||
),
|
||||
),
|
||||
_ => early_error_handler.early_error(format!(
|
||||
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
|
||||
matches.free[0], matches.free[1],
|
||||
)),
|
||||
},
|
||||
};
|
||||
|
||||
early_error_handler.abort_if_errors();
|
||||
|
||||
interface::run_compiler(config, |compiler| {
|
||||
let sess = compiler.session();
|
||||
let should_stop = print_crate_info(&**compiler.codegen_backend(), sess, true)
|
||||
.and_then(|| list_metadata(sess, &*compiler.codegen_backend().metadata_loader()))
|
||||
let handler = EarlyErrorHandler::new(sess.opts.error_format);
|
||||
|
||||
let should_stop = print_crate_info(&handler, &**compiler.codegen_backend(), sess, true)
|
||||
.and_then(|| {
|
||||
list_metadata(&handler, sess, &*compiler.codegen_backend().metadata_loader())
|
||||
})
|
||||
.and_then(|| try_process_rlink(sess, compiler));
|
||||
|
||||
if should_stop == Compilation::Stop {
|
||||
|
@ -421,7 +435,7 @@ fn run_compiler(
|
|||
|
||||
queries.global_ctxt()?.enter(|tcx| tcx.analysis(()))?;
|
||||
|
||||
if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
|
||||
if callbacks.after_analysis(&handler, compiler, queries) == Compilation::Stop {
|
||||
return early_exit();
|
||||
}
|
||||
|
||||
|
@ -475,7 +489,7 @@ fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<OutFileNa
|
|||
|
||||
// Extract input (string or file and optional path) from matches.
|
||||
fn make_input(
|
||||
error_format: ErrorOutputType,
|
||||
handler: &EarlyErrorHandler,
|
||||
free_matches: &[String],
|
||||
) -> Result<Option<Input>, ErrorGuaranteed> {
|
||||
if free_matches.len() == 1 {
|
||||
|
@ -485,8 +499,7 @@ fn make_input(
|
|||
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).
|
||||
let reported = early_error_no_abort(
|
||||
error_format,
|
||||
let reported = handler.early_error_no_abort(
|
||||
"couldn't read from stdin, as it did not contain valid UTF-8",
|
||||
);
|
||||
return Err(reported);
|
||||
|
@ -527,7 +540,7 @@ impl Compilation {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
|
||||
fn handle_explain(handler: &EarlyErrorHandler, registry: Registry, code: &str) {
|
||||
let upper_cased_code = code.to_ascii_uppercase();
|
||||
let normalised =
|
||||
if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") };
|
||||
|
@ -557,7 +570,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
|
|||
}
|
||||
}
|
||||
Err(InvalidErrorCode) => {
|
||||
early_error(output, format!("{code} is not a valid error code"));
|
||||
handler.early_error(format!("{code} is not a valid error code"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -636,7 +649,11 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp
|
|||
}
|
||||
}
|
||||
|
||||
pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Compilation {
|
||||
pub fn list_metadata(
|
||||
handler: &EarlyErrorHandler,
|
||||
sess: &Session,
|
||||
metadata_loader: &dyn MetadataLoader,
|
||||
) -> Compilation {
|
||||
if sess.opts.unstable_opts.ls {
|
||||
match sess.io.input {
|
||||
Input::File(ref ifile) => {
|
||||
|
@ -646,7 +663,7 @@ pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Co
|
|||
safe_println!("{}", String::from_utf8(v).unwrap());
|
||||
}
|
||||
Input::Str { .. } => {
|
||||
early_error(ErrorOutputType::default(), "cannot list metadata for stdin");
|
||||
handler.early_error("cannot list metadata for stdin");
|
||||
}
|
||||
}
|
||||
return Compilation::Stop;
|
||||
|
@ -656,6 +673,7 @@ pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Co
|
|||
}
|
||||
|
||||
fn print_crate_info(
|
||||
handler: &EarlyErrorHandler,
|
||||
codegen_backend: &dyn CodegenBackend,
|
||||
sess: &Session,
|
||||
parse_attrs: bool,
|
||||
|
@ -787,10 +805,8 @@ fn print_crate_info(
|
|||
.expect("unknown Apple target OS")
|
||||
)
|
||||
} else {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
"only Apple targets currently support deployment version info",
|
||||
)
|
||||
handler
|
||||
.early_error("only Apple targets currently support deployment version info")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -801,11 +817,12 @@ fn print_crate_info(
|
|||
/// Prints version information
|
||||
///
|
||||
/// 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) {
|
||||
pub macro version($handler: expr, $binary: literal, $matches: expr) {
|
||||
fn unw(x: Option<&str>) -> &str {
|
||||
x.unwrap_or("unknown")
|
||||
}
|
||||
$crate::version_at_macro_invocation(
|
||||
$handler,
|
||||
$binary,
|
||||
$matches,
|
||||
unw(option_env!("CFG_VERSION")),
|
||||
|
@ -817,6 +834,7 @@ pub macro version($binary: literal, $matches: expr) {
|
|||
|
||||
#[doc(hidden)] // use the macro instead
|
||||
pub fn version_at_macro_invocation(
|
||||
handler: &EarlyErrorHandler,
|
||||
binary: &str,
|
||||
matches: &getopts::Matches,
|
||||
version: &str,
|
||||
|
@ -837,7 +855,7 @@ pub fn version_at_macro_invocation(
|
|||
|
||||
let debug_flags = matches.opt_strs("Z");
|
||||
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
|
||||
get_codegen_backend(&None, backend_name).print_version();
|
||||
get_codegen_backend(handler, &None, backend_name).print_version();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1032,7 @@ Available lint options:
|
|||
/// 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 {
|
||||
pub fn describe_flag_categories(handler: &EarlyErrorHandler, matches: &Matches) -> bool {
|
||||
// Handle the special case of -Wall.
|
||||
let wall = matches.opt_strs("W");
|
||||
if wall.iter().any(|x| *x == "all") {
|
||||
|
@ -1036,15 +1054,12 @@ pub fn describe_flag_categories(matches: &Matches) -> bool {
|
|||
}
|
||||
|
||||
if cg_flags.iter().any(|x| *x == "no-stack-check") {
|
||||
early_warn(
|
||||
ErrorOutputType::default(),
|
||||
"the --no-stack-check flag is deprecated and does nothing",
|
||||
);
|
||||
handler.early_warn("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();
|
||||
get_codegen_backend(handler, &None, backend_name).print_passes();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1101,7 +1116,7 @@ fn print_flag_list<T>(
|
|||
///
|
||||
/// 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.
|
||||
pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
||||
pub fn handle_options(handler: &EarlyErrorHandler, args: &[String]) -> Option<getopts::Matches> {
|
||||
if args.is_empty() {
|
||||
// user did not write `-v` nor `-Z unstable-options`, so do not
|
||||
// include that extra information.
|
||||
|
@ -1127,7 +1142,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
|||
.map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
|
||||
_ => None,
|
||||
};
|
||||
early_error(ErrorOutputType::default(), msg.unwrap_or_else(|| e.to_string()));
|
||||
handler.early_error(msg.unwrap_or_else(|| e.to_string()));
|
||||
});
|
||||
|
||||
// For all options we just parsed, we check a few aspects:
|
||||
|
@ -1141,7 +1156,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
|||
// we're good to go.
|
||||
// * Otherwise, if we're an unstable option then we generate an error
|
||||
// (unstable option being used on stable)
|
||||
nightly_options::check_nightly_options(&matches, &config::rustc_optgroups());
|
||||
nightly_options::check_nightly_options(handler, &matches, &config::rustc_optgroups());
|
||||
|
||||
if matches.opt_present("h") || matches.opt_present("help") {
|
||||
// Only show unstable options in --help if we accept unstable options.
|
||||
|
@ -1151,12 +1166,12 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
|||
return None;
|
||||
}
|
||||
|
||||
if describe_flag_categories(&matches) {
|
||||
if describe_flag_categories(handler, &matches) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if matches.opt_present("version") {
|
||||
version!("rustc", &matches);
|
||||
version!(handler, "rustc", &matches);
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -1276,7 +1291,8 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
|
|||
if let Some(msg) = info.payload().downcast_ref::<String>() {
|
||||
if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") {
|
||||
// the error code is already going to be reported when the panic unwinds up the stack
|
||||
let _ = early_error_no_abort(ErrorOutputType::default(), msg.clone());
|
||||
let handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
let _ = handler.early_error_no_abort(msg.clone());
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -1359,16 +1375,16 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info:
|
|||
|
||||
/// This allows tools to enable rust logging without having to magically match rustc's
|
||||
/// tracing crate version.
|
||||
pub fn init_rustc_env_logger() {
|
||||
init_env_logger("RUSTC_LOG");
|
||||
pub fn init_rustc_env_logger(handler: &EarlyErrorHandler) {
|
||||
init_env_logger(handler, "RUSTC_LOG");
|
||||
}
|
||||
|
||||
/// This allows tools to enable rust logging without having to magically match rustc's
|
||||
/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var
|
||||
/// other than `RUSTC_LOG`.
|
||||
pub fn init_env_logger(env: &str) {
|
||||
pub fn init_env_logger(handler: &EarlyErrorHandler, env: &str) {
|
||||
if let Err(error) = rustc_log::init_env_logger(env) {
|
||||
early_error(ErrorOutputType::default(), error.to_string());
|
||||
handler.early_error(error.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1424,7 +1440,10 @@ mod signal_handler {
|
|||
pub fn main() -> ! {
|
||||
let start_time = Instant::now();
|
||||
let start_rss = get_resident_set_size();
|
||||
init_rustc_env_logger();
|
||||
|
||||
let handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
|
||||
init_rustc_env_logger(&handler);
|
||||
signal_handler::install();
|
||||
let mut callbacks = TimePassesCallbacks::default();
|
||||
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
|
||||
|
@ -1433,10 +1452,7 @@ pub fn main() -> ! {
|
|||
.enumerate()
|
||||
.map(|(i, arg)| {
|
||||
arg.into_string().unwrap_or_else(|arg| {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
format!("argument {i} is not valid Unicode: {arg:?}"),
|
||||
)
|
||||
handler.early_error(format!("argument {i} is not valid Unicode: {arg:?}"))
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
|
|
@ -445,7 +445,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||
/// If attributes are not allowed on expressions, emit an error for `attr`
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
|
||||
if !self.features.map_or(true, |features| features.stmt_expr_attributes) {
|
||||
if self.features.is_some_and(|features| !features.stmt_expr_attributes) {
|
||||
let mut err = feature_err(
|
||||
&self.sess.parse_sess,
|
||||
sym::stmt_expr_attributes,
|
||||
|
|
|
@ -140,7 +140,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
impl1_def_id: DefId,
|
||||
impl2_def_id: DefId,
|
||||
) {
|
||||
traits::overlapping_impls(
|
||||
let maybe_overlap = traits::overlapping_impls(
|
||||
self.tcx,
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
|
@ -148,11 +148,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
// inherent impls without warning.
|
||||
SkipLeakCheck::Yes,
|
||||
overlap_mode,
|
||||
)
|
||||
.map_or(true, |overlap| {
|
||||
);
|
||||
|
||||
if let Some(overlap) = maybe_overlap {
|
||||
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
|
||||
false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item(&mut self, id: hir::ItemId) {
|
||||
|
|
|
@ -955,9 +955,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// - f(0, 1,)
|
||||
// + f()
|
||||
if only_extras_so_far
|
||||
&& errors
|
||||
&& !errors
|
||||
.peek()
|
||||
.map_or(true, |next_error| !matches!(next_error, Error::Extra(_)))
|
||||
.is_some_and(|next_error| matches!(next_error, Error::Extra(_)))
|
||||
{
|
||||
let next = provided_arg_tys
|
||||
.get(arg_idx + 1)
|
||||
|
|
|
@ -14,12 +14,11 @@ use rustc_middle::{bug, ty};
|
|||
use rustc_parse::maybe_new_parser_from_source_str;
|
||||
use rustc_query_impl::QueryCtxt;
|
||||
use rustc_query_system::query::print_query_stack;
|
||||
use rustc_session::config::{self, ErrorOutputType, Input, OutFileName, OutputFilenames};
|
||||
use rustc_session::config::{CheckCfg, ExpectedValues};
|
||||
use rustc_session::lint;
|
||||
use rustc_session::config::{self, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames};
|
||||
use rustc_session::parse::{CrateConfig, ParseSess};
|
||||
use rustc_session::CompilerIO;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::{early_error, CompilerIO};
|
||||
use rustc_session::{lint, EarlyErrorHandler};
|
||||
use rustc_span::source_map::{FileLoader, FileName};
|
||||
use rustc_span::symbol::sym;
|
||||
use std::path::PathBuf;
|
||||
|
@ -66,7 +65,10 @@ pub fn set_thread_safe_mode(sopts: &config::UnstableOptions) {
|
|||
}
|
||||
|
||||
/// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
|
||||
pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
|
||||
pub fn parse_cfgspecs(
|
||||
handler: &EarlyErrorHandler,
|
||||
cfgspecs: Vec<String>,
|
||||
) -> FxHashSet<(String, Option<String>)> {
|
||||
rustc_span::create_default_session_if_not_set_then(move |_| {
|
||||
let cfg = cfgspecs
|
||||
.into_iter()
|
||||
|
@ -78,10 +80,10 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
|
|||
|
||||
macro_rules! error {
|
||||
($reason: expr) => {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
format!(concat!("invalid `--cfg` argument: `{}` (", $reason, ")"), s),
|
||||
);
|
||||
handler.early_error(format!(
|
||||
concat!("invalid `--cfg` argument: `{}` (", $reason, ")"),
|
||||
s
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -125,7 +127,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
|
|||
}
|
||||
|
||||
/// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
|
||||
pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
|
||||
pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg {
|
||||
rustc_span::create_default_session_if_not_set_then(move |_| {
|
||||
let mut check_cfg = CheckCfg::default();
|
||||
|
||||
|
@ -137,10 +139,10 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
|
|||
|
||||
macro_rules! error {
|
||||
($reason: expr) => {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
format!(concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"), s),
|
||||
)
|
||||
handler.early_error(format!(
|
||||
concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"),
|
||||
s
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -294,8 +296,11 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
|||
|
||||
let registry = &config.registry;
|
||||
|
||||
let handler = EarlyErrorHandler::new(config.opts.error_format);
|
||||
|
||||
let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
|
||||
let (mut sess, codegen_backend) = util::create_session(
|
||||
&handler,
|
||||
config.opts,
|
||||
config.crate_cfg,
|
||||
config.crate_check_cfg,
|
||||
|
|
|
@ -21,8 +21,8 @@ use rustc_session::config::{InstrumentCoverage, Passes};
|
|||
use rustc_session::lint::Level;
|
||||
use rustc_session::search_paths::SearchPath;
|
||||
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
|
||||
use rustc_session::CompilerIO;
|
||||
use rustc_session::{build_session, getopts, Session};
|
||||
use rustc_session::{CompilerIO, EarlyErrorHandler};
|
||||
use rustc_span::edition::{Edition, DEFAULT_EDITION};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::FileName;
|
||||
|
@ -36,15 +36,18 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
type CfgSpecs = FxHashSet<(String, Option<String>)>;
|
||||
|
||||
fn build_session_options_and_crate_config(matches: getopts::Matches) -> (Options, CfgSpecs) {
|
||||
let sessopts = build_session_options(&matches);
|
||||
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
|
||||
fn build_session_options_and_crate_config(
|
||||
handler: &mut EarlyErrorHandler,
|
||||
matches: getopts::Matches,
|
||||
) -> (Options, CfgSpecs) {
|
||||
let sessopts = build_session_options(handler, &matches);
|
||||
let cfg = parse_cfgspecs(handler, matches.opt_strs("cfg"));
|
||||
(sessopts, cfg)
|
||||
}
|
||||
|
||||
fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
|
||||
fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Session, CfgSpecs) {
|
||||
let registry = registry::Registry::new(&[]);
|
||||
let (sessopts, cfg) = build_session_options_and_crate_config(matches);
|
||||
let (sessopts, cfg) = build_session_options_and_crate_config(handler, matches);
|
||||
let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
|
||||
let io = CompilerIO {
|
||||
input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
|
||||
|
@ -52,8 +55,18 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
|
|||
output_file: None,
|
||||
temps_dir,
|
||||
};
|
||||
let sess =
|
||||
build_session(sessopts, io, None, registry, vec![], Default::default(), None, None, "");
|
||||
let sess = build_session(
|
||||
handler,
|
||||
sessopts,
|
||||
io,
|
||||
None,
|
||||
registry,
|
||||
vec![],
|
||||
Default::default(),
|
||||
None,
|
||||
None,
|
||||
"",
|
||||
);
|
||||
(sess, cfg)
|
||||
}
|
||||
|
||||
|
@ -120,7 +133,8 @@ fn assert_non_crate_hash_different(x: &Options, y: &Options) {
|
|||
fn test_switch_implies_cfg_test() {
|
||||
rustc_span::create_default_session_globals_then(|| {
|
||||
let matches = optgroups().parse(&["--test".to_string()]).unwrap();
|
||||
let (sess, cfg) = mk_session(matches);
|
||||
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
let (sess, cfg) = mk_session(&mut handler, matches);
|
||||
let cfg = build_configuration(&sess, to_crate_config(cfg));
|
||||
assert!(cfg.contains(&(sym::test, None)));
|
||||
});
|
||||
|
@ -131,7 +145,8 @@ fn test_switch_implies_cfg_test() {
|
|||
fn test_switch_implies_cfg_test_unless_cfg_test() {
|
||||
rustc_span::create_default_session_globals_then(|| {
|
||||
let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
|
||||
let (sess, cfg) = mk_session(matches);
|
||||
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
let (sess, cfg) = mk_session(&mut handler, matches);
|
||||
let cfg = build_configuration(&sess, to_crate_config(cfg));
|
||||
let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
|
||||
assert!(test_items.next().is_some());
|
||||
|
@ -143,20 +158,23 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
|
|||
fn test_can_print_warnings() {
|
||||
rustc_span::create_default_session_globals_then(|| {
|
||||
let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
|
||||
let (sess, _) = mk_session(matches);
|
||||
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
let (sess, _) = mk_session(&mut handler, matches);
|
||||
assert!(!sess.diagnostic().can_emit_warnings());
|
||||
});
|
||||
|
||||
rustc_span::create_default_session_globals_then(|| {
|
||||
let matches =
|
||||
optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap();
|
||||
let (sess, _) = mk_session(matches);
|
||||
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
let (sess, _) = mk_session(&mut handler, matches);
|
||||
assert!(sess.diagnostic().can_emit_warnings());
|
||||
});
|
||||
|
||||
rustc_span::create_default_session_globals_then(|| {
|
||||
let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
|
||||
let (sess, _) = mk_session(matches);
|
||||
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
let (sess, _) = mk_session(&mut handler, matches);
|
||||
assert!(sess.diagnostic().can_emit_warnings());
|
||||
});
|
||||
}
|
||||
|
@ -302,35 +320,36 @@ fn test_search_paths_tracking_hash_different_order() {
|
|||
let mut v3 = Options::default();
|
||||
let mut v4 = Options::default();
|
||||
|
||||
let handler = EarlyErrorHandler::new(JSON);
|
||||
const JSON: ErrorOutputType = ErrorOutputType::Json {
|
||||
pretty: false,
|
||||
json_rendered: HumanReadableErrorType::Default(ColorConfig::Never),
|
||||
};
|
||||
|
||||
// Reference
|
||||
v1.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
|
||||
v1.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
|
||||
v1.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
|
||||
v1.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
|
||||
v1.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
|
||||
v1.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
|
||||
v1.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
|
||||
v1.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
|
||||
v1.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
|
||||
v1.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
|
||||
|
||||
v2.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
|
||||
v2.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
|
||||
v2.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
|
||||
v2.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
|
||||
v2.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
|
||||
v2.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
|
||||
v2.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
|
||||
v2.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
|
||||
v2.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
|
||||
v2.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
|
||||
|
||||
v3.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
|
||||
v3.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
|
||||
v3.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
|
||||
v3.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
|
||||
v3.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
|
||||
v3.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
|
||||
v3.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
|
||||
v3.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
|
||||
v3.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
|
||||
v3.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
|
||||
|
||||
v4.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
|
||||
v4.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
|
||||
v4.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
|
||||
v4.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
|
||||
v4.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
|
||||
v4.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
|
||||
v4.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
|
||||
v4.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
|
||||
v4.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
|
||||
v4.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
|
||||
|
||||
assert_same_hash(&v1, &v2);
|
||||
assert_same_hash(&v1, &v3);
|
||||
|
@ -851,7 +870,9 @@ fn test_edition_parsing() {
|
|||
let options = Options::default();
|
||||
assert!(options.edition == DEFAULT_EDITION);
|
||||
|
||||
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
|
||||
let matches = optgroups().parse(&["--edition=2018".to_string()]).unwrap();
|
||||
let (sessopts, _) = build_session_options_and_crate_config(matches);
|
||||
let (sessopts, _) = build_session_options_and_crate_config(&mut handler, matches);
|
||||
assert!(sessopts.edition == Edition::Edition2018)
|
||||
}
|
||||
|
|
|
@ -11,16 +11,16 @@ use rustc_parse::validate_attr;
|
|||
use rustc_session as session;
|
||||
use rustc_session::config::CheckCfg;
|
||||
use rustc_session::config::{self, CrateType};
|
||||
use rustc_session::config::{ErrorOutputType, OutFileName, OutputFilenames, OutputTypes};
|
||||
use rustc_session::config::{OutFileName, OutputFilenames, OutputTypes};
|
||||
use rustc_session::filesearch::sysroot_candidates;
|
||||
use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::parse::CrateConfig;
|
||||
use rustc_session::{early_error, filesearch, output, Session};
|
||||
use rustc_session::{filesearch, output, Session};
|
||||
use rustc_span::edit_distance::find_best_match_for_name;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::FileLoader;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use session::CompilerIO;
|
||||
use session::{CompilerIO, EarlyErrorHandler};
|
||||
use std::env;
|
||||
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
|
||||
use std::mem;
|
||||
|
@ -58,6 +58,7 @@ pub fn add_configuration(
|
|||
}
|
||||
|
||||
pub fn create_session(
|
||||
handler: &EarlyErrorHandler,
|
||||
sopts: config::Options,
|
||||
cfg: FxHashSet<(String, Option<String>)>,
|
||||
check_cfg: CheckCfg,
|
||||
|
@ -73,7 +74,11 @@ pub fn create_session(
|
|||
let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend {
|
||||
make_codegen_backend(&sopts)
|
||||
} else {
|
||||
get_codegen_backend(&sopts.maybe_sysroot, sopts.unstable_opts.codegen_backend.as_deref())
|
||||
get_codegen_backend(
|
||||
handler,
|
||||
&sopts.maybe_sysroot,
|
||||
sopts.unstable_opts.codegen_backend.as_deref(),
|
||||
)
|
||||
};
|
||||
|
||||
// target_override is documented to be called before init(), so this is okay
|
||||
|
@ -88,7 +93,7 @@ pub fn create_session(
|
|||
) {
|
||||
Ok(bundle) => bundle,
|
||||
Err(e) => {
|
||||
early_error(sopts.error_format, format!("failed to load fluent bundle: {e}"));
|
||||
handler.early_error(format!("failed to load fluent bundle: {e}"));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -96,6 +101,7 @@ pub fn create_session(
|
|||
locale_resources.push(codegen_backend.locale_resource());
|
||||
|
||||
let mut sess = session::build_session(
|
||||
handler,
|
||||
sopts,
|
||||
io,
|
||||
bundle,
|
||||
|
@ -218,16 +224,16 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
|
|||
})
|
||||
}
|
||||
|
||||
fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
|
||||
fn load_backend_from_dylib(handler: &EarlyErrorHandler, path: &Path) -> MakeBackendFn {
|
||||
let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
|
||||
let err = format!("couldn't load codegen backend {path:?}: {err}");
|
||||
early_error(ErrorOutputType::default(), err);
|
||||
handler.early_error(err);
|
||||
});
|
||||
|
||||
let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") }
|
||||
.unwrap_or_else(|e| {
|
||||
let err = format!("couldn't load codegen backend: {e}");
|
||||
early_error(ErrorOutputType::default(), err);
|
||||
handler.early_error(err);
|
||||
});
|
||||
|
||||
// Intentionally leak the dynamic library. We can't ever unload it
|
||||
|
@ -242,6 +248,7 @@ fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
|
|||
///
|
||||
/// A name of `None` indicates that the default backend should be used.
|
||||
pub fn get_codegen_backend(
|
||||
handler: &EarlyErrorHandler,
|
||||
maybe_sysroot: &Option<PathBuf>,
|
||||
backend_name: Option<&str>,
|
||||
) -> Box<dyn CodegenBackend> {
|
||||
|
@ -251,10 +258,12 @@ pub fn get_codegen_backend(
|
|||
let default_codegen_backend = option_env!("CFG_DEFAULT_CODEGEN_BACKEND").unwrap_or("llvm");
|
||||
|
||||
match backend_name.unwrap_or(default_codegen_backend) {
|
||||
filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
|
||||
filename if filename.contains('.') => {
|
||||
load_backend_from_dylib(handler, filename.as_ref())
|
||||
}
|
||||
#[cfg(feature = "llvm")]
|
||||
"llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
|
||||
backend_name => get_codegen_sysroot(maybe_sysroot, backend_name),
|
||||
backend_name => get_codegen_sysroot(handler, maybe_sysroot, backend_name),
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -286,7 +295,11 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
|
|||
})
|
||||
}
|
||||
|
||||
fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
|
||||
fn get_codegen_sysroot(
|
||||
handler: &EarlyErrorHandler,
|
||||
maybe_sysroot: &Option<PathBuf>,
|
||||
backend_name: &str,
|
||||
) -> MakeBackendFn {
|
||||
// For now we only allow this function to be called once as it'll dlopen a
|
||||
// few things, which seems to work best if we only do that once. In
|
||||
// general this assertion never trips due to the once guard in `get_codegen_backend`,
|
||||
|
@ -321,7 +334,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
|
|||
"failed to find a `codegen-backends` folder \
|
||||
in the sysroot candidates:\n* {candidates}"
|
||||
);
|
||||
early_error(ErrorOutputType::default(), err);
|
||||
handler.early_error(err);
|
||||
});
|
||||
info!("probing {} for a codegen backend", sysroot.display());
|
||||
|
||||
|
@ -332,7 +345,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
|
|||
sysroot.display(),
|
||||
e
|
||||
);
|
||||
early_error(ErrorOutputType::default(), err);
|
||||
handler.early_error(err);
|
||||
});
|
||||
|
||||
let mut file: Option<PathBuf> = None;
|
||||
|
@ -360,16 +373,16 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
|
|||
prev.display(),
|
||||
path.display()
|
||||
);
|
||||
early_error(ErrorOutputType::default(), err);
|
||||
handler.early_error(err);
|
||||
}
|
||||
file = Some(path.clone());
|
||||
}
|
||||
|
||||
match file {
|
||||
Some(ref s) => load_backend_from_dylib(s),
|
||||
Some(ref s) => load_backend_from_dylib(handler, s),
|
||||
None => {
|
||||
let err = format!("unsupported builtin codegen backend `{backend_name}`");
|
||||
early_error(ErrorOutputType::default(), err);
|
||||
handler.early_error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -388,10 +388,11 @@ pub fn struct_lint_level(
|
|||
// it'll become a hard error, so we have to emit *something*. Also,
|
||||
// if this lint occurs in the expansion of a macro from an external crate,
|
||||
// allow individual lints to opt-out from being reported.
|
||||
let not_future_incompatible =
|
||||
future_incompatible.map(|f| f.reason.edition().is_some()).unwrap_or(true);
|
||||
if not_future_incompatible && !lint.report_in_external_macro {
|
||||
let incompatible = future_incompatible.is_some_and(|f| f.reason.edition().is_none());
|
||||
|
||||
if !incompatible && !lint.report_in_external_macro {
|
||||
err.cancel();
|
||||
|
||||
// Don't continue further, since we don't want to have
|
||||
// `diag_span_note_once` called for a diagnostic that isn't emitted.
|
||||
return;
|
||||
|
|
|
@ -272,7 +272,8 @@ impl<'tcx> Debug for TerminatorKind<'tcx> {
|
|||
|
||||
let unwind = match self.unwind() {
|
||||
// Not needed or included in successors
|
||||
None | Some(UnwindAction::Continue) | Some(UnwindAction::Cleanup(_)) => None,
|
||||
None | Some(UnwindAction::Cleanup(_)) => None,
|
||||
Some(UnwindAction::Continue) => Some("unwind continue"),
|
||||
Some(UnwindAction::Unreachable) => Some("unwind unreachable"),
|
||||
Some(UnwindAction::Terminate) => Some("unwind terminate"),
|
||||
};
|
||||
|
|
|
@ -62,7 +62,18 @@ impl<'tcx> InhabitedPredicate<'tcx> {
|
|||
Some(1..) => Ok(false),
|
||||
},
|
||||
Self::NotInModule(id) => in_module(id).map(|in_mod| !in_mod),
|
||||
Self::GenericType(_) => Ok(true),
|
||||
// `t` may be a projection, for which `inhabited_predicate` returns a `GenericType`. As
|
||||
// we have a param_env available, we can do better.
|
||||
Self::GenericType(t) => {
|
||||
let normalized_pred = tcx
|
||||
.try_normalize_erasing_regions(param_env, t)
|
||||
.map_or(self, |t| t.inhabited_predicate(tcx));
|
||||
match normalized_pred {
|
||||
// We don't have more information than we started with, so consider inhabited.
|
||||
Self::GenericType(_) => Ok(true),
|
||||
pred => pred.apply_inner(tcx, param_env, in_module),
|
||||
}
|
||||
}
|
||||
Self::And([a, b]) => try_and(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
|
||||
Self::Or([a, b]) => try_or(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
|
||||
}
|
||||
|
|
|
@ -387,7 +387,7 @@ impl BasicCoverageBlockData {
|
|||
// If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
|
||||
// have an expression (to be injected into an existing `BasicBlock` represented by this
|
||||
// `BasicCoverageBlock`).
|
||||
if !self.counter_kind.as_ref().map_or(true, |c| c.is_expression()) {
|
||||
if self.counter_kind.as_ref().is_some_and(|c| !c.is_expression()) {
|
||||
return Error::from_string(format!(
|
||||
"attempt to add an incoming edge counter from {:?} when the target BCB already \
|
||||
has a `Counter`",
|
||||
|
|
|
@ -480,9 +480,10 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
|
|||
|
||||
fn check_invoked_macro_name_span(&mut self) {
|
||||
if let Some(visible_macro) = self.curr().visible_macro(self.body_span) {
|
||||
if self.prev_expn_span.map_or(true, |prev_expn_span| {
|
||||
self.curr().expn_span.ctxt() != prev_expn_span.ctxt()
|
||||
}) {
|
||||
if !self
|
||||
.prev_expn_span
|
||||
.is_some_and(|prev_expn_span| self.curr().expn_span.ctxt() == prev_expn_span.ctxt())
|
||||
{
|
||||
let merged_prefix_len = self.curr_original_span.lo() - self.curr().span.lo();
|
||||
let after_macro_bang =
|
||||
merged_prefix_len + BytePos(visible_macro.as_str().len() as u32 + 1);
|
||||
|
|
|
@ -422,15 +422,12 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn maybe_needs_tokens(attrs: &[ast::Attribute]) -> bool {
|
||||
// One of the attributes may either itself be a macro,
|
||||
// or expand to macro attributes (`cfg_attr`).
|
||||
attrs.iter().any(|attr| {
|
||||
if attr.is_doc_comment() {
|
||||
return false;
|
||||
}
|
||||
attr.ident().map_or(true, |ident| {
|
||||
ident.name == sym::cfg_attr || !rustc_feature::is_builtin_attr_name(ident.name)
|
||||
})
|
||||
/// The attributes are complete if all attributes are either a doc comment or a builtin attribute other than `cfg_attr`
|
||||
pub fn is_complete(attrs: &[ast::Attribute]) -> bool {
|
||||
attrs.iter().all(|attr| {
|
||||
attr.is_doc_comment()
|
||||
|| attr.ident().is_some_and(|ident| {
|
||||
ident.name != sym::cfg_attr && rustc_feature::is_builtin_attr_name(ident.name)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ impl AttrWrapper {
|
|||
self.attrs.is_empty()
|
||||
}
|
||||
|
||||
pub fn maybe_needs_tokens(&self) -> bool {
|
||||
crate::parser::attr::maybe_needs_tokens(&self.attrs)
|
||||
pub fn is_complete(&self) -> bool {
|
||||
crate::parser::attr::is_complete(&self.attrs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ impl<'a> Parser<'a> {
|
|||
// by definition
|
||||
if matches!(force_collect, ForceCollect::No)
|
||||
// None of our outer attributes can require tokens (e.g. a proc-macro)
|
||||
&& !attrs.maybe_needs_tokens()
|
||||
&& attrs.is_complete()
|
||||
// If our target supports custom inner attributes, then we cannot bail
|
||||
// out early, since we may need to capture tokens for a custom inner attribute
|
||||
// invocation.
|
||||
|
@ -244,9 +244,9 @@ impl<'a> Parser<'a> {
|
|||
// Now that we've parsed an AST node, we have more information available.
|
||||
if matches!(force_collect, ForceCollect::No)
|
||||
// We now have inner attributes available, so this check is more precise
|
||||
// than `attrs.maybe_needs_tokens()` at the start of the function.
|
||||
// than `attrs.is_complete()` at the start of the function.
|
||||
// As a result, we don't need to check `R::SUPPORTS_CUSTOM_INNER_ATTRS`
|
||||
&& !crate::parser::attr::maybe_needs_tokens(ret.attrs())
|
||||
&& crate::parser::attr::is_complete(ret.attrs())
|
||||
// Subtle: We call `has_cfg_or_cfg_attr` with the attrs from `ret`.
|
||||
// This ensures that we consider inner attributes (e.g. `#![cfg]`),
|
||||
// which require us to have tokens available
|
||||
|
|
|
@ -2183,10 +2183,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||
None => {
|
||||
debug!(?param.ident, ?param.ident.span);
|
||||
let deletion_span = deletion_span();
|
||||
// the give lifetime originates from expanded code so we won't be able to remove it #104432
|
||||
let lifetime_only_in_expanded_code =
|
||||
deletion_span.map(|sp| sp.in_derive_expansion()).unwrap_or(true);
|
||||
if !lifetime_only_in_expanded_code {
|
||||
|
||||
// if the lifetime originates from expanded code, we won't be able to remove it #104432
|
||||
if deletion_span.is_some_and(|sp| !sp.in_derive_expansion()) {
|
||||
self.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||
lint::builtin::UNUSED_LIFETIMES,
|
||||
param.id,
|
||||
|
|
|
@ -5,8 +5,8 @@ pub use crate::options::*;
|
|||
|
||||
use crate::search_paths::SearchPath;
|
||||
use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
|
||||
use crate::{early_error, early_warn, Session};
|
||||
use crate::{lint, HashStableContext};
|
||||
use crate::{EarlyErrorHandler, Session};
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
|
||||
|
@ -1389,6 +1389,7 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
|
|||
}
|
||||
|
||||
pub(super) fn build_target_config(
|
||||
handler: &EarlyErrorHandler,
|
||||
opts: &Options,
|
||||
target_override: Option<Target>,
|
||||
sysroot: &Path,
|
||||
|
@ -1398,27 +1399,21 @@ pub(super) fn build_target_config(
|
|||
|t| Ok((t, TargetWarnings::empty())),
|
||||
);
|
||||
let (target, target_warnings) = target_result.unwrap_or_else(|e| {
|
||||
early_error(
|
||||
opts.error_format,
|
||||
format!(
|
||||
"Error loading target specification: {}. \
|
||||
handler.early_error(format!(
|
||||
"Error loading target specification: {}. \
|
||||
Run `rustc --print target-list` for a list of built-in targets",
|
||||
e
|
||||
),
|
||||
)
|
||||
e
|
||||
))
|
||||
});
|
||||
for warning in target_warnings.warning_messages() {
|
||||
early_warn(opts.error_format, warning)
|
||||
handler.early_warn(warning)
|
||||
}
|
||||
|
||||
if !matches!(target.pointer_width, 16 | 32 | 64) {
|
||||
early_error(
|
||||
opts.error_format,
|
||||
format!(
|
||||
"target specification was invalid: unrecognized target-pointer-width {}",
|
||||
target.pointer_width
|
||||
),
|
||||
)
|
||||
handler.early_error(format!(
|
||||
"target specification was invalid: unrecognized target-pointer-width {}",
|
||||
target.pointer_width
|
||||
))
|
||||
}
|
||||
|
||||
target
|
||||
|
@ -1654,8 +1649,8 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
|
|||
}
|
||||
|
||||
pub fn get_cmd_lint_options(
|
||||
handler: &EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
error_format: ErrorOutputType,
|
||||
) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
|
||||
let mut lint_opts_with_position = vec![];
|
||||
let mut describe_lints = false;
|
||||
|
@ -1679,14 +1674,14 @@ pub fn get_cmd_lint_options(
|
|||
|
||||
let lint_cap = matches.opt_str("cap-lints").map(|cap| {
|
||||
lint::Level::from_str(&cap)
|
||||
.unwrap_or_else(|| early_error(error_format, format!("unknown lint level: `{cap}`")))
|
||||
.unwrap_or_else(|| handler.early_error(format!("unknown lint level: `{cap}`")))
|
||||
});
|
||||
|
||||
(lint_opts, describe_lints, lint_cap)
|
||||
}
|
||||
|
||||
/// Parses the `--color` flag.
|
||||
pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
|
||||
pub fn parse_color(handler: &EarlyErrorHandler, matches: &getopts::Matches) -> ColorConfig {
|
||||
match matches.opt_str("color").as_deref() {
|
||||
Some("auto") => ColorConfig::Auto,
|
||||
Some("always") => ColorConfig::Always,
|
||||
|
@ -1694,13 +1689,10 @@ pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
|
|||
|
||||
None => ColorConfig::Auto,
|
||||
|
||||
Some(arg) => early_error(
|
||||
ErrorOutputType::default(),
|
||||
format!(
|
||||
"argument for `--color` must be auto, \
|
||||
Some(arg) => handler.early_error(format!(
|
||||
"argument for `--color` must be auto, \
|
||||
always or never (instead was `{arg}`)"
|
||||
),
|
||||
),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1743,7 +1735,7 @@ impl JsonUnusedExterns {
|
|||
///
|
||||
/// The first value returned is how to render JSON diagnostics, and the second
|
||||
/// is whether or not artifact notifications are enabled.
|
||||
pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
|
||||
pub fn parse_json(handler: &EarlyErrorHandler, matches: &getopts::Matches) -> JsonConfig {
|
||||
let mut json_rendered: fn(ColorConfig) -> HumanReadableErrorType =
|
||||
HumanReadableErrorType::Default;
|
||||
let mut json_color = ColorConfig::Never;
|
||||
|
@ -1755,10 +1747,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
|
|||
// won't actually be emitting any colors and anything colorized is
|
||||
// embedded in a diagnostic message anyway.
|
||||
if matches.opt_str("color").is_some() {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
"cannot specify the `--color` option with `--json`",
|
||||
);
|
||||
handler.early_error("cannot specify the `--color` option with `--json`");
|
||||
}
|
||||
|
||||
for sub_option in option.split(',') {
|
||||
|
@ -1769,10 +1758,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
|
|||
"unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
|
||||
"unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
|
||||
"future-incompat" => json_future_incompat = true,
|
||||
s => early_error(
|
||||
ErrorOutputType::default(),
|
||||
format!("unknown `--json` option `{s}`"),
|
||||
),
|
||||
s => handler.early_error(format!("unknown `--json` option `{s}`")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1787,6 +1773,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
|
|||
|
||||
/// Parses the `--error-format` flag.
|
||||
pub fn parse_error_format(
|
||||
handler: &mut EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
color: ColorConfig,
|
||||
json_rendered: HumanReadableErrorType,
|
||||
|
@ -1807,13 +1794,15 @@ pub fn parse_error_format(
|
|||
Some("pretty-json") => ErrorOutputType::Json { pretty: true, json_rendered },
|
||||
Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)),
|
||||
|
||||
Some(arg) => early_error(
|
||||
ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
|
||||
format!(
|
||||
Some(arg) => {
|
||||
handler.abort_if_error_and_set_error_format(ErrorOutputType::HumanReadable(
|
||||
HumanReadableErrorType::Default(color),
|
||||
));
|
||||
handler.early_error(format!(
|
||||
"argument for `--error-format` must be `human`, `json` or \
|
||||
`short` (instead was `{arg}`)"
|
||||
),
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color))
|
||||
|
@ -1826,10 +1815,7 @@ pub fn parse_error_format(
|
|||
// `--error-format=json`. This means that `--json` is specified we
|
||||
// should actually be emitting JSON blobs.
|
||||
_ if !matches.opt_strs("json").is_empty() => {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
"using `--json` requires also using `--error-format=json`",
|
||||
);
|
||||
handler.early_error("using `--json` requires also using `--error-format=json`");
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
@ -1838,16 +1824,13 @@ pub fn parse_error_format(
|
|||
error_format
|
||||
}
|
||||
|
||||
pub fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
|
||||
pub fn parse_crate_edition(handler: &EarlyErrorHandler, matches: &getopts::Matches) -> Edition {
|
||||
let edition = match matches.opt_str("edition") {
|
||||
Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
format!(
|
||||
"argument for `--edition` must be one of: \
|
||||
handler.early_error(format!(
|
||||
"argument for `--edition` must be one of: \
|
||||
{EDITION_NAME_LIST}. (instead was `{arg}`)"
|
||||
),
|
||||
)
|
||||
))
|
||||
}),
|
||||
None => DEFAULT_EDITION,
|
||||
};
|
||||
|
@ -1862,39 +1845,42 @@ pub fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
|
|||
} else {
|
||||
format!("edition {edition} is unstable and only available with -Z unstable-options")
|
||||
};
|
||||
early_error(ErrorOutputType::default(), msg)
|
||||
handler.early_error(msg)
|
||||
}
|
||||
|
||||
edition
|
||||
}
|
||||
|
||||
fn check_error_format_stability(
|
||||
handler: &mut EarlyErrorHandler,
|
||||
unstable_opts: &UnstableOptions,
|
||||
error_format: ErrorOutputType,
|
||||
json_rendered: HumanReadableErrorType,
|
||||
) {
|
||||
if !unstable_opts.unstable_options {
|
||||
if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format {
|
||||
early_error(
|
||||
ErrorOutputType::Json { pretty: false, json_rendered },
|
||||
"`--error-format=pretty-json` is unstable",
|
||||
);
|
||||
handler.abort_if_error_and_set_error_format(ErrorOutputType::Json {
|
||||
pretty: false,
|
||||
json_rendered,
|
||||
});
|
||||
handler.early_error("`--error-format=pretty-json` is unstable");
|
||||
}
|
||||
if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) =
|
||||
error_format
|
||||
{
|
||||
early_error(
|
||||
ErrorOutputType::Json { pretty: false, json_rendered },
|
||||
"`--error-format=human-annotate-rs` is unstable",
|
||||
);
|
||||
handler.abort_if_error_and_set_error_format(ErrorOutputType::Json {
|
||||
pretty: false,
|
||||
json_rendered,
|
||||
});
|
||||
handler.early_error("`--error-format=human-annotate-rs` is unstable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_output_types(
|
||||
handler: &EarlyErrorHandler,
|
||||
unstable_opts: &UnstableOptions,
|
||||
matches: &getopts::Matches,
|
||||
error_format: ErrorOutputType,
|
||||
) -> OutputTypes {
|
||||
let mut output_types = BTreeMap::new();
|
||||
if !unstable_opts.parse_only {
|
||||
|
@ -1908,13 +1894,10 @@ fn parse_output_types(
|
|||
}
|
||||
};
|
||||
let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
|
||||
early_error(
|
||||
error_format,
|
||||
format!(
|
||||
"unknown emission type: `{shorthand}` - expected one of: {display}",
|
||||
display = OutputType::shorthands_display(),
|
||||
),
|
||||
)
|
||||
handler.early_error(format!(
|
||||
"unknown emission type: `{shorthand}` - expected one of: {display}",
|
||||
display = OutputType::shorthands_display(),
|
||||
))
|
||||
});
|
||||
output_types.insert(output_type, path);
|
||||
}
|
||||
|
@ -1927,9 +1910,9 @@ fn parse_output_types(
|
|||
}
|
||||
|
||||
fn should_override_cgus_and_disable_thinlto(
|
||||
handler: &EarlyErrorHandler,
|
||||
output_types: &OutputTypes,
|
||||
matches: &getopts::Matches,
|
||||
error_format: ErrorOutputType,
|
||||
mut codegen_units: Option<usize>,
|
||||
) -> (bool, Option<usize>) {
|
||||
let mut disable_local_thinlto = false;
|
||||
|
@ -1947,15 +1930,12 @@ fn should_override_cgus_and_disable_thinlto(
|
|||
Some(n) if n > 1 => {
|
||||
if matches.opt_present("o") {
|
||||
for ot in &incompatible {
|
||||
early_warn(
|
||||
error_format,
|
||||
format!(
|
||||
"`--emit={ot}` with `-o` incompatible with \
|
||||
handler.early_warn(format!(
|
||||
"`--emit={ot}` with `-o` incompatible with \
|
||||
`-C codegen-units=N` for N > 1",
|
||||
),
|
||||
);
|
||||
));
|
||||
}
|
||||
early_warn(error_format, "resetting to default -C codegen-units=1");
|
||||
handler.early_warn("resetting to default -C codegen-units=1");
|
||||
codegen_units = Some(1);
|
||||
disable_local_thinlto = true;
|
||||
}
|
||||
|
@ -1968,27 +1948,27 @@ fn should_override_cgus_and_disable_thinlto(
|
|||
}
|
||||
|
||||
if codegen_units == Some(0) {
|
||||
early_error(error_format, "value for codegen units must be a positive non-zero integer");
|
||||
handler.early_error("value for codegen units must be a positive non-zero integer");
|
||||
}
|
||||
|
||||
(disable_local_thinlto, codegen_units)
|
||||
}
|
||||
|
||||
fn check_thread_count(unstable_opts: &UnstableOptions, error_format: ErrorOutputType) {
|
||||
fn check_thread_count(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) {
|
||||
if unstable_opts.threads == 0 {
|
||||
early_error(error_format, "value for threads must be a positive non-zero integer");
|
||||
handler.early_error("value for threads must be a positive non-zero integer");
|
||||
}
|
||||
|
||||
if unstable_opts.threads > 1 && unstable_opts.fuel.is_some() {
|
||||
early_error(error_format, "optimization fuel is incompatible with multiple threads");
|
||||
handler.early_error("optimization fuel is incompatible with multiple threads");
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_print_requests(
|
||||
handler: &EarlyErrorHandler,
|
||||
cg: &mut CodegenOptions,
|
||||
unstable_opts: &mut UnstableOptions,
|
||||
matches: &getopts::Matches,
|
||||
error_format: ErrorOutputType,
|
||||
) -> Vec<PrintRequest> {
|
||||
let mut prints = Vec::<PrintRequest>::new();
|
||||
if cg.target_cpu.as_ref().is_some_and(|s| s == "help") {
|
||||
|
@ -2028,8 +2008,7 @@ fn collect_print_requests(
|
|||
if unstable_opts.unstable_options {
|
||||
PrintRequest::TargetSpec
|
||||
} else {
|
||||
early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"the `-Z unstable-options` flag must also be passed to \
|
||||
enable the target-spec-json print option",
|
||||
);
|
||||
|
@ -2039,8 +2018,7 @@ fn collect_print_requests(
|
|||
if unstable_opts.unstable_options {
|
||||
PrintRequest::AllTargetSpecs
|
||||
} else {
|
||||
early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"the `-Z unstable-options` flag must also be passed to \
|
||||
enable the all-target-specs-json print option",
|
||||
);
|
||||
|
@ -2051,10 +2029,9 @@ fn collect_print_requests(
|
|||
let prints =
|
||||
PRINT_REQUESTS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
|
||||
let prints = prints.join(", ");
|
||||
early_error(
|
||||
error_format,
|
||||
format!("unknown print request `{req}`. Valid print requests are: {prints}"),
|
||||
);
|
||||
handler.early_error(format!(
|
||||
"unknown print request `{req}`. Valid print requests are: {prints}"
|
||||
));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
@ -2063,14 +2040,14 @@ fn collect_print_requests(
|
|||
}
|
||||
|
||||
pub fn parse_target_triple(
|
||||
handler: &EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
error_format: ErrorOutputType,
|
||||
) -> TargetTriple {
|
||||
match matches.opt_str("target") {
|
||||
Some(target) if target.ends_with(".json") => {
|
||||
let path = Path::new(&target);
|
||||
TargetTriple::from_path(path).unwrap_or_else(|_| {
|
||||
early_error(error_format, format!("target file {path:?} does not exist"))
|
||||
handler.early_error(format!("target file {path:?} does not exist"))
|
||||
})
|
||||
}
|
||||
Some(target) => TargetTriple::TargetTriple(target),
|
||||
|
@ -2079,9 +2056,9 @@ pub fn parse_target_triple(
|
|||
}
|
||||
|
||||
fn parse_opt_level(
|
||||
handler: &EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
cg: &CodegenOptions,
|
||||
error_format: ErrorOutputType,
|
||||
) -> OptLevel {
|
||||
// The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
|
||||
// to use them interchangeably. However, because they're technically different flags,
|
||||
|
@ -2109,13 +2086,10 @@ fn parse_opt_level(
|
|||
"s" => OptLevel::Size,
|
||||
"z" => OptLevel::SizeMin,
|
||||
arg => {
|
||||
early_error(
|
||||
error_format,
|
||||
format!(
|
||||
"optimization level needs to be \
|
||||
handler.early_error(format!(
|
||||
"optimization level needs to be \
|
||||
between 0-3, s or z (instead was `{arg}`)"
|
||||
),
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2135,23 +2109,23 @@ fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInf
|
|||
}
|
||||
|
||||
pub(crate) fn parse_assert_incr_state(
|
||||
handler: &EarlyErrorHandler,
|
||||
opt_assertion: &Option<String>,
|
||||
error_format: ErrorOutputType,
|
||||
) -> Option<IncrementalStateAssertion> {
|
||||
match opt_assertion {
|
||||
Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded),
|
||||
Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded),
|
||||
Some(s) => {
|
||||
early_error(error_format, format!("unexpected incremental state assertion value: {s}"))
|
||||
handler.early_error(format!("unexpected incremental state assertion value: {s}"))
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_native_lib_kind(
|
||||
handler: &EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
kind: &str,
|
||||
error_format: ErrorOutputType,
|
||||
) -> (NativeLibKind, Option<bool>) {
|
||||
let (kind, modifiers) = match kind.split_once(':') {
|
||||
None => (kind, None),
|
||||
|
@ -2169,35 +2143,31 @@ fn parse_native_lib_kind(
|
|||
} else {
|
||||
", the `-Z unstable-options` flag must also be passed to use it"
|
||||
};
|
||||
early_error(error_format, format!("library kind `link-arg` is unstable{why}"))
|
||||
handler.early_error(format!("library kind `link-arg` is unstable{why}"))
|
||||
}
|
||||
NativeLibKind::LinkArg
|
||||
}
|
||||
_ => early_error(
|
||||
error_format,
|
||||
format!(
|
||||
"unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
|
||||
),
|
||||
),
|
||||
_ => handler.early_error(format!(
|
||||
"unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
|
||||
)),
|
||||
};
|
||||
match modifiers {
|
||||
None => (kind, None),
|
||||
Some(modifiers) => parse_native_lib_modifiers(kind, modifiers, error_format, matches),
|
||||
Some(modifiers) => parse_native_lib_modifiers(handler, kind, modifiers, matches),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_native_lib_modifiers(
|
||||
handler: &EarlyErrorHandler,
|
||||
mut kind: NativeLibKind,
|
||||
modifiers: &str,
|
||||
error_format: ErrorOutputType,
|
||||
matches: &getopts::Matches,
|
||||
) -> (NativeLibKind, Option<bool>) {
|
||||
let mut verbatim = None;
|
||||
for modifier in modifiers.split(',') {
|
||||
let (modifier, value) = match modifier.strip_prefix(['+', '-']) {
|
||||
Some(m) => (m, modifier.starts_with('+')),
|
||||
None => early_error(
|
||||
error_format,
|
||||
None => handler.early_error(
|
||||
"invalid linking modifier syntax, expected '+' or '-' prefix \
|
||||
before one of: bundle, verbatim, whole-archive, as-needed",
|
||||
),
|
||||
|
@ -2210,21 +2180,20 @@ fn parse_native_lib_modifiers(
|
|||
} else {
|
||||
", the `-Z unstable-options` flag must also be passed to use it"
|
||||
};
|
||||
early_error(error_format, format!("linking modifier `{modifier}` is unstable{why}"))
|
||||
handler.early_error(format!("linking modifier `{modifier}` is unstable{why}"))
|
||||
}
|
||||
};
|
||||
let assign_modifier = |dst: &mut Option<bool>| {
|
||||
if dst.is_some() {
|
||||
let msg = format!("multiple `{modifier}` modifiers in a single `-l` option");
|
||||
early_error(error_format, msg)
|
||||
handler.early_error(msg)
|
||||
} else {
|
||||
*dst = Some(value);
|
||||
}
|
||||
};
|
||||
match (modifier, &mut kind) {
|
||||
("bundle", NativeLibKind::Static { bundle, .. }) => assign_modifier(bundle),
|
||||
("bundle", _) => early_error(
|
||||
error_format,
|
||||
("bundle", _) => handler.early_error(
|
||||
"linking modifier `bundle` is only compatible with `static` linking kind",
|
||||
),
|
||||
|
||||
|
@ -2233,8 +2202,7 @@ fn parse_native_lib_modifiers(
|
|||
("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
|
||||
assign_modifier(whole_archive)
|
||||
}
|
||||
("whole-archive", _) => early_error(
|
||||
error_format,
|
||||
("whole-archive", _) => handler.early_error(
|
||||
"linking modifier `whole-archive` is only compatible with `static` linking kind",
|
||||
),
|
||||
|
||||
|
@ -2243,28 +2211,24 @@ fn parse_native_lib_modifiers(
|
|||
report_unstable_modifier();
|
||||
assign_modifier(as_needed)
|
||||
}
|
||||
("as-needed", _) => early_error(
|
||||
error_format,
|
||||
("as-needed", _) => handler.early_error(
|
||||
"linking modifier `as-needed` is only compatible with \
|
||||
`dylib` and `framework` linking kinds",
|
||||
),
|
||||
|
||||
// Note: this error also excludes the case with empty modifier
|
||||
// string, like `modifiers = ""`.
|
||||
_ => early_error(
|
||||
error_format,
|
||||
format!(
|
||||
"unknown linking modifier `{modifier}`, expected one \
|
||||
_ => handler.early_error(format!(
|
||||
"unknown linking modifier `{modifier}`, expected one \
|
||||
of: bundle, verbatim, whole-archive, as-needed"
|
||||
),
|
||||
),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
(kind, verbatim)
|
||||
}
|
||||
|
||||
fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<NativeLib> {
|
||||
fn parse_libs(handler: &EarlyErrorHandler, matches: &getopts::Matches) -> Vec<NativeLib> {
|
||||
matches
|
||||
.opt_strs("l")
|
||||
.into_iter()
|
||||
|
@ -2278,7 +2242,7 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<
|
|||
let (name, kind, verbatim) = match s.split_once('=') {
|
||||
None => (s, NativeLibKind::Unspecified, None),
|
||||
Some((kind, name)) => {
|
||||
let (kind, verbatim) = parse_native_lib_kind(matches, kind, error_format);
|
||||
let (kind, verbatim) = parse_native_lib_kind(handler, matches, kind);
|
||||
(name.to_string(), kind, verbatim)
|
||||
}
|
||||
};
|
||||
|
@ -2288,7 +2252,7 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<
|
|||
Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())),
|
||||
};
|
||||
if name.is_empty() {
|
||||
early_error(error_format, "library name must not be empty");
|
||||
handler.early_error("library name must not be empty");
|
||||
}
|
||||
NativeLib { name, new_name, kind, verbatim }
|
||||
})
|
||||
|
@ -2296,9 +2260,9 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<
|
|||
}
|
||||
|
||||
pub fn parse_externs(
|
||||
handler: &EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
unstable_opts: &UnstableOptions,
|
||||
error_format: ErrorOutputType,
|
||||
) -> Externs {
|
||||
let is_unstable_enabled = unstable_opts.unstable_options;
|
||||
let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
|
||||
|
@ -2362,8 +2326,7 @@ pub fn parse_externs(
|
|||
let mut force = false;
|
||||
if let Some(opts) = options {
|
||||
if !is_unstable_enabled {
|
||||
early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"the `-Z unstable-options` flag must also be passed to \
|
||||
enable `--extern` options",
|
||||
);
|
||||
|
@ -2375,15 +2338,14 @@ pub fn parse_externs(
|
|||
if let ExternLocation::ExactPaths(_) = &entry.location {
|
||||
add_prelude = false;
|
||||
} else {
|
||||
early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"the `noprelude` --extern option requires a file path",
|
||||
);
|
||||
}
|
||||
}
|
||||
"nounused" => nounused_dep = true,
|
||||
"force" => force = true,
|
||||
_ => early_error(error_format, format!("unknown --extern option `{opt}`")),
|
||||
_ => handler.early_error(format!("unknown --extern option `{opt}`")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2402,18 +2364,15 @@ pub fn parse_externs(
|
|||
}
|
||||
|
||||
fn parse_remap_path_prefix(
|
||||
handler: &EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
unstable_opts: &UnstableOptions,
|
||||
error_format: ErrorOutputType,
|
||||
) -> Vec<(PathBuf, PathBuf)> {
|
||||
let mut mapping: Vec<(PathBuf, PathBuf)> = matches
|
||||
.opt_strs("remap-path-prefix")
|
||||
.into_iter()
|
||||
.map(|remap| match remap.rsplit_once('=') {
|
||||
None => early_error(
|
||||
error_format,
|
||||
"--remap-path-prefix must contain '=' between FROM and TO",
|
||||
),
|
||||
None => handler.early_error("--remap-path-prefix must contain '=' between FROM and TO"),
|
||||
Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
|
||||
})
|
||||
.collect();
|
||||
|
@ -2429,86 +2388,75 @@ fn parse_remap_path_prefix(
|
|||
|
||||
// JUSTIFICATION: before wrapper fn is available
|
||||
#[allow(rustc::bad_opt_access)]
|
||||
pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
let color = parse_color(matches);
|
||||
pub fn build_session_options(
|
||||
handler: &mut EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
) -> Options {
|
||||
let color = parse_color(handler, matches);
|
||||
|
||||
let edition = parse_crate_edition(matches);
|
||||
let edition = parse_crate_edition(handler, matches);
|
||||
|
||||
let JsonConfig {
|
||||
json_rendered,
|
||||
json_artifact_notifications,
|
||||
json_unused_externs,
|
||||
json_future_incompat,
|
||||
} = parse_json(matches);
|
||||
} = parse_json(handler, matches);
|
||||
|
||||
let error_format = parse_error_format(matches, color, json_rendered);
|
||||
let error_format = parse_error_format(handler, matches, color, json_rendered);
|
||||
|
||||
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
|
||||
early_error(error_format, "`--diagnostic-width` must be an positive integer");
|
||||
handler.early_error("`--diagnostic-width` must be an positive integer");
|
||||
});
|
||||
|
||||
let unparsed_crate_types = matches.opt_strs("crate-type");
|
||||
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
|
||||
.unwrap_or_else(|e| early_error(error_format, e));
|
||||
.unwrap_or_else(|e| handler.early_error(e));
|
||||
|
||||
let mut unstable_opts = UnstableOptions::build(matches, error_format);
|
||||
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
|
||||
let mut unstable_opts = UnstableOptions::build(handler, matches);
|
||||
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(handler, matches);
|
||||
|
||||
check_error_format_stability(&unstable_opts, error_format, json_rendered);
|
||||
check_error_format_stability(handler, &unstable_opts, error_format, json_rendered);
|
||||
|
||||
if !unstable_opts.unstable_options && json_unused_externs.is_enabled() {
|
||||
early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"the `-Z unstable-options` flag must also be passed to enable \
|
||||
the flag `--json=unused-externs`",
|
||||
);
|
||||
}
|
||||
|
||||
let output_types = parse_output_types(&unstable_opts, matches, error_format);
|
||||
let output_types = parse_output_types(handler, &unstable_opts, matches);
|
||||
|
||||
let mut cg = CodegenOptions::build(matches, error_format);
|
||||
let (disable_local_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto(
|
||||
&output_types,
|
||||
matches,
|
||||
error_format,
|
||||
cg.codegen_units,
|
||||
);
|
||||
let mut cg = CodegenOptions::build(handler, matches);
|
||||
let (disable_local_thinlto, mut codegen_units) =
|
||||
should_override_cgus_and_disable_thinlto(handler, &output_types, matches, cg.codegen_units);
|
||||
|
||||
check_thread_count(&unstable_opts, error_format);
|
||||
check_thread_count(handler, &unstable_opts);
|
||||
|
||||
let incremental = cg.incremental.as_ref().map(PathBuf::from);
|
||||
|
||||
let assert_incr_state = parse_assert_incr_state(&unstable_opts.assert_incr_state, error_format);
|
||||
let assert_incr_state = parse_assert_incr_state(handler, &unstable_opts.assert_incr_state);
|
||||
|
||||
if unstable_opts.profile && incremental.is_some() {
|
||||
early_error(
|
||||
error_format,
|
||||
"can't instrument with gcov profiling when compiling incrementally",
|
||||
);
|
||||
handler.early_error("can't instrument with gcov profiling when compiling incrementally");
|
||||
}
|
||||
if unstable_opts.profile {
|
||||
match codegen_units {
|
||||
Some(1) => {}
|
||||
None => codegen_units = Some(1),
|
||||
Some(_) => early_error(
|
||||
error_format,
|
||||
"can't instrument with gcov profiling with multiple codegen units",
|
||||
),
|
||||
Some(_) => handler
|
||||
.early_error("can't instrument with gcov profiling with multiple codegen units"),
|
||||
}
|
||||
}
|
||||
|
||||
if cg.profile_generate.enabled() && cg.profile_use.is_some() {
|
||||
early_error(
|
||||
error_format,
|
||||
"options `-C profile-generate` and `-C profile-use` are exclusive",
|
||||
);
|
||||
handler.early_error("options `-C profile-generate` and `-C profile-use` are exclusive");
|
||||
}
|
||||
|
||||
if unstable_opts.profile_sample_use.is_some()
|
||||
&& (cg.profile_generate.enabled() || cg.profile_use.is_some())
|
||||
{
|
||||
early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
|
||||
);
|
||||
}
|
||||
|
@ -2517,23 +2465,19 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
// precedence.
|
||||
match (cg.symbol_mangling_version, unstable_opts.symbol_mangling_version) {
|
||||
(Some(smv_c), Some(smv_z)) if smv_c != smv_z => {
|
||||
early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"incompatible values passed for `-C symbol-mangling-version` \
|
||||
and `-Z symbol-mangling-version`",
|
||||
);
|
||||
}
|
||||
(Some(SymbolManglingVersion::V0), _) => {}
|
||||
(Some(_), _) if !unstable_opts.unstable_options => {
|
||||
early_error(
|
||||
error_format,
|
||||
"`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
|
||||
);
|
||||
handler
|
||||
.early_error("`-C symbol-mangling-version=legacy` requires `-Z unstable-options`");
|
||||
}
|
||||
(None, None) => {}
|
||||
(None, smv) => {
|
||||
early_warn(
|
||||
error_format,
|
||||
handler.early_warn(
|
||||
"`-Z symbol-mangling-version` is deprecated; use `-C symbol-mangling-version`",
|
||||
);
|
||||
cg.symbol_mangling_version = smv;
|
||||
|
@ -2545,25 +2489,19 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
// precedence.
|
||||
match (cg.instrument_coverage, unstable_opts.instrument_coverage) {
|
||||
(Some(ic_c), Some(ic_z)) if ic_c != ic_z => {
|
||||
early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"incompatible values passed for `-C instrument-coverage` \
|
||||
and `-Z instrument-coverage`",
|
||||
);
|
||||
}
|
||||
(Some(InstrumentCoverage::Off | InstrumentCoverage::All), _) => {}
|
||||
(Some(_), _) if !unstable_opts.unstable_options => {
|
||||
early_error(
|
||||
error_format,
|
||||
"`-C instrument-coverage=except-*` requires `-Z unstable-options`",
|
||||
);
|
||||
handler.early_error("`-C instrument-coverage=except-*` requires `-Z unstable-options`");
|
||||
}
|
||||
(None, None) => {}
|
||||
(None, ic) => {
|
||||
early_warn(
|
||||
error_format,
|
||||
"`-Z instrument-coverage` is deprecated; use `-C instrument-coverage`",
|
||||
);
|
||||
handler
|
||||
.early_warn("`-Z instrument-coverage` is deprecated; use `-C instrument-coverage`");
|
||||
cg.instrument_coverage = ic;
|
||||
}
|
||||
_ => {}
|
||||
|
@ -2571,8 +2509,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
|
||||
if cg.instrument_coverage.is_some() && cg.instrument_coverage != Some(InstrumentCoverage::Off) {
|
||||
if cg.profile_generate.enabled() || cg.profile_use.is_some() {
|
||||
early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"option `-C instrument-coverage` is not compatible with either `-C profile-use` \
|
||||
or `-C profile-generate`",
|
||||
);
|
||||
|
@ -2585,8 +2522,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
match cg.symbol_mangling_version {
|
||||
None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
|
||||
Some(SymbolManglingVersion::Legacy) => {
|
||||
early_warn(
|
||||
error_format,
|
||||
handler.early_warn(
|
||||
"-C instrument-coverage requires symbol mangling version `v0`, \
|
||||
but `-C symbol-mangling-version=legacy` was specified",
|
||||
);
|
||||
|
@ -2602,10 +2538,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
if !cg.embed_bitcode {
|
||||
match cg.lto {
|
||||
LtoCli::No | LtoCli::Unspecified => {}
|
||||
LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => early_error(
|
||||
error_format,
|
||||
"options `-C embed-bitcode=no` and `-C lto` are incompatible",
|
||||
),
|
||||
LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
|
||||
handler.early_error("options `-C embed-bitcode=no` and `-C lto` are incompatible")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2618,17 +2553,17 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
flag must also be passed to explicitly use it",
|
||||
flavor.desc()
|
||||
);
|
||||
early_error(error_format, msg);
|
||||
handler.early_error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
let prints = collect_print_requests(&mut cg, &mut unstable_opts, matches, error_format);
|
||||
let prints = collect_print_requests(handler, &mut cg, &mut unstable_opts, matches);
|
||||
|
||||
let cg = cg;
|
||||
|
||||
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
|
||||
let target_triple = parse_target_triple(matches, error_format);
|
||||
let opt_level = parse_opt_level(matches, &cg, error_format);
|
||||
let target_triple = parse_target_triple(handler, matches);
|
||||
let opt_level = parse_opt_level(handler, matches, &cg);
|
||||
// The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
|
||||
// to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
|
||||
// for more details.
|
||||
|
@ -2637,28 +2572,28 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
|
||||
let mut search_paths = vec![];
|
||||
for s in &matches.opt_strs("L") {
|
||||
search_paths.push(SearchPath::from_cli_opt(s, error_format));
|
||||
search_paths.push(SearchPath::from_cli_opt(handler, s));
|
||||
}
|
||||
|
||||
let libs = parse_libs(matches, error_format);
|
||||
let libs = parse_libs(handler, matches);
|
||||
|
||||
let test = matches.opt_present("test");
|
||||
|
||||
if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
|
||||
early_warn(error_format, "-C remark requires \"-C debuginfo=n\" to show source locations");
|
||||
handler.early_warn("-C remark requires \"-C debuginfo=n\" to show source locations");
|
||||
}
|
||||
|
||||
let externs = parse_externs(matches, &unstable_opts, error_format);
|
||||
let externs = parse_externs(handler, matches, &unstable_opts);
|
||||
|
||||
let crate_name = matches.opt_str("crate-name");
|
||||
|
||||
let remap_path_prefix = parse_remap_path_prefix(matches, &unstable_opts, error_format);
|
||||
let remap_path_prefix = parse_remap_path_prefix(handler, matches, &unstable_opts);
|
||||
|
||||
let pretty = parse_pretty(&unstable_opts, error_format);
|
||||
let pretty = parse_pretty(handler, &unstable_opts);
|
||||
|
||||
// query-dep-graph is required if dump-dep-graph is given #106736
|
||||
if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
|
||||
early_error(error_format, "can't dump dependency graph without `-Z query-dep-graph`");
|
||||
handler.early_error("can't dump dependency graph without `-Z query-dep-graph`");
|
||||
}
|
||||
|
||||
// Try to find a directory containing the Rust `src`, for more details see
|
||||
|
@ -2690,7 +2625,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
};
|
||||
|
||||
let working_dir = std::env::current_dir().unwrap_or_else(|e| {
|
||||
early_error(error_format, format!("Current directory is invalid: {e}"));
|
||||
handler.early_error(format!("Current directory is invalid: {e}"));
|
||||
});
|
||||
|
||||
let remap = FilePathMapping::new(remap_path_prefix.clone());
|
||||
|
@ -2741,7 +2676,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Option<PpMode> {
|
||||
fn parse_pretty(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) -> Option<PpMode> {
|
||||
use PpMode::*;
|
||||
|
||||
let first = match unstable_opts.unpretty.as_deref()? {
|
||||
|
@ -2760,16 +2695,13 @@ fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Optio
|
|||
"thir-flat" => ThirFlat,
|
||||
"mir" => Mir,
|
||||
"mir-cfg" => MirCFG,
|
||||
name => early_error(
|
||||
efmt,
|
||||
format!(
|
||||
"argument to `unpretty` must be one of `normal`, `identified`, \
|
||||
name => handler.early_error(format!(
|
||||
"argument to `unpretty` must be one of `normal`, `identified`, \
|
||||
`expanded`, `expanded,identified`, `expanded,hygiene`, \
|
||||
`ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
|
||||
`hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir` or \
|
||||
`mir-cfg`; got {name}"
|
||||
),
|
||||
),
|
||||
)),
|
||||
};
|
||||
debug!("got unpretty option: {first:?}");
|
||||
Some(first)
|
||||
|
@ -2809,8 +2741,8 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
|
|||
}
|
||||
|
||||
pub mod nightly_options {
|
||||
use super::{ErrorOutputType, OptionStability, RustcOptGroup};
|
||||
use crate::early_error;
|
||||
use super::{OptionStability, RustcOptGroup};
|
||||
use crate::EarlyErrorHandler;
|
||||
use rustc_feature::UnstableFeatures;
|
||||
|
||||
pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
|
||||
|
@ -2826,7 +2758,11 @@ pub mod nightly_options {
|
|||
UnstableFeatures::from_environment(krate).is_nightly_build()
|
||||
}
|
||||
|
||||
pub fn check_nightly_options(matches: &getopts::Matches, flags: &[RustcOptGroup]) {
|
||||
pub fn check_nightly_options(
|
||||
handler: &EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
flags: &[RustcOptGroup],
|
||||
) {
|
||||
let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
|
||||
let really_allows_unstable_options = match_is_nightly_build(matches);
|
||||
|
||||
|
@ -2838,14 +2774,11 @@ pub mod nightly_options {
|
|||
continue;
|
||||
}
|
||||
if opt.name != "Z" && !has_z_unstable_option {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
format!(
|
||||
"the `-Z unstable-options` flag must also be passed to enable \
|
||||
handler.early_error(format!(
|
||||
"the `-Z unstable-options` flag must also be passed to enable \
|
||||
the flag `{}`",
|
||||
opt.name
|
||||
),
|
||||
);
|
||||
opt.name
|
||||
));
|
||||
}
|
||||
if really_allows_unstable_options {
|
||||
continue;
|
||||
|
@ -2856,7 +2789,12 @@ pub mod nightly_options {
|
|||
"the option `{}` is only accepted on the nightly compiler",
|
||||
opt.name
|
||||
);
|
||||
early_error(ErrorOutputType::default(), msg);
|
||||
let _ = handler.early_error_no_abort(msg);
|
||||
handler.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
|
||||
handler.early_help(
|
||||
"consider switching to a nightly toolchain: `rustup default nightly`",
|
||||
);
|
||||
handler.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>");
|
||||
}
|
||||
OptionStability::Stable => {}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::config::*;
|
||||
|
||||
use crate::early_error;
|
||||
use crate::lint;
|
||||
use crate::search_paths::SearchPath;
|
||||
use crate::utils::NativeLib;
|
||||
use crate::{lint, EarlyErrorHandler};
|
||||
use rustc_data_structures::profiling::TimePassesFormat;
|
||||
use rustc_errors::{LanguageIdentifier, TerminalUrl};
|
||||
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet};
|
||||
|
@ -245,10 +244,10 @@ macro_rules! options {
|
|||
|
||||
impl $struct_name {
|
||||
pub fn build(
|
||||
handler: &EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
error_format: ErrorOutputType,
|
||||
) -> $struct_name {
|
||||
build_options(matches, $stat, $prefix, $outputname, error_format)
|
||||
build_options(handler, matches, $stat, $prefix, $outputname)
|
||||
}
|
||||
|
||||
fn dep_tracking_hash(&self, for_crate_hash: bool, error_format: ErrorOutputType) -> u64 {
|
||||
|
@ -309,11 +308,11 @@ type OptionSetter<O> = fn(&mut O, v: Option<&str>) -> bool;
|
|||
type OptionDescrs<O> = &'static [(&'static str, OptionSetter<O>, &'static str, &'static str)];
|
||||
|
||||
fn build_options<O: Default>(
|
||||
handler: &EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
descrs: OptionDescrs<O>,
|
||||
prefix: &str,
|
||||
outputname: &str,
|
||||
error_format: ErrorOutputType,
|
||||
) -> O {
|
||||
let mut op = O::default();
|
||||
for option in matches.opt_strs(prefix) {
|
||||
|
@ -327,15 +326,13 @@ fn build_options<O: Default>(
|
|||
Some((_, setter, type_desc, _)) => {
|
||||
if !setter(&mut op, value) {
|
||||
match value {
|
||||
None => early_error(
|
||||
error_format,
|
||||
None => handler.early_error(
|
||||
format!(
|
||||
"{0} option `{1}` requires {2} ({3} {1}=<value>)",
|
||||
outputname, key, type_desc, prefix
|
||||
),
|
||||
),
|
||||
Some(value) => early_error(
|
||||
error_format,
|
||||
Some(value) => handler.early_error(
|
||||
format!(
|
||||
"incorrect value `{value}` for {outputname} option `{key}` - {type_desc} was expected"
|
||||
),
|
||||
|
@ -343,7 +340,7 @@ fn build_options<O: Default>(
|
|||
}
|
||||
}
|
||||
}
|
||||
None => early_error(error_format, format!("unknown {outputname} option: `{key}`")),
|
||||
None => handler.early_error(format!("unknown {outputname} option: `{key}`")),
|
||||
}
|
||||
}
|
||||
return op;
|
||||
|
|
|
@ -51,13 +51,6 @@ impl GatedSpans {
|
|||
debug_assert_eq!(span, removed_span);
|
||||
}
|
||||
|
||||
/// Is the provided `feature` gate ungated currently?
|
||||
///
|
||||
/// Using this is discouraged unless you have a really good reason to.
|
||||
pub fn is_ungated(&self, feature: Symbol) -> bool {
|
||||
self.spans.borrow().get(&feature).map_or(true, |spans| spans.is_empty())
|
||||
}
|
||||
|
||||
/// Prepend the given set of `spans` onto the set in `self`.
|
||||
pub fn merge(&self, mut spans: FxHashMap<Symbol, Vec<Span>>) {
|
||||
let mut inner = self.spans.borrow_mut();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::filesearch::make_target_lib_path;
|
||||
use crate::{config, early_error};
|
||||
use crate::EarlyErrorHandler;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -46,7 +46,7 @@ impl PathKind {
|
|||
}
|
||||
|
||||
impl SearchPath {
|
||||
pub fn from_cli_opt(path: &str, output: config::ErrorOutputType) -> Self {
|
||||
pub fn from_cli_opt(handler: &EarlyErrorHandler, path: &str) -> Self {
|
||||
let (kind, path) = if let Some(stripped) = path.strip_prefix("native=") {
|
||||
(PathKind::Native, stripped)
|
||||
} else if let Some(stripped) = path.strip_prefix("crate=") {
|
||||
|
@ -61,7 +61,7 @@ impl SearchPath {
|
|||
(PathKind::All, path)
|
||||
};
|
||||
if path.is_empty() {
|
||||
early_error(output, "empty search path given via `-L`");
|
||||
handler.early_error("empty search path given via `-L`");
|
||||
}
|
||||
|
||||
let dir = PathBuf::from(path);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::cgu_reuse_tracker::CguReuseTracker;
|
||||
use crate::code_stats::CodeStats;
|
||||
pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
|
||||
use crate::config::Input;
|
||||
use crate::config::{
|
||||
self, CrateType, InstrumentCoverage, OptLevel, OutFileName, OutputType, SwitchWithOptPath,
|
||||
};
|
||||
use crate::config::{ErrorOutputType, Input};
|
||||
use crate::errors;
|
||||
use crate::parse::{add_feature_diagnostics, ParseSess};
|
||||
use crate::search_paths::{PathKind, SearchPath};
|
||||
|
@ -25,7 +25,7 @@ use rustc_errors::json::JsonEmitter;
|
|||
use rustc_errors::registry::Registry;
|
||||
use rustc_errors::{
|
||||
error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
|
||||
ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted,
|
||||
ErrorGuaranteed, FluentBundle, Handler, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted,
|
||||
TerminalUrl,
|
||||
};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
|
@ -1382,6 +1382,7 @@ fn default_emitter(
|
|||
// JUSTIFICATION: literally session construction
|
||||
#[allow(rustc::bad_opt_access)]
|
||||
pub fn build_session(
|
||||
handler: &EarlyErrorHandler,
|
||||
sopts: config::Options,
|
||||
io: CompilerIO,
|
||||
bundle: Option<Lrc<rustc_errors::FluentBundle>>,
|
||||
|
@ -1408,13 +1409,12 @@ pub fn build_session(
|
|||
None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"),
|
||||
};
|
||||
|
||||
let target_cfg = config::build_target_config(&sopts, target_override, &sysroot);
|
||||
let target_cfg = config::build_target_config(handler, &sopts, target_override, &sysroot);
|
||||
let host_triple = TargetTriple::from_triple(config::host_triple());
|
||||
let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| {
|
||||
early_error(sopts.error_format, format!("Error loading host specification: {e}"))
|
||||
});
|
||||
let (host, target_warnings) = Target::search(&host_triple, &sysroot)
|
||||
.unwrap_or_else(|e| handler.early_error(format!("Error loading host specification: {e}")));
|
||||
for warning in target_warnings.warning_messages() {
|
||||
early_warn(sopts.error_format, warning)
|
||||
handler.early_warn(warning)
|
||||
}
|
||||
|
||||
let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
|
||||
|
@ -1456,7 +1456,7 @@ pub fn build_session(
|
|||
match profiler {
|
||||
Ok(profiler) => Some(Arc::new(profiler)),
|
||||
Err(e) => {
|
||||
early_warn(sopts.error_format, format!("failed to create profiler: {e}"));
|
||||
handler.early_warn(format!("failed to create profiler: {e}"));
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -1723,7 +1723,64 @@ pub enum IncrCompSession {
|
|||
InvalidBecauseOfErrors { session_directory: PathBuf },
|
||||
}
|
||||
|
||||
fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler {
|
||||
/// A wrapper around an [`Handler`] that is used for early error emissions.
|
||||
pub struct EarlyErrorHandler {
|
||||
handler: Handler,
|
||||
}
|
||||
|
||||
impl EarlyErrorHandler {
|
||||
pub fn new(output: ErrorOutputType) -> Self {
|
||||
let emitter = mk_emitter(output);
|
||||
Self { handler: rustc_errors::Handler::with_emitter(true, None, emitter) }
|
||||
}
|
||||
|
||||
pub fn abort_if_errors(&self) {
|
||||
self.handler.abort_if_errors()
|
||||
}
|
||||
|
||||
/// Swap out the underlying handler once we acquire the user's preference on error emission
|
||||
/// format. Any errors prior to that will cause an abort and all stashed diagnostics of the
|
||||
/// previous handler will be emitted.
|
||||
pub fn abort_if_error_and_set_error_format(&mut self, output: ErrorOutputType) {
|
||||
self.handler.abort_if_errors();
|
||||
|
||||
let emitter = mk_emitter(output);
|
||||
self.handler = Handler::with_emitter(true, None, emitter);
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn early_note(&self, msg: impl Into<DiagnosticMessage>) {
|
||||
self.handler.struct_note_without_error(msg).emit()
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn early_help(&self, msg: impl Into<DiagnosticMessage>) {
|
||||
self.handler.struct_help(msg).emit()
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"]
|
||||
pub fn early_error_no_abort(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
|
||||
self.handler.struct_err(msg).emit()
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn early_error(&self, msg: impl Into<DiagnosticMessage>) -> ! {
|
||||
self.handler.struct_fatal(msg).emit()
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn early_warn(&self, msg: impl Into<DiagnosticMessage>) {
|
||||
self.handler.struct_warn(msg).emit()
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_emitter(output: ErrorOutputType) -> Box<dyn Emitter + sync::Send + 'static> {
|
||||
// FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will
|
||||
// need to reference every crate that might emit an early error for translation to work.
|
||||
let fallback_bundle =
|
||||
|
@ -1755,27 +1812,5 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
|
|||
TerminalUrl::No,
|
||||
)),
|
||||
};
|
||||
rustc_errors::Handler::with_emitter(true, None, emitter)
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"]
|
||||
pub fn early_error_no_abort(
|
||||
output: config::ErrorOutputType,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> ErrorGuaranteed {
|
||||
early_error_handler(output).struct_err(msg).emit()
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn early_error(output: config::ErrorOutputType, msg: impl Into<DiagnosticMessage>) -> ! {
|
||||
early_error_handler(output).struct_fatal(msg).emit()
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn early_warn(output: config::ErrorOutputType, msg: impl Into<DiagnosticMessage>) {
|
||||
early_error_handler(output).struct_warn(msg).emit()
|
||||
emitter
|
||||
}
|
||||
|
|
|
@ -1319,39 +1319,56 @@ impl Clone for Box<str> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for Box<T, A> {
|
||||
impl<T, A1, A2> PartialEq<Box<T, A2>> for Box<T, A1>
|
||||
where
|
||||
T: ?Sized + PartialEq,
|
||||
A1: Allocator,
|
||||
A2: Allocator,
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
fn eq(&self, other: &Box<T, A2>) -> bool {
|
||||
PartialEq::eq(&**self, &**other)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ne(&self, other: &Self) -> bool {
|
||||
fn ne(&self, other: &Box<T, A2>) -> bool {
|
||||
PartialEq::ne(&**self, &**other)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for Box<T, A> {
|
||||
impl<T, A1, A2> PartialOrd<Box<T, A2>> for Box<T, A1>
|
||||
where
|
||||
T: ?Sized + PartialOrd,
|
||||
A1: Allocator,
|
||||
A2: Allocator,
|
||||
{
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
fn partial_cmp(&self, other: &Box<T, A2>) -> Option<Ordering> {
|
||||
PartialOrd::partial_cmp(&**self, &**other)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn lt(&self, other: &Self) -> bool {
|
||||
fn lt(&self, other: &Box<T, A2>) -> bool {
|
||||
PartialOrd::lt(&**self, &**other)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn le(&self, other: &Self) -> bool {
|
||||
fn le(&self, other: &Box<T, A2>) -> bool {
|
||||
PartialOrd::le(&**self, &**other)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ge(&self, other: &Self) -> bool {
|
||||
fn ge(&self, other: &Box<T, A2>) -> bool {
|
||||
PartialOrd::ge(&**self, &**other)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn gt(&self, other: &Self) -> bool {
|
||||
fn gt(&self, other: &Box<T, A2>) -> bool {
|
||||
PartialOrd::gt(&**self, &**other)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + Ord, A: Allocator> Ord for Box<T, A> {
|
||||
#[inline]
|
||||
|
|
|
@ -15,6 +15,7 @@ use rustc_session::config::{
|
|||
use rustc_session::getopts;
|
||||
use rustc_session::lint::Level;
|
||||
use rustc_session::search_paths::SearchPath;
|
||||
use rustc_session::EarlyErrorHandler;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_target::spec::TargetTriple;
|
||||
|
||||
|
@ -311,32 +312,33 @@ impl Options {
|
|||
/// Parses the given command-line for options. If an error message or other early-return has
|
||||
/// been printed, returns `Err` with the exit code.
|
||||
pub(crate) fn from_matches(
|
||||
handler: &mut EarlyErrorHandler,
|
||||
matches: &getopts::Matches,
|
||||
args: Vec<String>,
|
||||
) -> Result<(Options, RenderOptions), i32> {
|
||||
// Check for unstable options.
|
||||
nightly_options::check_nightly_options(matches, &opts());
|
||||
nightly_options::check_nightly_options(handler, matches, &opts());
|
||||
|
||||
if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
|
||||
crate::usage("rustdoc");
|
||||
return Err(0);
|
||||
} else if matches.opt_present("version") {
|
||||
rustc_driver::version!("rustdoc", matches);
|
||||
rustc_driver::version!(&handler, "rustdoc", matches);
|
||||
return Err(0);
|
||||
}
|
||||
|
||||
if rustc_driver::describe_flag_categories(&matches) {
|
||||
if rustc_driver::describe_flag_categories(handler, &matches) {
|
||||
return Err(0);
|
||||
}
|
||||
|
||||
let color = config::parse_color(matches);
|
||||
let color = config::parse_color(handler, matches);
|
||||
let config::JsonConfig { json_rendered, json_unused_externs, .. } =
|
||||
config::parse_json(matches);
|
||||
let error_format = config::parse_error_format(matches, color, json_rendered);
|
||||
config::parse_json(handler, matches);
|
||||
let error_format = config::parse_error_format(handler, matches, color, json_rendered);
|
||||
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default();
|
||||
|
||||
let codegen_options = CodegenOptions::build(matches, error_format);
|
||||
let unstable_opts = UnstableOptions::build(matches, error_format);
|
||||
let codegen_options = CodegenOptions::build(handler, matches);
|
||||
let unstable_opts = UnstableOptions::build(handler, matches);
|
||||
|
||||
let diag = new_handler(error_format, None, diagnostic_width, &unstable_opts);
|
||||
|
||||
|
@ -393,8 +395,7 @@ impl Options {
|
|||
&& !matches.opt_present("show-coverage")
|
||||
&& !nightly_options::is_unstable_enabled(matches)
|
||||
{
|
||||
rustc_session::early_error(
|
||||
error_format,
|
||||
handler.early_error(
|
||||
"the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)",
|
||||
);
|
||||
}
|
||||
|
@ -432,7 +433,7 @@ impl Options {
|
|||
return Err(0);
|
||||
}
|
||||
|
||||
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
|
||||
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(handler, matches);
|
||||
|
||||
let input = PathBuf::from(if describe_lints {
|
||||
"" // dummy, this won't be used
|
||||
|
@ -446,12 +447,9 @@ impl Options {
|
|||
&matches.free[0]
|
||||
});
|
||||
|
||||
let libs = matches
|
||||
.opt_strs("L")
|
||||
.iter()
|
||||
.map(|s| SearchPath::from_cli_opt(s, error_format))
|
||||
.collect();
|
||||
let externs = parse_externs(matches, &unstable_opts, error_format);
|
||||
let libs =
|
||||
matches.opt_strs("L").iter().map(|s| SearchPath::from_cli_opt(handler, s)).collect();
|
||||
let externs = parse_externs(handler, matches, &unstable_opts);
|
||||
let extern_html_root_urls = match parse_extern_html_roots(matches) {
|
||||
Ok(ex) => ex,
|
||||
Err(err) => {
|
||||
|
@ -589,7 +587,7 @@ impl Options {
|
|||
}
|
||||
}
|
||||
|
||||
let edition = config::parse_crate_edition(matches);
|
||||
let edition = config::parse_crate_edition(handler, matches);
|
||||
|
||||
let mut id_map = html::markdown::IdMap::new();
|
||||
let Some(external_html) = ExternalHtml::load(
|
||||
|
@ -623,7 +621,7 @@ impl Options {
|
|||
}
|
||||
}
|
||||
|
||||
let target = parse_target_triple(matches, error_format);
|
||||
let target = parse_target_triple(handler, matches);
|
||||
|
||||
let show_coverage = matches.opt_present("show-coverage");
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ use rustc_interface::interface;
|
|||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
|
||||
use rustc_session::config::{self, CrateType, ErrorOutputType, ResolveDocLinks};
|
||||
use rustc_session::lint;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::{lint, EarlyErrorHandler};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{source_map, Span};
|
||||
|
||||
|
@ -181,6 +181,7 @@ pub(crate) fn new_handler(
|
|||
|
||||
/// Parse, resolve, and typecheck the given crate.
|
||||
pub(crate) fn create_config(
|
||||
handler: &EarlyErrorHandler,
|
||||
RustdocOptions {
|
||||
input,
|
||||
crate_name,
|
||||
|
@ -258,8 +259,8 @@ pub(crate) fn create_config(
|
|||
|
||||
interface::Config {
|
||||
opts: sessopts,
|
||||
crate_cfg: interface::parse_cfgspecs(cfgs),
|
||||
crate_check_cfg: interface::parse_check_cfg(check_cfgs),
|
||||
crate_cfg: interface::parse_cfgspecs(handler, cfgs),
|
||||
crate_check_cfg: interface::parse_check_cfg(handler, check_cfgs),
|
||||
input,
|
||||
output_file: None,
|
||||
output_dir: None,
|
||||
|
|
|
@ -12,7 +12,7 @@ use rustc_parse::maybe_new_parser_from_source_str;
|
|||
use rustc_parse::parser::attr::InnerAttrPolicy;
|
||||
use rustc_session::config::{self, CrateType, ErrorOutputType};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_session::{lint, Session};
|
||||
use rustc_session::{lint, EarlyErrorHandler, Session};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -85,13 +85,18 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
|
|||
..config::Options::default()
|
||||
};
|
||||
|
||||
let early_error_handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
|
||||
let mut cfgs = options.cfgs.clone();
|
||||
cfgs.push("doc".to_owned());
|
||||
cfgs.push("doctest".to_owned());
|
||||
let config = interface::Config {
|
||||
opts: sessopts,
|
||||
crate_cfg: interface::parse_cfgspecs(cfgs),
|
||||
crate_check_cfg: interface::parse_check_cfg(options.check_cfgs.clone()),
|
||||
crate_cfg: interface::parse_cfgspecs(&early_error_handler, cfgs),
|
||||
crate_check_cfg: interface::parse_check_cfg(
|
||||
&early_error_handler,
|
||||
options.check_cfgs.clone(),
|
||||
),
|
||||
input,
|
||||
output_file: None,
|
||||
output_dir: None,
|
||||
|
|
|
@ -79,8 +79,7 @@ use rustc_errors::ErrorGuaranteed;
|
|||
use rustc_interface::interface;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup};
|
||||
use rustc_session::getopts;
|
||||
use rustc_session::{early_error, early_warn};
|
||||
use rustc_session::{getopts, EarlyErrorHandler};
|
||||
|
||||
use crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL;
|
||||
|
||||
|
@ -155,6 +154,8 @@ pub fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
|
||||
rustc_driver::install_ice_hook(
|
||||
"https://github.com/rust-lang/rust/issues/new\
|
||||
?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md",
|
||||
|
@ -170,11 +171,12 @@ pub fn main() {
|
|||
// NOTE: The reason this doesn't show double logging when `download-rustc = false` and
|
||||
// `debug_logging = true` is because all rustc logging goes to its version of tracing (the one
|
||||
// in the sysroot), and all of rustdoc's logging goes to its version (the one in Cargo.toml).
|
||||
init_logging();
|
||||
rustc_driver::init_env_logger("RUSTDOC_LOG");
|
||||
|
||||
let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() {
|
||||
Some(args) => main_args(&args),
|
||||
init_logging(&handler);
|
||||
rustc_driver::init_env_logger(&handler, "RUSTDOC_LOG");
|
||||
|
||||
let exit_code = rustc_driver::catch_with_exit_code(|| match get_args(&handler) {
|
||||
Some(args) => main_args(&mut handler, &args),
|
||||
_ =>
|
||||
{
|
||||
#[allow(deprecated)]
|
||||
|
@ -184,22 +186,19 @@ pub fn main() {
|
|||
process::exit(exit_code);
|
||||
}
|
||||
|
||||
fn init_logging() {
|
||||
fn init_logging(handler: &EarlyErrorHandler) {
|
||||
let color_logs = match std::env::var("RUSTDOC_LOG_COLOR").as_deref() {
|
||||
Ok("always") => true,
|
||||
Ok("never") => false,
|
||||
Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
|
||||
Ok(value) => early_error(
|
||||
ErrorOutputType::default(),
|
||||
format!("invalid log color value '{}': expected one of always, never, or auto", value),
|
||||
),
|
||||
Err(VarError::NotUnicode(value)) => early_error(
|
||||
ErrorOutputType::default(),
|
||||
format!(
|
||||
"invalid log color value '{}': expected one of always, never, or auto",
|
||||
value.to_string_lossy()
|
||||
),
|
||||
),
|
||||
Ok(value) => handler.early_error(format!(
|
||||
"invalid log color value '{}': expected one of always, never, or auto",
|
||||
value
|
||||
)),
|
||||
Err(VarError::NotUnicode(value)) => handler.early_error(format!(
|
||||
"invalid log color value '{}': expected one of always, never, or auto",
|
||||
value.to_string_lossy()
|
||||
)),
|
||||
};
|
||||
let filter = tracing_subscriber::EnvFilter::from_env("RUSTDOC_LOG");
|
||||
let layer = tracing_tree::HierarchicalLayer::default()
|
||||
|
@ -219,16 +218,13 @@ fn init_logging() {
|
|||
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||
}
|
||||
|
||||
fn get_args() -> Option<Vec<String>> {
|
||||
fn get_args(handler: &EarlyErrorHandler) -> Option<Vec<String>> {
|
||||
env::args_os()
|
||||
.enumerate()
|
||||
.map(|(i, arg)| {
|
||||
arg.into_string()
|
||||
.map_err(|arg| {
|
||||
early_warn(
|
||||
ErrorOutputType::default(),
|
||||
format!("Argument {} is not valid Unicode: {:?}", i, arg),
|
||||
);
|
||||
handler.early_warn(format!("Argument {} is not valid Unicode: {:?}", i, arg));
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
|
@ -710,7 +706,7 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
|
|||
}
|
||||
}
|
||||
|
||||
fn main_args(at_args: &[String]) -> MainResult {
|
||||
fn main_args(handler: &mut EarlyErrorHandler, at_args: &[String]) -> MainResult {
|
||||
// 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,
|
||||
|
@ -721,7 +717,7 @@ fn main_args(at_args: &[String]) -> MainResult {
|
|||
// the compiler with @empty_file as argv[0] and no more arguments.
|
||||
let at_args = at_args.get(1..).unwrap_or_default();
|
||||
|
||||
let args = rustc_driver::args::arg_expand_all(at_args);
|
||||
let args = rustc_driver::args::arg_expand_all(handler, at_args);
|
||||
|
||||
let mut options = getopts::Options::new();
|
||||
for option in opts() {
|
||||
|
@ -730,13 +726,13 @@ fn main_args(at_args: &[String]) -> MainResult {
|
|||
let matches = match options.parse(&args) {
|
||||
Ok(m) => m,
|
||||
Err(err) => {
|
||||
early_error(ErrorOutputType::default(), err.to_string());
|
||||
handler.early_error(err.to_string());
|
||||
}
|
||||
};
|
||||
|
||||
// Note that we discard any distinction between different non-zero exit
|
||||
// codes from `from_matches` here.
|
||||
let (options, render_options) = match config::Options::from_matches(&matches, args) {
|
||||
let (options, render_options) = match config::Options::from_matches(handler, &matches, args) {
|
||||
Ok(opts) => opts,
|
||||
Err(code) => {
|
||||
return if code == 0 {
|
||||
|
@ -764,7 +760,7 @@ fn main_args(at_args: &[String]) -> MainResult {
|
|||
(false, true) => {
|
||||
let input = options.input.clone();
|
||||
let edition = options.edition;
|
||||
let config = core::create_config(options, &render_options);
|
||||
let config = core::create_config(handler, options, &render_options);
|
||||
|
||||
// `markdown::render` can invoke `doctest::make_test`, which
|
||||
// requires session globals and a thread pool, so we use
|
||||
|
@ -797,7 +793,7 @@ fn main_args(at_args: &[String]) -> MainResult {
|
|||
let scrape_examples_options = options.scrape_examples_options.clone();
|
||||
let bin_crate = options.bin_crate;
|
||||
|
||||
let config = core::create_config(options, &render_options);
|
||||
let config = core::create_config(handler, options, &render_options);
|
||||
|
||||
interface::run_compiler(config, |compiler| {
|
||||
let sess = compiler.session();
|
||||
|
|
|
@ -16,6 +16,8 @@ extern crate rustc_session;
|
|||
extern crate rustc_span;
|
||||
|
||||
use rustc_interface::interface;
|
||||
use rustc_session::EarlyErrorHandler;
|
||||
use rustc_session::config::ErrorOutputType;
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
||||
|
@ -187,7 +189,9 @@ const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/ne
|
|||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn main() {
|
||||
rustc_driver::init_rustc_env_logger();
|
||||
let handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
|
||||
rustc_driver::init_rustc_env_logger(&handler);
|
||||
|
||||
rustc_driver::install_ice_hook(BUG_REPORT_URL, |handler| {
|
||||
// FIXME: this macro calls unwrap internally but is called in a panicking context! It's not
|
||||
|
|
|
@ -453,7 +453,7 @@ impl TargetCfgs {
|
|||
let mut all_families = HashSet::new();
|
||||
let mut all_pointer_widths = HashSet::new();
|
||||
|
||||
for (target, cfg) in targets.into_iter() {
|
||||
for (target, cfg) in targets.iter() {
|
||||
all_archs.insert(cfg.arch.clone());
|
||||
all_oses.insert(cfg.os.clone());
|
||||
all_oses_and_envs.insert(cfg.os_and_env());
|
||||
|
@ -464,11 +464,11 @@ impl TargetCfgs {
|
|||
}
|
||||
all_pointer_widths.insert(format!("{}bit", cfg.pointer_width));
|
||||
|
||||
all_targets.insert(target.into());
|
||||
all_targets.insert(target.clone());
|
||||
}
|
||||
|
||||
Self {
|
||||
current: Self::get_current_target_config(config),
|
||||
current: Self::get_current_target_config(config, &targets),
|
||||
all_targets,
|
||||
all_archs,
|
||||
all_oses,
|
||||
|
@ -480,16 +480,20 @@ impl TargetCfgs {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_current_target_config(config: &Config) -> TargetCfg {
|
||||
let mut arch = None;
|
||||
let mut os = None;
|
||||
let mut env = None;
|
||||
let mut abi = None;
|
||||
let mut families = Vec::new();
|
||||
let mut pointer_width = None;
|
||||
let mut endian = None;
|
||||
let mut panic = None;
|
||||
fn get_current_target_config(
|
||||
config: &Config,
|
||||
targets: &HashMap<String, TargetCfg>,
|
||||
) -> TargetCfg {
|
||||
let mut cfg = targets[&config.target].clone();
|
||||
|
||||
// To get the target information for the current target, we take the target spec obtained
|
||||
// from `--print=all-target-specs-json`, and then we enrich it with the information
|
||||
// gathered from `--print=cfg --target=$target`.
|
||||
//
|
||||
// This is done because some parts of the target spec can be overridden with `-C` flags,
|
||||
// which are respected for `--print=cfg` but not for `--print=all-target-specs-json`. The
|
||||
// code below extracts them from `--print=cfg`: make sure to only override fields that can
|
||||
// actually be changed with `-C` flags.
|
||||
for config in
|
||||
rustc_output(config, &["--print=cfg", "--target", &config.target]).trim().lines()
|
||||
{
|
||||
|
@ -507,60 +511,16 @@ impl TargetCfgs {
|
|||
})
|
||||
.unwrap_or_else(|| (config, None));
|
||||
|
||||
match name {
|
||||
"target_arch" => {
|
||||
arch = Some(value.expect("target_arch should be a key-value pair").to_string());
|
||||
}
|
||||
"target_os" => {
|
||||
os = Some(value.expect("target_os sould be a key-value pair").to_string());
|
||||
}
|
||||
"target_env" => {
|
||||
env = Some(value.expect("target_env should be a key-value pair").to_string());
|
||||
}
|
||||
"target_abi" => {
|
||||
abi = Some(value.expect("target_abi should be a key-value pair").to_string());
|
||||
}
|
||||
"target_family" => {
|
||||
families
|
||||
.push(value.expect("target_family should be a key-value pair").to_string());
|
||||
}
|
||||
"target_pointer_width" => {
|
||||
pointer_width = Some(
|
||||
value
|
||||
.expect("target_pointer_width should be a key-value pair")
|
||||
.parse::<u32>()
|
||||
.expect("target_pointer_width should be a valid u32"),
|
||||
);
|
||||
}
|
||||
"target_endian" => {
|
||||
endian = Some(match value.expect("target_endian should be a key-value pair") {
|
||||
"big" => Endian::Big,
|
||||
"little" => Endian::Little,
|
||||
_ => panic!("target_endian should be either 'big' or 'little'"),
|
||||
});
|
||||
}
|
||||
"panic" => {
|
||||
panic = Some(match value.expect("panic should be a key-value pair") {
|
||||
"abort" => PanicStrategy::Abort,
|
||||
"unwind" => PanicStrategy::Unwind,
|
||||
_ => panic!("panic should be either 'abort' or 'unwind'"),
|
||||
});
|
||||
}
|
||||
_ => (),
|
||||
match (name, value) {
|
||||
// Can be overridden with `-C panic=$strategy`.
|
||||
("panic", Some("abort")) => cfg.panic = PanicStrategy::Abort,
|
||||
("panic", Some("unwind")) => cfg.panic = PanicStrategy::Unwind,
|
||||
("panic", other) => panic!("unexpected value for panic cfg: {other:?}"),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
TargetCfg {
|
||||
arch: arch.expect("target configuration should specify target_arch"),
|
||||
os: os.expect("target configuration should specify target_os"),
|
||||
env: env.expect("target configuration should specify target_env"),
|
||||
abi: abi.expect("target configuration should specify target_abi"),
|
||||
families,
|
||||
pointer_width: pointer_width
|
||||
.expect("target configuration should specify target_pointer_width"),
|
||||
endian: endian.expect("target configuration should specify target_endian"),
|
||||
panic: panic.expect("target configuration should specify panic"),
|
||||
}
|
||||
cfg
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,6 +542,8 @@ pub struct TargetCfg {
|
|||
endian: Endian,
|
||||
#[serde(rename = "panic-strategy", default)]
|
||||
pub(crate) panic: PanicStrategy,
|
||||
#[serde(default)]
|
||||
pub(crate) dynamic_linking: bool,
|
||||
}
|
||||
|
||||
impl TargetCfg {
|
||||
|
|
|
@ -130,6 +130,11 @@ pub(super) fn handle_needs(
|
|||
condition: config.git_hash,
|
||||
ignore_reason: "ignored when git hashes have been omitted for building",
|
||||
},
|
||||
Need {
|
||||
name: "needs-dynamic-linking",
|
||||
condition: config.target_cfg().dynamic_linking,
|
||||
ignore_reason: "ignored on targets without dynamic linking",
|
||||
},
|
||||
];
|
||||
|
||||
let (name, comment) = match ln.split_once([':', ' ']) {
|
||||
|
|
|
@ -1810,8 +1810,8 @@ impl<'test> TestCx<'test> {
|
|||
|| self.config.target.contains("wasm32")
|
||||
|| self.config.target.contains("nvptx")
|
||||
|| self.is_vxworks_pure_static()
|
||||
|| self.config.target.contains("sgx")
|
||||
|| self.config.target.contains("bpf")
|
||||
|| !self.config.target_cfg().dynamic_linking
|
||||
{
|
||||
// We primarily compile all auxiliary libraries as dynamic libraries
|
||||
// to avoid code size bloat and large binaries as much as possible
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#![feature(rustc_private)]
|
||||
|
||||
extern crate rustc_driver;
|
||||
extern crate rustc_session;
|
||||
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
|
@ -170,7 +171,9 @@ fn parse_args() -> (OutputFormat, PathBuf) {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
rustc_driver::init_env_logger("RUST_LOG");
|
||||
let handler =
|
||||
rustc_session::EarlyErrorHandler::new(rustc_session::config::ErrorOutputType::default());
|
||||
rustc_driver::init_env_logger(&handler, "RUST_LOG");
|
||||
let (format, dst) = parse_args();
|
||||
let result = main_with_result(format, &dst);
|
||||
if let Err(e) = result {
|
||||
|
|
|
@ -31,9 +31,9 @@ use rustc_middle::{
|
|||
query::{ExternProviders, LocalCrate},
|
||||
ty::TyCtxt,
|
||||
};
|
||||
use rustc_session::config::OptLevel;
|
||||
|
||||
use rustc_session::{config::CrateType, search_paths::PathKind, CtfeBacktrace};
|
||||
use rustc_session::{EarlyErrorHandler, CtfeBacktrace};
|
||||
use rustc_session::config::{OptLevel, CrateType, ErrorOutputType};
|
||||
use rustc_session::search_paths::PathKind;
|
||||
|
||||
use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields};
|
||||
|
||||
|
@ -59,6 +59,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
|
|||
|
||||
fn after_analysis<'tcx>(
|
||||
&mut self,
|
||||
handler: &EarlyErrorHandler,
|
||||
_: &rustc_interface::interface::Compiler,
|
||||
queries: &'tcx rustc_interface::Queries<'tcx>,
|
||||
) -> Compilation {
|
||||
|
@ -66,8 +67,8 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
|
|||
if tcx.sess.compile_status().is_err() {
|
||||
tcx.sess.fatal("miri cannot be run on programs that fail compilation");
|
||||
}
|
||||
|
||||
init_late_loggers(tcx);
|
||||
;
|
||||
init_late_loggers(handler, tcx);
|
||||
if !tcx.sess.crate_types().contains(&CrateType::Executable) {
|
||||
tcx.sess.fatal("miri only makes sense on bin crates");
|
||||
}
|
||||
|
@ -181,7 +182,7 @@ macro_rules! show_error {
|
|||
($($tt:tt)*) => { show_error(&format_args!($($tt)*)) };
|
||||
}
|
||||
|
||||
fn init_early_loggers() {
|
||||
fn init_early_loggers(handler: &EarlyErrorHandler) {
|
||||
// Note that our `extern crate log` is *not* the same as rustc's; as a result, we have to
|
||||
// initialize them both, and we always initialize `miri`'s first.
|
||||
let env = env_logger::Env::new().filter("MIRI_LOG").write_style("MIRI_LOG_STYLE");
|
||||
|
@ -195,11 +196,11 @@ fn init_early_loggers() {
|
|||
// later with our custom settings, and *not* log anything for what happens before
|
||||
// `miri` gets started.
|
||||
if env::var_os("RUSTC_LOG").is_some() {
|
||||
rustc_driver::init_rustc_env_logger();
|
||||
rustc_driver::init_rustc_env_logger(handler);
|
||||
}
|
||||
}
|
||||
|
||||
fn init_late_loggers(tcx: TyCtxt<'_>) {
|
||||
fn init_late_loggers(handler: &EarlyErrorHandler, tcx: TyCtxt<'_>) {
|
||||
// We initialize loggers right before we start evaluation. We overwrite the `RUSTC_LOG`
|
||||
// env var if it is not set, control it based on `MIRI_LOG`.
|
||||
// (FIXME: use `var_os`, but then we need to manually concatenate instead of `format!`.)
|
||||
|
@ -218,7 +219,7 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
|
|||
} else {
|
||||
env::set_var("RUSTC_LOG", &var);
|
||||
}
|
||||
rustc_driver::init_rustc_env_logger();
|
||||
rustc_driver::init_rustc_env_logger(handler);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,6 +285,8 @@ fn parse_comma_list<T: FromStr>(input: &str) -> Result<Vec<T>, T::Err> {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
let handler = EarlyErrorHandler::new(ErrorOutputType::default());
|
||||
|
||||
// Snapshot a copy of the environment before `rustc` starts messing with it.
|
||||
// (`install_ice_hook` might change `RUST_BACKTRACE`.)
|
||||
let env_snapshot = env::vars_os().collect::<Vec<_>>();
|
||||
|
@ -292,7 +295,7 @@ fn main() {
|
|||
if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") {
|
||||
// Earliest rustc setup.
|
||||
rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ());
|
||||
rustc_driver::init_rustc_env_logger();
|
||||
rustc_driver::init_rustc_env_logger(&handler);
|
||||
|
||||
let target_crate = if crate_kind == "target" {
|
||||
true
|
||||
|
@ -314,7 +317,7 @@ fn main() {
|
|||
rustc_driver::install_ice_hook("https://github.com/rust-lang/miri/issues/new", |_| ());
|
||||
|
||||
// Init loggers the Miri way.
|
||||
init_early_loggers();
|
||||
init_early_loggers(&handler);
|
||||
|
||||
// Parse our arguments and split them across `rustc` and `miri`.
|
||||
let mut miri_config = miri::MiriConfig::default();
|
||||
|
|
|
@ -36,7 +36,7 @@ fn main() -> () {
|
|||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = _3;
|
||||
_5 = foo(move _6) -> bb1;
|
||||
_5 = foo(move _6) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -45,7 +45,7 @@ fn main() -> () {
|
|||
_7 = _2;
|
||||
_8 = Len(_1);
|
||||
_9 = Lt(_7, _8);
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2;
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
bb4: {
|
||||
StorageDead(_5);
|
||||
- drop(_4) -> bb5;
|
||||
- drop(_4) -> [return: bb5, unwind continue];
|
||||
+ goto -> bb5;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ fn main() -> () {
|
|||
StorageLive(_1);
|
||||
_2 = SizeOf(S);
|
||||
_3 = AlignOf(S);
|
||||
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1;
|
||||
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -30,7 +30,7 @@ fn main() -> () {
|
|||
|
||||
bb2: {
|
||||
_1 = move _5;
|
||||
drop(_5) -> bb3;
|
||||
drop(_5) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
|
@ -45,7 +45,7 @@ fn main() -> () {
|
|||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
_0 = const ();
|
||||
drop(_1) -> bb5;
|
||||
drop(_1) -> [return: bb5, unwind continue];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
|
|
|
@ -30,7 +30,7 @@ fn a::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:11:14: 11:16]>
|
|||
}
|
||||
|
||||
bb2: {
|
||||
assert(const false, "`async fn` resumed after completion") -> bb2;
|
||||
assert(const false, "`async fn` resumed after completion") -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
|
|
|
@ -310,7 +310,7 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>,
|
|||
}
|
||||
|
||||
bb28: {
|
||||
assert(const false, "`async fn` resumed after completion") -> bb28;
|
||||
assert(const false, "`async fn` resumed after completion") -> [success: bb28, unwind continue];
|
||||
}
|
||||
|
||||
bb29: {
|
||||
|
|
|
@ -4,7 +4,7 @@ fn direct_call(_1: i32) -> i32 {
|
|||
let mut _0: i32;
|
||||
|
||||
bb0: {
|
||||
_0 = ident::<i32>(_1) -> bb1;
|
||||
_0 = ident::<i32>(_1) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -4,7 +4,7 @@ fn drop_first(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () {
|
|||
let mut _0: ();
|
||||
|
||||
bb0: {
|
||||
drop(_1) -> bb1;
|
||||
drop(_1) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -4,7 +4,7 @@ fn drop_second(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () {
|
|||
let mut _0: ();
|
||||
|
||||
bb0: {
|
||||
drop(_2) -> bb1;
|
||||
drop(_2) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -4,7 +4,7 @@ fn indirect_call(_1: i32, _2: fn(i32) -> i32) -> i32 {
|
|||
let mut _0: i32;
|
||||
|
||||
bb0: {
|
||||
_0 = _2(_1) -> bb1;
|
||||
_0 = _2(_1) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
- _4 = Len(_1);
|
||||
+ _4 = const 2_usize;
|
||||
_5 = Lt(_3, _4);
|
||||
assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
|
||||
assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -44,7 +44,7 @@
|
|||
- _8 = Len(_1);
|
||||
+ _8 = const 2_usize;
|
||||
_9 = Lt(_7, _8);
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2;
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
_4 = &((*_1).0: T);
|
||||
- _3 = &(*_4);
|
||||
+ _3 = _4;
|
||||
_2 = <T as Clone>::clone(move _3) -> bb1;
|
||||
_2 = <T as Clone>::clone(move _3) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
StorageLive(_5);
|
||||
- _5 = _1;
|
||||
+ _5 = const 1_u8;
|
||||
_4 = foo(move _5) -> bb1;
|
||||
_4 = foo(move _5) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -23,7 +23,7 @@ fn main() -> () {
|
|||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = const 1_u8;
|
||||
_4 = foo(move _5) -> bb1;
|
||||
_4 = foo(move _5) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(_3, _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(_3, _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -24,21 +24,21 @@
|
|||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
- _4 = Eq(_3, const 0_i32);
|
||||
- assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1;
|
||||
- assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> [success: bb1, unwind continue];
|
||||
+ _3 = const 0_i32;
|
||||
+ _4 = const true;
|
||||
+ assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> bb1;
|
||||
+ assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _5 = Eq(_3, const -1_i32);
|
||||
- _6 = Eq(const 1_i32, const i32::MIN);
|
||||
- _7 = BitAnd(move _5, move _6);
|
||||
- assert(!move _7, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> bb2;
|
||||
- assert(!move _7, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
|
||||
+ _5 = const false;
|
||||
+ _6 = const false;
|
||||
+ _7 = const false;
|
||||
+ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> bb2;
|
||||
+ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -24,21 +24,21 @@
|
|||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
- _4 = Eq(_3, const 0_i32);
|
||||
- assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1;
|
||||
- assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> [success: bb1, unwind continue];
|
||||
+ _3 = const 0_i32;
|
||||
+ _4 = const true;
|
||||
+ assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1;
|
||||
+ assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _5 = Eq(_3, const -1_i32);
|
||||
- _6 = Eq(const 1_i32, const i32::MIN);
|
||||
- _7 = BitAnd(move _5, move _6);
|
||||
- assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2;
|
||||
- assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
|
||||
+ _5 = const false;
|
||||
+ _6 = const false;
|
||||
+ _7 = const false;
|
||||
+ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2;
|
||||
+ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -36,9 +36,9 @@
|
|||
_6 = const 3_usize;
|
||||
_7 = const 3_usize;
|
||||
- _8 = Lt(_6, _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -36,9 +36,9 @@
|
|||
_6 = const 3_usize;
|
||||
_7 = const 3_usize;
|
||||
- _8 = Lt(_6, _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
- _5 = AlignOf(i32);
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const 4_usize;
|
||||
_6 = alloc::alloc::exchange_malloc(move _4, move _5) -> bb1;
|
||||
_6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _2 = CheckedAdd(const 1_u32, const 1_u32);
|
||||
- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1;
|
||||
- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind continue];
|
||||
+ _2 = const (2_u32, false);
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1;
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = _1;
|
||||
_4 = read(move _5) -> bb1;
|
||||
_4 = read(move _5) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
}
|
||||
|
||||
bb1: {
|
||||
_2 = begin_panic::<&str>(const "explicit panic");
|
||||
_2 = begin_panic::<&str>(const "explicit panic") -> unwind continue;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
StorageLive(_2);
|
||||
- _2 = const 2_u32 as u8 (IntToInt);
|
||||
- _3 = CheckedAdd(_2, const 1_u8);
|
||||
- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1;
|
||||
- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind continue];
|
||||
+ _2 = const 2_u8;
|
||||
+ _3 = const (3_u8, false);
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1;
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
StorageLive(_3);
|
||||
_3 = const 1_u8;
|
||||
- _4 = CheckedAdd(_2, _3);
|
||||
- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> bb1;
|
||||
- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const (0_u8, true);
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", _2, _3) -> bb1;
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
bb0: {
|
||||
StorageLive(_2);
|
||||
_2 = (const (), const 0_u8, const 0_u8);
|
||||
_1 = encode(move _2) -> bb1;
|
||||
_1 = encode(move _2) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
+ _3 = const (1_u8, 2_u8);
|
||||
_2 = (move _3,);
|
||||
StorageDead(_3);
|
||||
_1 = test(move _2) -> bb1;
|
||||
_1 = test(move _2) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(_3, _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(_3, _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = foo() -> bb1;
|
||||
_1 = foo() -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = foo() -> bb1;
|
||||
_1 = foo() -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
StorageLive(_2);
|
||||
- _2 = OffsetOf(Alpha, [0]);
|
||||
+ _2 = const 4_usize;
|
||||
_1 = must_use::<usize>(move _2) -> bb1;
|
||||
_1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -38,7 +38,7 @@
|
|||
StorageLive(_4);
|
||||
- _4 = OffsetOf(Alpha, [1]);
|
||||
+ _4 = const 0_usize;
|
||||
_3 = must_use::<usize>(move _4) -> bb2;
|
||||
_3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
@ -47,7 +47,7 @@
|
|||
StorageLive(_6);
|
||||
- _6 = OffsetOf(Alpha, [2, 0]);
|
||||
+ _6 = const 2_usize;
|
||||
_5 = must_use::<usize>(move _6) -> bb3;
|
||||
_5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
|
@ -56,7 +56,7 @@
|
|||
StorageLive(_8);
|
||||
- _8 = OffsetOf(Alpha, [2, 1]);
|
||||
+ _8 = const 3_usize;
|
||||
_7 = must_use::<usize>(move _8) -> bb4;
|
||||
_7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = OffsetOf(Gamma<T>, [0]);
|
||||
_1 = must_use::<usize>(move _2) -> bb1;
|
||||
_1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -36,7 +36,7 @@
|
|||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = OffsetOf(Gamma<T>, [1]);
|
||||
_3 = must_use::<usize>(move _4) -> bb2;
|
||||
_3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
@ -44,7 +44,7 @@
|
|||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = OffsetOf(Delta<T>, [1]);
|
||||
_5 = must_use::<usize>(move _6) -> bb3;
|
||||
_5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
|
@ -52,7 +52,7 @@
|
|||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = OffsetOf(Delta<T>, [2]);
|
||||
_7 = must_use::<usize>(move _8) -> bb4;
|
||||
_7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(_4, _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1;
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(_4, _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1;
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
bb0: {
|
||||
- _1 = CheckedAdd(const 2_u32, const 2_u32);
|
||||
- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1;
|
||||
- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind continue];
|
||||
+ _1 = const (4_u32, false);
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1;
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -6,7 +6,7 @@ fn add() -> u32 {
|
|||
|
||||
bb0: {
|
||||
_1 = const (4_u32, false);
|
||||
assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1;
|
||||
assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
+ _3 = const 1_u32;
|
||||
_2 = consume(move _3) -> bb1;
|
||||
_2 = consume(move _3) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
_6 = const 1_usize;
|
||||
- _7 = Len((*_2));
|
||||
- _8 = Lt(_6, _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
_6 = const 1_usize;
|
||||
- _7 = Len((*_2));
|
||||
- _8 = Lt(_6, _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
}
|
||||
|
||||
bb1: {
|
||||
_0 = foo(const -1_i32) -> bb3;
|
||||
_0 = foo(const -1_i32) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_0 = foo(const 0_i32) -> bb3;
|
||||
_0 = foo(const 0_i32) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
}
|
||||
|
||||
bb1: {
|
||||
_0 = foo(const -1_i32) -> bb3;
|
||||
_0 = foo(const -1_i32) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_0 = foo(const 0_i32) -> bb3;
|
||||
_0 = foo(const 0_i32) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
+ _3 = const (1_u32, 2_u32);
|
||||
_2 = consume(move _3) -> bb1;
|
||||
_2 = consume(move _3) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
_2 = &_1;
|
||||
_3 = _1;
|
||||
_4 = &_3;
|
||||
_0 = cmp_ref(_2, _4) -> bb1;
|
||||
_0 = cmp_ref(_2, _4) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_0 = opaque::<u8>(_3) -> bb2;
|
||||
_0 = opaque::<u8>(_3) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = val() -> bb1;
|
||||
_1 = val() -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = cond() -> bb2;
|
||||
_3 = cond() -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
@ -36,7 +36,7 @@
|
|||
|
||||
bb4: {
|
||||
StorageLive(_4);
|
||||
_4 = val() -> bb5;
|
||||
_4 = val() -> [return: bb5, unwind continue];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = _1;
|
||||
_2 = dummy(move _3) -> bb1;
|
||||
_2 = dummy(move _3) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = _1;
|
||||
_2 = dummy(move _3) -> bb1;
|
||||
_2 = dummy(move _3) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
|
||||
bb0: {
|
||||
- _2 = _1;
|
||||
- _0 = opaque::<NotCopy>(move _1) -> bb1;
|
||||
+ _0 = opaque::<NotCopy>(_1) -> bb1;
|
||||
- _0 = opaque::<NotCopy>(move _1) -> [return: bb1, unwind continue];
|
||||
+ _0 = opaque::<NotCopy>(_1) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _3 = move _2;
|
||||
- _0 = opaque::<NotCopy>(_3) -> bb2;
|
||||
+ _0 = opaque::<NotCopy>(_1) -> bb2;
|
||||
- _0 = opaque::<NotCopy>(_3) -> [return: bb2, unwind continue];
|
||||
+ _0 = opaque::<NotCopy>(_1) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = val() -> bb1;
|
||||
_1 = val() -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -38,7 +38,7 @@
|
|||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = _1;
|
||||
_5 = std::mem::drop::<i32>(move _6) -> bb2;
|
||||
_5 = std::mem::drop::<i32>(move _6) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -16,7 +16,7 @@ fn f(_1: usize) -> usize {
|
|||
_1 = _2;
|
||||
StorageLive(_4);
|
||||
_4 = _1;
|
||||
_0 = id::<usize>(move _4) -> bb1;
|
||||
_0 = id::<usize>(move _4) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -16,7 +16,7 @@ fn f(_1: usize) -> usize {
|
|||
_1 = _2;
|
||||
StorageLive(_4);
|
||||
_4 = _1;
|
||||
_0 = id::<usize>(move _4) -> bb1;
|
||||
_0 = id::<usize>(move _4) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -49,14 +49,14 @@
|
|||
_7 = &_2;
|
||||
_6 = move _7 as &[i32] (Pointer(Unsize));
|
||||
StorageDead(_7);
|
||||
_5 = core::slice::<impl [i32]>::len(move _6) -> bb1;
|
||||
_5 = core::slice::<impl [i32]>::len(move _6) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_6);
|
||||
_4 = std::ops::Range::<usize> { start: const 0_usize, end: move _5 };
|
||||
StorageDead(_5);
|
||||
_3 = <std::ops::Range<usize> as IntoIterator>::into_iter(move _4) -> bb2;
|
||||
_3 = <std::ops::Range<usize> as IntoIterator>::into_iter(move _4) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
@ -73,7 +73,7 @@
|
|||
StorageLive(_13);
|
||||
_13 = &mut _8;
|
||||
_12 = &mut (*_13);
|
||||
_11 = <std::ops::Range<usize> as Iterator>::next(move _12) -> bb4;
|
||||
_11 = <std::ops::Range<usize> as Iterator>::next(move _12) -> [return: bb4, unwind continue];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
|
@ -90,9 +90,9 @@
|
|||
- _18 = _16;
|
||||
_19 = Len(_2);
|
||||
- _20 = Lt(_18, _19);
|
||||
- assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _18) -> bb8;
|
||||
- assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _18) -> [success: bb8, unwind continue];
|
||||
+ _20 = Lt(_16, _19);
|
||||
+ assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _16) -> bb8;
|
||||
+ assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, _16) -> [success: bb8, unwind continue];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
- _4 = _1;
|
||||
- StorageLive(_5);
|
||||
- _5 = _2;
|
||||
- _3 = g::<T>(move _4, move _5) -> bb1;
|
||||
+ _3 = g::<T>(_1, _1) -> bb1;
|
||||
- _3 = g::<T>(move _4, move _5) -> [return: bb1, unwind continue];
|
||||
+ _3 = g::<T>(_1, _1) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
bb0: {
|
||||
- _2 = _1;
|
||||
- _3 = move (_2.0: u8);
|
||||
- _0 = opaque::<Foo>(move _1) -> bb1;
|
||||
- _0 = opaque::<Foo>(move _1) -> [return: bb1, unwind continue];
|
||||
+ _3 = (_1.0: u8);
|
||||
+ _0 = opaque::<Foo>(_1) -> bb1;
|
||||
+ _0 = opaque::<Foo>(_1) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_0 = opaque::<u8>(move _3) -> bb2;
|
||||
_0 = opaque::<u8>(move _3) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
StorageLive(_6);
|
||||
- StorageLive(_7);
|
||||
- _7 = _5;
|
||||
- _6 = opaque::<*mut u8>(move _7) -> bb1;
|
||||
+ _6 = opaque::<*mut u8>(_2) -> bb1;
|
||||
- _6 = opaque::<*mut u8>(move _7) -> [return: bb1, unwind continue];
|
||||
+ _6 = opaque::<*mut u8>(_2) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
StorageLive(_5);
|
||||
- StorageLive(_6);
|
||||
- _6 = _4;
|
||||
- _5 = opaque::<*mut u8>(move _6) -> bb1;
|
||||
+ _5 = opaque::<*mut u8>(_2) -> bb1;
|
||||
- _5 = opaque::<*mut u8>(move _6) -> [return: bb1, unwind continue];
|
||||
+ _5 = opaque::<*mut u8>(_2) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
StorageLive(_5);
|
||||
- StorageLive(_6);
|
||||
- _6 = move _4;
|
||||
- _5 = opaque::<&mut u8>(move _6) -> bb1;
|
||||
+ _5 = opaque::<&mut u8>(move _2) -> bb1;
|
||||
- _5 = opaque::<&mut u8>(move _6) -> [return: bb1, unwind continue];
|
||||
+ _5 = opaque::<&mut u8>(move _2) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
StorageLive(_5);
|
||||
- StorageLive(_6);
|
||||
- _6 = move _4;
|
||||
- _5 = opaque::<&mut u8>(move _6) -> bb1;
|
||||
+ _5 = opaque::<&mut u8>(move _2) -> bb1;
|
||||
- _5 = opaque::<&mut u8>(move _6) -> [return: bb1, unwind continue];
|
||||
+ _5 = opaque::<&mut u8>(move _2) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -41,10 +41,10 @@
|
|||
StorageLive(_5);
|
||||
- _5 = _2;
|
||||
- _6 = CheckedAdd(_4, _5);
|
||||
- assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> bb1;
|
||||
- assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> [success: bb1, unwind continue];
|
||||
+ _5 = const 2_i32;
|
||||
+ _6 = CheckedAdd(const 1_i32, const 2_i32);
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> bb1;
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -58,10 +58,10 @@
|
|||
StorageLive(_9);
|
||||
- _9 = _7;
|
||||
- _10 = CheckedAdd(_9, const 1_i32);
|
||||
- assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> bb2;
|
||||
- assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> [success: bb2, unwind continue];
|
||||
+ _9 = const i32::MAX;
|
||||
+ _10 = CheckedAdd(const i32::MAX, const 1_i32);
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2;
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
StorageLive(_3);
|
||||
_3 = const 1_u8;
|
||||
- _4 = CheckedAdd(_2, _3);
|
||||
- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> bb1;
|
||||
- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = CheckedAdd(const u8::MAX, const 1_u8);
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1;
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
StorageLive(_4);
|
||||
_4 = &_1;
|
||||
_3 = &(*_4);
|
||||
_2 = escape::<i32>(move _3) -> bb1;
|
||||
_2 = escape::<i32>(move _3) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -33,7 +33,7 @@
|
|||
StorageDead(_2);
|
||||
_1 = const 1_i32;
|
||||
StorageLive(_5);
|
||||
_5 = some_function() -> bb2;
|
||||
_5 = some_function() -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = _3;
|
||||
_4 = ptr::mut_ptr::<impl *mut u8>::add(move _5, const 1_usize) -> bb1;
|
||||
_4 = ptr::mut_ptr::<impl *mut u8>::add(move _5, const 1_usize) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
+ _4 = const 1_i32;
|
||||
+ _3 = const 2_i32;
|
||||
StorageDead(_4);
|
||||
- _2 = foo(move _3) -> bb1;
|
||||
+ _2 = foo(const 2_i32) -> bb1;
|
||||
- _2 = foo(move _3) -> [return: bb1, unwind continue];
|
||||
+ _2 = foo(const 2_i32) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
|
||||
bb1: {
|
||||
- StorageLive(_5);
|
||||
- _5 = cond() -> bb2;
|
||||
- _5 = cond() -> [return: bb2, unwind continue];
|
||||
+ StorageLive(_4);
|
||||
+ _4 = cond() -> bb2;
|
||||
+ _4 = cond() -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = &(*_1);
|
||||
_2 = core::str::<impl str>::as_bytes(move _3) -> bb1;
|
||||
_2 = core::str::<impl str>::as_bytes(move _3) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue