Skip to content

Commit e6f450b

Browse files
committed
Auto merge of #86489 - cjgillot:lower, r=petrochenkov
Simplify early compilation interface * separate resolver creation and AST configuration. * bundle lowering with global_ctxt creation.
2 parents 868c702 + f698774 commit e6f450b

File tree

7 files changed

+101
-168
lines changed

7 files changed

+101
-168
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ pub fn lower_crate<'a, 'hir>(
296296
resolver: &'a mut dyn ResolverAstLowering,
297297
nt_to_tokenstream: NtToTokenstream,
298298
arena: &'hir Arena<'hir>,
299-
) -> hir::Crate<'hir> {
299+
) -> &'hir hir::Crate<'hir> {
300300
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
301301

302302
LoweringContext {
@@ -403,7 +403,7 @@ enum AnonymousLifetimeMode {
403403
}
404404

405405
impl<'a, 'hir> LoweringContext<'a, 'hir> {
406-
fn lower_crate(mut self, c: &Crate) -> hir::Crate<'hir> {
406+
fn lower_crate(mut self, c: &Crate) -> &'hir hir::Crate<'hir> {
407407
/// Full-crate AST visitor that inserts into a fresh
408408
/// `LoweringContext` any information that may be
409409
/// needed from arbitrary locations in the crate,
@@ -530,7 +530,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
530530
}
531531
}
532532

533-
hir::Crate {
533+
let krate = hir::Crate {
534534
item: module,
535535
exported_macros: self.arena.alloc_from_iter(self.exported_macros),
536536
non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs),
@@ -545,7 +545,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
545545
proc_macros,
546546
trait_map,
547547
attrs: self.attrs,
548-
}
548+
};
549+
self.arena.alloc(krate)
549550
}
550551

