Skip to content

Commit 2efc90e

Browse files
committed
Auto merge of #102769 - nnethercote:rustdoc-startup, r=jyn514
Clean up rustdoc startup Startup is pretty hairy, in both rustdoc and rustc. The first commit here improves the rustdoc situation quite a bit. The remaining commits are smaller but also help. Best reviewed one commit at a time. r? `@jyn514`
2 parents a24a020 + ca2561a commit 2efc90e

File tree

7 files changed

+161
-165
lines changed

7 files changed

+161
-165
lines changed

Diff for: compiler/rustc_interface/src/interface.rs

+47-53
Original file line numberDiff line numberDiff line change
@@ -275,66 +275,60 @@ pub struct Config {
275275
pub registry: Registry,
276276
}
277277

278-
pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R) -> R {
279-
crate::callbacks::setup_callbacks();
280-
281-
let registry = &config.registry;
282-
let (mut sess, codegen_backend) = util::create_session(
283-
config.opts,
284-
config.crate_cfg,
285-
config.crate_check_cfg,
286-
config.file_loader,
287-
config.input_path.clone(),
288-
config.lint_caps,
289-
config.make_codegen_backend,
290-
registry.clone(),
291-
);
292-
293-
if let Some(parse_sess_created) = config.parse_sess_created {
294-
parse_sess_created(
295-
&mut Lrc::get_mut(&mut sess)
296-
.expect("create_session() should never share the returned session")
297-
.parse_sess,
298-
);
299-
}
300-
301-
let temps_dir = sess.opts.unstable_opts.temps_dir.as_ref().map(|o| PathBuf::from(&o));
302-
303-
let compiler = Compiler {
304-
sess,
305-
codegen_backend,
306-
input: config.input,
307-
input_path: config.input_path,
308-
output_dir: config.output_dir,
309-
output_file: config.output_file,
310-
temps_dir,
311-
register_lints: config.register_lints,
312-
override_queries: config.override_queries,
313-
};
314-
315-
rustc_span::with_source_map(compiler.sess.parse_sess.clone_source_map(), move || {
316-
let r = {
317-
let _sess_abort_error = OnDrop(|| {
318-
compiler.sess.finish_diagnostics(registry);
319-
});
320-
321-
f(&compiler)
322-
};
323-
324-
let prof = compiler.sess.prof.clone();
325-
prof.generic_activity("drop_compiler").run(move || drop(compiler));
326-
r
327-
})
328-
}
329-
330278
// JUSTIFICATION: before session exists, only config
331279
#[allow(rustc::bad_opt_access)]
332280
pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
333281
trace!("run_compiler");
334282
util::run_in_thread_pool_with_globals(
335283
config.opts.edition,
336284
config.opts.unstable_opts.threads,
337-
|| create_compiler_and_run(config, f),
285+
|| {
286+
crate::callbacks::setup_callbacks();
287+
288+
let registry = &config.registry;
289+
let (mut sess, codegen_backend) = util::create_session(
290+
config.opts,
291+
config.crate_cfg,
292+
config.crate_check_cfg,
293+
config.file_loader,
294+
config.input_path.clone(),
295+
config.lint_caps,
296+
config.make_codegen_backend,
297+
registry.clone(),
298+
);
299+
300+
if let Some(parse_sess_created) = config.parse_sess_created {
301+
parse_sess_created(&mut sess.parse_sess);
302+
}
303+
304+
let temps_dir = sess.opts.unstable_opts.temps_dir.as_ref().map(|o| PathBuf::from(&o));
305+
306+
let compiler = Compiler {
307+
sess: Lrc::new(sess),
308+
codegen_backend: Lrc::new(codegen_backend),
309+
input: config.input,
310+
input_path: config.input_path,
311+
output_dir: config.output_dir,
312+
output_file: config.output_file,
313+
temps_dir,
314+
register_lints: config.register_lints,
315+
override_queries: config.override_queries,
316+
};
317+
318+
rustc_span::with_source_map(compiler.sess.parse_sess.clone_source_map(), move || {
319+
let r = {
320+
let _sess_abort_error = OnDrop(|| {
321+
compiler.sess.finish_diagnostics(registry);
322+
});
323+
324+
f(&compiler)
325+
};
326+
327+
let prof = compiler.sess.prof.clone();
328+
prof.generic_activity("drop_compiler").run(move || drop(compiler));
329+
r
330+
})
331+
},
338332
)
339333
}
340334

Diff for: compiler/rustc_interface/src/util.rs

