Skip to content

Commit 2deff71

Browse files
committed
Auto merge of rust-lang#105462 - oli-obk:feeding_full, r=cjgillot,petrochenkov
give the resolver access to TyCtxt The resolver is now created after TyCtxt is created. Then macro expansion and name resolution are run and the results fed into queries just like before this PR. Since the resolver had (before this PR) mutable access to the `CStore` and the source span table, these two datastructures are now behind a `RwLock`. To ensure that these are not mutated anymore after the resolver is done, a read lock to them is leaked right after the resolver finishes. ### PRs split out of this one and leading up to it: * rust-lang#105423 * rust-lang#105357 * rust-lang#105603 * rust-lang#106776 * rust-lang#106810 * rust-lang#106812 * rust-lang#108032
2 parents 8f55d60 + 0847b79 commit 2deff71

35 files changed

+480
-453
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4180,6 +4180,7 @@ dependencies = [
41804180
"rustc_hir_analysis",
41814181
"rustc_hir_typeck",
41824182
"rustc_incremental",
4183+
"rustc_index",
41834184
"rustc_lint",
41844185
"rustc_macros",
41854186
"rustc_metadata",

compiler/rustc_codegen_ssa/src/back/metadata.rs

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use rustc_target::spec::{RelocModel, Target};
3333
/// <dt>dylib</dt>
3434
/// <dd>The metadata can be found in the `.rustc` section of the shared library.</dd>
3535
/// </dl>
36+
#[derive(Debug)]
3637
pub struct DefaultMetadataLoader;
3738

3839
fn load_metadata_with(

compiler/rustc_driver_impl/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ fn run_compiler(
320320
}
321321

322322
// Make sure name resolution and macro expansion is run.
323-
queries.global_ctxt()?;
323+
queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering(()));
324324

325325
if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
326326
return early_exit();

compiler/rustc_expand/src/mbe/macro_rules.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use rustc_ast_pretty::pprust;
1616
use rustc_attr::{self as attr, TransparencyError};
1717
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
1818
use rustc_errors::{Applicability, ErrorGuaranteed};
19-
use rustc_feature::Features;
2019
use rustc_lint_defs::builtin::{
2120
RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
2221
};
@@ -379,7 +378,6 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>(
379378
/// Converts a macro item into a syntax extension.
380379
pub fn compile_declarative_macro(
381380
sess: &Session,
382-
features: &Features,
383381
def: &ast::Item,
384382
edition: Edition,
385383
) -> (SyntaxExtension, Vec<(usize, Span)>) {
@@ -508,7 +506,7 @@ pub fn compile_declarative_macro(
508506
true,
509507
&sess.parse_sess,
510508
def.id,
511-
features,
509+
sess.features_untracked(),
512510
edition,
513511
)
514512
.pop()
@@ -532,7 +530,7 @@ pub fn compile_declarative_macro(
532530
false,
533531
&sess.parse_sess,
534532
def.id,
535-
features,
533+
sess.features_untracked(),
536534
edition,
537535
)
538536
.pop()

compiler/rustc_interface/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ rustc_middle = { path = "../rustc_middle" }
2424
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
2525
rustc_ast_passes = { path = "../rustc_ast_passes" }
2626
rustc_incremental = { path = "../rustc_incremental" }
27+
rustc_index = { path = "../rustc_index" }
2728
rustc_traits = { path = "../rustc_traits" }
2829
rustc_data_structures = { path = "../rustc_data_structures" }
2930
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }

compiler/rustc_interface/src/passes.rs

+42-21
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ use rustc_ast::{self as ast, visit};
88
use rustc_borrowck as mir_borrowck;
99
use rustc_codegen_ssa::traits::CodegenBackend;
1010
use rustc_data_structures::parallel;
11+
use rustc_data_structures::steal::Steal;
1112
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
12-
use rustc_errors::{ErrorGuaranteed, PResult};
13+
use rustc_errors::PResult;
1314
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
1415
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
15-
use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore};
16+
use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
1617
use rustc_metadata::creader::CStore;
1718
use rustc_middle::arena::Arena;
1819
use rustc_middle::dep_graph::DepGraph;
@@ -171,14 +172,12 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> {
171172
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
172173
/// harness if one is to be provided, injection of a dependency on the
173174
/// standard library and prelude, and name resolution.
174-
pub fn configure_and_expand(
175-
sess: &Session,
176-
lint_store: &LintStore,
177-
mut krate: ast::Crate,
178-
crate_name: Symbol,
179-
resolver: &mut Resolver<'_, '_>,
180-
) -> Result<ast::Crate> {
181-
trace!("configure_and_expand");
175+
#[instrument(level = "trace", skip(krate, resolver))]
176+
fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>) -> ast::Crate {
177+
let tcx = resolver.tcx();
178+
let sess = tcx.sess;
179+
let lint_store = unerased_lint_store(tcx);
180+
let crate_name = tcx.crate_name(LOCAL_CRATE);
182181
pre_expansion_lint(sess, lint_store, resolver.registered_tools(), &krate, crate_name);
183182
rustc_builtin_macros::register_builtin_macros(resolver);
184183

@@ -249,20 +248,19 @@ pub fn configure_and_expand(
249248
ecx.check_unused_macros();
250249
});
251250

252-
let recursion_limit_hit = ecx.reduced_recursion_limit.is_some();
251+
// If we hit a recursion limit, exit early to avoid later passes getting overwhelmed
252+
// with a large AST
253+
if ecx.reduced_recursion_limit.is_some() {
254+
sess.abort_if_errors();
255+
unreachable!();
256+
}
253257

254258
if cfg!(windows) {
255259
env::set_var("PATH", &old_path);
256260
}
257261

258-
if recursion_limit_hit {
259-
// If we hit a recursion limit, exit early to avoid later passes getting overwhelmed
260-
// with a large AST
261-
Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
262-
} else {
263-
Ok(krate)
264-
}
265-
})?;
262+
krate
263+
});
266264

