Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove queries from the driver interface #134302

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 47 additions & 54 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use rustc_errors::registry::Registry;
use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, FatalError, PResult, markdown};
use rustc_feature::find_gated_cfg;
use rustc_interface::util::{self, get_codegen_backend};
use rustc_interface::{Linker, interface, passes};
use rustc_interface::{Linker, create_and_enter_global_ctxt, interface, passes};
use rustc_lint::unerased_lint_store;
use rustc_metadata::creader::MetadataLoader;
use rustc_metadata::locator;
Expand Down Expand Up @@ -387,76 +387,69 @@ fn run_compiler(
return early_exit();
}

let linker = compiler.enter(|queries| {
// Parse the crate root source code (doesn't parse submodules yet)
// Everything else is parsed during macro expansion.
let krate = passes::parse(sess);

// If pretty printing is requested: Figure out the representation, print it and exit
if let Some(pp_mode) = sess.opts.pretty {
if pp_mode.needs_ast_map() {
create_and_enter_global_ctxt(compiler, krate, |tcx| {
tcx.ensure().early_lint_checks(());
pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx });
passes::write_dep_info(tcx);
});
} else {
pretty::print(sess, pp_mode, pretty::PrintExtra::AfterParsing { krate: &krate });
}
trace!("finished pretty-printing");
return early_exit();
}

if callbacks.after_crate_root_parsing(compiler, &krate) == Compilation::Stop {
return early_exit();
}

if sess.opts.unstable_opts.parse_crate_root_only {
return early_exit();
}

let linker = create_and_enter_global_ctxt(compiler, krate, |tcx| {
let early_exit = || {
sess.dcx().abort_if_errors();
None
};

// Parse the crate root source code (doesn't parse submodules yet)
// Everything else is parsed during macro expansion.
queries.parse();

// If pretty printing is requested: Figure out the representation, print it and exit
if let Some(pp_mode) = sess.opts.pretty {
if pp_mode.needs_ast_map() {
queries.global_ctxt().enter(|tcx| {
tcx.ensure().early_lint_checks(());
pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx });
passes::write_dep_info(tcx);
});
} else {
let krate = queries.parse();
pretty::print(sess, pp_mode, pretty::PrintExtra::AfterParsing {
krate: &*krate.borrow(),
});
}
trace!("finished pretty-printing");
// Make sure name resolution and macro expansion is run.
let _ = tcx.resolver_for_lowering();

if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
dump_feature_usage_metrics(tcx, metrics_dir);
}

if callbacks.after_expansion(compiler, tcx) == Compilation::Stop {
return early_exit();
}

if callbacks.after_crate_root_parsing(compiler, &*queries.parse().borrow())
== Compilation::Stop
passes::write_dep_info(tcx);

if sess.opts.output_types.contains_key(&OutputType::DepInfo)
&& sess.opts.output_types.len() == 1
{
return early_exit();
}

if sess.opts.unstable_opts.parse_crate_root_only {
if sess.opts.unstable_opts.no_analysis {
return early_exit();
}

queries.global_ctxt().enter(|tcx| {
// Make sure name resolution and macro expansion is run.
let _ = tcx.resolver_for_lowering();

if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
dump_feature_usage_metrics(tcx, metrics_dir);
}

if callbacks.after_expansion(compiler, tcx) == Compilation::Stop {
return early_exit();
}

passes::write_dep_info(tcx);

if sess.opts.output_types.contains_key(&OutputType::DepInfo)
&& sess.opts.output_types.len() == 1
{
return early_exit();
}

if sess.opts.unstable_opts.no_analysis {
return early_exit();
}
tcx.ensure().analysis(());

tcx.ensure().analysis(());

if callbacks.after_analysis(compiler, tcx) == Compilation::Stop {
return early_exit();
}
if callbacks.after_analysis(compiler, tcx) == Compilation::Stop {
return early_exit();
}

Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend))
})
Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend))
});

// Linking is done outside the `compiler.enter()` so that the
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// tidy-alphabetical-end

mod callbacks;
mod errors;
pub mod errors;
pub mod interface;
pub mod passes;
mod proc_macro_decls;
Expand All @@ -17,8 +17,8 @@ pub mod util;

