Skip to content

Commit 95f0ca1

Browse files
committed
Turn macro expansion and name resolution into a query
1 parent b8c1493 commit 95f0ca1

File tree

12 files changed

+144
-118
lines changed

12 files changed

+144
-118
lines changed

src/librustc/hir/def_id.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,10 @@ impl fmt::Debug for DefId {
222222

223223
ty::tls::with_opt(|opt_tcx| {
224224
if let Some(tcx) = opt_tcx {
225-
write!(f, " ~ {}", tcx.def_path_debug_str(*self))?;
225+
// Only print the path after HIR lowering is done
226+
if tcx.is_hir_lowered() {
227+
write!(f, " ~ {}", tcx.def_path_debug_str(*self))?;
228+
}
226229
}
227230
Ok(())
228231
})?;

src/librustc/query/mod.rs

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

src/librustc/ty/context.rs

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5151
StableVec};
5252
use arena::{TypedArena, SyncDroplessArena};
5353
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
54-
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal, AtomicOnce, OneThread};
54+
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal, AtomicOnce, Once, OneThread};
5555
use std::any::Any;
5656
use std::borrow::Borrow;
5757
use std::cmp::Ordering;
@@ -1019,15 +1019,20 @@ pub struct GlobalCtxt<'tcx> {
10191019

10201020
pub io: InputsAndOutputs,
10211021

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

1024-
/// This stores a `Lrc<Option<Lock<BoxedResolver>>>)>`, but that type depends on
1025-
/// librustc_resolve, so it cannot be used here.
1026-
pub boxed_resolver: Steal<OneThread<Box<dyn Any>>>,
1026+
pub sess_rc: Lrc<Session>,
1027+
1028+
/// The AST after registering plugins.
1029+
pub ast_crate: Steal<(ast::Crate, ty::PluginInfo)>,
10271030

10281031
lowered_hir: AtomicOnce<&'tcx hir::LoweredHir>,
10291032
hir_map: AtomicOnce<&'tcx hir_map::Map<'tcx>>,
10301033

1034+
metadata_dep_nodes: Once<()>,
1035+
10311036
pub queries: query::Queries<'tcx>,
10321037

10331038
// Internal cache for metadata decoding. No need to track deps on this.
@@ -1087,10 +1092,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
10871092
self.lowered_hir.get_or_init(|| {
10881093
// FIXME: The ignore here is only sound because all queries
10891094
// used to compute LoweredHir are eval_always
1090-
self.dep_graph.with_ignore(|| self.lower_ast_to_hir(LocalCrate).unwrap())
1095+
self.dep_graph.with_ignore(|| {
1096+
let map = self.lower_ast_to_hir(LocalCrate).unwrap();
1097+
self.lowered_hir.init(map);
1098+
self.allocate_metadata_dep_nodes();
1099+
map
1100+
})
10911101
})
10921102
}
10931103

