Skip to content

Commit 031d968

Browse files
authored
Rollup merge of rust-lang#64648 - alexreg:rush-parsing, r=Mark-Simulacrum
REPL, part 1: Added interpreter mode to compiler interface, interpreter parsing functionality Summary: * Adds "interpreter mode" to compiler interface. This will be used later in several places, including diagnostics. * Adds "interpreter tag" to `ast::Local`s to track info like whether they came from a previous eval session or have been moved. * Added interface for injecting a pre-parsed "user body" into the parsing pipeline. cf. `TyCtxt::get_interp_user_fn`, `expr.rs` * Moved `Steal` data structure to `rustc_data_structures` crate since a) it was already used outside of `rustc::ty` crate, b) it's now used even a little more outside there. * Made a few more things `pub` (as little as possible), so the interpreter can use them. If you want the big picture of where this is going in terms of compiler changes (probably 2/3 more PRs needed), take a look at my [personal branch](https://github.com/alexreg/rust/tree/rush). I will also be publishing the REPL repo itself soon. Also, sorry for the lack of commits; I basically just carved this out of an even bigger squashed commit after much, much hacking! (It might be a tad heavy on cosmetic stuff too, for the same reason. If it's okay, then great, otherwise I can try to revert certain areas that people really don't want.) Maybe @Centril / @Zoxc for review? Not wholly sure. CC @nikomatsakis @mw @eddyb
2 parents e463a22 + 7062164 commit 031d968

File tree

31 files changed

+335
-114
lines changed

31 files changed

+335
-114
lines changed

src/librustc/arena.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ macro_rules! arena_types {
2323
[] generics: rustc::ty::Generics,
2424
[] trait_def: rustc::ty::TraitDef,
2525
[] adt_def: rustc::ty::AdtDef,
26-
[] steal_mir: rustc::ty::steal::Steal<rustc::mir::Body<$tcx>>,
26+
[] steal_mir: rustc_data_structures::steal::Steal<rustc::mir::Body<$tcx>>,
2727
[] mir: rustc::mir::Body<$tcx>,
28-
[] steal_promoted: rustc::ty::steal::Steal<
28+
[] steal_promoted: rustc_data_structures::steal::Steal<
2929
rustc_index::vec::IndexVec<
3030
rustc::mir::Promoted,
3131
rustc::mir::Body<$tcx>

src/librustc/hir/lowering.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2079,6 +2079,7 @@ impl<'a> LoweringContext<'a> {
20792079
span: l.span,
20802080
attrs: l.attrs.clone(),
20812081
source: hir::LocalSource::Normal,
2082+
interp_tag: l.interp_tag.clone(),
20822083
}, ids)
20832084
}
20842085

@@ -3048,6 +3049,7 @@ impl<'a> LoweringContext<'a> {
30483049
source,
30493050
span,
30503051
ty: None,
3052+
interp_tag: None,
30513053
};
30523054
self.stmt(span, hir::StmtKind::Local(P(local)))
30533055
}

src/librustc/hir/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,8 @@ pub struct Local {
12731273
/// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
12741274
/// desugaring. Otherwise will be `Normal`.
12751275
pub source: LocalSource,
1276+
/// See comment on `syntax::ast::Local`.
1277+
pub interp_tag: Option<ast::LocalInterpTag>,
12761278
}
12771279

12781280
/// Represents a single arm of a `match` expression, e.g.

src/librustc/ich/impls_hir.rs

+11
Original file line numberDiff line numberDiff line change
@@ -392,3 +392,14 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
392392
mem::discriminant(self).hash_stable(hcx, hasher);
393393
}
394394
}
395+
396+
impl_stable_hash_for!(enum ast::LocalInterpState {
397+
Uninitialized,
398+
Set,
399+
Moved,
400+
});
401+
402+
impl_stable_hash_for!(struct ast::LocalInterpTag {
403+
id,
404+
state,
405+
});

src/librustc/ich/impls_ty.rs

+5-13
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
//! This module contains `HashStable` implementations for various data types
2-
//! from rustc::ty in no particular order.
2+
//! from `rustc::ty` in no particular order.
33
44
use crate::ich::{Fingerprint, StableHashingContext, NodeIdHashingMode};
5+
use crate::middle::region;
6+
use crate::mir;
7+
use crate::ty;
8+
59
use rustc_data_structures::fx::FxHashMap;
610
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher};
711
use std::cell::RefCell;
812
use std::mem;
9-
use crate::middle::region;
10-
use crate::ty;
11-
use crate::mir;
1213

