Auto merge of #106810 - oli-obk:resolver_reverse_plumbing, r=petrochenkov

Various cleanups around pre-TyCtxt queries and functions

part of #105462

based on https://github.com/rust-lang/rust/pull/106776 (everything starting at [0e2b39f](0e2b39fd1f) is new in this PR)

r? `@petrochenkov`

I think this should be most of the uncontroversial part of #105462.
This commit is contained in:
bors 2023-01-19 05:23:40 +00:00
commit 65d2f2a5f9
22 changed files with 203 additions and 300 deletions

View file

@ -68,7 +68,7 @@ pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa) -> Self {
.working_dir
.to_string_lossy(FileNameDisplayPreference::Remapped)
.into_owned();
let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
let (name, file_info) = match tcx.sess.local_crate_source_file() {
Some(path) => {
let name = path.to_string_lossy().into_owned();
(name, None)

View file

@ -782,10 +782,10 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
codegen_unit_name: &str,
debug_context: &CodegenUnitDebugContext<'ll, 'tcx>,
) -> &'ll DIDescriptor {
let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
Some(ref path) => path.clone(),
None => PathBuf::from(tcx.crate_name(LOCAL_CRATE).as_str()),
};
let mut name_in_debuginfo = tcx
.sess
.local_crate_source_file()
.unwrap_or_else(|| PathBuf::from(tcx.crate_name(LOCAL_CRATE).as_str()));
// To avoid breaking split DWARF, we need to ensure that each codegen unit
// has a unique `DW_AT_name`. This is because there's a remote chance that

View file

@ -219,7 +219,6 @@ fn run_compiler(
crate_cfg: cfg,
crate_check_cfg: check_cfg,
input: Input::File(PathBuf::new()),
input_path: None,
output_file: ofile,
output_dir: odir,
file_loader,
@ -237,9 +236,8 @@ fn run_compiler(
match make_input(config.opts.error_format, &matches.free) {
Err(reported) => return Err(reported),
Ok(Some((input, input_file_path))) => {
Ok(Some(input)) => {
config.input = input;
config.input_path = input_file_path;
callbacks.config(&mut config);
}
@ -261,14 +259,8 @@ fn run_compiler(
describe_lints(compiler.session(), &lint_store, registered_lints);
return;
}
let should_stop = print_crate_info(
&***compiler.codegen_backend(),
compiler.session(),
None,
compiler.output_dir(),
compiler.output_file(),
compiler.temps_dir(),
);
let should_stop =
print_crate_info(&***compiler.codegen_backend(), compiler.session(), false);
if should_stop == Compilation::Stop {
return;
@ -290,18 +282,9 @@ fn run_compiler(
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)
.and_then(|| list_metadata(sess, &*compiler.codegen_backend().metadata_loader()))
.and_then(|| try_process_rlink(sess, compiler));
if should_stop == Compilation::Stop {
return sess.compile_status();
@ -315,24 +298,12 @@ fn run_compiler(
if ppm.needs_ast_map() {
let expanded_crate = queries.expansion()?.borrow().0.clone();
queries.global_ctxt()?.enter(|tcx| {
pretty::print_after_hir_lowering(
tcx,
compiler.input(),
&*expanded_crate,
*ppm,
compiler.output_file().as_deref(),
);
pretty::print_after_hir_lowering(tcx, &*expanded_crate, *ppm);
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, &krate, *ppm);
}
trace!("finished pretty-printing");
return early_exit();
@ -357,21 +328,17 @@ fn run_compiler(
}
}
queries.expansion()?;
queries.global_ctxt()?;
if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
return early_exit();
}
queries.prepare_outputs()?;
if sess.opts.output_types.contains_key(&OutputType::DepInfo)
&& sess.opts.output_types.len() == 1
{
return early_exit();
}
queries.global_ctxt()?;
if sess.opts.unstable_opts.no_analysis {
return early_exit();
}
@ -384,9 +351,9 @@ fn run_compiler(
save::process_crate(
tcx,
crate_name,
compiler.input(),
&sess.io.input,
None,
DumpHandler::new(compiler.output_dir().as_deref(), crate_name),
DumpHandler::new(sess.io.output_dir.as_deref(), crate_name),
)
});
}
@ -439,7 +406,7 @@ fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>)
fn make_input(
error_format: ErrorOutputType,
free_matches: &[String],
) -> Result<Option<(Input, Option<PathBuf>)>, ErrorGuaranteed> {
) -> Result<Option<Input>, ErrorGuaranteed> {
if free_matches.len() == 1 {
let ifile = &free_matches[0];
if ifile == "-" {
@ -461,12 +428,12 @@ fn make_input(
let line = isize::from_str_radix(&line, 10)
.expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
let file_name = FileName::doc_test_source_code(PathBuf::from(path), line);
Ok(Some((Input::Str { name: file_name, input: src }, None)))
Ok(Some(Input::Str { name: file_name, input: src }))
} else {
Ok(Some((Input::Str { name: FileName::anon_source_code(&src), input: src }, None)))
Ok(Some(Input::Str { name: FileName::anon_source_code(&src), input: src }))
}
} else {
Ok(Some((Input::File(PathBuf::from(ifile)), Some(PathBuf::from(ifile)))))
Ok(Some(Input::File(PathBuf::from(ifile))))
}
} else {
Ok(None)
@ -560,7 +527,7 @@ fn show_content_with_pager(content: &str) {
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) = &sess.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, &[]);
@ -601,13 +568,9 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp
}
}
pub fn list_metadata(
sess: &Session,
metadata_loader: &dyn MetadataLoader,
input: &Input,
) -> Compilation {
pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Compilation {
if sess.opts.unstable_opts.ls {
match *input {
match sess.io.input {
Input::File(ref ifile) => {
let path = &(*ifile);
let mut v = Vec::new();
@ -627,10 +590,7 @@ pub fn list_metadata(
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,
) -> Compilation {
use rustc_session::config::PrintRequest::*;
// NativeStaticLibs and LinkArgs are special - printed during linking
@ -639,18 +599,17 @@ fn print_crate_info(
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);
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 {
@ -665,14 +624,9 @@ fn print_crate_info(
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(attrs, sess);
let id = rustc_session::output::find_crate_name(sess, attrs);
if *req == PrintRequest::CrateName {
println!("{id}");
continue;
@ -1108,8 +1062,8 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
Some(matches)
}
fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::AttrVec> {
match input {
fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
match &sess.io.input {
Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess),
Input::Str { name, input } => rustc_parse::parse_crate_attrs_from_source_str(
name.clone(),

View file

@ -9,14 +9,13 @@
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 rustc_session::config::{Input, PpAstTreeMode, PpHirMode, PpMode, PpSourceMode};
use rustc_session::config::{PpAstTreeMode, PpHirMode, PpMode, PpSourceMode};
use rustc_session::Session;
use rustc_span::symbol::Ident;
use rustc_span::FileName;
use std::cell::Cell;
use std::fmt::Write;
use std::path::Path;
pub use self::PpMode::*;
pub use self::PpSourceMode::*;
@ -345,8 +344,8 @@ fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
}
}
fn get_source(input: &Input, sess: &Session) -> (String, FileName) {
let src_name = input.source_name();
fn get_source(sess: &Session) -> (String, FileName) {
let src_name = sess.io.input.source_name();
let src = String::clone(
sess.source_map()
.get_source_file(&src_name)
@ -358,8 +357,8 @@ fn get_source(input: &Input, sess: &Session) -> (String, FileName) {
(src, src_name)
}
fn write_or_print(out: &str, ofile: Option<&Path>, sess: &Session) {
match ofile {
fn write_or_print(out: &str, sess: &Session) {
match &sess.io.output_file {
None => print!("{out}"),
Some(p) => {
if let Err(e) = std::fs::write(p, out) {
@ -372,14 +371,8 @@ fn write_or_print(out: &str, ofile: Option<&Path>, sess: &Session) {
}
}
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, krate: &ast::Crate, ppm: PpMode) {
let (src, src_name) = get_source(sess);
let out = match ppm {
Source(s) => {
@ -407,22 +400,16 @@ pub fn print_after_parsing(
_ => unreachable!(),
};
write_or_print(&out, ofile, sess);
write_or_print(&out, sess);
}
pub fn print_after_hir_lowering<'tcx>(
tcx: TyCtxt<'tcx>,
input: &Input,
krate: &ast::Crate,
ppm: PpMode,
ofile: Option<&Path>,
) {
pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, krate: &ast::Crate, ppm: PpMode) {
if ppm.needs_analysis() {
abort_on_err(print_with_analysis(tcx, ppm, ofile), tcx.sess);
abort_on_err(print_with_analysis(tcx, ppm), tcx.sess);
return;
}
let (src, src_name) = get_source(input, tcx.sess);
let (src, src_name) = get_source(tcx.sess);
let out = match ppm {
Source(s) => {
@ -474,18 +461,14 @@ pub fn print_after_hir_lowering<'tcx>(
_ => unreachable!(),
};
write_or_print(&out, ofile, tcx.sess);
write_or_print(&out, tcx.sess);
}
// In an ideal world, this would be a public function called by the driver after
// analysis is performed. However, we want to call `phase_3_run_analysis_passes`
// with a different callback than the standard driver, so that isn't easy.
// Instead, we call that function ourselves.
fn print_with_analysis(
tcx: TyCtxt<'_>,
ppm: PpMode,
ofile: Option<&Path>,
) -> Result<(), ErrorGuaranteed> {
fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuaranteed> {
tcx.analysis(())?;
let out = match ppm {
Mir => {
@ -518,7 +501,7 @@ fn print_with_analysis(
_ => unreachable!(),
};
write_or_print(&out, ofile, tcx.sess);
write_or_print(&out, tcx.sess);
Ok(())
}

View file

@ -14,10 +14,10 @@
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_query_impl::QueryCtxt;
use rustc_session::config::{self, CheckCfg, ErrorOutputType, Input, OutputFilenames};
use rustc_session::early_error;
use rustc_session::lint;
use rustc_session::parse::{CrateConfig, ParseSess};
use rustc_session::Session;
use rustc_session::{early_error, CompilerIO};
use rustc_span::source_map::{FileLoader, FileName};
use rustc_span::symbol::sym;
use std::path::PathBuf;
@ -35,11 +35,6 @@
pub struct Compiler {
pub(crate) sess: Lrc<Session>,
codegen_backend: Lrc<Box<dyn CodegenBackend>>,
pub(crate) input: Input,
pub(crate) input_path: Option<PathBuf>,
pub(crate) output_dir: Option<PathBuf>,
pub(crate) output_file: Option<PathBuf>,
pub(crate) temps_dir: Option<PathBuf>,
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)>,
@ -52,18 +47,6 @@ pub fn session(&self) -> &Lrc<Session> {
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 register_lints(&self) -> &Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>> {
&self.register_lints
}
@ -72,14 +55,7 @@ pub fn build_output_filenames(
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(attrs, sess)
}
}
@ -244,7 +220,6 @@ pub struct Config {
pub crate_check_cfg: CheckCfg,
pub input: Input,
pub input_path: Option<PathBuf>,
pub output_dir: Option<PathBuf>,
pub output_file: Option<PathBuf>,
pub file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
@ -287,12 +262,19 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
crate::callbacks::setup_callbacks();
let registry = &config.registry;
let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
let (mut sess, codegen_backend) = util::create_session(
config.opts,
config.crate_cfg,
config.crate_check_cfg,
config.file_loader,
config.input_path.clone(),
CompilerIO {
input: config.input,
output_dir: config.output_dir,
output_file: config.output_file,
temps_dir,
},
config.lint_caps,
config.make_codegen_backend,
registry.clone(),
@ -302,16 +284,9 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
parse_sess_created(&mut sess.parse_sess);
}
let temps_dir = sess.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
let compiler = Compiler {
sess: Lrc::new(sess),
codegen_backend: Lrc::new(codegen_backend),
input: config.input,
input_path: config.input_path,
output_dir: config.output_dir,
output_file: config.output_file,
temps_dir,
register_lints: config.register_lints,
override_queries: config.override_queries,
};

View file

@ -13,7 +13,6 @@
use rustc_borrowck as mir_borrowck;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::parallel;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
use rustc_errors::{ErrorGuaranteed, PResult};
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
@ -31,7 +30,7 @@
use rustc_query_impl::{OnDiskCache, Queries as TcxQueries};
use rustc_resolve::{Resolver, ResolverArenas};
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType};
use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn};
use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn, Untracked};
use rustc_session::output::filename_for_input;
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
@ -51,8 +50,8 @@
use std::sync::LazyLock;
use std::{env, fs, iter};
pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
let krate = sess.time("parse_crate", || match input {
pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
let krate = sess.time("parse_crate", || match &sess.io.input {
Input::File(file) => parse_crate_from_file(file, &sess.parse_sess),
Input::Str { input, name } => {
parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess)
@ -666,7 +665,6 @@ fn write_out_deps(
pub fn prepare_outputs(
sess: &Session,
compiler: &Compiler,
krate: &ast::Crate,
boxed_resolver: &RefCell<BoxedResolver>,
crate_name: Symbol,
@ -674,20 +672,13 @@ pub fn prepare_outputs(
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(&krate.attrs, sess);
let output_paths =
generated_output_paths(sess, &outputs, compiler.output_file.is_some(), crate_name);
generated_output_paths(sess, &outputs, sess.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_path {
if let Some(ref input_path) = sess.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 });
@ -701,7 +692,7 @@ pub fn prepare_outputs(
}
}
if let Some(ref dir) = compiler.temps_dir {
if let Some(ref dir) = sess.io.temps_dir {
if fs::create_dir_all(dir).is_err() {
let reported = sess.emit_err(TempsDirError);
return Err(reported);
@ -714,7 +705,7 @@ pub fn prepare_outputs(
&& sess.opts.output_types.len() == 1;
if !only_dep_info {
if let Some(ref dir) = compiler.output_dir {
if let Some(ref dir) = sess.io.output_dir {
if fs::create_dir_all(dir).is_err() {
let reported = sess.emit_err(OutDirError);
return Err(reported);
@ -775,11 +766,8 @@ pub fn enter<F, R>(&mut self, f: F) -> R
pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler,
lint_store: Lrc<LintStore>,
krate: Lrc<ast::Crate>,
dep_graph: DepGraph,
resolver: Rc<RefCell<BoxedResolver>>,
outputs: OutputFilenames,
crate_name: Symbol,
untracked: Untracked,
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
@ -790,8 +778,6 @@ pub fn create_global_ctxt<'tcx>(
// incr. comp. yet.
dep_graph.assert_ignored();
let resolver_outputs = BoxedResolver::to_resolver_outputs(resolver);
let sess = &compiler.session();
let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
@ -810,12 +796,6 @@ pub fn create_global_ctxt<'tcx>(
TcxQueries::new(local_providers, extern_providers, query_result_on_disk_cache)
});
let ty::ResolverOutputs {
global_ctxt: untracked_resolutions,
ast_lowering: untracked_resolver_for_lowering,
untracked,
} = resolver_outputs;
let gcx = sess.time("setup_global_ctxt", || {
global_ctxt.get_or_init(move || {
TyCtxt::create_global_ctxt(
@ -832,19 +812,7 @@ pub fn create_global_ctxt<'tcx>(
})
});
let mut qcx = QueryContext { gcx };
qcx.enter(|tcx| {
let feed = tcx.feed_unit_query();
feed.resolver_for_lowering(
tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))),
);
feed.resolutions(tcx.arena.alloc(untracked_resolutions));
feed.output_filenames(tcx.arena.alloc(std::sync::Arc::new(outputs)));
feed.features_query(sess.features_untracked());
let feed = tcx.feed_local_crate();
feed.crate_name(crate_name);
});
qcx
QueryContext { gcx }
}
/// Runs the resolution, type-checking, region checking and other

View file

@ -13,7 +13,7 @@
use rustc_lint::LintStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::{GlobalCtxt, TyCtxt};
use rustc_middle::ty::{self, GlobalCtxt, TyCtxt};
use rustc_query_impl::Queries as TcxQueries;
use rustc_session::config::{self, OutputFilenames, OutputType};
use rustc_session::{output::find_crate_name, Session};
@ -90,7 +90,6 @@ pub struct Queries<'tcx> {
register_plugins: Query<(ast::Crate, Lrc<LintStore>)>,
expansion: Query<(Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>,
dep_graph: Query<DepGraph>,
prepare_outputs: Query<OutputFilenames>,
global_ctxt: Query<QueryContext<'tcx>>,
ongoing_codegen: Query<Box<dyn Any>>,
}
@ -109,7 +108,6 @@ pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> {
register_plugins: Default::default(),
expansion: Default::default(),
dep_graph: Default::default(),
prepare_outputs: Default::default(),
global_ctxt: Default::default(),
ongoing_codegen: Default::default(),
}
@ -130,10 +128,8 @@ fn dep_graph_future(&self) -> Result<QueryResult<'_, Option<DepGraphFuture>>> {
}
pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
self.parse.compute(|| {
passes::parse(self.session(), &self.compiler.input)
.map_err(|mut parse_error| parse_error.emit())
})
self.parse
.compute(|| passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit()))
}
pub fn register_plugins(&self) -> Result<QueryResult<'_, (ast::Crate, Lrc<LintStore>)>> {
@ -161,13 +157,13 @@ pub fn register_plugins(&self) -> Result<QueryResult<'_, (ast::Crate, Lrc<LintSt
})
}
pub fn crate_name(&self) -> Result<QueryResult<'_, Symbol>> {
fn crate_name(&self) -> Result<QueryResult<'_, Symbol>> {
self.crate_name.compute(|| {
Ok({
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)
})
})
}
@ -211,40 +207,42 @@ fn dep_graph(&self) -> Result<QueryResult<'_, DepGraph>> {
})
}
pub fn prepare_outputs(&self) -> Result<QueryResult<'_, OutputFilenames>> {
self.prepare_outputs.compute(|| {
let expansion = self.expansion()?;
let (krate, boxed_resolver, _) = &*expansion.borrow();
let crate_name = *self.crate_name()?.borrow();
passes::prepare_outputs(
self.session(),
self.compiler,
krate,
&*boxed_resolver,
crate_name,
)
})
}
pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, QueryContext<'tcx>>> {
self.global_ctxt.compute(|| {
let crate_name = *self.crate_name()?.borrow();
let outputs = self.prepare_outputs()?.steal();
let dep_graph = self.dep_graph()?.borrow().clone();
let (krate, resolver, lint_store) = self.expansion()?.steal();
Ok(passes::create_global_ctxt(
let outputs = passes::prepare_outputs(self.session(), &krate, &resolver, crate_name)?;
let ty::ResolverOutputs {
untracked,
global_ctxt: untracked_resolutions,
ast_lowering: untracked_resolver_for_lowering,
} = BoxedResolver::to_resolver_outputs(resolver);
let mut qcx = passes::create_global_ctxt(
self.compiler,
lint_store,
krate,
dep_graph,
resolver,
outputs,
crate_name,
self.dep_graph()?.steal(),
untracked,
&self.queries,
&self.gcx,
&self.arena,
&self.hir_arena,
))
);
qcx.enter(|tcx| {
let feed = tcx.feed_unit_query();
feed.resolver_for_lowering(
tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))),
);
feed.resolutions(tcx.arena.alloc(untracked_resolutions));
feed.output_filenames(tcx.arena.alloc(std::sync::Arc::new(outputs)));
feed.features_query(tcx.sess.features_untracked());
let feed = tcx.feed_local_crate();
feed.crate_name(crate_name);
});
Ok(qcx)
})
}

View file

@ -4,6 +4,7 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
use rustc_session::config::rustc_optgroups;
use rustc_session::config::Input;
use rustc_session::config::TraitSolver;
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
use rustc_session::config::{
@ -17,9 +18,11 @@
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_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym;
use rustc_span::FileName;
use rustc_span::SourceFileHashAlgorithm;
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
@ -39,7 +42,14 @@ fn build_session_options_and_crate_config(matches: getopts::Matches) -> (Options
fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
let registry = registry::Registry::new(&[]);
let (sessopts, cfg) = build_session_options_and_crate_config(matches);
let sess = build_session(sessopts, None, None, registry, Default::default(), None, None);
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() },
output_dir: None,
output_file: None,
temps_dir,
};
let sess = build_session(sessopts, io, None, registry, Default::default(), None, None);
(sess, cfg)
}

View file

@ -8,7 +8,7 @@
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;
@ -17,6 +17,7 @@
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::source_map::FileLoader;
use rustc_span::symbol::{sym, Symbol};
use session::CompilerIO;
use std::env;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::mem;
@ -58,7 +59,7 @@ pub fn create_session(
cfg: FxHashSet<(String, Option<String>)>,
check_cfg: CheckCfg,
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
input_path: Option<PathBuf>,
io: CompilerIO,
lint_caps: FxHashMap<lint::LintId, lint::Level>,
make_codegen_backend: Option<
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
@ -89,7 +90,7 @@ pub fn create_session(
let mut sess = session::build_session(
sopts,
input_path,
io,
bundle,
descriptions,
lint_caps,
@ -486,20 +487,13 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
base
}
pub fn build_output_filenames(
input: &Input,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>,
temps_dir: &Option<PathBuf>,
attrs: &[ast::Attribute],
sess: &Session,
) -> OutputFilenames {
match *ofile {
pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> OutputFilenames {
match sess.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 = sess.io.output_dir.clone().unwrap_or_default();
// If a crate name is present, we use it as the link name
let stem = sess
@ -507,13 +501,13 @@ pub fn build_output_filenames(
.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(|| sess.io.input.filestem().to_owned());
OutputFilenames::new(
dirpath,
stem,
None,
temps_dir.clone(),
sess.io.temps_dir.clone(),
sess.opts.cg.extra_filename.clone(),
sess.opts.output_types.clone(),
)
@ -534,7 +528,7 @@ pub fn build_output_filenames(
}
Some(out_file.clone())
};
if *odir != None {
if sess.io.output_dir != None {
sess.warn("ignoring --out-dir flag due to -o flag");
}
@ -542,7 +536,7 @@ pub fn build_output_filenames(
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(),
sess.io.temps_dir.clone(),
sess.opts.cg.extra_filename.clone(),
sess.opts.output_types.clone(),
)

View file

@ -195,7 +195,7 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) {
// There is no main function.
let mut has_filename = true;
let filename = tcx.sess.local_crate_source_file.clone().unwrap_or_else(|| {
let filename = tcx.sess.local_crate_source_file().unwrap_or_else(|| {
has_filename = false;
Default::default()
});

View file

@ -112,9 +112,7 @@ fn lookup_def_id(&self, ref_id: hir::HirId) -> Option<DefId> {
}
pub fn dump_crate_info(&mut self, name: Symbol) {
let source_file = self.tcx.sess.local_crate_source_file.as_ref();
let crate_root = source_file.map(|source_file| {
let source_file = Path::new(source_file);
let crate_root = self.tcx.sess.local_crate_source_file().map(|source_file| {
match source_file.file_name() {
Some(_) => source_file.parent().unwrap().display(),
None => source_file.display(),
@ -157,10 +155,14 @@ pub fn dump_compilation_options(&mut self, input: &Input, crate_name: Symbol) {
.enumerate()
.filter(|(i, _)| !remap_arg_indices.contains(i))
.map(|(_, arg)| match input {
Input::File(ref path) if path == Path::new(&arg) => {
let mapped = &self.tcx.sess.local_crate_source_file;
mapped.as_ref().unwrap().to_string_lossy().into()
}
Input::File(ref path) if path == Path::new(&arg) => self
.tcx
.sess
.local_crate_source_file()
.as_ref()
.unwrap()
.to_string_lossy()
.into(),
_ => arg,
});

View file

@ -18,13 +18,7 @@ pub fn make_filename_string(&self, file: &SourceFile) -> String {
match &file.name {
FileName::Real(RealFileName::LocalPath(path)) => {
if path.is_absolute() {
self.sess
.source_map()
.path_mapping()
.map_prefix(path.into())
.0
.display()
.to_string()
self.sess.source_map().path_mapping().map_prefix(path).0.display().to_string()
} else {
self.sess
.opts

View file

@ -591,6 +591,24 @@ pub fn source_name(&self) -> FileName {
Input::Str { ref name, .. } => name.clone(),
}
}
pub fn opt_path(&self) -> Option<&Path> {
match self {
Input::File(file) => Some(file),
Input::Str { name, .. } => match name {
FileName::Real(real) => real.local_path(),
FileName::QuoteExpansion(_) => None,
FileName::Anon(_) => None,
FileName::MacroExpansion(_) => None,
FileName::ProcMacroSourceCode(_) => None,
FileName::CfgSpec(_) => None,
FileName::CliCrateAttr(_) => None,
FileName::Custom(_) => None,
FileName::DocTest(path, _) => Some(path),
FileName::InlineAsm(_) => None,
},
}
}
}
#[derive(Clone, Hash, Debug, HashStable_Generic)]
@ -2496,12 +2514,12 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
early_error(error_format, &format!("Current directory is invalid: {e}"));
});
let (path, remapped) =
FilePathMapping::new(remap_path_prefix.clone()).map_prefix(working_dir.clone());
let remap = FilePathMapping::new(remap_path_prefix.clone());
let (path, remapped) = remap.map_prefix(&working_dir);
let working_dir = if remapped {
RealFileName::Remapped { local_path: Some(working_dir), virtual_name: path }
RealFileName::Remapped { virtual_name: path.into_owned(), local_path: Some(working_dir) }
} else {
RealFileName::LocalPath(path)
RealFileName::LocalPath(path.into_owned())
};
Options {

View file

@ -45,7 +45,7 @@ fn is_writeable(p: &Path) -> bool {
}
}
pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) -> Symbol {
pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol {
let validate = |s: Symbol, span: Option<Span>| {
validate_crate_name(sess, s, span);
s
@ -71,7 +71,7 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input)
if let Some((attr, s)) = attr_crate_name {
return validate(s, Some(attr.span));
}
if let Input::File(ref path) = *input {
if let Input::File(ref path) = sess.io.input {
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
if s.starts_with('-') {
sess.emit_err(CrateNameInvalid { s });

View file

@ -1,6 +1,7 @@
use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
use crate::config::Input;
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
use crate::errors::{
BranchProtectionRequiresAArch64, CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers,
@ -137,6 +138,13 @@ pub struct Limits {
pub const_eval_limit: Limit,
}
pub struct CompilerIO {
pub input: Input,
pub output_dir: Option<PathBuf>,
pub output_file: Option<PathBuf>,
pub temps_dir: Option<PathBuf>,
}
/// Represents the data associated with a compilation
/// session for a single crate.
pub struct Session {
@ -147,9 +155,8 @@ pub struct Session {
pub target_tlib_path: Lrc<SearchPath>,
pub parse_sess: ParseSess,
pub sysroot: PathBuf,
/// The name of the root source file of the crate, in the local file system.
/// `None` means that there is no source file.
pub local_crate_source_file: Option<PathBuf>,
/// Input, input file path and output file path to this compilation process.
pub io: CompilerIO,
crate_types: OnceCell<Vec<CrateType>>,
/// The `stable_crate_id` is constructed out of the crate name and all the
@ -228,6 +235,11 @@ pub fn miri_unleashed_feature(&self, span: Span, feature_gate: Option<Symbol>) {
self.miri_unleashed_features.lock().push((span, feature_gate));
}
pub fn local_crate_source_file(&self) -> Option<PathBuf> {
let path = self.io.input.opt_path()?;
Some(self.opts.file_path_mapping().map_prefix(path).0.into_owned())
}
fn check_miri_unleashed_features(&self) {
let unleashed_features = self.miri_unleashed_features.lock();
if !unleashed_features.is_empty() {
@ -1298,7 +1310,7 @@ fn default_emitter(
#[allow(rustc::bad_opt_access)]
pub fn build_session(
sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
io: CompilerIO,
bundle: Option<Lrc<rustc_errors::FluentBundle>>,
registry: rustc_errors::registry::Registry,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
@ -1391,11 +1403,6 @@ pub fn build_session(
Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
};
let file_path_mapping = sopts.file_path_mapping();
let local_crate_source_file =
local_crate_source_file.map(|path| file_path_mapping.map_prefix(path).0);
let optimization_fuel = Lock::new(OptimizationFuel {
remaining: sopts.unstable_opts.fuel.as_ref().map_or(0, |&(_, i)| i),
out_of_fuel: false,
@ -1427,7 +1434,7 @@ pub fn build_session(
target_tlib_path,
parse_sess,
sysroot,
local_crate_source_file,
io,
crate_types: OnceCell::new(),
stable_crate_id: OnceCell::new(),
features: OnceCell::new(),

View file

@ -1150,7 +1150,8 @@ pub fn new(mapping: Vec<(PathBuf, PathBuf)>) -> FilePathMapping {
/// Applies any path prefix substitution as defined by the mapping.
/// The return value is the remapped path and a boolean indicating whether
/// the path was affected by the mapping.
pub fn map_prefix(&self, path: PathBuf) -> (PathBuf, bool) {
pub fn map_prefix<'a>(&'a self, path: impl Into<Cow<'a, Path>>) -> (Cow<'a, Path>, bool) {
let path = path.into();
if path.as_os_str().is_empty() {
// Exit early if the path is empty and therefore there's nothing to remap.
// This is mostly to reduce spam for `RUSTC_LOG=[remap_path_prefix]`.
@ -1160,7 +1161,10 @@ pub fn map_prefix(&self, path: PathBuf) -> (PathBuf, bool) {
return remap_path_prefix(&self.mapping, path);
#[instrument(level = "debug", skip(mapping), ret)]
fn remap_path_prefix(mapping: &[(PathBuf, PathBuf)], path: PathBuf) -> (PathBuf, bool) {
fn remap_path_prefix<'a>(
mapping: &'a [(PathBuf, PathBuf)],
path: Cow<'a, Path>,
) -> (Cow<'a, Path>, bool) {
// NOTE: We are iterating over the mapping entries from last to first
// because entries specified later on the command line should
// take precedence.
@ -1175,9 +1179,9 @@ fn remap_path_prefix(mapping: &[(PathBuf, PathBuf)], path: PathBuf) -> (PathBuf,
// in remapped paths down the line.
// So, if we have an exact match, we just return that without a call
// to `Path::join()`.
to.clone()
to.into()
} else {
to.join(rest)
to.join(rest).into()
};
debug!("Match - remapped");
@ -1195,11 +1199,11 @@ fn remap_path_prefix(mapping: &[(PathBuf, PathBuf)], path: PathBuf) -> (PathBuf,
fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) {
match file {
FileName::Real(realfile) if let RealFileName::LocalPath(local_path) = realfile => {
let (mapped_path, mapped) = self.map_prefix(local_path.to_path_buf());
let (mapped_path, mapped) = self.map_prefix(local_path);
let realfile = if mapped {
RealFileName::Remapped {
local_path: Some(local_path.clone()),
virtual_name: mapped_path,
virtual_name: mapped_path.into_owned(),
}
} else {
realfile.clone()
@ -1240,14 +1244,17 @@ pub fn to_embeddable_absolute_path(
let (new_path, was_remapped) = self.map_prefix(unmapped_file_path);
if was_remapped {
// It was remapped, so don't modify further
return RealFileName::Remapped { local_path: None, virtual_name: new_path };
return RealFileName::Remapped {
local_path: None,
virtual_name: new_path.into_owned(),
};
}
if new_path.is_absolute() {
// No remapping has applied to this path and it is absolute,
// so the working directory cannot influence it either, so
// we are done.
return RealFileName::LocalPath(new_path);
return RealFileName::LocalPath(new_path.into_owned());
}
debug_assert!(new_path.is_relative());
@ -1265,12 +1272,12 @@ pub fn to_embeddable_absolute_path(
RealFileName::Remapped {
// Erase the actual path
local_path: None,
virtual_name: file_path_abs,
virtual_name: file_path_abs.into_owned(),
}
} else {
// No kind of remapping applied to this path, so
// we leave it as it is.
RealFileName::LocalPath(file_path_abs)
RealFileName::LocalPath(file_path_abs.into_owned())
}
}
RealFileName::Remapped {

View file

@ -391,7 +391,7 @@ fn path_prefix_remapping_expand_to_absolute() {
let working_directory = path("/foo");
let working_directory = RealFileName::Remapped {
local_path: Some(working_directory.clone()),
virtual_name: mapping.map_prefix(working_directory).0,
virtual_name: mapping.map_prefix(working_directory).0.into_owned(),
};
assert_eq!(working_directory.remapped_path_if_available(), path("FOO"));

View file

@ -225,7 +225,6 @@ pub(crate) fn create_config(
// Add the doc cfg into the doc build.
cfgs.push("doc".to_string());
let cpath = Some(input.clone());
let input = Input::File(input);
// By default, rustdoc ignores all lints.
@ -277,7 +276,6 @@ pub(crate) fn create_config(
crate_cfg: interface::parse_cfgspecs(cfgs),
crate_check_cfg: interface::parse_check_cfg(check_cfgs),
input,
input_path: cpath,
output_file: None,
output_dir: None,
file_loader: None,

View file

@ -95,7 +95,6 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
crate_cfg: interface::parse_cfgspecs(cfgs),
crate_check_cfg: interface::parse_check_cfg(options.check_cfgs.clone()),
input,
input_path: None,
output_file: None,
output_dir: None,
file_loader: None,

View file

@ -2921,7 +2921,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
// Look for the example file in the source map if it exists, otherwise return a dummy span
let file_span = (|| {
let source_map = tcx.sess.source_map();
let crate_src = tcx.sess.local_crate_source_file.as_ref()?;
let crate_src = tcx.sess.local_crate_source_file()?;
let abs_crate_src = crate_src.canonicalize().ok()?;
let crate_root = abs_crate_src.parent()?.parent()?;
let rel_path = path.strip_prefix(crate_root).ok()?;

View file

@ -56,12 +56,12 @@ fn config(&mut self, config: &mut Config) {
fn after_analysis<'tcx>(
&mut self,
compiler: &rustc_interface::interface::Compiler,
_: &rustc_interface::interface::Compiler,
queries: &'tcx rustc_interface::Queries<'tcx>,
) -> Compilation {
compiler.session().abort_if_errors();
queries.global_ctxt().unwrap().enter(|tcx| {
tcx.sess.abort_if_errors();
init_late_loggers(tcx);
if !tcx.sess.crate_types().contains(&CrateType::Executable) {
tcx.sess.fatal("miri only makes sense on bin crates");
@ -75,7 +75,7 @@ fn after_analysis<'tcx>(
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, tcx.sess.io.input.filestem().to_string());
// Adjust working directory for interpretation.
if let Some(cwd) = env::var_os("MIRI_CWD") {
@ -87,10 +87,9 @@ fn after_analysis<'tcx>(
i32::try_from(return_code).expect("Return value was too large!"),
);
}
tcx.sess.abort_if_errors();
});
compiler.session().abort_if_errors();
Compilation::Stop
}
}

View file

@ -1,12 +1,12 @@
#![feature(rustc_private)]
extern crate rustc_interface;
extern crate rustc_driver;
extern crate rustc_interface;
extern crate rustc_session;
extern crate rustc_span;
use rustc_session::config::{Input, Options, OutputType, OutputTypes};
use rustc_interface::interface;
use rustc_session::config::{Input, Options, OutputType, OutputTypes};
use rustc_span::source_map::FileName;
use std::path::PathBuf;
@ -50,7 +50,6 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
crate_cfg: Default::default(),
crate_check_cfg: Default::default(),
input,
input_path: None,
output_file: Some(output),
output_dir: None,
file_loader: None,
@ -64,9 +63,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
interface::run_compiler(config, |compiler| {
// This runs all the passes prior to linking, too.
let linker = compiler.enter(|queries| {
queries.linker()
});
let linker = compiler.enter(|queries| queries.linker());
if let Ok(linker) = linker {
linker.link();
}