pub use callbacks::setup_callbacks;
pub use interface::{Config, run_compiler};
pub use passes::DEFAULT_QUERY_PROVIDERS;
pub use queries::{Linker, Queries};
pub use passes::{DEFAULT_QUERY_PROVIDERS, create_and_enter_global_ctxt, parse};
pub use queries::Linker;

#[cfg(test)]
mod tests;
Expand Down
106 changes: 62 additions & 44 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use tracing::{info, instrument};
use crate::interface::Compiler;
use crate::{errors, proc_macro_decls, util};

pub(crate) fn parse<'a>(sess: &'a Session) -> ast::Crate {
pub fn parse<'a>(sess: &'a Session) -> ast::Crate {
let krate = sess
.time("parse_crate", || {
let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
Expand Down Expand Up @@ -709,13 +709,11 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
*providers
});

pub(crate) fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler,
pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
compiler: &Compiler,
mut krate: rustc_ast::Crate,
gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
) -> &'tcx GlobalCtxt<'tcx> {
f: F,
) -> T {
let sess = &compiler.sess;

rustc_builtin_macros::cmdline_attrs::inject(
Expand Down Expand Up @@ -763,44 +761,64 @@ pub(crate) fn create_global_ctxt<'tcx>(

let incremental = dep_graph.is_fully_enabled();

sess.time("setup_global_ctxt", || {
let qcx = gcx_cell.get_or_init(move || {
TyCtxt::create_global_ctxt(
sess,
crate_types,
stable_crate_id,
arena,
hir_arena,
untracked,
dep_graph,
rustc_query_impl::query_callbacks(arena),
rustc_query_impl::query_system(
providers.queries,
providers.extern_queries,
query_result_on_disk_cache,
incremental,
),
providers.hooks,
compiler.current_gcx.clone(),
)
});

qcx.enter(|tcx| {
let feed = tcx.create_crate_num(stable_crate_id).unwrap();
assert_eq!(feed.key(), LOCAL_CRATE);
feed.crate_name(crate_name);
let gcx_cell = OnceLock::new();
let arena = WorkerLocal::new(|_| Arena::default());
let hir_arena = WorkerLocal::new(|_| rustc_hir::Arena::default());

// This closure is necessary to force rustc to perform the correct lifetime
// subtyping for GlobalCtxt::enter to be allowed.
let inner: Box<
dyn for<'tcx> FnOnce(
&'tcx Compiler,
&'tcx OnceLock<GlobalCtxt<'tcx>>,
&'tcx WorkerLocal<Arena<'tcx>>,
&'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
F,
) -> T,
> = Box::new(move |compiler, gcx_cell, arena, hir_arena, f| {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ugly, but the only way I could figure out to get all invariant lifetimes correctly inferred by rustc.

let sess = &compiler.sess;

TyCtxt::create_global_ctxt(
gcx_cell,
sess,
crate_types,
stable_crate_id,
arena,
hir_arena,
untracked,
dep_graph,
rustc_query_impl::query_callbacks(arena),
rustc_query_impl::query_system(
providers.queries,
providers.extern_queries,
query_result_on_disk_cache,
incremental,
),
providers.hooks,
compiler.current_gcx.clone(),
|tcx| {
let feed = tcx.create_crate_num(stable_crate_id).unwrap();
assert_eq!(feed.key(), LOCAL_CRATE);
feed.crate_name(crate_name);

let feed = tcx.feed_unit_query();
feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
sess,
&pre_configured_attrs,
crate_name,
)));
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
feed.output_filenames(Arc::new(outputs));

let res = f(tcx);
// FIXME maybe run finish even when a fatal error occured? or at least tcx.alloc_self_profile_query_strings()?
tcx.finish();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixme is a pre-existing issue.

res
},
)
});

let feed = tcx.feed_unit_query();
feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
sess,
&pre_configured_attrs,
crate_name,
)));
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
feed.output_filenames(Arc::new(outputs));
});
qcx
})
inner(compiler, &gcx_cell, &arena, &hir_arena, f)
}

/// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses.
Expand Down
Loading
Loading