1314
impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::List<T>
1415
where
@@ -197,15 +198,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::FloatVid {
197198
}
198199
}
199200

200-
impl<'a, T> HashStable<StableHashingContext<'a>> for ty::steal::Steal<T>
201-
where
202-
T: HashStable<StableHashingContext<'a>>,
203-
{
204-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
205-
self.borrow().hash_stable(hcx, hasher);
206-
}
207-
}
208-
209201
impl<'a> HashStable<StableHashingContext<'a>>
210202
for crate::middle::privacy::AccessLevels {
211203
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {

src/librustc/query/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1120,8 +1120,7 @@ rustc_queries! {
11201120
}
11211121

11221122
// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
1123-
query instance_def_size_estimate(def: ty::InstanceDef<'tcx>)
1124-
-> usize {
1123+
query instance_def_size_estimate(def: ty::InstanceDef<'tcx>) -> usize {
11251124
no_force
11261125
desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) }
11271126
}
@@ -1130,5 +1129,10 @@ rustc_queries! {
11301129
eval_always
11311130
desc { "looking up enabled feature gates" }
11321131
}
1132+
1133+
query interp_user_fn(_: CrateNum) -> DefId {
1134+
eval_always
1135+
desc { "locating interpreter user fn in HIR" }
1136+
}
11331137
}
11341138
}

src/librustc/session/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ top_level_options!(
391391
// can influence whether overflow checks are done or not.
392392
debug_assertions: bool [TRACKED],
393393
debuginfo: DebugInfo [TRACKED],
394+
interp_mode: bool [TRACKED],
394395
lint_opts: Vec<(String, lint::Level)> [TRACKED],
395396
lint_cap: Option<lint::Level> [TRACKED],
396397
describe_lints: bool [UNTRACKED],
@@ -599,6 +600,7 @@ impl Default for Options {
599600
crate_types: Vec::new(),
600601
optimize: OptLevel::No,
601602
debuginfo: DebugInfo::None,
603+
interp_mode: false,
602604
lint_opts: Vec::new(),
603605
lint_cap: None,
604606
describe_lints: false,
@@ -2467,6 +2469,7 @@ pub fn build_session_options_and_crate_config(
24672469
crate_types,
24682470
optimize: opt_level,
24692471
debuginfo,
2472+
interp_mode: false,
24702473
lint_opts,
24712474
lint_cap,
24722475
describe_lints,

src/librustc/ty/context.rs

+44-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ use crate::ty::{InferConst, ParamConst};
3838
use crate::ty::GenericParamDefKind;
3939
use crate::ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx};
4040
use crate::ty::query;
41-
use crate::ty::steal::Steal;
4241
use crate::ty::subst::{UserSubsts, GenericArgKind};
4342
use crate::ty::{BoundVar, BindingMode};
4443
use crate::ty::CanonicalPolyFnSig;
@@ -49,12 +48,13 @@ use crate::util::nodemap::{FxHashMap, FxHashSet};
4948
use errors::DiagnosticBuilder;
5049
use arena::SyncDroplessArena;
5150
use smallvec::SmallVec;
51+
use rustc_index::vec::{Idx, IndexVec};
5252
use rustc_data_structures::stable_hasher::{
5353
HashStable, StableHasher, StableVec, hash_stable_hashmap,
5454
};
55-
use rustc_index::vec::{Idx, IndexVec};
5655
use rustc_data_structures::sharded::ShardedHashMap;
5756
use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal};
57+
use rustc_data_structures::steal::Steal;
5858
use std::any::Any;
5959
use std::borrow::Borrow;
6060
use std::cmp::Ordering;
@@ -2894,6 +2894,44 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
28942894
t as *const () == u as *const ()
28952895
}
28962896

