Skip to content

Commit 0a8629b

Browse files
committed
Auto merge of #85885 - bjorn3:remove_box_region, r=cjgillot
Don't use a generator for BoxedResolver The generator is non-trivial and requires unsafe code anyway. Using regular unsafe code without a generator is much easier to follow. Based on #85810 as it touches rustc_interface too.
2 parents dddebf9 + 4301d1e commit 0a8629b

File tree

6 files changed

+91
-215
lines changed

6 files changed

+91
-215
lines changed

compiler/rustc_data_structures/src/box_region.rs

-169
This file was deleted.

compiler/rustc_data_structures/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#![feature(array_windows)]
1111
#![feature(control_flow_enum)]
1212
#![feature(in_band_lifetimes)]
13-
#![feature(generator_trait)]
1413
#![feature(min_specialization)]
1514
#![feature(auto_traits)]
1615
#![feature(nll)]
@@ -63,7 +62,6 @@ macro_rules! unlikely {
6362

6463
pub mod base_n;
6564
pub mod binary_search_util;
66-
pub mod box_region;
6765
pub mod captures;
6866
pub mod flock;
6967
pub mod functor;

compiler/rustc_interface/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
#![feature(box_patterns)]
33
#![feature(internal_output_capture)]
44
#![feature(nll)]
5-
#![feature(generator_trait)]
6-
#![feature(generators)]
75
#![feature(once_cell)]
86
#![recursion_limit = "256"]
97

compiler/rustc_interface/src/passes.rs

+87-38
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use rustc_ast::mut_visit::MutVisitor;
66
use rustc_ast::{self as ast, visit};
77
use rustc_codegen_ssa::back::link::emit_metadata;
88
use rustc_codegen_ssa::traits::CodegenBackend;
9+
use rustc_data_structures::parallel;
910
use rustc_data_structures::steal::Steal;
1011
use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal};
1112
use rustc_data_structures::temp_dir::MaybeTempDir;
12-
use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
1313
use rustc_errors::{ErrorReported, PResult};
1414
use rustc_expand::base::ExtCtxt;
1515
use rustc_hir::def_id::LOCAL_CRATE;
@@ -47,7 +47,9 @@ use std::cell::RefCell;
4747
use std::ffi::OsString;
4848
use std::io::{self, BufWriter, Write};
4949
use std::lazy::SyncLazy;
50+
use std::marker::PhantomPinned;
5051
use std::path::PathBuf;
52+
use std::pin::Pin;
5153
use std::rc::Rc;
5254
use std::{env, fs, iter};
5355

@@ -85,11 +87,83 @@ fn count_nodes(krate: &ast::Crate) -> usize {
8587
counter.count
8688
}
8789

88-
declare_box_region_type!(
89-
pub BoxedResolver,
90-
for(),
91-
(&mut Resolver<'_>) -> (Result<ast::Crate>, ResolverOutputs)
92-
);
90+
pub use boxed_resolver::BoxedResolver;
91+
mod boxed_resolver {
92+
use super::*;
93+
94+
pub struct BoxedResolver(Pin<Box<BoxedResolverInner>>);
95+
96+
struct BoxedResolverInner {
97+
session: Lrc<Session>,
98+
resolver_arenas: Option<ResolverArenas<'static>>,
99+
resolver: Option<Resolver<'static>>,
100+
_pin: PhantomPinned,
101+
}
102+
103+
// Note: Drop order is important to prevent dangling references. Resolver must be dropped first,
104+
// then resolver_arenas and finally session.
105+
impl Drop for BoxedResolverInner {
106+
fn drop(&mut self) {
107+
self.resolver.take();
108+
self.resolver_arenas.take();
109+
}
110+
}
111+
112+
impl BoxedResolver {
113+
pub(super) fn new<F>(session: Lrc<Session>, make_resolver: F) -> Result<(ast::Crate, Self)>
114+
where
115+
F: for<'a> FnOnce(
116+
&'a Session,
117+
&'a ResolverArenas<'a>,
118+
) -> Result<(ast::Crate, Resolver<'a>)>,
119+
{
120+
let mut boxed_resolver = Box::new(BoxedResolverInner {
121+
session,
122+
resolver_arenas: Some(Resolver::arenas()),
123+
resolver: None,
124+
_pin: PhantomPinned,
125+
});
126+
// SAFETY: `make_resolver` takes a resolver arena with an arbitrary lifetime and
127+
// returns a resolver with the same lifetime as the arena. We ensure that the arena
128+
// outlives the resolver in the drop impl and elsewhere so these transmutes are sound.
129+
unsafe {
130+
let (crate_, resolver) = make_resolver(
131+
std::mem::transmute::<&Session, &Session>(&boxed_resolver.session),
132+
std::mem::transmute::<&ResolverArenas<'_>, &ResolverArenas<'_>>(
133+
boxed_resolver.resolver_arenas.as_ref().unwrap(),
134+
),
135+
)?;
136+
boxed_resolver.resolver = Some(resolver);
137+
Ok((crate_, BoxedResolver(Pin::new_unchecked(boxed_resolver))))
138+
}
139+
}
140+
141+
pub fn access<F: for<'a> FnOnce(&mut Resolver<'a>) -> R, R>(&mut self, f: F) -> R {
142+
// SAFETY: The resolver doesn't need to be pinned.
143+
let mut resolver = unsafe {
144+
self.0.as_mut().map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
145+
};
146+
f((&mut *resolver).as_mut().unwrap())
147+
}
148+
149+
pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ResolverOutputs {
150+
match Rc::try_unwrap(resolver) {
151+
Ok(resolver) => {
152+
let mut resolver = resolver.into_inner();
153+
// SAFETY: The resolver doesn't need to be pinned.
154+
let mut resolver = unsafe {
155+
resolver
156+
.0
157+
.as_mut()
158+
.map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
159+
};
160+
resolver.take().unwrap().into_outputs()
161+
}
162+
Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
163+
}
164+
}
165+
}
166+
}
93167

94168
/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
95169
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
@@ -111,41 +185,16 @@ pub fn configure_and_expand(
111185
// its contents but the results of name resolution on those contents. Hopefully we'll push
112186
// this back at some point.
113187
let crate_name = crate_name.to_string();
114-
let (result, resolver) = BoxedResolver::new(static move |mut action| {
115-
let _ = action;
116-
let sess = &*sess;
117-
let resolver_arenas = Resolver::arenas();
118-
let res = configure_and_expand_inner(
188+
BoxedResolver::new(sess, move |sess, resolver_arenas| {
189+
configure_and_expand_inner(
119190
sess,
120191
&lint_store,
121192
krate,
122193
&crate_name,
123194
&resolver_arenas,
124-
&*metadata_loader,
125-
);
126-
let mut resolver = match res {
127-
Err(v) => {
128-
yield BoxedResolver::initial_yield(Err(v));
129-
panic!()
130-
}
131-
Ok((krate, resolver)) => {
132-
action = yield BoxedResolver::initial_yield(Ok(krate));
133-
resolver
134-
}
135-
};
136-
box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver), action);
137-
resolver.into_outputs()
138-
});
139-
result.map(|k| (k, resolver))
140-
}
141-
142-
impl BoxedResolver {
143-
pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ResolverOutputs {
144-
match Rc::try_unwrap(resolver) {
145-
Ok(resolver) => resolver.into_inner().complete(),
146-
Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
147-
}
148-
}
195+
metadata_loader,
196+
)
197+
})
149198
}
150199

151200
pub fn register_plugins<'a>(
@@ -231,11 +280,11 @@ fn pre_expansion_lint(
231280

232281
fn configure_and_expand_inner<'a>(
233282
sess: &'a Session,
234-
lint_store: &'a LintStore,
283+
lint_store: &LintStore,
235284
mut krate: ast::Crate,
236285
crate_name: &str,
237286
resolver_arenas: &'a ResolverArenas<'a>,
238-
metadata_loader: &'a MetadataLoaderDyn,
287+
metadata_loader: Box<MetadataLoaderDyn>,
239288
) -> Result<(ast::Crate, Resolver<'a>)> {
240289
tracing::trace!("configure_and_expand_inner");
241290
pre_expansion_lint(sess, lint_store, &krate, crate_name);

compiler/rustc_metadata/src/creader.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub struct CStore {
5454
pub struct CrateLoader<'a> {
5555
// Immutable configuration.
5656
sess: &'a Session,
57-
metadata_loader: &'a MetadataLoaderDyn,
57+
metadata_loader: Box<MetadataLoaderDyn>,
5858
local_crate_name: Symbol,
5959
// Mutable output.
6060
cstore: CStore,
@@ -219,7 +219,7 @@ impl CStore {
219219
impl<'a> CrateLoader<'a> {
220220
pub fn new(
221221
sess: &'a Session,
222-
metadata_loader: &'a MetadataLoaderDyn,
222+
metadata_loader: Box<MetadataLoaderDyn>,
223223
local_crate_name: &str,
224224
) -> Self {
225225
let local_crate_stable_id =
@@ -544,7 +544,7 @@ impl<'a> CrateLoader<'a> {
544544
info!("falling back to a load");
545545
let mut locator = CrateLocator::new(
546546
self.sess,
547-
self.metadata_loader,
547+
&*self.metadata_loader,
548548
name,
549549
hash,
550550
host_hash,

0 commit comments

Comments
 (0)