1104+
pub fn is_hir_lowered(self) -> bool {
1105+
self.lowered_hir.is_initalized()
1106+
}
1107+
10941108
#[inline(always)]
10951109
pub fn hir(self) -> &'gcx hir_map::Map<'gcx> {
10961110
self.hir_map.get_or_init(|| {
@@ -1194,14 +1208,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11941208
/// value (types, substs, etc.) can only be used while `ty::tls` has a valid
11951209
/// reference to the context, to allow formatting values that need it.
11961210
pub fn create_global_ctxt(
1197-
s: &'tcx Session,
1211+
s: &'tcx Lrc<Session>,
11981212
cstore: &'tcx CrateStoreDyn,
1213+
cstore_rc: Box<dyn Any>,
11991214
local_providers: ty::query::Providers<'tcx>,
12001215
extern_providers: ty::query::Providers<'tcx>,
12011216
arenas: &'tcx AllArenas<'tcx>,
12021217
dep_graph: DepGraph,
12031218
ast_crate: ast::Crate,
1204-
boxed_resolver: Box<dyn Any>,
1219+
plugin_info: ty::PluginInfo,
12051220
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
12061221
crate_name: &str,
12071222
tx: mpsc::Sender<Box<dyn Any + Send>>,
@@ -1217,16 +1232,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12171232
providers[LOCAL_CRATE] = local_providers;
12181233

12191234
GlobalCtxt {
1220-
sess: s,
1235+
sess: &**s,
12211236
cstore,
1237+
cstore_rc: OneThread::new(Steal::new(cstore_rc)),
1238+
sess_rc: s.clone(),
12221239
global_arenas: &arenas.global,
12231240
global_interners: interners,
12241241
dep_graph,
12251242
types: common_types,
1226-
ast_crate: Steal::new(ast_crate),
1227-
boxed_resolver: Steal::new(OneThread::new(boxed_resolver)),
1243+
ast_crate: Steal::new((ast_crate, plugin_info)),
12281244
lowered_hir: AtomicOnce::new(),
12291245
hir_map: AtomicOnce::new(),
1246+
metadata_dep_nodes: Once::new(),
12301247
queries: query::Queries::new(
12311248
providers,
12321249
extern_providers,
@@ -1391,18 +1408,24 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13911408
// With full-fledged red/green, the method will probably become unnecessary
13921409
// as this will be done on-demand.
13931410
pub fn allocate_metadata_dep_nodes(self) {
1394-
// We cannot use the query versions of crates() and crate_hash(), since
1395-
// those would need the DepNodes that we are allocating here.
1396-
for cnum in self.cstore.crates_untracked() {
1397-
let dep_node = DepNode::new(self, DepConstructor::CrateMetadata(cnum));
1398-
let crate_hash = self.cstore.crate_hash_untracked(cnum);
1399-
self.dep_graph.with_task(dep_node,
1400-
self,
1401-
crate_hash,
1402-
|_, x| x, // No transformation needed
1403-
Some(dep_graph::hash_result),
1404-
);
1405-
}
1411+
if !self.dep_graph.is_fully_enabled() {
1412+
return
1413+
}
1414+
1415+
self.metadata_dep_nodes.init_locking(|| {
1416+
// We cannot use the query versions of crates() and crate_hash(), since
1417+
// those would need the DepNodes that we are allocating here.
1418+
for cnum in self.cstore.crates_untracked() {
1419+
let dep_node = DepNode::new(self, DepConstructor::CrateMetadata(cnum));
1420+
let crate_hash = self.cstore.crate_hash_untracked(cnum);
1421+
self.dep_graph.with_task(dep_node,
1422+
self,
1423+
crate_hash,
1424+
|_, x| x, // No transformation needed
1425+
Some(dep_graph::hash_result),
1426+
);
1427+
}
1428+
});
14061429
}
14071430

14081431
pub fn serialize_query_result_cache<E>(self,

src/librustc/ty/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,15 @@ 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 syntax::ast::{self, Name, Ident, NodeId};
4546
use syntax::attr;
4647
use syntax::ext::hygiene::Mark;
48+
use syntax::ext::base::NamedSyntaxExtension;
49+
use syntax::feature_gate::AttributeType;
4750
use syntax::symbol::{keywords, Symbol, LocalInternedString, InternedString};
4851
use syntax_pos::Span;
4952

@@ -117,6 +120,19 @@ mod sty;
117120

118121
// Data types
119122

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

src/librustc_data_structures/sync.rs

Lines changed: 10 additions & 0 deletions
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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,11 @@ pub fn run_compiler(
253253
if ppm.needs_ast_map(&opt_uii) {
254254
pretty::visit_crate(sess, &mut compiler.parse()?.peek_mut(), ppm);
255255
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
256+
let expansion_result = tcx.expand_macros(LocalCrate)?;
256257
pretty::print_after_hir_lowering(
257258
tcx,
258259
compiler.input(),
259-
&tcx.ast_crate.borrow(),
260+
&expansion_result.ast_crate.borrow(),
260261
ppm,
261262
opt_uii.clone(),
262263
compiler.output_file().as_ref().map(|p| &**p),
@@ -319,13 +320,14 @@ pub fn run_compiler(
319320

320321
if sess.opts.debugging_opts.save_analysis {
321322
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
323+
let expansion_result = tcx.expand_macros(LocalCrate)?;
322324
let result = tcx.analysis(LOCAL_CRATE);
323325
let crate_name = &tcx.crate_name.as_str();
324326

325327
time(sess, "save analysis", || {
326328
save::process_crate(
327329
tcx,
328-
&tcx.ast_crate.borrow(),
330+
&expansion_result.ast_crate.borrow(),
329331
crate_name,
330332
&compiler.input(),
331333
None,
@@ -340,7 +342,7 @@ pub fn run_compiler(
340342
} else {
341343
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
342344
// Drop AST after lowering HIR to free memory
343-
mem::drop(tcx.ast_crate.steal());
345+
mem::drop(tcx.expand_macros(LocalCrate).unwrap().ast_crate.steal());
344346
});
345347
}
346348

@@ -353,7 +355,7 @@ pub fn run_compiler(
353355
if sess.opts.debugging_opts.save_analysis {
354356
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
355357
// Drop AST after lowering HIR to free memory
356-
mem::drop(tcx.ast_crate.steal());
358+
mem::drop(tcx.expand_macros(LocalCrate).unwrap().ast_crate.steal());
357359
});
358360
}
359361

src/librustc_incremental/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ pub mod assert_module_sources;
2121
mod persist;
2222

2323
pub use assert_dep_graph::assert_dep_graph;
24-
pub use persist::dep_graph_tcx_init;
2524
pub use persist::{DepGraphFuture, load_dep_graph};
2625
pub use persist::load_query_result_cache;
2726
pub use persist::LoadResult;

src/librustc_incremental/persist/load.rs

Lines changed: 0 additions & 9 deletions
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<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
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

Lines changed: 0 additions & 1 deletion
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)