551552
fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId {

compiler/rustc_driver/src/lib.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ use std::ffi::OsString;
4646
use std::fs;
4747
use std::io::{self, Read, Write};
4848
use std::lazy::SyncLazy;
49-
use std::mem;
5049
use std::panic::{self, catch_unwind};
5150
use std::path::PathBuf;
5251
use std::process::{self, Command, Stdio};
@@ -316,12 +315,12 @@ fn run_compiler(
316315

317316
if let Some(ppm) = &sess.opts.pretty {
318317
if ppm.needs_ast_map() {
318+
let expanded_crate = queries.expansion()?.peek().0.clone();
319319
queries.global_ctxt()?.peek_mut().enter(|tcx| {
320-
let expanded_crate = queries.expansion()?.take().0;
321320
pretty::print_after_hir_lowering(
322321
tcx,
323322
compiler.input(),
324-
&expanded_crate,
323+
&*expanded_crate,
325324
*ppm,
326325
compiler.output_file().as_ref().map(|p| &**p),
327326
);
@@ -377,12 +376,6 @@ fn run_compiler(
377376

378377
queries.global_ctxt()?;
379378

380-
// Drop AST after creating GlobalCtxt to free memory
381-
{
382-
let _timer = sess.prof.generic_activity("drop_ast");
383-
mem::drop(queries.expansion()?.take());
384-
}
385-
386379
if sess.opts.debugging_opts.no_analysis || sess.opts.debugging_opts.ast_json {
387380
return early_exit();
388381
}

compiler/rustc_incremental/src/persist/load.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ pub enum LoadResult<T> {
2121
Error { message: String },
2222
}
2323

24-
impl LoadResult<(SerializedDepGraph, WorkProductMap)> {
25-
pub fn open(self, sess: &Session) -> (SerializedDepGraph, WorkProductMap) {
24+
impl<T: Default> LoadResult<T> {
25+
pub fn open(self, sess: &Session) -> T {
2626
match self {
2727
LoadResult::Error { message } => {
2828
sess.warn(&message);
@@ -74,11 +74,14 @@ pub enum MaybeAsync<T> {
7474
Sync(T),
7575
Async(std::thread::JoinHandle<T>),
7676
}
77-
impl<T> MaybeAsync<T> {
78-
pub fn open(self) -> std::thread::Result<T> {
77+
78+
impl<T> MaybeAsync<LoadResult<T>> {
79+
pub fn open(self) -> LoadResult<T> {
7980
match self {
80-
MaybeAsync::Sync(result) => Ok(result),
81-
MaybeAsync::Async(handle) => handle.join(),
81+
MaybeAsync::Sync(result) => result,
82+
MaybeAsync::Async(handle) => handle.join().unwrap_or_else(|e| LoadResult::Error {
83+
message: format!("could not decode incremental cache: {:?}", e),
84+
}),
8285
}
8386
}
8487
}

compiler/rustc_interface/src/passes.rs

+52-73
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use rustc_ast::{self as ast, visit};
77
use rustc_codegen_ssa::back::link::emit_metadata;
88
use rustc_codegen_ssa::traits::CodegenBackend;
99
use rustc_data_structures::parallel;
10-
use rustc_data_structures::steal::Steal;
1110
use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal};
1211
use rustc_data_structures::temp_dir::MaybeTempDir;
1312
use rustc_errors::{ErrorReported, PResult};
@@ -101,7 +100,7 @@ mod boxed_resolver {
101100
}
102101

103102
// Note: Drop order is important to prevent dangling references. Resolver must be dropped first,
104-
// then resolver_arenas and finally session.
103+
// then resolver_arenas and session.
105104
impl Drop for BoxedResolverInner {
106105
fn drop(&mut self) {
107106
self.resolver.take();
@@ -110,13 +109,10 @@ mod boxed_resolver {
110109
}
111110

112111
impl BoxedResolver {
113-
pub(super) fn new<F>(session: Lrc<Session>, make_resolver: F) -> Result<(ast::Crate, Self)>
114-
where
115-
F: for<'a> FnOnce(
116-
&'a Session,
117-
&'a ResolverArenas<'a>,
118-
) -> Result<(ast::Crate, Resolver<'a>)>,
119-
{
112+
pub(super) fn new(
113+
session: Lrc<Session>,
114+
make_resolver: impl for<'a> FnOnce(&'a Session, &'a ResolverArenas<'a>) -> Resolver<'a>,
115+
) -> BoxedResolver {
120116
let mut boxed_resolver = Box::new(BoxedResolverInner {
121117
session,
122118
resolver_arenas: Some(Resolver::arenas()),
@@ -127,14 +123,14 @@ mod boxed_resolver {
127123
// returns a resolver with the same lifetime as the arena. We ensure that the arena
128124
// outlives the resolver in the drop impl and elsewhere so these transmutes are sound.
129125
unsafe {
130-
let (crate_, resolver) = make_resolver(
126+
let resolver = make_resolver(
131127
std::mem::transmute::<&Session, &Session>(&boxed_resolver.session),
132128
std::mem::transmute::<&ResolverArenas<'_>, &ResolverArenas<'_>>(
133129
boxed_resolver.resolver_arenas.as_ref().unwrap(),
134130
),
135-
)?;
131+
);
136132
boxed_resolver.resolver = Some(resolver);
137-
Ok((crate_, BoxedResolver(Pin::new_unchecked(boxed_resolver))))
133+
BoxedResolver(Pin::new_unchecked(boxed_resolver))
138134
}
139135
}
140136

@@ -165,35 +161,15 @@ mod boxed_resolver {
165161
}
166162
}
167163

168-
/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
169-
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
170-
/// harness if one is to be provided, injection of a dependency on the
171-
/// standard library and prelude, and name resolution.
172-
///
173-
/// Returns [`None`] if we're aborting after handling -W help.
174-
pub fn configure_and_expand(
164+
pub fn create_resolver(
175165
sess: Lrc<Session>,
176-
lint_store: Lrc<LintStore>,
177166
metadata_loader: Box<MetadataLoaderDyn>,
178-
krate: ast::Crate,
167+
krate: &ast::Crate,
179168
crate_name: &str,
180-
) -> Result<(ast::Crate, BoxedResolver)> {
181-
tracing::trace!("configure_and_expand");
182-
// Currently, we ignore the name resolution data structures for the purposes of dependency
183-
// tracking. Instead we will run name resolution and include its output in the hash of each
184-
// item, much like we do for macro expansion. In other words, the hash reflects not just
185-
// its contents but the results of name resolution on those contents. Hopefully we'll push
186-
// this back at some point.
187-
let crate_name = crate_name.to_string();
169+
) -> BoxedResolver {
170+
tracing::trace!("create_resolver");
188171
BoxedResolver::new(sess, move |sess, resolver_arenas| {
189-
configure_and_expand_inner(
190-
sess,
191-
&lint_store,
192-
krate,
193-
&crate_name,
194-
&resolver_arenas,
195-
metadata_loader,
196-
)
172+
Resolver::new(sess, &krate, &crate_name, metadata_loader, &resolver_arenas)
197173
})
198174
}
199175

@@ -278,28 +254,24 @@ fn pre_expansion_lint(
278254
});
279255
}
280256

281-
fn configure_and_expand_inner<'a>(
282-
sess: &'a Session,
257+
/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
258+
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
259+
/// harness if one is to be provided, injection of a dependency on the
260+
/// standard library and prelude, and name resolution.
261+
pub fn configure_and_expand(
262+
sess: &Session,
283263
lint_store: &LintStore,
284264
mut krate: ast::Crate,
285265
crate_name: &str,
286-
resolver_arenas: &'a ResolverArenas<'a>,
287-
metadata_loader: Box<MetadataLoaderDyn>,
288-
) -> Result<(ast::Crate, Resolver<'a>)> {
289-
tracing::trace!("configure_and_expand_inner");
266+
resolver: &mut Resolver<'_>,
267+
) -> Result<ast::Crate> {
268+
tracing::trace!("configure_and_expand");
290269
pre_expansion_lint(sess, lint_store, &krate, crate_name);
291-
292-
let mut resolver = Resolver::new(sess, &krate, crate_name, metadata_loader, &resolver_arenas);
293-
rustc_builtin_macros::register_builtin_macros(&mut resolver);
270+
rustc_builtin_macros::register_builtin_macros(resolver);
294271

295272
krate = sess.time("crate_injection", || {
296273
let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| Symbol::intern(s));
297-
rustc_builtin_macros::standard_library_imports::inject(
298-
krate,
299-
&mut resolver,
300-
&sess,
301-
alt_std_name,
302-
)
274+
rustc_builtin_macros::standard_library_imports::inject(krate, resolver, &sess, alt_std_name)
303275
});
304276

305277
util::check_attr_crate_type(&sess, &krate.attrs, &mut resolver.lint_buffer());
@@ -354,7 +326,7 @@ fn configure_and_expand_inner<'a>(
354326
pre_expansion_lint(sess, lint_store, &krate, &ident.name.as_str());
355327
(krate.attrs, krate.items)
356328
};
357-
let mut ecx = ExtCtxt::new(&sess, cfg, &mut resolver, Some(&extern_mod_loaded));
329+
let mut ecx = ExtCtxt::new(&sess, cfg, resolver, Some(&extern_mod_loaded));
358330

359331
// Expand macros now!
360332
let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate));
@@ -396,16 +368,16 @@ fn configure_and_expand_inner<'a>(
396368
})?;
397369

398370
sess.time("maybe_building_test_harness", || {
399-
rustc_builtin_macros::test_harness::inject(&sess, &mut resolver, &mut krate)
371+
rustc_builtin_macros::test_harness::inject(&sess, resolver, &mut krate)
400372
});
401373

402374
if let Some(PpMode::Source(PpSourceMode::EveryBodyLoops)) = sess.opts.pretty {
403375
tracing::debug!("replacing bodies with loop {{}}");
404-
util::ReplaceBodyWithLoop::new(&mut resolver).visit_crate(&mut krate);
376+
util::ReplaceBodyWithLoop::new(resolver).visit_crate(&mut krate);
405377
}
406378

407379
let has_proc_macro_decls = sess.time("AST_validation", || {
408-
rustc_ast_passes::ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer())
380+
rustc_ast_passes::ast_validation::check_crate(sess, &krate, resolver.lint_buffer())
409381
});
410382

411383
let crate_types = sess.crate_types();
@@ -431,7 +403,7 @@ fn configure_and_expand_inner<'a>(
431403
let is_test_crate = sess.opts.test;
432404
rustc_builtin_macros::proc_macro_harness::inject(
433405
&sess,
434-
&mut resolver,
406+
resolver,
435407
krate,
436408
is_proc_macro_crate,
437409
has_proc_macro_decls,
@@ -471,26 +443,20 @@ fn configure_and_expand_inner<'a>(
471443
}
472444
});
473445

474-
Ok((krate, resolver))
446+
Ok(krate)
475447
}
476448

477449
pub fn lower_to_hir<'res, 'tcx>(
478450
sess: &'tcx Session,
479451
lint_store: &LintStore,
480452
resolver: &'res mut Resolver<'_>,
481-
dep_graph: &'res DepGraph,
482-
krate: &'res ast::Crate,
453+
krate: Rc<ast::Crate>,
483454
arena: &'tcx rustc_ast_lowering::Arena<'tcx>,
484-
) -> Crate<'tcx> {
485-
// We're constructing the HIR here; we don't care what we will
486-
// read, since we haven't even constructed the *input* to
487-
// incr. comp. yet.
488-
dep_graph.assert_ignored();
489-
455+
) -> &'tcx Crate<'tcx> {
490456
// Lower AST to HIR.
491457
let hir_crate = rustc_ast_lowering::lower_crate(
492458
sess,
493-
&krate,
459+
&*krate,
494460
resolver,
495461
rustc_parse::nt_to_tokenstream,
496462
arena,
@@ -511,6 +477,9 @@ pub fn lower_to_hir<'res, 'tcx>(
511477
)
512478
});
513479

480+
// Drop AST to free memory
481+
sess.time("drop_ast", || std::mem::drop(krate));
482+
514483
// Discard hygiene data, which isn't required after lowering to HIR.
515484
if !sess.opts.debugging_opts.keep_hygiene_data {
516485
rustc_span::hygiene::clear_syntax_context_map();
@@ -603,7 +572,7 @@ fn escape_dep_env(symbol: Symbol) -> String {
603572

604573
fn write_out_deps(
605574
sess: &Session,
606-
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
575+
boxed_resolver: &RefCell<BoxedResolver>,
607576
outputs: &OutputFilenames,
608577
out_filenames: &[PathBuf],
609578
) {
@@ -630,7 +599,7 @@ fn write_out_deps(
630599
}
631600

632601
if sess.binary_dep_depinfo() {
633-
boxed_resolver.borrow().borrow_mut().access(|resolver| {
602+
boxed_resolver.borrow_mut().access(|resolver| {
634603
for cnum in resolver.cstore().crates_untracked() {
635604
let source = resolver.cstore().crate_source_untracked(cnum);
636605
if let Some((path, _)) = source.dylib {
@@ -699,7 +668,7 @@ pub fn prepare_outputs(
699668
sess: &Session,
700669
compiler: &Compiler,
701670
krate: &ast::Crate,
702-
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
671+
boxed_resolver: &RefCell<BoxedResolver>,
703672
crate_name: &str,
704673
) -> Result<OutputFilenames> {
705674
let _timer = sess.timer("prepare_outputs");
@@ -803,16 +772,26 @@ impl<'tcx> QueryContext<'tcx> {
803772
pub fn create_global_ctxt<'tcx>(
804773
compiler: &'tcx Compiler,
805774
lint_store: Lrc<LintStore>,
806-
krate: &'tcx Crate<'tcx>,
775+
krate: Rc<ast::Crate>,
807776
dep_graph: DepGraph,
808-
resolver_outputs: ResolverOutputs,
777+
resolver: Rc<RefCell<BoxedResolver>>,
809778
outputs: OutputFilenames,
810779
crate_name: &str,
811780
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
812781
global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
813782
arena: &'tcx WorkerLocal<Arena<'tcx>>,
783+
hir_arena: &'tcx WorkerLocal<rustc_ast_lowering::Arena<'tcx>>,
814784
) -> QueryContext<'tcx> {
785+
// We're constructing the HIR here; we don't care what we will
786+
// read, since we haven't even constructed the *input* to
787+
// incr. comp. yet.
788+
dep_graph.assert_ignored();
789+
815790
let sess = &compiler.session();
791+
let krate = resolver
792+
.borrow_mut()
793+
.access(|resolver| lower_to_hir(sess, &lint_store, resolver, krate, hir_arena));
794+
let resolver_outputs = BoxedResolver::to_resolver_outputs(resolver);
816795

817796
let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
818797

@@ -831,7 +810,7 @@ pub fn create_global_ctxt<'tcx>(
831810
let queries = queries.get_or_init(|| TcxQueries::new(local_providers, extern_providers));
832811

833812
let gcx = sess.time("setup_global_ctxt", || {
834-
global_ctxt.get_or_init(|| {
813+
global_ctxt.get_or_init(move || {
835814
TyCtxt::create_global_ctxt(
836815
sess,
837816
lint_store,

0 commit comments

Comments
 (0)