267265
sess.time("maybe_building_test_harness", || {
268266
rustc_builtin_macros::test_harness::inject(sess, resolver, &mut krate)
@@ -365,7 +363,7 @@ pub fn configure_and_expand(
365363
)
366364
});
367365

368-
Ok(krate)
366+
krate
369367
}
370368

371369
// Returns all the paths that correspond to generated files.
@@ -564,6 +562,28 @@ fn write_out_deps(
564562
}
565563
}
566564

565+
fn resolver_for_lowering<'tcx>(
566+
tcx: TyCtxt<'tcx>,
567+
(): (),
568+
) -> &'tcx Steal<(ty::ResolverAstLowering, Lrc<ast::Crate>)> {
569+
let arenas = Resolver::arenas();
570+
let krate = tcx.crate_for_resolver(()).steal();
571+
let mut resolver = Resolver::new(tcx, &krate, &arenas);
572+
let krate = configure_and_expand(krate, &mut resolver);
573+
574+
// Make sure we don't mutate the cstore from here on.
575+
tcx.untracked().cstore.leak();
576+
577+
let ty::ResolverOutputs {
578+
global_ctxt: untracked_resolutions,
579+
ast_lowering: untracked_resolver_for_lowering,
580+
} = resolver.into_outputs();
581+
582+
let feed = tcx.feed_unit_query();
583+
feed.resolutions(tcx.arena.alloc(untracked_resolutions));
584+
tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Lrc::new(krate))))
585+
}
586+
567587
fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
568588
let sess = tcx.sess;
569589
let _timer = sess.timer("prepare_outputs");
@@ -597,7 +617,7 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
597617
}
598618
}
599619

600-
write_out_deps(sess, tcx.cstore_untracked(), &outputs, &output_paths);
620+
write_out_deps(sess, &*tcx.cstore_untracked(), &outputs, &output_paths);
601621

602622
let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo)
603623
&& sess.opts.output_types.len() == 1;
@@ -618,6 +638,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
618638
providers.analysis = analysis;
619639
providers.hir_crate = rustc_ast_lowering::lower_to_hir;
620640
providers.output_filenames = output_filenames;
641+
providers.resolver_for_lowering = resolver_for_lowering;
621642
proc_macro_decls::provide(providers);
622643
rustc_const_eval::provide(providers);
623644
rustc_middle::hir::provide(providers);

compiler/rustc_interface/src/queries.rs

