Auto merge of #118002 - nnethercote:unify-input-no-input, r=bjorn3

Unify "input" and "no input" paths in `run_compiler`

A follow-up to #117649.

r? `@bjorn3`
This commit is contained in:
bors 2023-11-18 16:43:47 +00:00
commit 28345f06d7

View File

@ -293,7 +293,7 @@ fn run_compiler(
>, >,
using_internal_features: Arc<std::sync::atomic::AtomicBool>, using_internal_features: Arc<std::sync::atomic::AtomicBool>,
) -> interface::Result<()> { ) -> interface::Result<()> {
let mut early_error_handler = EarlyErrorHandler::new(ErrorOutputType::default()); let mut default_handler = EarlyErrorHandler::new(ErrorOutputType::default());
// Throw away the first argument, the name of the binary. // Throw away the first argument, the name of the binary.
// In case of at_args being empty, as might be the case by // In case of at_args being empty, as might be the case by
@ -305,14 +305,14 @@ fn run_compiler(
// the compiler with @empty_file as argv[0] and no more arguments. // the compiler with @empty_file as argv[0] and no more arguments.
let at_args = at_args.get(1..).unwrap_or_default(); let at_args = at_args.get(1..).unwrap_or_default();
let args = args::arg_expand_all(&early_error_handler, at_args); let args = args::arg_expand_all(&default_handler, at_args);
let Some(matches) = handle_options(&early_error_handler, &args) else { return Ok(()) }; let Some(matches) = handle_options(&default_handler, &args) else { return Ok(()) };
let sopts = config::build_session_options(&mut early_error_handler, &matches); let sopts = config::build_session_options(&mut default_handler, &matches);
if let Some(ref code) = matches.opt_str("explain") { if let Some(ref code) = matches.opt_str("explain") {
handle_explain(&early_error_handler, diagnostics_registry(), code, sopts.color); handle_explain(&default_handler, diagnostics_registry(), code, sopts.color);
return Ok(()); return Ok(());
} }
@ -338,61 +338,56 @@ fn run_compiler(
expanded_args: args, expanded_args: args,
}; };
match make_input(&early_error_handler, &matches.free) { let has_input = match make_input(&default_handler, &matches.free) {
Err(reported) => return Err(reported), Err(reported) => return Err(reported),
Ok(Some(input)) => { Ok(Some(input)) => {
config.input = input; config.input = input;
true // has input: normal compilation
callbacks.config(&mut config);
} }
Ok(None) => match matches.free.len() { Ok(None) => match matches.free.len() {
0 => { 0 => false, // no input: we will exit early
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 {
describe_lints(compiler.session());
return;
}
let should_stop = print_crate_info(
&handler,
compiler.codegen_backend(),
compiler.session(),
false,
);
if should_stop == Compilation::Stop {
return;
}
handler.early_error("no input filename given")
});
return Ok(());
}
1 => panic!("make_input should have provided valid inputs"), 1 => panic!("make_input should have provided valid inputs"),
_ => early_error_handler.early_error(format!( _ => default_handler.early_error(format!(
"multiple input filenames provided (first two filenames are `{}` and `{}`)", "multiple input filenames provided (first two filenames are `{}` and `{}`)",
matches.free[0], matches.free[1], matches.free[0], matches.free[1],
)), )),
}, },
}; };
early_error_handler.abort_if_errors(); callbacks.config(&mut config);
default_handler.abort_if_errors();
drop(default_handler);
interface::run_compiler(config, |compiler| { interface::run_compiler(config, |compiler| {
let sess = compiler.session(); let sess = compiler.session();
let codegen_backend = compiler.codegen_backend(); let codegen_backend = compiler.codegen_backend();
// This implements `-Whelp`. It should be handled very early, like
// `--help`/`-Zhelp`/`-Chelp`. This is the earliest it can run, because
// it must happen after lints are registered, during session creation.
if sess.opts.describe_lints {
describe_lints(sess);
return sess.compile_status();
}
let handler = EarlyErrorHandler::new(sess.opts.error_format); let handler = EarlyErrorHandler::new(sess.opts.error_format);
let should_stop = print_crate_info(&handler, codegen_backend, sess, true) if print_crate_info(&handler, codegen_backend, sess, has_input) == Compilation::Stop {
.and_then(|| list_metadata(&handler, sess, &*codegen_backend.metadata_loader())) return sess.compile_status();
.and_then(|| try_process_rlink(sess, compiler)); }
if should_stop == Compilation::Stop { if !has_input {
handler.early_error("no input filename given"); // this is fatal
}
if !sess.opts.unstable_opts.ls.is_empty() {
list_metadata(&handler, sess, &*codegen_backend.metadata_loader());
return sess.compile_status();
}
if sess.opts.unstable_opts.link_only {
process_rlink(sess, compiler);
return sess.compile_status(); return sess.compile_status();
} }
@ -431,11 +426,6 @@ fn run_compiler(
return early_exit(); return early_exit();
} }
if sess.opts.describe_lints {
describe_lints(sess);
return early_exit();
}
// Make sure name resolution and macro expansion is run. // Make sure name resolution and macro expansion is run.
queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering(())); queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering(()));
@ -550,15 +540,6 @@ pub enum Compilation {
Continue, Continue,
} }
impl Compilation {
fn and_then<F: FnOnce() -> Compilation>(self, next: F) -> Compilation {
match self {
Compilation::Stop => Compilation::Stop,
Compilation::Continue => next(),
}
}
}
fn handle_explain(handler: &EarlyErrorHandler, registry: Registry, code: &str, color: ColorConfig) { fn handle_explain(handler: &EarlyErrorHandler, registry: Registry, code: &str, color: ColorConfig) {
let upper_cased_code = code.to_ascii_uppercase(); let upper_cased_code = code.to_ascii_uppercase();
let normalised = let normalised =
@ -663,44 +644,34 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
} }
} }
fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation { fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
if sess.opts.unstable_opts.link_only { assert!(sess.opts.unstable_opts.link_only);
if let Input::File(file) = &sess.io.input { if let Input::File(file) = &sess.io.input {
let outputs = compiler.build_output_filenames(sess, &[]); let outputs = compiler.build_output_filenames(sess, &[]);
let rlink_data = fs::read(file).unwrap_or_else(|err| { let rlink_data = fs::read(file).unwrap_or_else(|err| {
sess.emit_fatal(RlinkUnableToRead { err }); sess.emit_fatal(RlinkUnableToRead { err });
}); });
let codegen_results = match CodegenResults::deserialize_rlink(sess, rlink_data) { let codegen_results = match CodegenResults::deserialize_rlink(sess, rlink_data) {
Ok(codegen) => codegen, Ok(codegen) => codegen,
Err(err) => { Err(err) => {
match err { match err {
CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType), CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType),
CodegenErrors::EmptyVersionNumber => { CodegenErrors::EmptyVersionNumber => sess.emit_fatal(RLinkEmptyVersionNumber),
sess.emit_fatal(RLinkEmptyVersionNumber) CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => sess
} .emit_fatal(RLinkEncodingVersionMismatch { version_array, rlink_version }),
CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => { CodegenErrors::RustcVersionMismatch { rustc_version } => {
sess.emit_fatal(RLinkEncodingVersionMismatch { sess.emit_fatal(RLinkRustcVersionMismatch {
version_array, rustc_version,
rlink_version, current_version: sess.cfg_version,
}) })
} }
CodegenErrors::RustcVersionMismatch { rustc_version } => { };
sess.emit_fatal(RLinkRustcVersionMismatch { }
rustc_version, };
current_version: sess.cfg_version, let result = compiler.codegen_backend().link(sess, codegen_results, &outputs);
}) abort_on_err(result, sess);
}
};
}
};
let result = compiler.codegen_backend().link(sess, codegen_results, &outputs);
abort_on_err(result, sess);
} else {
sess.emit_fatal(RlinkNotAFile {})
}
Compilation::Stop
} else { } else {
Compilation::Continue sess.emit_fatal(RlinkNotAFile {})
} }
} }
@ -708,25 +679,25 @@ fn list_metadata(
handler: &EarlyErrorHandler, handler: &EarlyErrorHandler,
sess: &Session, sess: &Session,
metadata_loader: &dyn MetadataLoader, metadata_loader: &dyn MetadataLoader,
) -> Compilation { ) {
let ls_kinds = &sess.opts.unstable_opts.ls; match sess.io.input {
if !ls_kinds.is_empty() { Input::File(ref ifile) => {
match sess.io.input { let path = &(*ifile);
Input::File(ref ifile) => { let mut v = Vec::new();
let path = &(*ifile); locator::list_file_metadata(
let mut v = Vec::new(); &sess.target,
locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v, ls_kinds) path,
.unwrap(); metadata_loader,
safe_println!("{}", String::from_utf8(v).unwrap()); &mut v,
} &sess.opts.unstable_opts.ls,
Input::Str { .. } => { )
handler.early_error("cannot list metadata for stdin"); .unwrap();
} safe_println!("{}", String::from_utf8(v).unwrap());
}
Input::Str { .. } => {
handler.early_error("cannot list metadata for stdin");
} }
return Compilation::Stop;
} }
Compilation::Continue
} }
fn print_crate_info( fn print_crate_info(