Skip to content

Commit ed61c13

Browse files
committed
Auto merge of #105220 - oli-obk:feeding, r=cjgillot
feed resolver_for_lowering instead of storing it in a field r? `@cjgillot` opening this as * a discussion for `no_hash` + `feedable` queries. I think we'll want those, but I don't quite understand why they are rejected beyond a double check of the stable hashes for situations where the query is fed but also read from incremental caches. * and a discussion on removing all untracked fields from TyCtxt and setting it up so that they are fed queries instead
2 parents 226202d + f693b78 commit ed61c13

File tree

11 files changed

+86
-57
lines changed

11 files changed

+86
-57
lines changed

compiler/rustc_interface/src/passes.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_ast::{self as ast, visit};
1212
use rustc_borrowck as mir_borrowck;
1313
use rustc_codegen_ssa::traits::CodegenBackend;
1414
use rustc_data_structures::parallel;
15+
use rustc_data_structures::steal::Steal;
1516
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
1617
use rustc_errors::{ErrorGuaranteed, PResult};
1718
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
@@ -801,14 +802,21 @@ pub fn create_global_ctxt<'tcx>(
801802
TcxQueries::new(local_providers, extern_providers, query_result_on_disk_cache)
802803
});
803804

805+
let ty::ResolverOutputs {
806+
definitions,
807+
global_ctxt: untracked_resolutions,
808+
ast_lowering: untracked_resolver_for_lowering,
809+
} = resolver_outputs;
810+
804811
let gcx = sess.time("setup_global_ctxt", || {
805812
global_ctxt.get_or_init(move || {
806813
TyCtxt::create_global_ctxt(
807814
sess,
808815
lint_store,
809816
arena,
810817
hir_arena,
811-
resolver_outputs,
818+
definitions,
819+
untracked_resolutions,
812820
krate,
813821
dep_graph,
814822
queries.on_disk_cache.as_ref().map(OnDiskCache::as_dyn),
@@ -820,7 +828,12 @@ pub fn create_global_ctxt<'tcx>(
820828
})
821829
});
822830

823-
QueryContext { gcx }
831+
let mut qcx = QueryContext { gcx };
832+
qcx.enter(|tcx| {
833+
tcx.feed_unit_query()
834+
.resolver_for_lowering(tcx.arena.alloc(Steal::new(untracked_resolver_for_lowering)))
835+
});
836+
qcx
824837
}
825838