2897+
/// In interpreter mode, locates the `DefId` of the user fn (a closure marked by an attribute named
2898+
/// `rustc_interp_user_fn`) by visiting the local crate's HIR.
2899+
fn find_interp_user_fn(tcx: TyCtxt<'_>) -> DefId {
2900+
use hir::intravisit::{self, Visitor, NestedVisitorMap};
2901+
2902+
struct InterpUserFnVisitor<'tcx> {
2903+
tcx: TyCtxt<'tcx>,
2904+
def_id: Option<DefId>,
2905+
}
2906+
2907+
impl<'tcx> Visitor<'tcx> for InterpUserFnVisitor<'tcx> {
2908+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
2909+
NestedVisitorMap::OnlyBodies(&self.tcx.hir())
2910+
}
2911+
2912+
fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
2913+
if syntax::attr::contains_name(&ex.attrs, sym::rustc_interp_user_fn) {
2914+
self.def_id = Some(self.tcx.hir().local_def_id(ex.hir_id));
2915+
return;
2916+
}
2917+
2918+
intravisit::walk_expr(self, ex);
2919+
}
2920+
}
2921+
2922+
let mut visitor = InterpUserFnVisitor {
2923+
tcx,
2924+
def_id: None,
2925+
};
2926+
tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
2927+
visitor.def_id
2928+
.unwrap_or_else(|| tcx.sess.fatal(&format!(
2929+
"could not find interpreter user fn in HIR; it should be a closure expression \
2930+
marked with the `#[{}]` attribute",
2931+
sym::rustc_interp_user_fn
2932+
)))
2933+
}
2934+
28972935
pub fn provide(providers: &mut ty::query::Providers<'_>) {
28982936
providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id);
28992937
providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).map(|v| &v[..]);
@@ -2971,4 +3009,8 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
29713009
assert_eq!(cnum, LOCAL_CRATE);
29723010
attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
29733011
};
3012+
providers.interp_user_fn = |tcx, cnum| {
3013+
assert_eq!(cnum, LOCAL_CRATE);
3014+
find_interp_user_fn(tcx)
3015+
};
29743016
}

src/librustc/ty/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ pub mod outlives;
105105
pub mod print;
106106
pub mod query;
107107
pub mod relate;
108-
pub mod steal;
109108
pub mod subst;
110109
pub mod trait_def;
111110
pub mod walk;

src/librustc/ty/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use crate::traits::query::outlives_bounds::OutlivesBound;
3434
use crate::traits::specialization_graph;
3535
use crate::traits::Clauses;
3636
use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, AdtSizedConstraint};
37-
use crate::ty::steal::Steal;
37+
use rustc_data_structures::steal::Steal;
3838
use crate::ty::util::NeedsDrop;
3939
use crate::ty::subst::SubstsRef;
4040
use crate::util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet};

src/librustc_data_structures/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub use ena::unify;
9494
pub mod vec_linked_list;
9595
pub mod work_queue;
9696
pub mod fingerprint;
97+
pub mod steal;
9798

9899
pub struct OnDrop<F: Fn()>(pub F);
99100

src/librustc/ty/steal.rs renamed to src/librustc_data_structures/steal.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use rustc_data_structures::sync::{RwLock, ReadGuard, MappedReadGuard};
1+
use crate::stable_hasher::{StableHasher, HashStable};
2+
use crate::sync::{RwLock, ReadGuard, MappedReadGuard};
23

34
/// The `Steal` struct is intended to used as the value for a query.
4-
/// Specifically, we sometimes have queries (*cough* MIR *cough*)
5+
/// Specifically, we sometimes have queries (in particular, for MIR)
56
/// where we create a large, complex value that we want to iteratively
67
/// update (e.g., optimize). We could clone the value for each
78
/// optimization, but that'd be expensive. And yet we don't just want
@@ -26,21 +27,28 @@ pub struct Steal<T> {
2627

2728
impl<T> Steal<T> {
2829
pub fn new(value: T) -> Self {
29-
Steal {
30+
Self {
3031
value: RwLock::new(Some(value))
3132
}
3233
}
3334

3435
pub fn borrow(&self) -> MappedReadGuard<'_, T> {
3536
ReadGuard::map(self.value.borrow(), |opt| match *opt {
36-
None => bug!("attempted to read from stolen value"),
37+
None => panic!("attempted to read from stolen value"),
3738
Some(ref v) => v
3839
})
3940
}
4041

4142
pub fn steal(&self) -> T {
42-
let value_ref = &mut *self.value.try_write().expect("stealing value which is locked");
43+
let value_ref = &mut *self.value.try_write()
44+
.expect("stealing value that is locked");
4345
let value = value_ref.take();
4446
value.expect("attempt to read from stolen value")
4547
}
4648
}
49+
50+
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Steal<T> {
51+
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
52+
self.borrow().hash_stable(hcx, hasher);
53+
}
54+
}