+21-24
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use rustc_codegen_ssa::traits::CodegenBackend;
55
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
66
#[cfg(parallel_compiler)]
77
use rustc_data_structures::jobserver;
8-
use rustc_data_structures::sync::Lrc;
98
use rustc_errors::registry::Registry;
109
#[cfg(parallel_compiler)]
1110
use rustc_middle::ty::tls;
@@ -72,7 +71,7 @@ pub fn create_session(
7271
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
7372
>,
7473
descriptions: Registry,
75-
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>) {
74+
) -> (Session, Box<dyn CodegenBackend>) {
7675
let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend {
7776
make_codegen_backend(&sopts)
7877
} else {
@@ -119,7 +118,7 @@ pub fn create_session(
119118
sess.parse_sess.config = cfg;
120119
sess.parse_sess.check_config = check_cfg;
121120

122-
(Lrc::new(sess), Lrc::new(codegen_backend))
121+
(sess, codegen_backend)
123122
}
124123

125124
const STACK_SIZE: usize = 8 * 1024 * 1024;
@@ -130,33 +129,31 @@ fn get_stack_size() -> Option<usize> {
130129
env::var_os("RUST_MIN_STACK").is_none().then_some(STACK_SIZE)
131130
}
132131

133-
/// Like a `thread::Builder::spawn` followed by a `join()`, but avoids the need
134-
/// for `'static` bounds.
135132
#[cfg(not(parallel_compiler))]
136-
fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: F) -> R {
137-
// SAFETY: join() is called immediately, so any closure captures are still
138-
// alive.
139-
match unsafe { cfg.spawn_unchecked(f) }.unwrap().join() {
140-
Ok(v) => v,
141-
Err(e) => panic::resume_unwind(e),
142-
}
143-
}
144-
145-
#[cfg(not(parallel_compiler))]
146-
pub fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
133+
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
147134
edition: Edition,
148135
_threads: usize,
149136
f: F,
150137
) -> R {
151-
let mut cfg = thread::Builder::new().name("rustc".to_string());
152-
153-
if let Some(size) = get_stack_size() {
154-
cfg = cfg.stack_size(size);
155-
}
138+
// The thread pool is a single thread in the non-parallel compiler.
139+
thread::scope(|s| {
140+
let mut builder = thread::Builder::new().name("rustc".to_string());
141+
if let Some(size) = get_stack_size() {
142+
builder = builder.stack_size(size);
143+
}
156144

157-
let main_handler = move || rustc_span::create_session_globals_then(edition, f);
145+
// `unwrap` is ok here because `spawn_scoped` only panics if the thread
146+
// name contains null bytes.
147+
let r = builder
148+
.spawn_scoped(s, move || rustc_span::create_session_globals_then(edition, f))
149+
.unwrap()
150+
.join();
158151

159-
scoped_thread(cfg, main_handler)
152+
match r {
153+
Ok(v) => v,
154+
Err(e) => panic::resume_unwind(e),
155+
}
156+
})
160157
}
161158

162159
/// Creates a new thread and forwards information in thread locals to it.
@@ -175,7 +172,7 @@ unsafe fn handle_deadlock() {
175172
}
176173

177174
#[cfg(parallel_compiler)]
178-
pub fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
175+
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
179176
edition: Edition,
180177
threads: usize,
181178
f: F,

Diff for: src/librustdoc/config.rs

