Auto merge of #112982 - lukas-code:bootstrap-alias-default-crates, r=albertlarsan68
bootstrap: update defaults for `compiler` and `library` aliases * `x doc compiler` now documents all of compiler, not just `rustc_driver`. * `x doc` with compiler docs enabled now includes `rustc-main` and `rustc_smir`. `rustc_codegen_llvm` is only included if the LLVM backend is enabled, which is the default. * `x doc library` now excludes `sysroot`. * `x check compiler` and `x check library` now properly check tests/benches/examples of all compiler or library crates, respectively. Note that `x check compiler` will check the library artifacts, but not tests. fixes the fallout from https://github.com/rust-lang/rust/pull/111955, cc `@jyn514`
This commit is contained in:
commit
bacf5bcbc7
10 changed files with 118 additions and 89 deletions
|
@ -1,6 +1,6 @@
|
||||||
//! The WIP stable interface to rustc internals.
|
//! The WIP stable interface to rustc internals.
|
||||||
//!
|
//!
|
||||||
//! For more information see https://github.com/rust-lang/project-stable-mir
|
//! For more information see <https://github.com/rust-lang/project-stable-mir>
|
||||||
//!
|
//!
|
||||||
//! # Note
|
//! # Note
|
||||||
//!
|
//!
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
#![feature(local_key_cell_methods)]
|
#![feature(local_key_cell_methods)]
|
||||||
#![feature(ptr_metadata)]
|
#![feature(ptr_metadata)]
|
||||||
#![feature(type_alias_impl_trait)] // Used to define opaque types.
|
#![feature(type_alias_impl_trait)] // Used to define opaque types.
|
||||||
|
#![feature(intra_doc_pointers)]
|
||||||
|
|
||||||
// Declare extern rustc_* crates to enable building this crate separately from the compiler.
|
// Declare extern rustc_* crates to enable building this crate separately from the compiler.
|
||||||
#[cfg(not(feature = "default"))]
|
#[cfg(not(feature = "default"))]
|
||||||
|
|
|
@ -185,9 +185,9 @@ pub enum Rvalue {
|
||||||
/// [#91095]. Note too that the value of the discriminant is not the same thing as the
|
/// [#91095]. Note too that the value of the discriminant is not the same thing as the
|
||||||
/// variant index; use [`discriminant_for_variant`] to convert.
|
/// variant index; use [`discriminant_for_variant`] to convert.
|
||||||
///
|
///
|
||||||
/// [`discriminant_ty`]: crate::ty::Ty::discriminant_ty
|
/// [`discriminant_ty`]: rustc_middle::ty::Ty::discriminant_ty
|
||||||
/// [#91095]: https://github.com/rust-lang/rust/issues/91095
|
/// [#91095]: https://github.com/rust-lang/rust/issues/91095
|
||||||
/// [`discriminant_for_variant`]: crate::ty::Ty::discriminant_for_variant
|
/// [`discriminant_for_variant`]: rustc_middle::ty::Ty::discriminant_for_variant
|
||||||
Discriminant(Place),
|
Discriminant(Place),
|
||||||
|
|
||||||
/// Yields the length of the place, as a `usize`.
|
/// Yields the length of the place, as a `usize`.
|
||||||
|
|
|
@ -115,6 +115,43 @@ impl RunConfig<'_> {
|
||||||
}
|
}
|
||||||
INTERNER.intern_list(crates)
|
INTERNER.intern_list(crates)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Given an `alias` selected by the `Step` and the paths passed on the command line,
|
||||||
|
/// return a list of the crates that should be built.
|
||||||
|
///
|
||||||
|
/// Normally, people will pass *just* `library` if they pass it.
|
||||||
|
/// But it's possible (although strange) to pass something like `library std core`.
|
||||||
|
/// Build all crates anyway, as if they hadn't passed the other args.
|
||||||
|
pub fn make_run_crates(&self, alias: Alias) -> Interned<Vec<String>> {
|
||||||
|
let has_alias =
|
||||||
|
self.paths.iter().any(|set| set.assert_single_path().path.ends_with(alias.as_str()));
|
||||||
|
if !has_alias {
|
||||||
|
return self.cargo_crates_in_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
let crates = match alias {
|
||||||
|
Alias::Library => self.builder.in_tree_crates("sysroot", Some(self.target)),
|
||||||
|
Alias::Compiler => self.builder.in_tree_crates("rustc-main", Some(self.target)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let crate_names = crates.into_iter().map(|krate| krate.name.to_string()).collect();
|
||||||
|
INTERNER.intern_list(crate_names)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum Alias {
|
||||||
|
Library,
|
||||||
|
Compiler,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Alias {
|
||||||
|
fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Alias::Library => "library",
|
||||||
|
Alias::Compiler => "compiler",
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A description of the crates in this set, suitable for passing to `builder.info`.
|
/// A description of the crates in this set, suitable for passing to `builder.info`.
|
||||||
|
|
|
@ -68,13 +68,17 @@ macro_rules! std {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! doc_std {
|
macro_rules! doc_std {
|
||||||
($host:ident => $target:ident, stage = $stage:literal) => {
|
($host:ident => $target:ident, stage = $stage:literal) => {{
|
||||||
|
let config = configure("doc", &["A"], &["A"]);
|
||||||
|
let build = Build::new(config);
|
||||||
|
let builder = Builder::new(&build);
|
||||||
doc::Std::new(
|
doc::Std::new(
|
||||||
$stage,
|
$stage,
|
||||||
TargetSelection::from_user(stringify!($target)),
|
TargetSelection::from_user(stringify!($target)),
|
||||||
|
&builder,
|
||||||
DocumentationFormat::HTML,
|
DocumentationFormat::HTML,
|
||||||
)
|
)
|
||||||
};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! rustc {
|
macro_rules! rustc {
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
|
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
|
||||||
|
|
||||||
use crate::builder::{crate_description, Builder, Kind, RunConfig, ShouldRun, Step};
|
use crate::builder::{crate_description, Alias, Builder, Kind, RunConfig, ShouldRun, Step};
|
||||||
use crate::cache::Interned;
|
use crate::cache::Interned;
|
||||||
use crate::compile::{
|
use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo};
|
||||||
add_to_sysroot, make_run_crates, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo,
|
|
||||||
};
|
|
||||||
use crate::config::TargetSelection;
|
use crate::config::TargetSelection;
|
||||||
use crate::tool::{prepare_tool_cargo, SourceType};
|
use crate::tool::{prepare_tool_cargo, SourceType};
|
||||||
use crate::INTERNER;
|
use crate::INTERNER;
|
||||||
|
@ -89,7 +87,7 @@ impl Step for Std {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_run(run: RunConfig<'_>) {
|
fn make_run(run: RunConfig<'_>) {
|
||||||
let crates = make_run_crates(&run, "library");
|
let crates = run.make_run_crates(Alias::Library);
|
||||||
run.builder.ensure(Std { target: run.target, crates });
|
run.builder.ensure(Std { target: run.target, crates });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +138,7 @@ impl Step for Std {
|
||||||
|
|
||||||
// don't run on std twice with x.py clippy
|
// don't run on std twice with x.py clippy
|
||||||
// don't check test dependencies if we haven't built libtest
|
// don't check test dependencies if we haven't built libtest
|
||||||
if builder.kind == Kind::Clippy || !self.crates.is_empty() {
|
if builder.kind == Kind::Clippy || !self.crates.iter().any(|krate| krate == "test") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,10 +198,11 @@ pub struct Rustc {
|
||||||
|
|
||||||
impl Rustc {
|
impl Rustc {
|
||||||
pub fn new(target: TargetSelection, builder: &Builder<'_>) -> Self {
|
pub fn new(target: TargetSelection, builder: &Builder<'_>) -> Self {
|
||||||
let mut crates = vec![];
|
let crates = builder
|
||||||
for krate in builder.in_tree_crates("rustc-main", None) {
|
.in_tree_crates("rustc-main", Some(target))
|
||||||
crates.push(krate.name.to_string());
|
.into_iter()
|
||||||
}
|
.map(|krate| krate.name.to_string())
|
||||||
|
.collect();
|
||||||
Self { target, crates: INTERNER.intern_list(crates) }
|
Self { target, crates: INTERNER.intern_list(crates) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,7 +217,7 @@ impl Step for Rustc {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_run(run: RunConfig<'_>) {
|
fn make_run(run: RunConfig<'_>) {
|
||||||
let crates = make_run_crates(&run, "compiler");
|
let crates = run.make_run_crates(Alias::Compiler);
|
||||||
run.builder.ensure(Rustc { target: run.target, crates });
|
run.builder.ensure(Rustc { target: run.target, crates });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,17 +55,6 @@ impl Std {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an `alias` selected by the `Step` and the paths passed on the command line,
|
|
||||||
/// return a list of the crates that should be built.
|
|
||||||
///
|
|
||||||
/// Normally, people will pass *just* `library` if they pass it.
|
|
||||||
/// But it's possible (although strange) to pass something like `library std core`.
|
|
||||||
/// Build all crates anyway, as if they hadn't passed the other args.
|
|
||||||
pub(crate) fn make_run_crates(run: &RunConfig<'_>, alias: &str) -> Interned<Vec<String>> {
|
|
||||||
let has_alias = run.paths.iter().any(|set| set.assert_single_path().path.ends_with(alias));
|
|
||||||
if has_alias { Default::default() } else { run.cargo_crates_in_set() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Step for Std {
|
impl Step for Std {
|
||||||
type Output = ();
|
type Output = ();
|
||||||
const DEFAULT: bool = true;
|
const DEFAULT: bool = true;
|
||||||
|
@ -80,10 +69,15 @@ impl Step for Std {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_run(run: RunConfig<'_>) {
|
fn make_run(run: RunConfig<'_>) {
|
||||||
|
// If the paths include "library", build the entire standard library.
|
||||||
|
let has_alias =
|
||||||
|
run.paths.iter().any(|set| set.assert_single_path().path.ends_with("library"));
|
||||||
|
let crates = if has_alias { Default::default() } else { run.cargo_crates_in_set() };
|
||||||
|
|
||||||
run.builder.ensure(Std {
|
run.builder.ensure(Std {
|
||||||
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
|
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
|
||||||
target: run.target,
|
target: run.target,
|
||||||
crates: make_run_crates(&run, "library"),
|
crates,
|
||||||
force_recompile: false,
|
force_recompile: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,12 @@ impl Step for JsonDocs {
|
||||||
/// Builds the `rust-docs-json` installer component.
|
/// Builds the `rust-docs-json` installer component.
|
||||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||||
let host = self.host;
|
let host = self.host;
|
||||||
builder.ensure(crate::doc::Std::new(builder.top_stage, host, DocumentationFormat::JSON));
|
builder.ensure(crate::doc::Std::new(
|
||||||
|
builder.top_stage,
|
||||||
|
host,
|
||||||
|
builder,
|
||||||
|
DocumentationFormat::JSON,
|
||||||
|
));
|
||||||
|
|
||||||
let dest = "share/doc/rust/json";
|
let dest = "share/doc/rust/json";
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,9 @@ use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use crate::builder::crate_description;
|
use crate::builder::crate_description;
|
||||||
use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
|
use crate::builder::{Alias, Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
|
||||||
use crate::cache::{Interned, INTERNER};
|
use crate::cache::{Interned, INTERNER};
|
||||||
use crate::compile;
|
use crate::compile;
|
||||||
use crate::compile::make_run_crates;
|
|
||||||
use crate::config::{Config, TargetSelection};
|
use crate::config::{Config, TargetSelection};
|
||||||
use crate::tool::{self, prepare_tool_cargo, SourceType, Tool};
|
use crate::tool::{self, prepare_tool_cargo, SourceType, Tool};
|
||||||
use crate::util::{symlink_dir, t, up_to_date};
|
use crate::util::{symlink_dir, t, up_to_date};
|
||||||
|
@ -424,8 +423,18 @@ pub struct Std {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Std {
|
impl Std {
|
||||||
pub(crate) fn new(stage: u32, target: TargetSelection, format: DocumentationFormat) -> Self {
|
pub(crate) fn new(
|
||||||
Std { stage, target, format, crates: INTERNER.intern_list(vec![]) }
|
stage: u32,
|
||||||
|
target: TargetSelection,
|
||||||
|
builder: &Builder<'_>,
|
||||||
|
format: DocumentationFormat,
|
||||||
|
) -> Self {
|
||||||
|
let crates = builder
|
||||||
|
.in_tree_crates("sysroot", Some(target))
|
||||||
|
.into_iter()
|
||||||
|
.map(|krate| krate.name.to_string())
|
||||||
|
.collect();
|
||||||
|
Std { stage, target, format, crates: INTERNER.intern_list(crates) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +456,7 @@ impl Step for Std {
|
||||||
} else {
|
} else {
|
||||||
DocumentationFormat::HTML
|
DocumentationFormat::HTML
|
||||||
},
|
},
|
||||||
crates: make_run_crates(&run, "library"),
|
crates: run.make_run_crates(Alias::Library),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +464,7 @@ impl Step for Std {
|
||||||
///
|
///
|
||||||
/// This will generate all documentation for the standard library and its
|
/// This will generate all documentation for the standard library and its
|
||||||
/// dependencies. This is largely just a wrapper around `cargo doc`.
|
/// dependencies. This is largely just a wrapper around `cargo doc`.
|
||||||
fn run(mut self, builder: &Builder<'_>) {
|
fn run(self, builder: &Builder<'_>) {
|
||||||
let stage = self.stage;
|
let stage = self.stage;
|
||||||
let target = self.target;
|
let target = self.target;
|
||||||
let out = match self.format {
|
let out = match self.format {
|
||||||
|
@ -493,20 +502,17 @@ impl Step for Std {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for library/std, library/core etc in the `x.py doc` arguments and
|
if builder.paths.iter().any(|path| path.ends_with("library")) {
|
||||||
// open the corresponding rendered docs.
|
|
||||||
if self.crates.is_empty() {
|
|
||||||
self.crates = INTERNER.intern_list(vec!["library".to_owned()]);
|
|
||||||
};
|
|
||||||
|
|
||||||
for requested_crate in &*self.crates {
|
|
||||||
if requested_crate == "library" {
|
|
||||||
// For `x.py doc library --open`, open `std` by default.
|
// For `x.py doc library --open`, open `std` by default.
|
||||||
let index = out.join("std").join("index.html");
|
let index = out.join("std").join("index.html");
|
||||||
builder.open_in_browser(index);
|
builder.open_in_browser(index);
|
||||||
} else if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
|
} else {
|
||||||
|
for requested_crate in &*self.crates {
|
||||||
|
if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
|
||||||
let index = out.join(requested_crate).join("index.html");
|
let index = out.join(requested_crate).join("index.html");
|
||||||
builder.open_in_browser(index);
|
builder.open_in_browser(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,9 +545,6 @@ impl DocumentationFormat {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the documentation for public standard library crates.
|
/// Build the documentation for public standard library crates.
|
||||||
///
|
|
||||||
/// `requested_crates` can be used to build only a subset of the crates. If empty, all crates will
|
|
||||||
/// be built.
|
|
||||||
fn doc_std(
|
fn doc_std(
|
||||||
builder: &Builder<'_>,
|
builder: &Builder<'_>,
|
||||||
format: DocumentationFormat,
|
format: DocumentationFormat,
|
||||||
|
@ -592,19 +595,11 @@ fn doc_std(
|
||||||
cargo.rustdocflag("--document-private-items").rustdocflag("--document-hidden-items");
|
cargo.rustdocflag("--document-private-items").rustdocflag("--document-hidden-items");
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: because we use `--manifest-path library/sysroot/Cargo.toml`, cargo thinks we only want to document that specific crate, not its dependencies.
|
for krate in requested_crates {
|
||||||
// Override its default.
|
if krate == "sysroot" {
|
||||||
let built_crates = if requested_crates.is_empty() {
|
// The sysroot crate is an implementation detail, don't include it in public docs.
|
||||||
builder
|
continue;
|
||||||
.in_tree_crates("sysroot", None)
|
}
|
||||||
.into_iter()
|
|
||||||
.map(|krate| krate.name.to_string())
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
requested_crates.to_vec()
|
|
||||||
};
|
|
||||||
|
|
||||||
for krate in built_crates {
|
|
||||||
cargo.arg("-p").arg(krate);
|
cargo.arg("-p").arg(krate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,20 +616,10 @@ pub struct Rustc {
|
||||||
|
|
||||||
impl Rustc {
|
impl Rustc {
|
||||||
pub(crate) fn new(stage: u32, target: TargetSelection, builder: &Builder<'_>) -> Self {
|
pub(crate) fn new(stage: u32, target: TargetSelection, builder: &Builder<'_>) -> Self {
|
||||||
// Find dependencies for top level crates.
|
let crates = builder
|
||||||
let root_crates = vec![
|
.in_tree_crates("rustc-main", Some(target))
|
||||||
INTERNER.intern_str("rustc_driver"),
|
|
||||||
INTERNER.intern_str("rustc_codegen_llvm"),
|
|
||||||
INTERNER.intern_str("rustc_codegen_ssa"),
|
|
||||||
];
|
|
||||||
let crates: Vec<_> = root_crates
|
|
||||||
.iter()
|
|
||||||
.flat_map(|krate| {
|
|
||||||
builder
|
|
||||||
.in_tree_crates(krate, Some(target))
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|krate| krate.name.to_string())
|
.map(|krate| krate.name.to_string())
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
Self { stage, target, crates: INTERNER.intern_list(crates) }
|
Self { stage, target, crates: INTERNER.intern_list(crates) }
|
||||||
}
|
}
|
||||||
|
@ -656,7 +641,7 @@ impl Step for Rustc {
|
||||||
run.builder.ensure(Rustc {
|
run.builder.ensure(Rustc {
|
||||||
stage: run.builder.top_stage,
|
stage: run.builder.top_stage,
|
||||||
target: run.target,
|
target: run.target,
|
||||||
crates: make_run_crates(&run, "compiler"),
|
crates: run.make_run_crates(Alias::Compiler),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,7 +651,7 @@ impl Step for Rustc {
|
||||||
/// Compiler documentation is distributed separately, so we make sure
|
/// Compiler documentation is distributed separately, so we make sure
|
||||||
/// we do not merge it with the other documentation from std, test and
|
/// we do not merge it with the other documentation from std, test and
|
||||||
/// proc_macros. This is largely just a wrapper around `cargo doc`.
|
/// proc_macros. This is largely just a wrapper around `cargo doc`.
|
||||||
fn run(mut self, builder: &Builder<'_>) {
|
fn run(self, builder: &Builder<'_>) {
|
||||||
let stage = self.stage;
|
let stage = self.stage;
|
||||||
let target = self.target;
|
let target = self.target;
|
||||||
|
|
||||||
|
@ -726,24 +711,26 @@ impl Step for Rustc {
|
||||||
|
|
||||||
let mut to_open = None;
|
let mut to_open = None;
|
||||||
|
|
||||||
if self.crates.is_empty() {
|
|
||||||
self.crates = INTERNER.intern_list(vec!["rustc_driver".to_owned()]);
|
|
||||||
};
|
|
||||||
|
|
||||||
for krate in &*self.crates {
|
for krate in &*self.crates {
|
||||||
// Create all crate output directories first to make sure rustdoc uses
|
// Create all crate output directories first to make sure rustdoc uses
|
||||||
// relative links.
|
// relative links.
|
||||||
// FIXME: Cargo should probably do this itself.
|
// FIXME: Cargo should probably do this itself.
|
||||||
t!(fs::create_dir_all(out_dir.join(krate)));
|
let dir_name = krate.replace("-", "_");
|
||||||
|
t!(fs::create_dir_all(out_dir.join(&*dir_name)));
|
||||||
cargo.arg("-p").arg(krate);
|
cargo.arg("-p").arg(krate);
|
||||||
if to_open.is_none() {
|
if to_open.is_none() {
|
||||||
to_open = Some(krate);
|
to_open = Some(dir_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.run(&mut cargo.into());
|
builder.run(&mut cargo.into());
|
||||||
|
|
||||||
|
if builder.paths.iter().any(|path| path.ends_with("compiler")) {
|
||||||
|
// For `x.py doc compiler --open`, open `rustc_middle` by default.
|
||||||
|
let index = out.join("rustc_middle").join("index.html");
|
||||||
|
builder.open_in_browser(index);
|
||||||
|
} else if let Some(krate) = to_open {
|
||||||
// Let's open the first crate documentation page:
|
// Let's open the first crate documentation page:
|
||||||
if let Some(krate) = to_open {
|
|
||||||
let index = out.join(krate).join("index.html");
|
let index = out.join(krate).join("index.html");
|
||||||
builder.open_in_browser(index);
|
builder.open_in_browser(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1502,6 +1502,7 @@ impl Build {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ret.sort_unstable_by_key(|krate| krate.name); // reproducible order needed for tests
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -901,6 +901,7 @@ impl Step for RustdocJSStd {
|
||||||
builder.ensure(crate::doc::Std::new(
|
builder.ensure(crate::doc::Std::new(
|
||||||
builder.top_stage,
|
builder.top_stage,
|
||||||
self.target,
|
self.target,
|
||||||
|
builder,
|
||||||
DocumentationFormat::HTML,
|
DocumentationFormat::HTML,
|
||||||
));
|
));
|
||||||
builder.run(&mut command);
|
builder.run(&mut command);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue