1
Fork 0

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:
bors 2023-07-14 12:09:27 +00:00
commit bacf5bcbc7
10 changed files with 118 additions and 89 deletions

View file

@ -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"))]

View file

@ -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`.

View file

@ -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`.

View file

@ -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 {

View file

@ -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 });
} }

View file

@ -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,
}); });
} }

View file

@ -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";

View file

@ -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. // For `x.py doc library --open`, open `std` by default.
if self.crates.is_empty() { let index = out.join("std").join("index.html");
self.crates = INTERNER.intern_list(vec!["library".to_owned()]); builder.open_in_browser(index);
}; } else {
for requested_crate in &*self.crates {
for requested_crate in &*self.crates { if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
if requested_crate == "library" { let index = out.join(requested_crate).join("index.html");
// For `x.py doc library --open`, open `std` by default. builder.open_in_browser(index);
let index = out.join("std").join("index.html"); break;
builder.open_in_browser(index); }
} else if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
let index = out.join(requested_crate).join("index.html");
builder.open_in_browser(index);
} }
} }
} }
@ -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"), .into_iter()
INTERNER.intern_str("rustc_codegen_llvm"), .map(|krate| krate.name.to_string())
INTERNER.intern_str("rustc_codegen_ssa"),
];
let crates: Vec<_> = root_crates
.iter()
.flat_map(|krate| {
builder
.in_tree_crates(krate, Some(target))
.into_iter()
.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());
// Let's open the first crate documentation page:
if let Some(krate) = to_open { 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 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);
} }

View file

@ -1502,6 +1502,7 @@ impl Build {
} }
} }
} }
ret.sort_unstable_by_key(|krate| krate.name); // reproducible order needed for tests
ret ret
} }

View file

@ -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);