+43-37
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,6 @@ pub(crate) struct Options {
142142
// Options that alter generated documentation pages
143143
/// Crate version to note on the sidebar of generated docs.
144144
pub(crate) crate_version: Option<String>,
145-
/// Collected options specific to outputting final pages.
146-
pub(crate) render_options: RenderOptions,
147145
/// The format that we output when rendering.
148146
///
149147
/// Currently used only for the `--show-coverage` option.
@@ -159,6 +157,10 @@ pub(crate) struct Options {
159157
/// Configuration for scraping examples from the current crate. If this option is Some(..) then
160158
/// the compiler will scrape examples and not generate documentation.
161159
pub(crate) scrape_examples_options: Option<ScrapeExamplesOptions>,
160+
161+
/// Note: this field is duplicated in `RenderOptions` because it's useful
162+
/// to have it in both places.
163+
pub(crate) unstable_features: rustc_feature::UnstableFeatures,
162164
}
163165

164166
impl fmt::Debug for Options {
@@ -194,14 +196,14 @@ impl fmt::Debug for Options {
194196
.field("persist_doctests", &self.persist_doctests)
195197
.field("show_coverage", &self.show_coverage)
196198
.field("crate_version", &self.crate_version)
197-
.field("render_options", &self.render_options)
198199
.field("runtool", &self.runtool)
199200
.field("runtool_args", &self.runtool_args)
200201
.field("enable-per-target-ignores", &self.enable_per_target_ignores)
201202
.field("run_check", &self.run_check)
202203
.field("no_run", &self.no_run)
203204
.field("nocapture", &self.nocapture)
204205
.field("scrape_examples_options", &self.scrape_examples_options)
206+
.field("unstable_features", &self.unstable_features)
205207
.finish()
206208
}
207209
}
@@ -267,6 +269,8 @@ pub(crate) struct RenderOptions {
267269
pub(crate) generate_redirect_map: bool,
268270
/// Show the memory layout of types in the docs.
269271
pub(crate) show_type_layout: bool,
272+
/// Note: this field is duplicated in `Options` because it's useful to have
273+
/// it in both places.
270274
pub(crate) unstable_features: rustc_feature::UnstableFeatures,
271275
pub(crate) emit: Vec<EmitType>,
272276
/// If `true`, HTML source pages will generate links for items to their definition.
@@ -316,7 +320,7 @@ impl Options {
316320
pub(crate) fn from_matches(
317321
matches: &getopts::Matches,
318322
args: Vec<String>,
319-
) -> Result<Options, i32> {
323+
) -> Result<(Options, RenderOptions), i32> {
320324
let args = &args[1..];
321325
// Check for unstable options.
322326
nightly_options::check_nightly_options(matches, &opts());
@@ -710,7 +714,9 @@ impl Options {
710714
let with_examples = matches.opt_strs("with-examples");
711715
let call_locations = crate::scrape_examples::load_call_locations(with_examples, &diag)?;
712716

713-
Ok(Options {
717+
let unstable_features =
718+
rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
719+
let options = Options {
714720
input,
715721
proc_macro_crate,
716722
error_format,
@@ -744,42 +750,42 @@ impl Options {
744750
run_check,
745751
no_run,
746752
nocapture,
747-
render_options: RenderOptions {
748-
output,
749-
external_html,
750-
id_map,
751-
playground_url,
752-
module_sorting,
753-
themes,
754-
extension_css,
755-
extern_html_root_urls,
756-
extern_html_root_takes_precedence,
757-
default_settings,
758-
resource_suffix,
759-
enable_minification,
760-
enable_index_page,
761-
index_page,
762-
static_root_path,
763-
markdown_no_toc,
764-
markdown_css,
765-
markdown_playground_url,
766-
document_private,
767-
document_hidden,
768-
generate_redirect_map,
769-
show_type_layout,
770-
unstable_features: rustc_feature::UnstableFeatures::from_environment(
771-
crate_name.as_deref(),
772-
),
773-
emit,
774-
generate_link_to_definition,
775-
call_locations,
776-
no_emit_shared: false,
777-
},
778753
crate_name,
779754
output_format,
780755
json_unused_externs,
781756
scrape_examples_options,
782-
})
757+
unstable_features,
758+
};
759+
let render_options = RenderOptions {
760+
output,
761+
external_html,
762+
id_map,
763+
playground_url,
764+
module_sorting,
765+
themes,
766+
extension_css,
767+
extern_html_root_urls,
768+
extern_html_root_takes_precedence,
769+
default_settings,
770+
resource_suffix,
771+
enable_minification,
772+
enable_index_page,
773+
index_page,
774+
static_root_path,
775+
markdown_no_toc,
776+
markdown_css,
777+
markdown_playground_url,
778+
document_private,
779+
document_hidden,
780+
generate_redirect_map,
781+
show_type_layout,
782+
unstable_features,
783+
emit,
784+
generate_link_to_definition,
785+
call_locations,
786+
no_emit_shared: false,
787+
};
788+
Ok((options, render_options))
783789
}
784790

785791
/// Returns `true` if the file given as `self.input` is a Markdown file.

Diff for: src/librustdoc/doctest.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use rustc_session::{lint, Session};
1818
use rustc_span::edition::Edition;
1919
use rustc_span::source_map::SourceMap;
2020
use rustc_span::symbol::sym;
21-
use rustc_span::Symbol;
2221
use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP};
2322
use rustc_target::spec::TargetTriple;
2423
use tempfile::Builder as TempFileBuilder;
@@ -80,7 +79,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
8079
lint_cap: Some(options.lint_cap.unwrap_or(lint::Forbid)),
8180
cg: options.codegen_options.clone(),
8281
externs: options.externs.clone(),
83-
unstable_features: options.render_options.unstable_features,
82+
unstable_features: options.unstable_features,
8483
actually_rustdoc: true,
8584
edition: options.edition,
8685
target_triple: options.target.clone(),
@@ -124,7 +123,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
124123
let opts = scrape_test_config(crate_attrs);
125124
let enable_per_target_ignores = options.enable_per_target_ignores;
126125
let mut collector = Collector::new(
127-
tcx.crate_name(LOCAL_CRATE),
126+
tcx.crate_name(LOCAL_CRATE).to_string(),
128127
options,
129128
false,
130129
opts,
@@ -908,7 +907,7 @@ pub(crate) struct Collector {
908907
rustdoc_options: RustdocOptions,
909908
use_headers: bool,
910909
enable_per_target_ignores: bool,
911-
crate_name: Symbol,
910+
crate_name: String,
912911
opts: GlobalTestOptions,
913912
position: Span,
914913
source_map: Option<Lrc<SourceMap>>,
@@ -920,7 +919,7 @@ pub(crate) struct Collector {
920919

921920
impl Collector {
922921
pub(crate) fn new(
923-
crate_name: Symbol,
922+
crate_name: String,
924923
rustdoc_options: RustdocOptions,
925924
use_headers: bool,
926925
opts: GlobalTestOptions,
@@ -983,7 +982,7 @@ impl Tester for Collector {
983982
fn add_test(&mut self, test: String, config: LangString, line: usize) {
984983
let filename = self.get_filename();
985984
let name = self.generate_name(line, &filename);
986-
let crate_name = self.crate_name.to_string();
985+
let crate_name = self.crate_name.clone();
987986
let opts = self.opts.clone();
988987
let edition = config.edition.unwrap_or(self.rustdoc_options.edition);
989988
let rustdoc_options = self.rustdoc_options.clone();

0 commit comments

Comments
 (0)