src/librustc_interface/interface.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ use rustc::session::{DiagnosticOutput, Session};
99
use rustc::util::common::ErrorReported;
1010
use rustc_codegen_utils::codegen_backend::CodegenBackend;
1111
use rustc_data_structures::OnDrop;
12+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1213
use rustc_data_structures::sync::Lrc;
13-
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
14+
use rustc_data_structures::steal::Steal;
1415
use rustc_metadata::cstore::CStore;
1516
use std::path::PathBuf;
1617
use std::result;
1718
use std::sync::{Arc, Mutex};
1819
use syntax;
20+
use syntax::parse::parser::InterpUserFn;
1921
use syntax::source_map::{FileLoader, SourceMap};
2022
use syntax_pos::edition;
2123

@@ -35,9 +37,19 @@ pub struct Compiler {
3537
pub(crate) queries: Queries,
3638
pub(crate) cstore: Lrc<CStore>,
3739
pub(crate) crate_name: Option<String>,
40+
/// In interpreter mode, the user fn to use when parsing.
41+
pub(crate) interp_user_fn: Option<Steal<InterpUserFn>>,
3842
}
3943

4044
impl Compiler {
45+
pub fn set_interp_user_fn(
46+
&mut self,
47+
interp_user_fn: Option<InterpUserFn>,
48+
) -> &mut Self {
49+
self.interp_user_fn = interp_user_fn.map(|user_fn| Steal::new(user_fn));
50+
self
51+
}
52+
4153
pub fn session(&self) -> &Lrc<Session> {
4254
&self.sess
4355
}
@@ -61,12 +73,12 @@ impl Compiler {
6173
}
6274
}
6375

64-
/// The compiler configuration
76+
/// The compiler configuration.
6577
pub struct Config {
66-
/// Command line options
78+
/// The command-line options.
6779
pub opts: config::Options,
6880

69-
/// cfg! configuration in addition to the default ones
81+
/// `cfg!` configuration in addition to the default ones.
7082
pub crate_cfg: FxHashSet<(String, Option<String>)>,
7183

7284
pub input: Input,
@@ -76,17 +88,14 @@ pub struct Config {
7688
pub file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
7789
pub diagnostic_output: DiagnosticOutput,
7890

79-
/// Set to capture stderr output during compiler execution
91+
/// `Some` to capture stderr output during compiler execution.
8092
pub stderr: Option<Arc<Mutex<Vec<u8>>>>,
8193

8294
pub crate_name: Option<String>,
8395
pub lint_caps: FxHashMap<lint::LintId, lint::Level>,
8496
}
8597

86-
pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
87-
where
88-
F: FnOnce(&Compiler) -> R,
89-
{
98+
pub fn create_compiler(config: Config) -> Compiler {
9099
let (sess, codegen_backend, source_map) = util::create_session(
91100
config.opts,
92101
config.crate_cfg,
@@ -98,7 +107,7 @@ where
98107

99108
let cstore = Lrc::new(CStore::new(codegen_backend.metadata_loader()));
100109

101-
let compiler = Compiler {
110+
Compiler {
102111
sess,
103112
codegen_backend,
104113
source_map,
@@ -109,7 +118,15 @@ where
109118
output_file: config.output_file,
110119
queries: Default::default(),
111120
crate_name: config.crate_name,
112-
};
121+
interp_user_fn: None,
122+
}
123+
}
124+
125+
pub fn run_compiler_in_existing_thread_pool<R>(
126+
config: Config,
127+
f: impl FnOnce(&Compiler) -> R,
128+
) -> R {
129+
let compiler = create_compiler(config);
113130

114131
let _sess_abort_error = OnDrop(|| {
115132
compiler.sess.diagnostic().print_error_count(&util::diagnostics_registry());

src/librustc_interface/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ mod proc_macro_decls;
1919
mod profile;
2020

2121
pub use interface::{run_compiler, Config};
22+
pub use passes::BoxedGlobalCtxt;

0 commit comments

Comments
 (0)