use rustc_errors::{ErrorGuaranteed, PResult};
use rustc_feature::find_gated_cfg;
use rustc_hir::def_id::LOCAL_CRATE;
+use rustc_interface::interface::CompilerIO;
use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
use rustc_interface::{interface, Queries};
use rustc_lint::LintStore;
let should_stop = print_crate_info(
&***compiler.codegen_backend(),
compiler.session(),
- None,
- compiler.output_dir(),
- compiler.output_file(),
- compiler.temps_dir(),
+ false,
+ compiler.io(),
);
if should_stop == Compilation::Stop {
interface::run_compiler(config, |compiler| {
let sess = compiler.session();
- let should_stop = print_crate_info(
- &***compiler.codegen_backend(),
- sess,
- Some(compiler.input()),
- compiler.output_dir(),
- compiler.output_file(),
- compiler.temps_dir(),
- )
- .and_then(|| {
- list_metadata(sess, &*compiler.codegen_backend().metadata_loader(), compiler.input())
- })
- .and_then(|| try_process_rlink(sess, compiler));
+ let should_stop =
+ print_crate_info(&***compiler.codegen_backend(), sess, true, compiler.io())
+ .and_then(|| {
+ list_metadata(
+ sess,
+ &*compiler.codegen_backend().metadata_loader(),
+ &compiler.io().input,
+ )
+ })
+ .and_then(|| try_process_rlink(sess, compiler));
if should_stop == Compilation::Stop {
return sess.compile_status();
queries.global_ctxt()?.enter(|tcx| {
pretty::print_after_hir_lowering(
tcx,
- compiler.input(),
+ compiler.io(),
&*expanded_crate,
*ppm,
- compiler.output_file().as_deref(),
);
Ok(())
})?;
} else {
let krate = queries.parse()?.steal();
- pretty::print_after_parsing(
- sess,
- compiler.input(),
- &krate,
- *ppm,
- compiler.output_file().as_deref(),
- );
+ pretty::print_after_parsing(sess, compiler.io(), &krate, *ppm);
}
trace!("finished pretty-printing");
return early_exit();
save::process_crate(
tcx,
crate_name,
- compiler.input(),
+ &compiler.io().input,
None,
- DumpHandler::new(compiler.output_dir().as_deref(), crate_name),
+ DumpHandler::new(compiler.io().output_dir.as_deref(), crate_name),
)
});
}
pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation {
if sess.opts.unstable_opts.link_only {
- if let Input::File(file) = compiler.input() {
+ if let Input::File(file) = &compiler.io().input {
// FIXME: #![crate_type] and #![crate_name] support not implemented yet
sess.init_crate_types(collect_crate_types(sess, &[]));
let outputs = compiler.build_output_filenames(sess, &[]);
fn print_crate_info(
codegen_backend: &dyn CodegenBackend,
sess: &Session,
- input: Option<&Input>,
- odir: &Option<PathBuf>,
- ofile: &Option<PathBuf>,
- temps_dir: &Option<PathBuf>,
+ parse_attrs: bool,
+ io: &CompilerIO,
) -> Compilation {
use rustc_session::config::PrintRequest::*;
// NativeStaticLibs and LinkArgs are special - printed during linking
return Compilation::Continue;
}
- let attrs = match input {
- None => None,
- Some(input) => {
- let result = parse_crate_attrs(sess, input);
- match result {
- Ok(attrs) => Some(attrs),
- Err(mut parse_error) => {
- parse_error.emit();
- return Compilation::Stop;
- }
+ let attrs = if parse_attrs {
+ let result = parse_crate_attrs(sess, &io.input);
+ match result {
+ Ok(attrs) => Some(attrs),
+ Err(mut parse_error) => {
+ parse_error.emit();
+ return Compilation::Stop;
}
}
+ } else {
+ None
};
for req in &sess.opts.prints {
match *req {
println!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
}
FileNames | CrateName => {
- let input = input.unwrap_or_else(|| {
- early_error(ErrorOutputType::default(), "no input file provided")
- });
let attrs = attrs.as_ref().unwrap();
- let t_outputs = rustc_interface::util::build_output_filenames(
- input, odir, ofile, temps_dir, attrs, sess,
- );
- let id = rustc_session::output::find_crate_name(sess, attrs, input);
+ let t_outputs = rustc_interface::util::build_output_filenames(io, attrs, sess);
+ let id = rustc_session::output::find_crate_name(sess, attrs, &io.input);
if *req == PrintRequest::CrateName {
println!("{id}");
continue;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir_pretty as pprust_hir;
+use rustc_interface::interface::CompilerIO;
use rustc_middle::hir::map as hir_map;
use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty};
use rustc_middle::ty::{self, TyCtxt};
use std::cell::Cell;
use std::fmt::Write;
-use std::path::Path;
+use std::path::PathBuf;
pub use self::PpMode::*;
pub use self::PpSourceMode::*;
(src, src_name)
}
-fn write_or_print(out: &str, ofile: Option<&Path>, sess: &Session) {
+fn write_or_print(out: &str, ofile: &Option<PathBuf>, sess: &Session) {
match ofile {
None => print!("{out}"),
Some(p) => {
}
}
-pub fn print_after_parsing(
- sess: &Session,
- input: &Input,
- krate: &ast::Crate,
- ppm: PpMode,
- ofile: Option<&Path>,
-) {
- let (src, src_name) = get_source(input, sess);
+pub fn print_after_parsing(sess: &Session, io: &CompilerIO, krate: &ast::Crate, ppm: PpMode) {
+ let (src, src_name) = get_source(&io.input, sess);
let out = match ppm {
Source(s) => {
_ => unreachable!(),
};
- write_or_print(&out, ofile, sess);
+ write_or_print(&out, &io.output_file, sess);
}
pub fn print_after_hir_lowering<'tcx>(
tcx: TyCtxt<'tcx>,
- input: &Input,
+ io: &CompilerIO,
krate: &ast::Crate,
ppm: PpMode,
- ofile: Option<&Path>,
) {
if ppm.needs_analysis() {
- abort_on_err(print_with_analysis(tcx, ppm, ofile), tcx.sess);
+ abort_on_err(print_with_analysis(tcx, ppm, &io.output_file), tcx.sess);
return;
}
- let (src, src_name) = get_source(input, tcx.sess);
+ let (src, src_name) = get_source(&io.input, tcx.sess);
let out = match ppm {
Source(s) => {
_ => unreachable!(),
};
- write_or_print(&out, ofile, tcx.sess);
+ write_or_print(&out, &io.output_file, tcx.sess);
}
// In an ideal world, this would be a public function called by the driver after
fn print_with_analysis(
tcx: TyCtxt<'_>,
ppm: PpMode,
- ofile: Option<&Path>,
+ ofile: &Option<PathBuf>,
) -> Result<(), ErrorGuaranteed> {
tcx.analysis(())?;
let out = match ppm {
pub struct Compiler {
pub(crate) sess: Lrc<Session>,
codegen_backend: Lrc<Box<dyn CodegenBackend>>,
- pub(crate) input: Input,
- pub(crate) output_dir: Option<PathBuf>,
- pub(crate) output_file: Option<PathBuf>,
- pub(crate) temps_dir: Option<PathBuf>,
+ pub(crate) io: CompilerIO,
pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>,
pub(crate) override_queries:
Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>,
}
+pub struct CompilerIO {
+ pub input: Input,
+ pub output_dir: Option<PathBuf>,
+ pub output_file: Option<PathBuf>,
+ pub temps_dir: Option<PathBuf>,
+}
+
impl Compiler {
pub fn session(&self) -> &Lrc<Session> {
&self.sess
pub fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
&self.codegen_backend
}
- pub fn input(&self) -> &Input {
- &self.input
- }
- pub fn output_dir(&self) -> &Option<PathBuf> {
- &self.output_dir
- }
- pub fn output_file(&self) -> &Option<PathBuf> {
- &self.output_file
- }
- pub fn temps_dir(&self) -> &Option<PathBuf> {
- &self.temps_dir
+ pub fn io(&self) -> &CompilerIO {
+ &self.io
}
pub fn register_lints(&self) -> &Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>> {
&self.register_lints
sess: &Session,
attrs: &[ast::Attribute],
) -> OutputFilenames {
- util::build_output_filenames(
- &self.input,
- &self.output_dir,
- &self.output_file,
- &self.temps_dir,
- attrs,
- sess,
- )
+ util::build_output_filenames(&self.io, attrs, sess)
}
}
let compiler = Compiler {
sess: Lrc::new(sess),
codegen_backend: Lrc::new(codegen_backend),
- input: config.input,
- output_dir: config.output_dir,
- output_file: config.output_file,
- temps_dir,
+ io: CompilerIO {
+ input: config.input,
+ output_dir: config.output_dir,
+ output_file: config.output_file,
+ temps_dir,
+ },
register_lints: config.register_lints,
override_queries: config.override_queries,
};
let _timer = sess.timer("prepare_outputs");
// FIXME: rustdoc passes &[] instead of &krate.attrs here
- let outputs = util::build_output_filenames(
- &compiler.input,
- &compiler.output_dir,
- &compiler.output_file,
- &compiler.temps_dir,
- &krate.attrs,
- sess,
- );
+ let outputs = util::build_output_filenames(&compiler.io, &krate.attrs, sess);
let output_paths =
- generated_output_paths(sess, &outputs, compiler.output_file.is_some(), crate_name);
+ generated_output_paths(sess, &outputs, compiler.io.output_file.is_some(), crate_name);
// Ensure the source file isn't accidentally overwritten during compilation.
- if let Some(ref input_path) = compiler.input.opt_path() {
+ if let Some(ref input_path) = compiler.io.input.opt_path() {
if sess.opts.will_create_output_file() {
if output_contains_path(&output_paths, input_path) {
let reported = sess.emit_err(InputFileWouldBeOverWritten { path: input_path });
}
}
- if let Some(ref dir) = compiler.temps_dir {
+ if let Some(ref dir) = compiler.io.temps_dir {
if fs::create_dir_all(dir).is_err() {
let reported = sess.emit_err(TempsDirError);
return Err(reported);
&& sess.opts.output_types.len() == 1;
if !only_dep_info {
- if let Some(ref dir) = compiler.output_dir {
+ if let Some(ref dir) = compiler.io.output_dir {
if fs::create_dir_all(dir).is_err() {
let reported = sess.emit_err(OutDirError);
return Err(reported);
pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
self.parse.compute(|| {
- passes::parse(self.session(), &self.compiler.input)
+ passes::parse(self.session(), &self.compiler.io.input)
.map_err(|mut parse_error| parse_error.emit())
})
}
let parse_result = self.parse()?;
let krate = parse_result.borrow();
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
- find_crate_name(self.session(), &krate.attrs, &self.compiler.input)
+ find_crate_name(self.session(), &krate.attrs, &self.compiler.io.input)
})
})
}
use rustc_session as session;
use rustc_session::config::CheckCfg;
use rustc_session::config::{self, CrateType};
-use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
+use rustc_session::config::{ErrorOutputType, OutputFilenames};
use rustc_session::filesearch::sysroot_candidates;
use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
use rustc_session::parse::CrateConfig;
use std::sync::OnceLock;
use std::thread;
+use crate::interface::CompilerIO;
+
/// Function pointer type that constructs a new CodegenBackend.
pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;
}
pub fn build_output_filenames(
- input: &Input,
- odir: &Option<PathBuf>,
- ofile: &Option<PathBuf>,
- temps_dir: &Option<PathBuf>,
+ io: &CompilerIO,
attrs: &[ast::Attribute],
sess: &Session,
) -> OutputFilenames {
- match *ofile {
+ match io.output_file {
None => {
// "-" as input file will cause the parser to read from stdin so we
// have to make up a name
// We want to toss everything after the final '.'
- let dirpath = (*odir).as_ref().cloned().unwrap_or_default();
+ let dirpath = io.output_dir.clone().unwrap_or_default();
// If a crate name is present, we use it as the link name
let stem = sess
.crate_name
.clone()
.or_else(|| rustc_attr::find_crate_name(sess, attrs).map(|n| n.to_string()))
- .unwrap_or_else(|| input.filestem().to_owned());
+ .unwrap_or_else(|| io.input.filestem().to_owned());
OutputFilenames::new(
dirpath,
stem,
None,
- temps_dir.clone(),
+ io.temps_dir.clone(),
sess.opts.cg.extra_filename.clone(),
sess.opts.output_types.clone(),
)
}
Some(out_file.clone())
};
- if *odir != None {
+ if io.output_dir != None {
sess.warn("ignoring --out-dir flag due to -o flag");
}
out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(),
out_file.file_stem().unwrap_or_default().to_str().unwrap().to_string(),
ofile,
- temps_dir.clone(),
+ io.temps_dir.clone(),
sess.opts.cg.extra_filename.clone(),
sess.opts.output_types.clone(),
)
let mut config = self.miri_config.clone();
// Add filename to `miri` arguments.
- config.args.insert(0, compiler.input().filestem().to_string());
+ config.args.insert(0, compiler.io().input.filestem().to_string());
// Adjust working directory for interpretation.
if let Some(cwd) = env::var_os("MIRI_CWD") {