Skip to content

Commit 65506bd

Browse files
committed
Turn macro expansion and name resolution into a query
1 parent a7c010d commit 65506bd

File tree

12 files changed

+143
-117
lines changed

12 files changed

+143
-117
lines changed

src/librustc/hir/def_id.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,10 @@ impl fmt::Debug for DefId {
151151

152152
ty::tls::with_opt(|opt_tcx| {
153153
if let Some(tcx) = opt_tcx {
154-
write!(f, " ~ {}", tcx.def_path_debug_str(*self))?;
154+
// Only print the path after HIR lowering is done
155+
if tcx.is_hir_lowered() {
156+
write!(f, " ~ {}", tcx.def_path_debug_str(*self))?;
157+
}
155158
}
156159
Ok(())
157160
})?;

src/librustc/query/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ use syntax_pos::symbol::InternedString;
3131
// as they will raise an fatal error on query cycles instead.
3232
rustc_queries! {
3333
Other {
34+
query expand_macros(_: ()) -> Result<Lrc<ty::ExpansionResult>, ErrorReported> {
35+
no_hash
36+
eval_always
37+
desc { "expanding macros" }
38+
}
39+
3440
query prepare_outputs(_: ()) -> Result<Arc<OutputFilenames>, ErrorReported> {
3541
no_hash
3642
eval_always

src/librustc/ty/context.rs

+46-23
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5353
StableVec};
5454
use arena::SyncDroplessArena;
5555
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
56-
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal, AtomicOnce, OneThread};
56+
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal, AtomicOnce, Once, OneThread};
5757
use std::any::Any;
5858
use std::borrow::Borrow;
5959
use std::cmp::Ordering;
@@ -1009,15 +1009,20 @@ pub struct GlobalCtxt<'tcx> {
10091009

10101010
pub io: InputsAndOutputs,
10111011

1012-
pub ast_crate: Steal<ast::Crate>,
1012+
/// This stores a `Lrc<CStore>`, but that type depends on
1013+
/// rustc_metadata, so it cannot be used here.
1014+
pub cstore_rc: OneThread<Steal<Box<dyn Any>>>,
10131015

1014-
/// This stores a `Lrc<Option<Lock<BoxedResolver>>>)>`, but that type depends on
1015-
/// librustc_resolve, so it cannot be used here.
1016-
pub boxed_resolver: Steal<OneThread<Box<dyn Any>>>,
1016+
pub sess_rc: Lrc<Session>,
1017+
1018+
/// The AST after registering plugins.
1019+
pub ast_crate: Steal<(ast::Crate, ty::PluginInfo)>,
10171020

10181021
lowered_hir: AtomicOnce<&'tcx hir::LoweredHir>,
10191022
hir_map: AtomicOnce<&'tcx hir_map::Map<'tcx>>,
10201023

1024+
metadata_dep_nodes: Once<()>,
1025+
10211026
pub queries: query::Queries<'tcx>,
10221027

10231028
// Internal cache for metadata decoding. No need to track deps on this.
@@ -1075,10 +1080,19 @@ impl<'tcx> TyCtxt<'tcx> {
10751080
self.lowered_hir.get_or_init(|| {
10761081
// FIXME: The ignore here is only sound because all queries
10771082
// used to compute LoweredHir are eval_always
1078-
self.dep_graph.with_ignore(|| self.lower_ast_to_hir(()).unwrap())
1083+
self.dep_graph.with_ignore(|| {
1084+
let map = self.lower_ast_to_hir(()).unwrap();
1085+
self.lowered_hir.init(map);
1086+
self.allocate_metadata_dep_nodes();
1087+
map
1088+
})
10791089
})
10801090
}
10811091

1092+
pub fn is_hir_lowered(self) -> bool {
1093+
self.lowered_hir.is_initalized()
1094+
}
1095+
10821096
#[inline(always)]
10831097
pub fn hir(self) -> &'tcx hir_map::Map<'tcx> {
10841098
self.hir_map.get_or_init(|| {
@@ -1163,14 +1177,15 @@ impl<'tcx> TyCtxt<'tcx> {
11631177
/// value (types, substs, etc.) can only be used while `ty::tls` has a valid
11641178
/// reference to the context, to allow formatting values that need it.
11651179
pub fn create_global_ctxt(
1166-
s: &'tcx Session,
1180+
s: &'tcx Lrc<Session>,
11671181
cstore: &'tcx CrateStoreDyn,
1182+
cstore_rc: Box<dyn Any>,
11681183
local_providers: ty::query::Providers<'tcx>,
11691184
extern_providers: ty::query::Providers<'tcx>,
11701185
arenas: &'tcx AllArenas,
11711186
dep_graph: DepGraph,
11721187
ast_crate: ast::Crate,
1173-
boxed_resolver: Box<dyn Any>,
1188+
plugin_info: ty::PluginInfo,
11741189
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
11751190
crate_name: &str,
11761191
tx: mpsc::Sender<Box<dyn Any + Send>>,
@@ -1194,19 +1209,21 @@ impl<'tcx> TyCtxt<'tcx> {
11941209
providers[LOCAL_CRATE] = local_providers;
11951210

11961211
GlobalCtxt {
1197-
sess: s,
1198-
cstore,
1212+
sess: &**s,
11991213
arena: WorkerLocal::new(|_| Arena::default()),
1214+
cstore,
1215+
cstore_rc: OneThread::new(Steal::new(cstore_rc)),
1216+
sess_rc: s.clone(),
12001217
interners,
12011218
dep_graph,
12021219
common,
12031220
types: common_types,
12041221
lifetimes: common_lifetimes,
12051222
consts: common_consts,
1206-
ast_crate: Steal::new(ast_crate),
1207-
boxed_resolver: Steal::new(OneThread::new(boxed_resolver)),
1223+
ast_crate: Steal::new((ast_crate, plugin_info)),
12081224
lowered_hir: AtomicOnce::new(),
12091225
hir_map: AtomicOnce::new(),
1226+
metadata_dep_nodes: Once::new(),
12101227
queries: query::Queries::new(
12111228
providers,
12121229
extern_providers,
@@ -1381,18 +1398,24 @@ impl<'tcx> TyCtxt<'tcx> {
13811398
// With full-fledged red/green, the method will probably become unnecessary
13821399
// as this will be done on-demand.
13831400
pub fn allocate_metadata_dep_nodes(self) {
1384-
// We cannot use the query versions of crates() and crate_hash(), since
1385-
// those would need the DepNodes that we are allocating here.
1386-
for cnum in self.cstore.crates_untracked() {
1387-
let dep_node = DepNode::new(self, DepConstructor::CrateMetadata(cnum));
1388-
let crate_hash = self.cstore.crate_hash_untracked(cnum);
1389-
self.dep_graph.with_task(dep_node,
1390-
self,
1391-
crate_hash,
1392-
|_, x| x, // No transformation needed
1393-
Some(dep_graph::hash_result),
1394-
);
1401+
if !self.dep_graph.is_fully_enabled() {
1402+
return
13951403
}
1404+
1405+
self.metadata_dep_nodes.init_locking(|| {
1406+
// We cannot use the query versions of crates() and crate_hash(), since
1407+
// those would need the DepNodes that we are allocating here.
1408+
for cnum in self.cstore.crates_untracked() {
1409+
let dep_node = DepNode::new(self, DepConstructor::CrateMetadata(cnum));
1410+
let crate_hash = self.cstore.crate_hash_untracked(cnum);
1411+
self.dep_graph.with_task(dep_node,
1412+
self,
1413+
crate_hash,
1414+
|_, x| x, // No transformation needed
1415+
Some(dep_graph::hash_result),
1416+
);
1417+
}
1418+
});
13961419
}
13971420

13981421
pub fn serialize_query_result_cache<E>(self,

src/librustc/ty/mod.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,16 @@ use std::cmp::{self, Ordering};
3838
use std::fmt;
3939
use std::hash::{Hash, Hasher};
4040
use std::ops::Deref;
41-
use rustc_data_structures::sync::{self, Lrc, ParallelIterator, par_iter};
41+
use std::any::Any;
42+
use rustc_data_structures::sync::{self, Lrc, OneThread, ParallelIterator, par_iter};
4243
use std::slice;
4344
use std::{mem, ptr};
4445
use std::ops::Range;
4546
use syntax::ast::{self, Name, Ident, NodeId};
4647
use syntax::attr;
4748
use syntax::ext::hygiene::Mark;
49+
use syntax::ext::base::NamedSyntaxExtension;
50+
use syntax::feature_gate::AttributeType;
4851
use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString};
4952
use syntax_pos::Span;
5053

@@ -119,6 +122,19 @@ mod sty;
119122

120123
// Data types
121124

125+
pub struct PluginInfo {
126+
pub syntax_exts: Vec<NamedSyntaxExtension>,
127+
pub attributes: Vec<(Symbol, AttributeType)>,
128+
}
129+
130+
pub struct ExpansionResult {
131+
pub ast_crate: steal::Steal<ast::Crate>,
132+
133+
/// This stores a `Lrc<Option<Lock<BoxedResolver>>>)>`, but that type depends on
134+
/// librustc_resolve, so it cannot be used here.
135+
pub boxed_resolver: steal::Steal<OneThread<Box<dyn Any>>>,
136+
}
137+
122138
#[derive(Clone)]
123139
pub struct Resolutions {
124140
pub trait_map: TraitMap,

src/librustc_data_structures/sync.rs

+10
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,16 @@ impl<T: Copy> AtomicOnce<T> {
600600
value.unwrap()
601601
}
602602
}
603+
604+
#[inline]
605+
pub fn init(&self, value: T) {
606+
self.0.store(Some(value));
607+
}
608+
609+
#[inline]
610+
pub fn is_initalized(&self) -> bool {
611+
self.0.load().is_some()
612+
}
603613
}
604614

605615
#[derive(Debug)]

src/librustc_driver/lib.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,11 @@ pub fn run_compiler(
268268
if ppm.needs_ast_map(&opt_uii) {
269269
pretty::visit_crate(sess, &mut compiler.parse()?.peek_mut(), ppm);
270270
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
271+
let expansion_result = tcx.expand_macros(())?;
271272
pretty::print_after_hir_lowering(
272273
tcx,
273274
compiler.input(),
274-
&tcx.ast_crate.borrow(),
275+
&expansion_result.ast_crate.borrow(),
275276
ppm,
276277
opt_uii.clone(),
277278
compiler.output_file().as_ref().map(|p| &**p),
@@ -334,13 +335,14 @@ pub fn run_compiler(
334335

335336
if sess.opts.debugging_opts.save_analysis {
336337
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
338+
let expansion_result = tcx.expand_macros(())?;
337339
let result = tcx.analysis(LOCAL_CRATE);
338340
let crate_name = &tcx.crate_name.as_str();
339341

340342
time(sess, "save analysis", || {
341343
save::process_crate(
342344
tcx,
343-
&tcx.ast_crate.borrow(),
345+
&expansion_result.ast_crate.borrow(),
344346
crate_name,
345347
&compiler.input(),
346348
None,
@@ -355,7 +357,7 @@ pub fn run_compiler(
355357
} else {
356358
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
357359
// Drop AST after lowering HIR to free memory
358-
mem::drop(tcx.ast_crate.steal());
360+
mem::drop(tcx.expand_macros(()).unwrap().ast_crate.steal());
359361
});
360362
}
361363

@@ -368,7 +370,7 @@ pub fn run_compiler(
368370
if sess.opts.debugging_opts.save_analysis {
369371
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
370372
// Drop AST after lowering HIR to free memory
371-
mem::drop(tcx.ast_crate.steal());
373+
mem::drop(tcx.expand_macros(()).unwrap().ast_crate.steal());
372374
});
373375
}
374376

src/librustc_incremental/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ pub mod assert_module_sources;
2222
mod persist;
2323

2424
pub use assert_dep_graph::assert_dep_graph;
25-
pub use persist::dep_graph_tcx_init;
2625
pub use persist::{DepGraphFuture, load_dep_graph};
2726
pub use persist::load_query_result_cache;
2827
pub use persist::LoadResult;

src/librustc_incremental/persist/load.rs

-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use rustc_data_structures::fx::FxHashMap;
44
use rustc::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
55
use rustc::session::Session;
6-
use rustc::ty::TyCtxt;
76
use rustc::ty::query::OnDiskCache;
87
use rustc::util::common::time_ext;
98
use rustc_serialize::Decodable as RustcDecodable;
@@ -15,14 +14,6 @@ use super::fs::*;
1514
use super::file_format;
1615
use super::work_product;
1716

18-
pub fn dep_graph_tcx_init(tcx: TyCtxt<'_>) {
19-
if !tcx.dep_graph.is_fully_enabled() {
20-
return
21-
}
22-
23-
tcx.allocate_metadata_dep_nodes();
24-
}
25-
2617
type WorkProductMap = FxHashMap<WorkProductId, WorkProduct>;
2718

2819
pub enum LoadResult<T> {

src/librustc_incremental/persist/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ pub use fs::garbage_collect_session_directories;
1515
pub use fs::in_incr_comp_dir;
1616
pub use fs::in_incr_comp_dir_sess;
1717
pub use fs::prepare_session_directory;
18-
pub use load::dep_graph_tcx_init;
1918
pub use load::{DepGraphFuture, load_dep_graph};
2019
pub use load::load_query_result_cache;
2120
pub use load::LoadResult;

0 commit comments

Comments
 (0)