826839
/// Runs the resolution, type-checking, region checking and other
@@ -965,12 +978,10 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
965978
pub fn start_codegen<'tcx>(
966979
codegen_backend: &dyn CodegenBackend,
967980
tcx: TyCtxt<'tcx>,
968-
outputs: &OutputFilenames,
969981
) -> Box<dyn Any> {
970982
info!("Pre-codegen\n{:?}", tcx.debug_stats());
971983

972-
let (metadata, need_metadata_module) =
973-
rustc_metadata::fs::encode_and_write_metadata(tcx, outputs);
984+
let (metadata, need_metadata_module) = rustc_metadata::fs::encode_and_write_metadata(tcx);
974985

975986
let codegen = tcx.sess.time("codegen_crate", move || {
976987
codegen_backend.codegen_crate(tcx, metadata, need_metadata_module)
@@ -986,7 +997,7 @@ pub fn start_codegen<'tcx>(
986997
info!("Post-codegen\n{:?}", tcx.debug_stats());
987998

988999
if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
989-
if let Err(error) = rustc_mir_transform::dump_mir::emit_mir(tcx, outputs) {
1000+
if let Err(error) = rustc_mir_transform::dump_mir::emit_mir(tcx) {
9901001
tcx.sess.emit_err(CantEmitMIR { error });
9911002
tcx.sess.abort_if_errors();
9921003
}

compiler/rustc_interface/src/queries.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc_span::symbol::sym;
2020
use std::any::Any;
2121
use std::cell::{Ref, RefCell, RefMut};
2222
use std::rc::Rc;
23+
use std::sync::Arc;
2324

2425
/// Represent the result of a query.
2526
///
@@ -214,7 +215,7 @@ impl<'tcx> Queries<'tcx> {
214215
pub fn global_ctxt(&'tcx self) -> Result<&Query<QueryContext<'tcx>>> {
215216
self.global_ctxt.compute(|| {
216217
let crate_name = self.crate_name()?.peek().clone();
217-
let outputs = self.prepare_outputs()?.peek().clone();
218+
let outputs = self.prepare_outputs()?.take();
218219
let dep_graph = self.dep_graph()?.peek().clone();
219220
let (krate, resolver, lint_store) = self.expansion()?.take();
220221
Ok(passes::create_global_ctxt(
@@ -235,7 +236,6 @@ impl<'tcx> Queries<'tcx> {
235236

236237
pub fn ongoing_codegen(&'tcx self) -> Result<&Query<Box<dyn Any>>> {
237238
self.ongoing_codegen.compute(|| {
238-
let outputs = self.prepare_outputs()?;
239239
self.global_ctxt()?.peek_mut().enter(|tcx| {
240240
tcx.analysis(()).ok();
241241

@@ -249,7 +249,7 @@ impl<'tcx> Queries<'tcx> {
249249
// Hook for UI tests.
250250
Self::check_for_rustc_errors_attr(tcx);
251251

252-
Ok(passes::start_codegen(&***self.codegen_backend(), tcx, &*outputs.peek()))
252+
Ok(passes::start_codegen(&***self.codegen_backend(), tcx))
253253
})
254254
})
255255
}
@@ -293,8 +293,10 @@ impl<'tcx> Queries<'tcx> {
293293
let codegen_backend = self.codegen_backend().clone();
294294

295295
let dep_graph = self.dep_graph()?.peek().clone();
296-
let prepare_outputs = self.prepare_outputs()?.take();
297-
let crate_hash = self.global_ctxt()?.peek_mut().enter(|tcx| tcx.crate_hash(LOCAL_CRATE));
296+
let (crate_hash, prepare_outputs) = self
297+
.global_ctxt()?
298+
.peek_mut()
299+
.enter(|tcx| (tcx.crate_hash(LOCAL_CRATE), tcx.output_filenames(()).clone()));
298300
let ongoing_codegen = self.ongoing_codegen()?.take();
299301

300302
Ok(Linker {
@@ -316,7 +318,7 @@ pub struct Linker {
316318

317319
// compilation outputs
318320
dep_graph: DepGraph,
319-
prepare_outputs: OutputFilenames,
321+
prepare_outputs: Arc<OutputFilenames>,
320322
crate_hash: Svh,
321323
ongoing_codegen: Box<dyn Any>,
322324
}

compiler/rustc_macros/src/query.rs

-4
Original file line numberDiff line numberDiff line change
@@ -364,10 +364,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
364364
modifiers.eval_always.is_none(),
365365
"Query {name} cannot be both `feedable` and `eval_always`."
366366
);
367-
assert!(
368-
modifiers.no_hash.is_none(),
369-
"Query {name} cannot be both `feedable` and `no_hash`."
370-
);
371367
feedable_queries.extend(quote! {
372368
#(#doc_comments)*
373369
[#attribute_stream] fn #name(#arg) #result,

compiler/rustc_metadata/src/fs.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{encode_metadata, EncodedMetadata};
66
use rustc_data_structures::temp_dir::MaybeTempDir;
77
use rustc_hir::def_id::LOCAL_CRATE;
88
use rustc_middle::ty::TyCtxt;
9-
use rustc_session::config::{CrateType, OutputFilenames, OutputType};
9+
use rustc_session::config::{CrateType, OutputType};
1010
use rustc_session::output::filename_for_metadata;
1111
use rustc_session::Session;
1212
use tempfile::Builder as TempFileBuilder;
@@ -38,10 +38,7 @@ pub fn emit_wrapper_file(
3838
out_filename
3939
}
4040

41-
pub fn encode_and_write_metadata(
42-
tcx: TyCtxt<'_>,
43-
outputs: &OutputFilenames,
44-
) -> (EncodedMetadata, bool) {
41+
pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
4542
#[derive(PartialEq, Eq, PartialOrd, Ord)]
4643
enum MetadataKind {
4744
None,
@@ -64,7 +61,8 @@ pub fn encode_and_write_metadata(
6461
.unwrap_or(MetadataKind::None);
6562

6663
let crate_name = tcx.crate_name(LOCAL_CRATE);
67-
let out_filename = filename_for_metadata(tcx.sess, crate_name.as_str(), outputs);
64+
let out_filename =
65+
filename_for_metadata(tcx.sess, crate_name.as_str(), tcx.output_filenames(()));
6866
// To avoid races with another rustc process scanning the output directory,
6967
// we need to write the file somewhere else and atomically move it to its
7068
// final destination, with an `fs::rename` call. In order for the rename to

compiler/rustc_middle/src/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ macro_rules! arena_types {
2828
[decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>,
2929
[decode] borrowck_result:
3030
rustc_middle::mir::BorrowCheckResult<'tcx>,
31+
[] resolver: rustc_data_structures::steal::Steal<rustc_middle::ty::ResolverAstLowering>,
3132
[decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult,
3233
[decode] code_region: rustc_middle::mir::coverage::CodeRegion,
3334
[] const_allocs: rustc_middle::mir::interpret::Allocation,

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ rustc_queries! {
3333
}
3434

3535
query resolver_for_lowering(_: ()) -> &'tcx Steal<ty::ResolverAstLowering> {
36-
eval_always
36+
feedable
3737
no_hash
3838
desc { "getting the resolver for lowering" }
3939
}

compiler/rustc_middle/src/ty/context.rs

+23-17
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ use std::mem;
8181
use std::ops::{Bound, Deref};
8282
use std::sync::Arc;
8383

84-
use super::{ImplPolarity, ResolverOutputs, RvalueScopes};
84+
use super::{ImplPolarity, RvalueScopes};
8585

8686
pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync {
8787
/// Creates a new `OnDiskCache` instance from the serialized data in `data`.
@@ -1034,16 +1034,29 @@ pub struct FreeRegionInfo {
10341034

10351035
/// This struct should only be created by `create_def`.
10361036
#[derive(Copy, Clone)]
1037-
pub struct TyCtxtFeed<'tcx> {
1037+
pub struct TyCtxtFeed<'tcx, KEY: Copy> {
10381038
pub tcx: TyCtxt<'tcx>,
10391039
// Do not allow direct access, as downstream code must not mutate this field.
1040-
def_id: LocalDefId,
1040+
key: KEY,
10411041
}
10421042

1043-
impl<'tcx> TyCtxtFeed<'tcx> {
1043+
impl<'tcx> TyCtxt<'tcx> {
1044+
pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1045+
TyCtxtFeed { tcx: self, key: () }
1046+
}
1047+
}
1048+
1049+
impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1050+
#[inline(always)]
1051+
pub fn key(&self) -> KEY {
1052+
self.key
1053+
}
1054+
}
1055+
1056+
impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
10441057
#[inline(always)]
10451058
pub fn def_id(&self) -> LocalDefId {
1046-
self.def_id
1059+
self.key
10471060
}
10481061
}
10491062

@@ -1099,7 +1112,6 @@ pub struct GlobalCtxt<'tcx> {
10991112

11001113
/// Output of the resolver.
11011114
pub(crate) untracked_resolutions: ty::ResolverGlobalCtxt,
1102-
untracked_resolver_for_lowering: Steal<ty::ResolverAstLowering>,
11031115
/// The entire crate as AST. This field serves as the input for the hir_crate query,
11041116
/// which lowers it from AST to HIR. It must not be read or used by anything else.
11051117
pub untracked_crate: Steal<Lrc<ast::Crate>>,
@@ -1262,7 +1274,8 @@ impl<'tcx> TyCtxt<'tcx> {
12621274
lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
12631275
arena: &'tcx WorkerLocal<Arena<'tcx>>,
12641276
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1265-
resolver_outputs: ResolverOutputs,
1277+
definitions: Definitions,
1278+
untracked_resolutions: ty::ResolverGlobalCtxt,
12661279
krate: Lrc<ast::Crate>,
12671280
dep_graph: DepGraph,
12681281
on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>,
@@ -1271,11 +1284,6 @@ impl<'tcx> TyCtxt<'tcx> {
12711284
crate_name: &str,
12721285
output_filenames: OutputFilenames,
12731286
) -> GlobalCtxt<'tcx> {
1274-
let ResolverOutputs {
1275-
definitions,
1276-
global_ctxt: untracked_resolutions,
1277-
ast_lowering: untracked_resolver_for_lowering,
1278-
} = resolver_outputs;
12791287
let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
12801288
s.emit_fatal(err);
12811289
});
@@ -1304,7 +1312,6 @@ impl<'tcx> TyCtxt<'tcx> {
13041312
lifetimes: common_lifetimes,
13051313
consts: common_consts,
13061314
untracked_resolutions,
1307-
untracked_resolver_for_lowering: Steal::new(untracked_resolver_for_lowering),
13081315
untracked_crate: Steal::new(krate),
13091316
on_disk_cache,
13101317
queries,
@@ -1515,7 +1522,7 @@ impl<'tcx> TyCtxtAt<'tcx> {
15151522
self,
15161523
parent: LocalDefId,
15171524
data: hir::definitions::DefPathData,
1518-
) -> TyCtxtFeed<'tcx> {
1525+
) -> TyCtxtFeed<'tcx, LocalDefId> {
15191526
// This function modifies `self.definitions` using a side-effect.
15201527
// We need to ensure that these side effects are re-run by the incr. comp. engine.
15211528
// Depending on the forever-red node will tell the graph that the calling query
@@ -1536,9 +1543,9 @@ impl<'tcx> TyCtxtAt<'tcx> {
15361543
// This is fine because:
15371544
// - those queries are `eval_always` so we won't miss their result changing;
15381545
// - this write will have happened before these queries are called.
1539-
let def_id = self.definitions.write().create_def(parent, data);
1546+
let key = self.definitions.write().create_def(parent, data);
15401547

1541-
let feed = TyCtxtFeed { tcx: self.tcx, def_id };
1548+
let feed = TyCtxtFeed { tcx: self.tcx, key };
15421549
feed.def_span(self.span);
15431550
feed
15441551
}
@@ -3107,7 +3114,6 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
31073114

31083115
pub fn provide(providers: &mut ty::query::Providers) {
31093116
providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
3110-
providers.resolver_for_lowering = |tcx, ()| &tcx.untracked_resolver_for_lowering;
31113117
providers.module_reexports =
31123118
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
31133119
providers.crate_name = |tcx, id| {

compiler/rustc_middle/src/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ pub use self::consts::{
8282
pub use self::context::{
8383
tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
8484
CtxtInterners, DeducedParamAttrs, FreeRegionInfo, GeneratorDiagnosticData,
85-
GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType,
86-
UserTypeAnnotationIndex,
85+
GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TyCtxtFeed, TypeckResults,
86+
UserType, UserTypeAnnotationIndex,
8787
};
8888
pub use self::instance::{Instance, InstanceDef, ShortInstance};
8989
pub use self::list::List;

compiler/rustc_middle/src/ty/query.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,25 @@ macro_rules! define_callbacks {
328328
};
329329
}
330330

331+
macro_rules! hash_result {
332+
([]) => {{
333+
Some(dep_graph::hash_result)
334+
}};
335+
([(no_hash) $($rest:tt)*]) => {{
336+
None
337+
}};
338+
([$other:tt $($modifiers:tt)*]) => {
339+
hash_result!([$($modifiers)*])
340+
};
341+
}
342+
331343
macro_rules! define_feedable {
332344
($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
333-
impl<'tcx> TyCtxtFeed<'tcx> {
334-
$($(#[$attr])*
345+
$(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
346+
$(#[$attr])*
335347
#[inline(always)]
336348
pub fn $name(self, value: $V) -> query_stored::$name<'tcx> {
337-
let key = self.def_id().into_query_param();
349+
let key = self.key().into_query_param();
338350
opt_remap_env_constness!([$($modifiers)*][key]);
339351

340352
let tcx = self.tcx;
@@ -358,11 +370,11 @@ macro_rules! define_feedable {
358370
tcx,
359371
key,
360372
&value,
361-
dep_graph::hash_result,
373+
hash_result!([$($modifiers)*]),
362374
);
363375
cache.complete(key, value, dep_node_index)
364-
})*
365-
}
376+
}
377+
})*
366378
}
367379
}
368380

compiler/rustc_mir_transform/src/dump_mir.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::MirPass;
77
use rustc_middle::mir::write_mir_pretty;
88
use rustc_middle::mir::Body;
99
use rustc_middle::ty::TyCtxt;
10-
use rustc_session::config::{OutputFilenames, OutputType};
10+
use rustc_session::config::OutputType;
1111

1212
pub struct Marker(pub &'static str);
1313

@@ -19,8 +19,8 @@ impl<'tcx> MirPass<'tcx> for Marker {
1919
fn run_pass(&self, _tcx: TyCtxt<'tcx>, _body: &mut Body<'tcx>) {}
2020
}
2121

22-
pub fn emit_mir(tcx: TyCtxt<'_>, outputs: &OutputFilenames) -> io::Result<()> {
23-
let path = outputs.path(OutputType::Mir);
22+
pub fn emit_mir(tcx: TyCtxt<'_>) -> io::Result<()> {
23+
let path = tcx.output_filenames(()).path(OutputType::Mir);
2424
let mut f = io::BufWriter::new(File::create(&path)?);
2525
write_mir_pretty(tcx, None, &mut f)?;
2626
Ok(())

0 commit comments

Comments
 (0)