+26-39
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@ use rustc_codegen_ssa::traits::CodegenBackend;
77
use rustc_codegen_ssa::CodegenResults;
88
use rustc_data_structures::steal::Steal;
99
use rustc_data_structures::svh::Svh;
10-
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
11-
use rustc_hir::def_id::LOCAL_CRATE;
10+
use rustc_data_structures::sync::{Lrc, OnceCell, RwLock, WorkerLocal};
11+
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
12+
use rustc_hir::definitions::Definitions;
1213
use rustc_incremental::DepGraphFuture;
14+
use rustc_index::vec::IndexVec;
1315
use rustc_lint::LintStore;
16+
use rustc_metadata::creader::CStore;
1417
use rustc_middle::arena::Arena;
1518
use rustc_middle::dep_graph::DepGraph;
16-
use rustc_middle::ty::{self, GlobalCtxt, TyCtxt};
19+
use rustc_middle::ty::{GlobalCtxt, TyCtxt};
1720
use rustc_query_impl::Queries as TcxQueries;
18-
use rustc_resolve::Resolver;
1921
use rustc_session::config::{self, OutputFilenames, OutputType};
22+
use rustc_session::cstore::Untracked;
2023
use rustc_session::{output::find_crate_name, Session};
2124
use rustc_span::symbol::sym;
2225
use rustc_span::Symbol;
@@ -187,35 +190,18 @@ impl<'tcx> Queries<'tcx> {
187190
self.gcx.compute(|| {
188191
let crate_name = *self.crate_name()?.borrow();
189192
let (krate, lint_store) = self.register_plugins()?.steal();
190-
let (krate, resolver_outputs) = {
191-
let _timer = self.session().timer("configure_and_expand");
192-
let sess = self.session();
193-
194-
let arenas = Resolver::arenas();
195-
let mut resolver = Resolver::new(
196-
sess,
197-
&krate,
198-
crate_name,
199-
self.codegen_backend().metadata_loader(),
200-
&arenas,
201-
);
202-
let krate = passes::configure_and_expand(
203-
sess,
204-
&lint_store,
205-
krate,
206-
crate_name,
207-
&mut resolver,
208-
)?;
209-
(Lrc::new(krate), resolver.into_outputs())
210-
};
211-
212-
let ty::ResolverOutputs {
213-
untracked,
214-
global_ctxt: untracked_resolutions,
215-
ast_lowering: untracked_resolver_for_lowering,
216-
} = resolver_outputs;
217193

218-
let gcx = passes::create_global_ctxt(
194+
let sess = self.session();
195+
196+
let cstore = RwLock::new(Box::new(CStore::new(sess)) as _);
197+
let definitions = RwLock::new(Definitions::new(sess.local_stable_crate_id()));
198+
let mut source_span = IndexVec::default();
199+
let _id = source_span.push(krate.spans.inner_span);
200+
debug_assert_eq!(_id, CRATE_DEF_ID);
201+
let source_span = RwLock::new(source_span);
202+
let untracked = Untracked { cstore, source_span, definitions };
203+
204+
let qcx = passes::create_global_ctxt(
219205
self.compiler,
220206
lint_store,
221207
self.dep_graph()?.steal(),
@@ -226,17 +212,18 @@ impl<'tcx> Queries<'tcx> {
226212
&self.hir_arena,
227213
);
228214

229-
gcx.enter(|tcx| {
215+
qcx.enter(|tcx| {
216+
let feed = tcx.feed_local_crate();
217+
feed.crate_name(crate_name);
218+
230219
let feed = tcx.feed_unit_query();
231-
feed.resolver_for_lowering(
232-
tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))),
220+
feed.crate_for_resolver(tcx.arena.alloc(Steal::new(krate)));
221+
feed.metadata_loader(
222+
tcx.arena.alloc(Steal::new(self.codegen_backend().metadata_loader())),
233223
);
234-
feed.resolutions(tcx.arena.alloc(untracked_resolutions));
235224
feed.features_query(tcx.sess.features_untracked());
236-
let feed = tcx.feed_local_crate();
237-
feed.crate_name(crate_name);
238225
});
239-
Ok(gcx)
226+
Ok(qcx)
240227
})
241228
}
242229

0 commit comments

Comments
 (0)