From a4a0342cf59a1bff43ed79586065eb97dba0cddb Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Fri, 9 Oct 2020 15:16:10 +0100 Subject: [PATCH 01/28] ci: disabled: riscv: work around QEMU regression This bumps the version of the bbl bootloader not to perform 64-bit accesses to the PLIC. Doing so resulted in the QEMU test machine to fail to boot: bbl loader ../machine/mtrap.c:21: machine mode: unhandlable trap 7 @ 0x0000000080001f6e Power off Signed-off-by: Tom Eccles --- .../docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile index 3c39a63849640..f3f52ed61d133 100644 --- a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile @@ -84,9 +84,9 @@ RUN riscv64-linux-gnu-gcc addentropy.c -o rootfs/addentropy -static # download and build the riscv bootloader RUN git clone https://github.com/riscv/riscv-pk WORKDIR /tmp/riscv-pk -# nothing special about this revision: it is just master at the time of writing -# v1.0.0 doesn't build -RUN git checkout 5d9ed238e1cabfbca3c47f50d32894ce94bfc304 +# This revision fixes a fault in recent QEMU from 64-bit accesses to the PLIC +# commits later than this one should work too +RUN git checkout 7d8b7c0dab72108e3ea7bb7744d3f6cc907c7ef4 RUN mkdir build && cd build && \ ../configure --with-payload=/tmp/vmlinux --host=riscv64-linux-gnu && \ make -j$(nproc) && \ From e0b033e965a7d422da70a409a028af7c8b64e709 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Fri, 9 Oct 2020 17:36:35 +0100 Subject: [PATCH 02/28] doc: fix broken link for crate::os::linux::raw::stat Fixing: Documenting std v0.0.0 (/checkout/library/std) error: `self::os::linux::raw::stat` is both a struct and a function --> library/std/src/os/linux/fs.rs:23:19 | 23 | /// [`stat`]: crate::os::linux::raw::stat | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous link | = note: `-D broken-intra-doc-links` implied by `-D warnings` help: to link to the struct, prefix with `struct@` | 23 | /// [`stat`]: struct@self::os::linux::raw::stat | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to link to the function, add parentheses | 23 | /// [`stat`]: self::os::linux::raw::stat() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error error: could not document `std` Signed-off-by: Tom Eccles --- library/std/src/os/linux/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/os/linux/fs.rs b/library/std/src/os/linux/fs.rs index ff23c3d67e3b4..9b7af97616c9d 100644 --- a/library/std/src/os/linux/fs.rs +++ b/library/std/src/os/linux/fs.rs @@ -20,7 +20,7 @@ pub trait MetadataExt { /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the /// cross-Unix abstractions contained within the raw stat. /// - /// [`stat`]: crate::os::linux::raw::stat + /// [`stat`]: struct@crate::os::linux::raw::stat /// /// # Examples /// From 46f2f023b0d02502a5a9b64b23247207b2279bfe Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 9 Oct 2020 19:35:17 +0200 Subject: [PATCH 03/28] Move supported_target_features query provider to cg_ssa --- compiler/rustc_codegen_llvm/src/attributes.rs | 20 ++----------------- compiler/rustc_codegen_llvm/src/lib.rs | 4 ++-- compiler/rustc_codegen_ssa/src/lib.rs | 1 + .../rustc_codegen_ssa/src/target_features.rs | 15 ++++++++++++++ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index f02c30c3ee392..b146d76d6662b 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -6,7 +6,7 @@ use rustc_codegen_ssa::traits::*; use rustc_data_structures::const_cstr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::query::Providers; @@ -352,23 +352,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: } } -pub fn provide(providers: &mut Providers) { - use rustc_codegen_ssa::target_features::{all_known_features, supported_target_features}; - providers.supported_target_features = |tcx, cnum| { - assert_eq!(cnum, LOCAL_CRATE); - if tcx.sess.opts.actually_rustdoc { - // rustdoc needs to be able to document functions that use all the features, so - // provide them all. - all_known_features().map(|(a, b)| (a.to_string(), b)).collect() - } else { - supported_target_features(tcx.sess).iter().map(|&(a, b)| (a.to_string(), b)).collect() - } - }; - - provide_extern(providers); -} - -pub fn provide_extern(providers: &mut Providers) { +pub fn provide_both(providers: &mut Providers) { providers.wasm_import_module_map = |tcx, cnum| { // Build up a map from DefId to a `NativeLib` structure, where // `NativeLib` internally contains information about diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 1237b39b300ff..e15248d843285 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -249,11 +249,11 @@ impl CodegenBackend for LlvmCodegenBackend { } fn provide(&self, providers: &mut ty::query::Providers) { - attributes::provide(providers); + attributes::provide_both(providers); } fn provide_extern(&self, providers: &mut ty::query::Providers) { - attributes::provide_extern(providers); + attributes::provide_both(providers); } fn codegen_crate<'tcx>( diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index e34371ef59ac4..851b6628758a6 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -144,6 +144,7 @@ pub struct CodegenResults { pub fn provide(providers: &mut Providers) { crate::back::symbol_export::provide(providers); crate::base::provide_both(providers); + crate::target_features::provide(providers); } pub fn provide_extern(providers: &mut Providers) { diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 4c61e21901bcd..24cd27cf3cf89 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -1,3 +1,5 @@ +use rustc_hir::def_id::LOCAL_CRATE; +use rustc_middle::ty::query::Providers; use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::symbol::Symbol; @@ -148,3 +150,16 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt _ => &[], } } + +pub(crate) fn provide(providers: &mut Providers) { + providers.supported_target_features = |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + if tcx.sess.opts.actually_rustdoc { + // rustdoc needs to be able to document functions that use all the features, so + // whitelist them all + all_known_features().map(|(a, b)| (a.to_string(), b)).collect() + } else { + supported_target_features(tcx.sess).iter().map(|&(a, b)| (a.to_string(), b)).collect() + } + }; +} From 69f45cd96517b4e380044b7d4593899e77afc0ae Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 10 Oct 2020 15:14:58 +0200 Subject: [PATCH 04/28] Move save_work_product_index call out of cg_llvm --- compiler/rustc_codegen_llvm/src/lib.rs | 14 ++++---------- compiler/rustc_codegen_ssa/src/traits/backend.rs | 6 +++--- compiler/rustc_interface/src/queries.rs | 14 +++++++++++--- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index e15248d843285..b3328deebe8bf 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -23,8 +23,9 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::{CodegenResults, CompiledModule}; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::{ErrorReported, FatalError, Handler}; -use rustc_middle::dep_graph::{DepGraph, WorkProduct}; +use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc_middle::ty::{self, TyCtxt}; use rustc_serialize::json; @@ -274,8 +275,7 @@ impl CodegenBackend for LlvmCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - dep_graph: &DepGraph, - ) -> Result, ErrorReported> { + ) -> Result<(Box, FxHashMap), ErrorReported> { let (codegen_results, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") @@ -284,13 +284,7 @@ impl CodegenBackend for LlvmCodegenBackend { rustc_codegen_ssa::back::write::dump_incremental_data(&codegen_results); } - sess.time("serialize_work_products", move || { - rustc_incremental::save_work_product_index(sess, &dep_graph, work_products) - }); - - sess.compile_status()?; - - Ok(Box::new(codegen_results)) + Ok((Box::new(codegen_results), work_products)) } fn link( diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 48c07b0089420..4a88f747a17ff 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -3,8 +3,9 @@ use super::CodegenObject; use crate::ModuleCodegen; use rustc_ast::expand::allocator::AllocatorKind; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorReported; -use rustc_middle::dep_graph::DepGraph; +use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout}; use rustc_middle::ty::query::Providers; @@ -80,8 +81,7 @@ pub trait CodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - dep_graph: &DepGraph, - ) -> Result, ErrorReported>; + ) -> Result<(Box, FxHashMap), ErrorReported>; /// This is called on the returned `Box` from `join_codegen` /// diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 8b82217a91ac6..b7e4c097c900d 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -356,10 +356,18 @@ pub struct Linker { impl Linker { pub fn link(self) -> Result<()> { - let codegen_results = - self.codegen_backend.join_codegen(self.ongoing_codegen, &self.sess, &self.dep_graph)?; - let prof = self.sess.prof.clone(); + let (codegen_results, work_products) = + self.codegen_backend.join_codegen(self.ongoing_codegen, &self.sess)?; + + self.sess.compile_status()?; + + let sess = &self.sess; let dep_graph = self.dep_graph; + sess.time("serialize_work_products", || { + rustc_incremental::save_work_product_index(&sess, &dep_graph, work_products) + }); + + let prof = self.sess.prof.clone(); prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph)); if !self From f141acf0678139ac31375d02feebcc2be220715b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 10 Oct 2020 15:20:35 +0200 Subject: [PATCH 05/28] Move finalize_session_directory call out of cg_llvm This causes it to be called even when passing `-Zno-link`, when linking fails or when neither `--emit link` nor `--emit metadata` is used. --- compiler/rustc_codegen_llvm/src/lib.rs | 4 ---- compiler/rustc_codegen_ssa/src/back/write.rs | 5 ----- compiler/rustc_codegen_ssa/src/lib.rs | 2 -- compiler/rustc_interface/src/queries.rs | 8 ++++++++ 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index b3328deebe8bf..4a4830552f84e 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -325,10 +325,6 @@ impl CodegenBackend for LlvmCodegenBackend { ); }); - // Now that we won't touch anything in the incremental compilation directory - // any more, we can finalize it (which involves renaming it) - rustc_incremental::finalize_session_directory(sess, codegen_results.crate_hash); - sess.time("llvm_dump_timing_file", || { if sess.opts.debugging_opts.llvm_time_trace { llvm_util::time_trace_profiler_finish("llvm_timings.json"); diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 0edf0fcd1a264..a61eca1dcaf3c 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -13,7 +13,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::profiling::TimingGuard; use rustc_data_structures::profiling::VerboseTimingGuard; -use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; use rustc_errors::emitter::Emitter; use rustc_errors::{DiagnosticId, FatalError, Handler, Level}; @@ -414,7 +413,6 @@ pub fn start_async_codegen( let sess = tcx.sess; let crate_name = tcx.crate_name(LOCAL_CRATE); - let crate_hash = tcx.crate_hash(LOCAL_CRATE); let no_builtins = tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::no_builtins); let is_compiler_builtins = tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::compiler_builtins); @@ -463,7 +461,6 @@ pub fn start_async_codegen( OngoingCodegen { backend, crate_name, - crate_hash, metadata, windows_subsystem, linker_info, @@ -1720,7 +1717,6 @@ impl SharedEmitterMain { pub struct OngoingCodegen { pub backend: B, pub crate_name: Symbol, - pub crate_hash: Svh, pub metadata: EncodedMetadata, pub windows_subsystem: Option, pub linker_info: LinkerInfo, @@ -1766,7 +1762,6 @@ impl OngoingCodegen { ( CodegenResults { crate_name: self.crate_name, - crate_hash: self.crate_hash, metadata: self.metadata, windows_subsystem: self.windows_subsystem, linker_info: self.linker_info, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 851b6628758a6..70b92b234e94c 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -21,7 +21,6 @@ extern crate tracing; extern crate rustc_middle; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; use rustc_hir::def_id::CrateNum; use rustc_hir::LangItem; @@ -134,7 +133,6 @@ pub struct CodegenResults { pub modules: Vec, pub allocator_module: Option, pub metadata_module: Option, - pub crate_hash: Svh, pub metadata: rustc_middle::middle::cstore::EncodedMetadata, pub windows_subsystem: Option, pub linker_info: back::linker::LinkerInfo, diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index b7e4c097c900d..e0134a0d67688 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -3,6 +3,7 @@ use crate::passes::{self, BoxedResolver, QueryContext}; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; +use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; use rustc_errors::ErrorReported; use rustc_hir::def_id::LOCAL_CRATE; @@ -331,6 +332,7 @@ impl<'tcx> Queries<'tcx> { pub fn linker(&'tcx self) -> Result { let dep_graph = self.dep_graph()?; let prepare_outputs = self.prepare_outputs()?; + let crate_hash = self.global_ctxt()?.peek_mut().enter(|tcx| tcx.crate_hash(LOCAL_CRATE)); let ongoing_codegen = self.ongoing_codegen()?; let sess = self.session().clone(); @@ -340,6 +342,7 @@ impl<'tcx> Queries<'tcx> { sess, dep_graph: dep_graph.peek().clone(), prepare_outputs: prepare_outputs.take(), + crate_hash, ongoing_codegen: ongoing_codegen.take(), codegen_backend, }) @@ -350,6 +353,7 @@ pub struct Linker { sess: Lrc, dep_graph: DepGraph, prepare_outputs: OutputFilenames, + crate_hash: Svh, ongoing_codegen: Box, codegen_backend: Lrc>, } @@ -370,6 +374,10 @@ impl Linker { let prof = self.sess.prof.clone(); prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph)); + // Now that we won't touch anything in the incremental compilation directory + // any more, we can finalize it (which involves renaming it) + rustc_incremental::finalize_session_directory(&self.sess, self.crate_hash); + if !self .sess .opts From 69f26b776124d3ed9ea87fec1703e42100f3434c Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 10 Oct 2020 16:18:36 +0200 Subject: [PATCH 06/28] Use fixed type for CodegenResults This also moves the -Zno-link implementation to rustc_interface --- compiler/rustc_codegen_llvm/src/lib.rs | 26 +++---------------- .../rustc_codegen_ssa/src/traits/backend.rs | 6 ++--- compiler/rustc_driver/src/lib.rs | 2 +- compiler/rustc_interface/src/queries.rs | 16 +++++++++++- 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 4a4830552f84e..b3ff0f9e700af 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -28,14 +28,12 @@ use rustc_errors::{ErrorReported, FatalError, Handler}; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_serialize::json; -use rustc_session::config::{self, OptLevel, OutputFilenames, PrintRequest}; +use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest}; use rustc_session::Session; use rustc_span::symbol::Symbol; use std::any::Any; use std::ffi::CStr; -use std::fs; use std::sync::Arc; mod back { @@ -275,7 +273,7 @@ impl CodegenBackend for LlvmCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - ) -> Result<(Box, FxHashMap), ErrorReported> { + ) -> Result<(CodegenResults, FxHashMap), ErrorReported> { let (codegen_results, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") @@ -284,31 +282,15 @@ impl CodegenBackend for LlvmCodegenBackend { rustc_codegen_ssa::back::write::dump_incremental_data(&codegen_results); } - Ok((Box::new(codegen_results), work_products)) + Ok((codegen_results, work_products)) } fn link( &self, sess: &Session, - codegen_results: Box, + codegen_results: CodegenResults, outputs: &OutputFilenames, ) -> Result<(), ErrorReported> { - let codegen_results = codegen_results - .downcast::() - .expect("Expected CodegenResults, found Box"); - - if sess.opts.debugging_opts.no_link { - // FIXME: use a binary format to encode the `.rlink` file - let rlink_data = json::encode(&codegen_results).map_err(|err| { - sess.fatal(&format!("failed to encode rlink: {}", err)); - })?; - let rlink_file = outputs.with_extension(config::RLINK_EXT); - fs::write(&rlink_file, rlink_data).map_err(|err| { - sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err)); - })?; - return Ok(()); - } - // Run the linker on any artifacts that resulted from the LLVM run. // This should produce either a finished executable or library. sess.time("link_crate", || { diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 4a88f747a17ff..c6fbca39ee451 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -1,6 +1,6 @@ use super::write::WriteBackendMethods; use super::CodegenObject; -use crate::ModuleCodegen; +use crate::{CodegenResults, ModuleCodegen}; use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::fx::FxHashMap; @@ -81,7 +81,7 @@ pub trait CodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - ) -> Result<(Box, FxHashMap), ErrorReported>; + ) -> Result<(CodegenResults, FxHashMap), ErrorReported>; /// This is called on the returned `Box` from `join_codegen` /// @@ -91,7 +91,7 @@ pub trait CodegenBackend { fn link( &self, sess: &Session, - codegen_results: Box, + codegen_results: CodegenResults, outputs: &OutputFilenames, ) -> Result<(), ErrorReported>; } diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 066a61a7a7b53..26a388aa3ed00 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -599,7 +599,7 @@ impl RustcDefaultCalls { let codegen_results: CodegenResults = json::decode(&rlink_data).unwrap_or_else(|err| { sess.fatal(&format!("failed to decode rlink: {}", err)); }); - compiler.codegen_backend().link(&sess, Box::new(codegen_results), &outputs) + compiler.codegen_backend().link(&sess, codegen_results, &outputs) } else { sess.fatal("rlink must be a file") } diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index e0134a0d67688..1de7350a3e21c 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -14,7 +14,8 @@ use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; use rustc_middle::ty::steal::Steal; use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt}; -use rustc_session::config::{OutputFilenames, OutputType}; +use rustc_serialize::json; +use rustc_session::config::{self, OutputFilenames, OutputType}; use rustc_session::{output::find_crate_name, Session}; use rustc_span::symbol::sym; use std::any::Any; @@ -387,6 +388,19 @@ impl Linker { { return Ok(()); } + + if sess.opts.debugging_opts.no_link { + // FIXME: use a binary format to encode the `.rlink` file + let rlink_data = json::encode(&codegen_results).map_err(|err| { + sess.fatal(&format!("failed to encode rlink: {}", err)); + })?; + let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT); + std::fs::write(&rlink_file, rlink_data).map_err(|err| { + sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err)); + })?; + return Ok(()); + } + self.codegen_backend.link(&self.sess, codegen_results, &self.prepare_outputs) } } From 0d27b765a6bd4abaa2787d13fbd438d35bcedf8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 9 Oct 2020 17:22:25 +0200 Subject: [PATCH 07/28] Take functions by value --- compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_mir/src/transform/check_const_item_mutation.rs | 2 +- compiler/rustc_typeck/src/check/mod.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 60705f68681a1..05b8dad3097e4 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -94,7 +94,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, adt_def => { cdata.get_adt_def(def_id.index, tcx) } adt_destructor => { let _ = cdata; - tcx.calculate_dtor(def_id, &mut |_,_| Ok(())) + tcx.calculate_dtor(def_id, |_,_| Ok(())) } variances_of => { tcx.arena.alloc_from_iter(cdata.get_item_variances(def_id.index)) } associated_item_def_ids => { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index d8ea2f67393b2..5ac12dfa99366 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -341,7 +341,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn calculate_dtor( self, adt_did: DefId, - validate: &mut dyn FnMut(Self, DefId) -> Result<(), ErrorReported>, + validate: impl Fn(Self, DefId) -> Result<(), ErrorReported>, ) -> Option { let drop_trait = self.lang_items().drop_trait()?; self.ensure().coherent_trait(drop_trait); diff --git a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs index 26993a6b941fb..fb89b36060a28 100644 --- a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs +++ b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs @@ -53,7 +53,7 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> { // // #[const_mutation_allowed] // pub const LOG: Log = Log { msg: "" }; - match self.tcx.calculate_dtor(def_id, &mut |_, _| Ok(())) { + match self.tcx.calculate_dtor(def_id, |_, _| Ok(())) { Some(_) => None, None => Some(def_id), } diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 97172d391ba65..1cb6ae21a47bb 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -264,7 +264,7 @@ pub fn provide(providers: &mut Providers) { } fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl) + tcx.calculate_dtor(def_id, dropck::check_drop_impl) } /// If this `DefId` is a "primary tables entry", returns From 12a294121422a223a8d0a6a9974efbe7577977e7 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 10 Oct 2020 16:20:42 +0200 Subject: [PATCH 08/28] Move llvm_util::time_trace_profiler_finish call to join_codegen This makes it also run when compilation has failed, neither --emit exe nor --emit metadata is passed, or -Zno-link is used. --- compiler/rustc_codegen_llvm/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index b3ff0f9e700af..02da175cac390 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -282,6 +282,12 @@ impl CodegenBackend for LlvmCodegenBackend { rustc_codegen_ssa::back::write::dump_incremental_data(&codegen_results); } + sess.time("llvm_dump_timing_file", || { + if sess.opts.debugging_opts.llvm_time_trace { + llvm_util::time_trace_profiler_finish("llvm_timings.json"); + } + }); + Ok((codegen_results, work_products)) } @@ -307,12 +313,6 @@ impl CodegenBackend for LlvmCodegenBackend { ); }); - sess.time("llvm_dump_timing_file", || { - if sess.opts.debugging_opts.llvm_time_trace { - llvm_util::time_trace_profiler_finish("llvm_timings.json"); - } - }); - Ok(()) } } From 23c3356f9a6069f566e9f6900f5575daed1d526d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 10 Oct 2020 09:55:35 -0400 Subject: [PATCH 09/28] Mention rustdoc in `x.py setup` This also allows 'rustdoc' as a string for the compiler profile. --- src/bootstrap/setup.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index dcfb9fd673421..f762dff2727f4 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -30,7 +30,7 @@ impl FromStr for Profile { fn from_str(s: &str) -> Result { match s { "a" | "lib" | "library" => Ok(Profile::Library), - "b" | "compiler" => Ok(Profile::Compiler), + "b" | "compiler" | "rustdoc" => Ok(Profile::Compiler), "c" | "llvm" | "codegen" => Ok(Profile::Codegen), "d" | "maintainer" | "user" => Ok(Profile::User), _ => Err(format!("unknown profile: '{}'", s)), @@ -107,7 +107,7 @@ pub fn interactive_path() -> io::Result { println!( "Welcome to the Rust project! What do you want to do with x.py? a) Contribute to the standard library -b) Contribute to the compiler +b) Contribute to the compiler or rustdoc c) Contribute to the compiler, and also modify LLVM or codegen d) Install Rust from source" ); From aa51449af43c428fd8ddbdc8dd53a11c3741f3ec Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 10 Oct 2020 17:59:16 +0200 Subject: [PATCH 10/28] Fix hotplug_codegen_backend test --- .../hotplug_codegen_backend/the_backend.rs | 58 +++++++++---------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index dd49ca67c6748..0e1bef6f68d53 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -3,7 +3,6 @@ extern crate rustc_codegen_ssa; extern crate rustc_errors; extern crate rustc_middle; -#[macro_use] extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_hir; @@ -12,17 +11,19 @@ extern crate rustc_span; extern crate rustc_symbol_mangling; extern crate rustc_target; +use rustc_codegen_ssa::back::linker::LinkerInfo; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_data_structures::owning_ref::OwningRef; +use rustc_codegen_ssa::{CodegenResults, CrateInfo}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::MetadataRef; use rustc_errors::ErrorReported; use rustc_middle::dep_graph::DepGraph; +use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::config::OutputFilenames; use rustc_session::Session; -use rustc_span::symbol::Symbol; use rustc_target::spec::Target; use std::any::Any; use std::path::Path; @@ -31,14 +32,11 @@ pub struct NoLlvmMetadataLoader; impl MetadataLoader for NoLlvmMetadataLoader { fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result { - let buf = - std::fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?; - let buf: OwningRef, [u8]> = OwningRef::new(buf); - Ok(rustc_erase_owner!(buf.map_owner_box())) + unreachable!("some_crate.rs shouldn't depend on any external crates"); } fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result { - self.get_rlib_metadata(target, filename) + unreachable!("some_crate.rs shouldn't depend on any external crates"); } } @@ -49,53 +47,49 @@ impl CodegenBackend for TheBackend { Box::new(NoLlvmMetadataLoader) } - fn provide(&self, providers: &mut Providers) { - rustc_symbol_mangling::provide(providers); - - providers.supported_target_features = |tcx, _cnum| { - Default::default() // Just a dummy - }; - providers.is_reachable_non_generic = |_tcx, _defid| true; - providers.exported_symbols = |_tcx, _crate| &[]; - } - - fn provide_extern(&self, providers: &mut Providers) { - providers.is_reachable_non_generic = |_tcx, _defid| true; - } + fn provide(&self, providers: &mut Providers) {} + fn provide_extern(&self, providers: &mut Providers) {} fn codegen_crate<'a, 'tcx>( &self, tcx: TyCtxt<'tcx>, - _metadata: EncodedMetadata, + metadata: EncodedMetadata, _need_metadata_module: bool, ) -> Box { use rustc_hir::def_id::LOCAL_CRATE; - Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol) + Box::new(CodegenResults { + crate_name: tcx.crate_name(LOCAL_CRATE), + modules: vec![], + allocator_module: None, + metadata_module: None, + metadata, + windows_subsystem: None, + linker_info: LinkerInfo::new(tcx), + crate_info: CrateInfo::new(tcx), + }) } fn join_codegen( &self, ongoing_codegen: Box, _sess: &Session, - _dep_graph: &DepGraph, - ) -> Result, ErrorReported> { - let crate_name = ongoing_codegen - .downcast::() - .expect("in join_codegen: ongoing_codegen is not a Symbol"); - Ok(crate_name) + ) -> Result<(CodegenResults, FxHashMap), ErrorReported> { + let codegen_results = ongoing_codegen + .downcast::() + .expect("in join_codegen: ongoing_codegen is not a CodegenResults"); + Ok((*codegen_results, FxHashMap::default())) } fn link( &self, sess: &Session, - codegen_results: Box, + codegen_results: CodegenResults, outputs: &OutputFilenames, ) -> Result<(), ErrorReported> { use rustc_session::{config::CrateType, output::out_filename}; use std::io::Write; - let crate_name = - codegen_results.downcast::().expect("in link: codegen_results is not a Symbol"); + let crate_name = codegen_results.crate_name; for &crate_type in sess.opts.crate_types.iter() { if crate_type != CrateType::Rlib { sess.fatal(&format!("Crate type is {:?}", crate_type)); From cc0d140baecbe6b38496f1d869de0698e639c7df Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 11 Oct 2020 09:55:17 -0400 Subject: [PATCH 11/28] Switch rustdoc from `clean::Stability` to `rustc_attr::Stability` This gives greater type safety and is less work to maintain on the rustdoc end. --- compiler/rustc_attr/src/builtin.rs | 16 +++++++++- src/librustdoc/clean/mod.rs | 24 +++----------- src/librustdoc/clean/types.rs | 23 +++++--------- src/librustdoc/clean/utils.rs | 5 +-- src/librustdoc/html/render/mod.rs | 50 +++++++++++++++++------------- 5 files changed, 59 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 325af56f3cd8c..5268d3f0ab043 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -9,6 +9,7 @@ use rustc_session::parse::{feature_err, ParseSess}; use rustc_session::Session; use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; +use std::cmp; use std::num::NonZeroU32; use version_check::Version; @@ -154,7 +155,7 @@ pub struct ConstStability { } /// The available stability levels. -#[derive(Encodable, Decodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)] +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(HashStable_Generic)] pub enum StabilityLevel { // Reason for the current stability level and the relevant rust-lang issue @@ -162,6 +163,19 @@ pub enum StabilityLevel { Stable { since: Symbol }, } +impl cmp::PartialOrd for StabilityLevel { + // This only take into account stability, not any fields. + // Therefore it is only `PartialOrd` and not `Ord`. + fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (Self::Unstable { .. }, Self::Unstable { .. }) => Some(cmp::Ordering::Equal), + (Self::Stable { .. }, Self::Stable { .. }) => Some(cmp::Ordering::Equal), + (Self::Unstable { .. }, Self::Stable { .. }) => Some(cmp::Ordering::Less), + (Self::Stable { .. }, Self::Unstable { .. }) => Some(cmp::Ordering::Greater), + } + } +} + impl StabilityLevel { pub fn is_unstable(&self) -> bool { matches!(self, StabilityLevel::Unstable { .. }) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 501891da573a6..bb1ee7f261514 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -19,7 +19,6 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_middle::bug; use rustc_middle::middle::resolve_lifetime as rl; -use rustc_middle::middle::stability; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt}; @@ -274,7 +273,7 @@ impl Clean for doctree::Module<'_> { attrs, source: span.clean(cx), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), inner: ModuleItem(Module { is_crate: self.is_crate, items }), @@ -2397,24 +2396,9 @@ impl Clean for doctree::ProcMacro<'_> { } } -impl Clean for attr::Stability { - fn clean(&self, _: &DocContext<'_>) -> Stability { - Stability { - level: stability::StabilityLevel::from_attr_level(&self.level), - feature: self.feature.to_string(), - since: match self.level { - attr::Stable { ref since } => since.to_string(), - _ => String::new(), - }, - unstable_reason: match self.level { - attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()), - _ => None, - }, - issue: match self.level { - attr::Unstable { issue, .. } => issue, - _ => None, - }, - } +impl Clean for attr::Stability { + fn clean(&self, _: &DocContext<'_>) -> attr::Stability { + self.clone() } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 1e07f8e2eac24..f347ba10e181a 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -4,7 +4,6 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::iter::FromIterator; use std::lazy::SyncOnceCell as OnceCell; -use std::num::NonZeroU32; use std::rc::Rc; use std::sync::Arc; use std::{slice, vec}; @@ -13,6 +12,7 @@ use rustc_ast::attr; use rustc_ast::util::comments::beautify_doc_string; use rustc_ast::{self as ast, AttrStyle}; use rustc_ast::{FloatTy, IntTy, UintTy}; +use rustc_attr::{Stability, StabilityLevel}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::Res; @@ -20,11 +20,10 @@ use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; use rustc_hir::Mutability; use rustc_index::vec::IndexVec; -use rustc_middle::middle::stability; use rustc_middle::ty::{AssocKind, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DUMMY_SP; -use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::symbol::{kw, sym, Ident, Symbol, SymbolStr}; use rustc_span::{self, FileName}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; @@ -197,7 +196,7 @@ impl Item { self.stability.as_ref().and_then(|ref s| { let mut classes = Vec::with_capacity(2); - if s.level == stability::Unstable { + if s.level.is_unstable() { classes.push("unstable"); } @@ -210,8 +209,11 @@ impl Item { }) } - pub fn stable_since(&self) -> Option<&str> { - self.stability.as_ref().map(|s| &s.since[..]) + pub fn stable_since(&self) -> Option { + match self.stability?.level { + StabilityLevel::Stable { since, .. } => Some(since.as_str()), + StabilityLevel::Unstable { .. } => None, + } } pub fn is_non_exhaustive(&self) -> bool { @@ -1719,15 +1721,6 @@ pub struct ProcMacro { pub helpers: Vec, } -#[derive(Clone, Debug)] -pub struct Stability { - pub level: stability::StabilityLevel, - pub feature: String, - pub since: String, - pub unstable_reason: Option, - pub issue: Option, -} - #[derive(Clone, Debug)] pub struct Deprecation { pub since: Option, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 913342e271513..25ba6e49bd563 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -3,12 +3,13 @@ use crate::clean::blanket_impl::BlanketImplFinder; use crate::clean::{ inline, Clean, Crate, Deprecation, ExternalCrate, FnDecl, FnRetTy, Generic, GenericArg, GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemEnum, Lifetime, - MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Stability, Type, - TypeBinding, TypeKind, Visibility, WherePredicate, + MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Type, TypeBinding, + TypeKind, Visibility, WherePredicate, }; use crate::core::DocContext; use itertools::Itertools; +use rustc_attr::Stability; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 76334f0213d15..36db5557b521b 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -49,6 +49,7 @@ use std::sync::Arc; use itertools::Itertools; use rustc_ast_pretty::pprust; +use rustc_attr::StabilityLevel; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_feature::UnstableFeatures; @@ -1984,8 +1985,10 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: let s1 = i1.stability.as_ref().map(|s| s.level); let s2 = i2.stability.as_ref().map(|s| s.level); match (s1, s2) { - (Some(stability::Unstable), Some(stability::Stable)) => return Ordering::Greater, - (Some(stability::Stable), Some(stability::Unstable)) => return Ordering::Less, + (Some(a), Some(b)) => match a.partial_cmp(&b) { + Some(Ordering::Equal) | None => {} + Some(other) => return other, + }, _ => {} } let lhs = i1.name.as_ref().map_or("", |s| &**s); @@ -2150,10 +2153,7 @@ fn stability_tags(item: &clean::Item) -> String { // The "rustc_private" crates are permanently unstable so it makes no sense // to render "unstable" everywhere. - if item - .stability - .as_ref() - .map(|s| s.level == stability::Unstable && s.feature != "rustc_private") + if item.stability.as_ref().map(|s| s.level.is_unstable() && s.feature != sym::rustc_private) == Some(true) { tags += &tag_html("unstable", "", "Experimental"); @@ -2204,16 +2204,17 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { // Render unstable items. But don't render "rustc_private" crates (internal compiler crates). // Those crates are permanently unstable so it makes no sense to render "unstable" everywhere. - if let Some(stab) = item + if let Some((StabilityLevel::Unstable { reason, issue, .. }, feature)) = item .stability .as_ref() - .filter(|stab| stab.level == stability::Unstable && stab.feature != "rustc_private") + .filter(|stab| stab.feature != sym::rustc_private) + .map(|stab| (stab.level, stab.feature)) { let mut message = "🔬 This is a nightly-only experimental API.".to_owned(); - let mut feature = format!("{}", Escape(&stab.feature)); - if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) { + let mut feature = format!("{}", Escape(&feature.as_str())); + if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, issue) { feature.push_str(&format!( " #{issue}", url = url, @@ -2223,13 +2224,13 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { message.push_str(&format!(" ({})", feature)); - if let Some(unstable_reason) = &stab.unstable_reason { + if let Some(unstable_reason) = reason { let mut ids = cx.id_map.borrow_mut(); message = format!( "
{}{}
", message, MarkdownHtml( - &unstable_reason, + &unstable_reason.as_str(), &mut ids, error_codes, cx.shared.edition, @@ -2355,7 +2356,7 @@ fn render_implementor( implementor, AssocItemLink::Anchor(None), RenderMode::Normal, - implementor.impl_item.stable_since(), + implementor.impl_item.stable_since().as_deref(), false, Some(use_absolute), false, @@ -2384,7 +2385,7 @@ fn render_impls( i, assoc_link, RenderMode::Normal, - containing_item.stable_since(), + containing_item.stable_since().as_deref(), true, None, false, @@ -2629,7 +2630,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, &implementor, assoc_link, RenderMode::Normal, - implementor.impl_item.stable_since(), + implementor.impl_item.stable_since().as_deref(), false, None, true, @@ -2780,7 +2781,11 @@ fn render_stability_since_raw(w: &mut Buffer, ver: Option<&str>, containing_ver: } fn render_stability_since(w: &mut Buffer, item: &clean::Item, containing_item: &clean::Item) { - render_stability_since_raw(w, item.stable_since(), containing_item.stable_since()) + render_stability_since_raw( + w, + item.stable_since().as_deref(), + containing_item.stable_since().as_deref(), + ) } fn render_assoc_item( @@ -3324,7 +3329,7 @@ fn render_assoc_items( i, AssocItemLink::Anchor(None), render_mode, - containing_item.stable_since(), + containing_item.stable_since().as_deref(), true, None, false, @@ -3564,8 +3569,11 @@ fn render_impl( ); } write!(w, "", id); - let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]); - render_stability_since_raw(w, since, outer_version); + let since = i.impl_item.stability.as_ref().and_then(|s| match s.level { + StabilityLevel::Stable { since } => Some(since.as_str()), + StabilityLevel::Unstable { .. } => None, + }); + render_stability_since_raw(w, since.as_deref(), outer_version); if let Some(l) = cx.src_href(&i.impl_item, cache) { write!(w, "[src]", l, "goto source code"); } @@ -3626,7 +3634,7 @@ fn render_impl( write!(w, ""); render_assoc_item(w, item, link.anchor(&id), ItemType::Impl); write!(w, ""); - render_stability_since_raw(w, item.stable_since(), outer_version); + render_stability_since_raw(w, item.stable_since().as_deref(), outer_version); if let Some(l) = cx.src_href(item, cache) { write!( w, @@ -3648,7 +3656,7 @@ fn render_impl( write!(w, "

", id, item_type, extra_class); assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), ""); write!(w, ""); - render_stability_since_raw(w, item.stable_since(), outer_version); + render_stability_since_raw(w, item.stable_since().as_deref(), outer_version); if let Some(l) = cx.src_href(item, cache) { write!( w, From 85c0479e179639180c13c5fe6a6789e6538ea891 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 11 Oct 2020 10:01:27 -0400 Subject: [PATCH 12/28] Remove unnecessary Clean impl --- src/librustdoc/clean/inline.rs | 4 ++-- src/librustdoc/clean/mod.rs | 36 ++++++++++++++-------------------- src/librustdoc/clean/utils.rs | 2 +- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 79ff7fc62d53e..6267b02e5d2c4 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -130,7 +130,7 @@ pub fn try_inline( attrs, inner, visibility: clean::Public, - stability: cx.tcx.lookup_stability(did).clean(cx), + stability: cx.tcx.lookup_stability(did).cloned(), deprecation: cx.tcx.lookup_deprecation(did).clean(cx), def_id: did, }); @@ -461,7 +461,7 @@ pub fn build_impl( name: None, attrs, visibility: clean::Inherited, - stability: tcx.lookup_stability(did).clean(cx), + stability: tcx.lookup_stability(did).cloned(), deprecation: tcx.lookup_deprecation(did).clean(cx), def_id: did, }); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bb1ee7f261514..776b131a07611 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -913,7 +913,7 @@ impl Clean for doctree::Function<'_> { attrs: self.attrs.clean(cx), source: self.span.clean(cx), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), def_id: did.to_def_id(), inner: FunctionItem(Function { @@ -1022,7 +1022,7 @@ impl Clean for doctree::Trait<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: TraitItem(Trait { auto: self.is_auto.clean(cx), @@ -1046,7 +1046,7 @@ impl Clean for doctree::TraitAlias<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: TraitAliasItem(TraitAlias { generics: self.generics.clean(cx), @@ -1831,7 +1831,7 @@ impl Clean for doctree::Struct<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: StructItem(Struct { struct_type: self.struct_type, @@ -1851,7 +1851,7 @@ impl Clean for doctree::Union<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: UnionItem(Union { struct_type: self.struct_type, @@ -1881,7 +1881,7 @@ impl Clean for doctree::Enum<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: EnumItem(Enum { variants: self.variants.iter().map(|v| v.clean(cx)).collect(), @@ -1899,7 +1899,7 @@ impl Clean for doctree::Variant<'_> { attrs: self.attrs.clean(cx), source: self.span.clean(cx), visibility: Inherited, - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), inner: VariantItem(Variant { kind: self.def.clean(cx) }), @@ -2048,7 +2048,7 @@ impl Clean for doctree::Typedef<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false), } @@ -2063,7 +2063,7 @@ impl Clean for doctree::OpaqueTy<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: OpaqueTyItem(OpaqueTy { bounds: self.opaque_ty.bounds.clean(cx), @@ -2091,7 +2091,7 @@ impl Clean for doctree::Static<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: StaticItem(Static { type_: self.type_.clean(cx), @@ -2112,7 +2112,7 @@ impl Clean for doctree::Constant<'_> { source: self.span.clean(cx), def_id: def_id.to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: ConstantItem(Constant { type_: self.type_.clean(cx), @@ -2166,7 +2166,7 @@ impl Clean> for doctree::Impl<'_> { source: self.span.clean(cx), def_id: def_id.to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner: ImplItem(Impl { unsafety: self.unsafety, @@ -2348,7 +2348,7 @@ impl Clean for doctree::ForeignItem<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), inner, } @@ -2363,7 +2363,7 @@ impl Clean for doctree::Macro<'_> { attrs: self.attrs.clean(cx), source: self.span.clean(cx), visibility: Public, - stability: cx.stability(self.hid).clean(cx), + stability: cx.stability(self.hid), deprecation: cx.deprecation(self.hid).clean(cx), def_id: self.def_id, inner: MacroItem(Macro { @@ -2388,7 +2388,7 @@ impl Clean for doctree::ProcMacro<'_> { attrs: self.attrs.clean(cx), source: self.span.clean(cx), visibility: Public, - stability: cx.stability(self.id).clean(cx), + stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), inner: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }), @@ -2396,12 +2396,6 @@ impl Clean for doctree::ProcMacro<'_> { } } -impl Clean for attr::Stability { - fn clean(&self, _: &DocContext<'_>) -> attr::Stability { - self.clone() - } -} - impl Clean for attr::Deprecation { fn clean(&self, _: &DocContext<'_>) -> Deprecation { Deprecation { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 25ba6e49bd563..e6693540b238b 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -103,7 +103,7 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { // extract the stability index for a node from tcx, if possible pub fn get_stability(cx: &DocContext<'_>, def_id: DefId) -> Option { - cx.tcx.lookup_stability(def_id).clean(cx) + cx.tcx.lookup_stability(def_id).cloned() } pub fn get_deprecation(cx: &DocContext<'_>, def_id: DefId) -> Option { From 96b0446b538a160c83ade3d9e5e9d2203868492d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 11 Oct 2020 11:11:33 -0400 Subject: [PATCH 13/28] Move `PartialOrd` impl out of rustc Rustdoc's ordering requirements are probably not relevant to the rest of the compiler. --- compiler/rustc_attr/src/builtin.rs | 14 -------------- src/librustdoc/html/render/mod.rs | 12 ++++++------ 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 5268d3f0ab043..9c309345000bb 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -9,7 +9,6 @@ use rustc_session::parse::{feature_err, ParseSess}; use rustc_session::Session; use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; -use std::cmp; use std::num::NonZeroU32; use version_check::Version; @@ -163,19 +162,6 @@ pub enum StabilityLevel { Stable { since: Symbol }, } -impl cmp::PartialOrd for StabilityLevel { - // This only take into account stability, not any fields. - // Therefore it is only `PartialOrd` and not `Ord`. - fn partial_cmp(&self, other: &Self) -> Option { - match (self, other) { - (Self::Unstable { .. }, Self::Unstable { .. }) => Some(cmp::Ordering::Equal), - (Self::Stable { .. }, Self::Stable { .. }) => Some(cmp::Ordering::Equal), - (Self::Unstable { .. }, Self::Stable { .. }) => Some(cmp::Ordering::Less), - (Self::Stable { .. }, Self::Unstable { .. }) => Some(cmp::Ordering::Greater), - } - } -} - impl StabilityLevel { pub fn is_unstable(&self) -> bool { matches!(self, StabilityLevel::Unstable { .. }) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 36db5557b521b..f81ea0f6d46ac 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1984,12 +1984,12 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: } let s1 = i1.stability.as_ref().map(|s| s.level); let s2 = i2.stability.as_ref().map(|s| s.level); - match (s1, s2) { - (Some(a), Some(b)) => match a.partial_cmp(&b) { - Some(Ordering::Equal) | None => {} - Some(other) => return other, - }, - _ => {} + if let (Some(a), Some(b)) = (s1, s2) { + match (a.is_stable(), b.is_stable()) { + (true, true) | (false, false) => {} + (false, true) => return Ordering::Less, + (true, false) => return Ordering::Greater, + } } let lhs = i1.name.as_ref().map_or("", |s| &**s); let rhs = i2.name.as_ref().map_or("", |s| &**s); From ca5478a5dffd322c9b371b44af9b4ea963a0ee47 Mon Sep 17 00:00:00 2001 From: George Burgess IV Date: Sun, 11 Oct 2020 12:05:31 -0700 Subject: [PATCH 14/28] bootstrap: only use compiler-builtins-c if they exist The assignment of `features` above was added in rust-lang#60981, but never used. Presumably the intent was to replace the string literal here with it. While I'm in the area, `compiler_builtins_c_feature` doesn't need to be a `String`. --- src/bootstrap/compile.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 40bf6c48296b2..5215ab3dd4f9b 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -234,14 +234,14 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car // Note that `libprofiler_builtins/build.rs` also computes this so if // you're changing something here please also change that. cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root); - " compiler-builtins-c".to_string() + " compiler-builtins-c" } else { - String::new() + "" }; if builder.no_std(target) == Some(true) { let mut features = "compiler-builtins-mem".to_string(); - features.push_str(&compiler_builtins_c_feature); + features.push_str(compiler_builtins_c_feature); // for no-std targets we only compile a few no_std crates cargo @@ -249,10 +249,10 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car .arg("--manifest-path") .arg(builder.src.join("library/alloc/Cargo.toml")) .arg("--features") - .arg("compiler-builtins-mem compiler-builtins-c"); + .arg(features); } else { let mut features = builder.std_features(); - features.push_str(&compiler_builtins_c_feature); + features.push_str(compiler_builtins_c_feature); cargo .arg("--features") From 01ac5a97c90c26ac35ca9d65f685dd6701edfa3b Mon Sep 17 00:00:00 2001 From: James Gill Date: Tue, 6 Oct 2020 21:54:05 -0400 Subject: [PATCH 15/28] Stabilize slice_select_nth_unstable This stabilizes the functionality in slice_partition_at_index, but under the names `select_nth_unstable*`. The functions `partition_at_index*` are left as deprecated, to be removed in a later release. Closes #55300 --- library/core/src/slice/mod.rs | 68 +++++++++++++++++++++++++++-------- library/core/tests/slice.rs | 32 ++++++++--------- 2 files changed, 69 insertions(+), 31 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index d0d88c01f5b2c..349c2cde274dd 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2034,6 +2034,50 @@ impl [T] { sort::quicksort(self, |a, b| f(a).lt(&f(b))); } + /// Reorder the slice such that the element at `index` is at its final sorted position. + #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[rustc_deprecated(since = "1.49.0", reason = "use the select_nth_unstable() instead")] + #[inline] + pub fn partition_at_index(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T]) + where + T: Ord, + { + self.select_nth_unstable(index) + } + + /// Reorder the slice with a comparator function such that the element at `index` is at its + /// final sorted position. + #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[rustc_deprecated(since = "1.49.0", reason = "use select_nth_unstable_by() instead")] + #[inline] + pub fn partition_at_index_by( + &mut self, + index: usize, + compare: F, + ) -> (&mut [T], &mut T, &mut [T]) + where + F: FnMut(&T, &T) -> Ordering, + { + self.select_nth_unstable_by(index, compare) + } + + /// Reorder the slice with a key extraction function such that the element at `index` is at its + /// final sorted position. + #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[rustc_deprecated(since = "1.49.0", reason = "use the select_nth_unstable_by_key() instead")] + #[inline] + pub fn partition_at_index_by_key( + &mut self, + index: usize, + f: F, + ) -> (&mut [T], &mut T, &mut [T]) + where + F: FnMut(&T) -> K, + K: Ord, + { + self.select_nth_unstable_by_key(index, f) + } + /// Reorder the slice such that the element at `index` is at its final sorted position. /// /// This reordering has the additional property that any value at position `i < index` will be @@ -2058,12 +2102,10 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_partition_at_index)] - /// /// let mut v = [-5i32, 4, 1, -3, 2]; /// /// // Find the median - /// v.partition_at_index(2); + /// v.select_nth_unstable(2); /// /// // We are only guaranteed the slice will be one of the following, based on the way we sort /// // about the specified index. @@ -2072,9 +2114,9 @@ impl [T] { /// v == [-3, -5, 1, 4, 2] || /// v == [-5, -3, 1, 4, 2]); /// ``` - #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")] #[inline] - pub fn partition_at_index(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T]) + pub fn select_nth_unstable(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T]) where T: Ord, { @@ -2108,12 +2150,10 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_partition_at_index)] - /// /// let mut v = [-5i32, 4, 1, -3, 2]; /// /// // Find the median as if the slice were sorted in descending order. - /// v.partition_at_index_by(2, |a, b| b.cmp(a)); + /// v.select_nth_unstable_by(2, |a, b| b.cmp(a)); /// /// // We are only guaranteed the slice will be one of the following, based on the way we sort /// // about the specified index. @@ -2122,9 +2162,9 @@ impl [T] { /// v == [4, 2, 1, -5, -3] || /// v == [4, 2, 1, -3, -5]); /// ``` - #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")] #[inline] - pub fn partition_at_index_by( + pub fn select_nth_unstable_by( &mut self, index: usize, mut compare: F, @@ -2162,12 +2202,10 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_partition_at_index)] - /// /// let mut v = [-5i32, 4, 1, -3, 2]; /// /// // Return the median as if the array were sorted according to absolute value. - /// v.partition_at_index_by_key(2, |a| a.abs()); + /// v.select_nth_unstable_by_key(2, |a| a.abs()); /// /// // We are only guaranteed the slice will be one of the following, based on the way we sort /// // about the specified index. @@ -2176,9 +2214,9 @@ impl [T] { /// v == [2, 1, -3, 4, -5] || /// v == [2, 1, -3, -5, 4]); /// ``` - #[unstable(feature = "slice_partition_at_index", issue = "55300")] + #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")] #[inline] - pub fn partition_at_index_by_key( + pub fn select_nth_unstable_by_key( &mut self, index: usize, mut f: F, diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 5ef30b1a8898a..ac5c9353ccb46 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1571,7 +1571,7 @@ fn sort_unstable() { #[test] #[cfg(not(target_arch = "wasm32"))] #[cfg_attr(miri, ignore)] // Miri is too slow -fn partition_at_index() { +fn select_nth_unstable() { use core::cmp::Ordering::{Equal, Greater, Less}; use rand::rngs::StdRng; use rand::seq::SliceRandom; @@ -1597,7 +1597,7 @@ fn partition_at_index() { // Sort in default order. for pivot in 0..len { let mut v = orig.clone(); - v.partition_at_index(pivot); + v.select_nth_unstable(pivot); assert_eq!(v_sorted[pivot], v[pivot]); for i in 0..pivot { @@ -1610,7 +1610,7 @@ fn partition_at_index() { // Sort in ascending order. for pivot in 0..len { let mut v = orig.clone(); - let (left, pivot, right) = v.partition_at_index_by(pivot, |a, b| a.cmp(b)); + let (left, pivot, right) = v.select_nth_unstable_by(pivot, |a, b| a.cmp(b)); assert_eq!(left.len() + right.len(), len - 1); @@ -1633,7 +1633,7 @@ fn partition_at_index() { for pivot in 0..len { let mut v = orig.clone(); - v.partition_at_index_by(pivot, sort_descending_comparator); + v.select_nth_unstable_by(pivot, sort_descending_comparator); assert_eq!(v_sorted_descending[pivot], v[pivot]); for i in 0..pivot { @@ -1654,7 +1654,7 @@ fn partition_at_index() { } for pivot in 0..v.len() { - v.partition_at_index_by(pivot, |_, _| *[Less, Equal, Greater].choose(&mut rng).unwrap()); + v.select_nth_unstable_by(pivot, |_, _| *[Less, Equal, Greater].choose(&mut rng).unwrap()); v.sort(); for i in 0..v.len() { assert_eq!(v[i], i as i32); @@ -1662,28 +1662,28 @@ fn partition_at_index() { } // Should not panic. - [(); 10].partition_at_index(0); - [(); 10].partition_at_index(5); - [(); 10].partition_at_index(9); - [(); 100].partition_at_index(0); - [(); 100].partition_at_index(50); - [(); 100].partition_at_index(99); + [(); 10].select_nth_unstable(0); + [(); 10].select_nth_unstable(5); + [(); 10].select_nth_unstable(9); + [(); 100].select_nth_unstable(0); + [(); 100].select_nth_unstable(50); + [(); 100].select_nth_unstable(99); let mut v = [0xDEADBEEFu64]; - v.partition_at_index(0); + v.select_nth_unstable(0); assert!(v == [0xDEADBEEF]); } #[test] #[should_panic(expected = "index 0 greater than length of slice")] -fn partition_at_index_zero_length() { - [0i32; 0].partition_at_index(0); +fn select_nth_unstable_zero_length() { + [0i32; 0].select_nth_unstable(0); } #[test] #[should_panic(expected = "index 20 greater than length of slice")] -fn partition_at_index_past_length() { - [0i32; 10].partition_at_index(20); +fn select_nth_unstable_past_length() { + [0i32; 10].select_nth_unstable(20); } pub mod memchr { From b620e49ccafa567bc0733b251586de60fa826441 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 12 Oct 2020 10:34:30 +0200 Subject: [PATCH 16/28] Remove dump_incremental_data --- compiler/rustc_codegen_llvm/src/lib.rs | 3 --- compiler/rustc_codegen_ssa/src/back/write.rs | 9 --------- 2 files changed, 12 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 02da175cac390..fb5f8ce322462 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -278,9 +278,6 @@ impl CodegenBackend for LlvmCodegenBackend { .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") .join(sess); - if sess.opts.debugging_opts.incremental_info { - rustc_codegen_ssa::back::write::dump_incremental_data(&codegen_results); - } sess.time("llvm_dump_timing_file", || { if sess.opts.debugging_opts.llvm_time_trace { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index a61eca1dcaf3c..2ff78898fb268 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -655,15 +655,6 @@ fn produce_final_output_artifacts( // These are used in linking steps and will be cleaned up afterward. } -pub fn dump_incremental_data(_codegen_results: &CodegenResults) { - // FIXME(mw): This does not work at the moment because the situation has - // become more complicated due to incremental LTO. Now a CGU - // can have more than two caching states. - // println!("[incremental] Re-using {} out of {} modules", - // codegen_results.modules.iter().filter(|m| m.pre_existing).count(), - // codegen_results.modules.len()); -} - pub enum WorkItem { /// Optimize a newly codegened, totally unoptimized module. Optimize(ModuleCodegen), From 02e6b861eb04737915636a63eec00ef126f59dd5 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 1 Sep 2020 14:19:24 +0200 Subject: [PATCH 17/28] rustdoc: skip allow missing doc in cover. report During the document coverage reporting with ```bash rustdoc something.rs -Z unstable-options --show-coverage ``` the coverage report also includes parts of the code that are marked with `#[allow(missing_docs)]`, which outputs lower numbers in the coverage report even though these parts should be ignored for the calculation. Co-authored-by: Joshua Nelson --- .../passes/calculate_doc_coverage.rs | 21 +++++++++++-- .../rustdoc-ui/coverage/allow_missing_docs.rs | 31 +++++++++++++++++++ .../coverage/allow_missing_docs.stdout | 7 +++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc-ui/coverage/allow_missing_docs.rs create mode 100644 src/test/rustdoc-ui/coverage/allow_missing_docs.stdout diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 4bca3996eb48f..30dd8def70e54 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -5,7 +5,7 @@ use crate::fold::{self, DocFolder}; use crate::html::markdown::{find_testable_code, ErrorCodes}; use crate::passes::doc_test_lints::{should_have_doc_example, Tests}; use crate::passes::Pass; -use rustc_span::symbol::sym; +use rustc_span::symbol::{sym, Ident}; use rustc_span::FileName; use serde::Serialize; @@ -41,8 +41,11 @@ impl ItemCount { has_docs: bool, has_doc_example: bool, should_have_doc_examples: bool, + should_have_docs: bool, ) { - self.total += 1; + if has_docs || should_have_docs { + self.total += 1; + } if has_docs { self.with_docs += 1; @@ -229,6 +232,15 @@ impl fold::DocFolder for CoverageCalculator { } _ => { let has_docs = !i.attrs.doc_strings.is_empty(); + let should_have_docs = !i.attrs.other_attrs.iter().any(|a| { + a.has_name(sym::allow) + && a.meta_item_list().iter().any(|meta_list_item| { + meta_list_item.iter().any(|li| match li.ident() { + Some(ident) => ident == Ident::from_str("missing_docs"), + _ => false, + }) + }) + }); let mut tests = Tests { found_tests: 0 }; find_testable_code( @@ -250,7 +262,12 @@ impl fold::DocFolder for CoverageCalculator { has_docs, has_doc_example, should_have_doc_example(&i.inner), + should_have_docs, ); + + if !should_have_docs { + return Some(i); + } } } diff --git a/src/test/rustdoc-ui/coverage/allow_missing_docs.rs b/src/test/rustdoc-ui/coverage/allow_missing_docs.rs new file mode 100644 index 0000000000000..8c076761edea9 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/allow_missing_docs.rs @@ -0,0 +1,31 @@ +// compile-flags:-Z unstable-options --show-coverage +// check-pass + +//! Make sure to have some docs on your crate root + +#[allow(missing_docs)] +pub mod mod_foo { + pub struct Bar; +} + +/// This is a struct with a `#[allow(missing_docs)]` +pub struct AllowTheMissingDocs { + #[allow(missing_docs)] + pub empty_str: String, + + /// This has + #[allow(missing_docs)] + /// but also has documentation comments + pub hello: usize, + + /// The doc id just to create a boilerplate comment + pub doc_id: Vec, +} + +/// A function that has a documentation +pub fn this_is_func() {} + +#[allow(missing_docs)] +pub struct DemoStruct { + something: usize, +} diff --git a/src/test/rustdoc-ui/coverage/allow_missing_docs.stdout b/src/test/rustdoc-ui/coverage/allow_missing_docs.stdout new file mode 100644 index 0000000000000..ea5380e320414 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/allow_missing_docs.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...i/coverage/allow_missing_docs.rs | 5 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 5 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ From b31f5d05b1c10c1f99b5bc3c14499ff537c7b692 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Oct 2020 18:05:01 +0200 Subject: [PATCH 18/28] Inherit lint level from parents --- .../passes/calculate_doc_coverage.rs | 40 ++++++++----------- .../rustdoc-ui/coverage/allow_missing_docs.rs | 8 ++++ .../coverage/allow_missing_docs.stdout | 4 +- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 30dd8def70e54..093b77d4e94f3 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -1,11 +1,13 @@ use crate::clean; -use crate::config::OutputFormat; use crate::core::DocContext; use crate::fold::{self, DocFolder}; use crate::html::markdown::{find_testable_code, ErrorCodes}; use crate::passes::doc_test_lints::{should_have_doc_example, Tests}; use crate::passes::Pass; -use rustc_span::symbol::{sym, Ident}; +use rustc_lint::builtin::MISSING_DOCS; +use rustc_middle::lint::LintSource; +use rustc_session::lint; +use rustc_span::symbol::sym; use rustc_span::FileName; use serde::Serialize; @@ -19,10 +21,10 @@ pub const CALCULATE_DOC_COVERAGE: Pass = Pass { }; fn calculate_doc_coverage(krate: clean::Crate, ctx: &DocContext<'_>) -> clean::Crate { - let mut calc = CoverageCalculator::new(); + let mut calc = CoverageCalculator::new(ctx); let krate = calc.fold_crate(krate); - calc.print_results(ctx.renderinfo.borrow().output_format); + calc.print_results(); krate } @@ -97,8 +99,9 @@ impl ops::AddAssign for ItemCount { } } -struct CoverageCalculator { +struct CoverageCalculator<'a, 'b> { items: BTreeMap, + ctx: &'a DocContext<'b>, } fn limit_filename_len(filename: String) -> String { @@ -111,9 +114,9 @@ fn limit_filename_len(filename: String) -> String { } } -impl CoverageCalculator { - fn new() -> CoverageCalculator { - CoverageCalculator { items: Default::default() } +impl<'a, 'b> CoverageCalculator<'a, 'b> { + fn new(ctx: &'a DocContext<'b>) -> CoverageCalculator<'a, 'b> { + CoverageCalculator { items: Default::default(), ctx } } fn to_json(&self) -> String { @@ -127,7 +130,8 @@ impl CoverageCalculator { .expect("failed to convert JSON data to string") } - fn print_results(&self, output_format: Option) { + fn print_results(&self) { + let output_format = self.ctx.renderinfo.borrow().output_format; if output_format.map(|o| o.is_json()).unwrap_or_else(|| false) { println!("{}", self.to_json()); return; @@ -181,7 +185,7 @@ impl CoverageCalculator { } } -impl fold::DocFolder for CoverageCalculator { +impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { fn fold_item(&mut self, i: clean::Item) -> Option { match i.inner { _ if !i.def_id.is_local() => { @@ -232,15 +236,6 @@ impl fold::DocFolder for CoverageCalculator { } _ => { let has_docs = !i.attrs.doc_strings.is_empty(); - let should_have_docs = !i.attrs.other_attrs.iter().any(|a| { - a.has_name(sym::allow) - && a.meta_item_list().iter().any(|meta_list_item| { - meta_list_item.iter().any(|li| match li.ident() { - Some(ident) => ident == Ident::from_str("missing_docs"), - _ => false, - }) - }) - }); let mut tests = Tests { found_tests: 0 }; find_testable_code( @@ -257,6 +252,9 @@ impl fold::DocFolder for CoverageCalculator { ); let has_doc_example = tests.found_tests != 0; + let hir_id = self.ctx.tcx.hir().local_def_id_to_hir_id(i.def_id.expect_local()); + let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id); + let should_have_docs = level != lint::Level::Allow || !matches!(source, LintSource::Node(..)); debug!("counting {:?} {:?} in {}", i.type_(), i.name, i.source.filename); self.items.entry(i.source.filename.clone()).or_default().count_item( has_docs, @@ -264,10 +262,6 @@ impl fold::DocFolder for CoverageCalculator { should_have_doc_example(&i.inner), should_have_docs, ); - - if !should_have_docs { - return Some(i); - } } } diff --git a/src/test/rustdoc-ui/coverage/allow_missing_docs.rs b/src/test/rustdoc-ui/coverage/allow_missing_docs.rs index 8c076761edea9..87af1a458648c 100644 --- a/src/test/rustdoc-ui/coverage/allow_missing_docs.rs +++ b/src/test/rustdoc-ui/coverage/allow_missing_docs.rs @@ -29,3 +29,11 @@ pub fn this_is_func() {} pub struct DemoStruct { something: usize, } + +#[allow(missing_docs)] +pub mod bar { + #[warn(missing_docs)] + pub struct Bar { //~ WARN + pub f: u32, //~ WARN + } +} diff --git a/src/test/rustdoc-ui/coverage/allow_missing_docs.stdout b/src/test/rustdoc-ui/coverage/allow_missing_docs.stdout index ea5380e320414..17e8ee9e23dcc 100644 --- a/src/test/rustdoc-ui/coverage/allow_missing_docs.stdout +++ b/src/test/rustdoc-ui/coverage/allow_missing_docs.stdout @@ -1,7 +1,7 @@ +-------------------------------------+------------+------------+------------+------------+ | File | Documented | Percentage | Examples | Percentage | +-------------------------------------+------------+------------+------------+------------+ -| ...i/coverage/allow_missing_docs.rs | 5 | 100.0% | 0 | 0.0% | +| ...i/coverage/allow_missing_docs.rs | 5 | 71.4% | 0 | 0.0% | +-------------------------------------+------------+------------+------------+------------+ -| Total | 5 | 100.0% | 0 | 0.0% | +| Total | 5 | 71.4% | 0 | 0.0% | +-------------------------------------+------------+------------+------------+------------+ From 22465b35a608487773f960574a798262b23c4abd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Oct 2020 18:20:00 +0200 Subject: [PATCH 19/28] Apply same treatment to MISSING_DOC_CODE_EXAMPLES --- .../passes/calculate_doc_coverage.rs | 5 +++-- src/librustdoc/passes/doc_test_lints.rs | 15 ++++++++++---- .../coverage/allow_missing_docs.stderr | 20 +++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 src/test/rustdoc-ui/coverage/allow_missing_docs.stderr diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 093b77d4e94f3..7cdd9a590ba3b 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -254,12 +254,13 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { let has_doc_example = tests.found_tests != 0; let hir_id = self.ctx.tcx.hir().local_def_id_to_hir_id(i.def_id.expect_local()); let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id); - let should_have_docs = level != lint::Level::Allow || !matches!(source, LintSource::Node(..)); + let should_have_docs = + level != lint::Level::Allow || !matches!(source, LintSource::Node(..)); debug!("counting {:?} {:?} in {}", i.type_(), i.name, i.source.filename); self.items.entry(i.source.filename.clone()).or_default().count_item( has_docs, has_doc_example, - should_have_doc_example(&i.inner), + should_have_doc_example(self.ctx, &i), should_have_docs, ); } diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index 78af9f9b8561a..1787d0a99d94e 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -9,6 +9,7 @@ use crate::clean::*; use crate::core::DocContext; use crate::fold::DocFolder; use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString}; +use rustc_middle::lint::LintSource; use rustc_session::lint; pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass { @@ -56,8 +57,8 @@ impl crate::doctest::Tester for Tests { } } -pub fn should_have_doc_example(item_kind: &clean::ItemEnum) -> bool { - !matches!(item_kind, +pub fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool { + if matches!(item.inner, clean::StructFieldItem(_) | clean::VariantItem(_) | clean::AssocConstItem(_, _) @@ -69,7 +70,13 @@ pub fn should_have_doc_example(item_kind: &clean::ItemEnum) -> bool { | clean::ImportItem(_) | clean::PrimitiveItem(_) | clean::KeywordItem(_) - ) + ) { + return false; + } + let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_local()); + let (level, source) = + cx.tcx.lint_level_at_node(lint::builtin::MISSING_DOC_CODE_EXAMPLES, hir_id); + level != lint::Level::Allow || !matches!(source, LintSource::Node(..)) } pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { @@ -88,7 +95,7 @@ pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { if tests.found_tests == 0 && rustc_feature::UnstableFeatures::from_environment().is_nightly_build() { - if should_have_doc_example(&item.inner) { + if should_have_doc_example(cx, &item) { debug!("reporting error for {:?} (hir_id={:?})", item, hir_id); let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span()); cx.tcx.struct_span_lint_hir( diff --git a/src/test/rustdoc-ui/coverage/allow_missing_docs.stderr b/src/test/rustdoc-ui/coverage/allow_missing_docs.stderr new file mode 100644 index 0000000000000..3d5b512d14d1a --- /dev/null +++ b/src/test/rustdoc-ui/coverage/allow_missing_docs.stderr @@ -0,0 +1,20 @@ +warning: missing documentation for a struct + --> $DIR/allow_missing_docs.rs:36:5 + | +LL | pub struct Bar { + | ^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/allow_missing_docs.rs:35:12 + | +LL | #[warn(missing_docs)] + | ^^^^^^^^^^^^ + +warning: missing documentation for a struct field + --> $DIR/allow_missing_docs.rs:37:9 + | +LL | pub f: u32, + | ^^^^^^^^^^ + +warning: 2 warnings emitted + From 5d20e1aa03c6d86fcf9197ccec16ad5faa94beee Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Oct 2020 13:48:45 +0200 Subject: [PATCH 20/28] Improve lint level handling --- src/librustdoc/passes/calculate_doc_coverage.rs | 4 +++- src/librustdoc/passes/doc_test_lints.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 7cdd9a590ba3b..ced26fcf5b0e9 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -254,8 +254,10 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { let has_doc_example = tests.found_tests != 0; let hir_id = self.ctx.tcx.hir().local_def_id_to_hir_id(i.def_id.expect_local()); let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id); + // `missing_docs` is allow-by-default, so don't treat this as ignoring the item + // unless the user had an explicit `allow` let should_have_docs = - level != lint::Level::Allow || !matches!(source, LintSource::Node(..)); + level != lint::Level::Allow || matches!(source, LintSource::Default); debug!("counting {:?} {:?} in {}", i.type_(), i.name, i.source.filename); self.items.entry(i.source.filename.clone()).or_default().count_item( has_docs, diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index 1787d0a99d94e..686ec51fb0604 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -76,7 +76,7 @@ pub fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_local()); let (level, source) = cx.tcx.lint_level_at_node(lint::builtin::MISSING_DOC_CODE_EXAMPLES, hir_id); - level != lint::Level::Allow || !matches!(source, LintSource::Node(..)) + level != lint::Level::Allow || matches!(source, LintSource::Default) } pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { From 685444008bb2631564b56068bcbf2462bf0cc6af Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Oct 2020 14:32:41 +0200 Subject: [PATCH 21/28] Extend test to ensure that items inherit lint level from the parent --- src/test/rustdoc-ui/coverage/allow_missing_docs.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/rustdoc-ui/coverage/allow_missing_docs.rs b/src/test/rustdoc-ui/coverage/allow_missing_docs.rs index 87af1a458648c..c077be31b209d 100644 --- a/src/test/rustdoc-ui/coverage/allow_missing_docs.rs +++ b/src/test/rustdoc-ui/coverage/allow_missing_docs.rs @@ -36,4 +36,6 @@ pub mod bar { pub struct Bar { //~ WARN pub f: u32, //~ WARN } + + pub struct NeedsNoDocs; } From 25cc75c9245664f239a52de60a0c0baa8b4c81d5 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 9 Oct 2020 15:34:57 +0200 Subject: [PATCH 22/28] build-manifest: accept the Rust version instead of the monorepo path This commit changes the way build-manifest is invoked, to let it accept the Rust version directly instead of requiring the path of the Rust monorepo and letting build-manifest figure out the path on its own. This allows to run build-manifest without a clone of the monorepo. --- src/bootstrap/dist.rs | 2 +- src/bootstrap/run.rs | 2 +- src/tools/build-manifest/README.md | 4 ++-- src/tools/build-manifest/src/main.rs | 4 ++-- src/tools/build-manifest/src/versions.rs | 13 +++---------- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 3a0743da7a415..8f4968d5ac69f 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2353,7 +2353,7 @@ impl Step for HashSign { cmd.arg(today.trim()); cmd.arg(addr); cmd.arg(&builder.config.channel); - cmd.arg(&builder.src); + cmd.arg(&builder.version); cmd.env("BUILD_MANIFEST_LEGACY", "1"); builder.create_dir(&distdir(builder)); diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 80c093e713eff..d8169549c07ba 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -77,7 +77,7 @@ impl Step for BuildManifest { cmd.arg(today.trim()); cmd.arg(addr); cmd.arg(&builder.config.channel); - cmd.arg(&builder.src); + cmd.arg(&builder.version); builder.create_dir(&distdir(builder)); builder.run(&mut cmd); diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md index 26e96c9fd8fda..b77c5a907c118 100644 --- a/src/tools/build-manifest/README.md +++ b/src/tools/build-manifest/README.md @@ -21,8 +21,8 @@ Then, you can generate the manifest and all the packages from `path/to/dist` to ``` $ cargo +nightly run path/to/dist path/to/output 1970-01-01 http://example.com \ - CHANNEL path/to/rust/repo + CHANNEL VERSION ``` Remember to replace `CHANNEL` with the channel you produced dist artifacts of -and `path/to/rust/repo` with the path to your checkout of the Rust repository. +and `VERSION` with the current Rust version. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 7ee28cd6e5d95..0efebe363f88f 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -221,7 +221,7 @@ fn main() { let date = args.next().unwrap(); let s3_address = args.next().unwrap(); let channel = args.next().unwrap(); - let monorepo_path = args.next().unwrap(); + let rustc_version = args.next().unwrap(); // Do not ask for a passphrase while manually testing let mut passphrase = String::new(); @@ -231,7 +231,7 @@ fn main() { } Builder { - versions: Versions::new(&channel, &input, Path::new(&monorepo_path)).unwrap(), + versions: Versions::new(&channel, &rustc_version, &input).unwrap(), input, output, diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 75b6979b54a78..c2bce0f1cf39c 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -1,4 +1,4 @@ -use anyhow::{Context, Error}; +use anyhow::Error; use flate2::read::GzDecoder; use std::collections::HashMap; use std::fs::File; @@ -93,17 +93,10 @@ pub(crate) struct Versions { } impl Versions { - pub(crate) fn new( - channel: &str, - dist_path: &Path, - monorepo_root: &Path, - ) -> Result { + pub(crate) fn new(channel: &str, rustc_version: &str, dist_path: &Path) -> Result { Ok(Self { channel: channel.into(), - rustc_version: std::fs::read_to_string(monorepo_root.join("src").join("version")) - .context("failed to read the rustc version from src/version")? - .trim() - .to_string(), + rustc_version: rustc_version.into(), dist_path: dist_path.into(), versions: HashMap::new(), }) From 2f387e9d11f1ea6222af0ff00e4de956496fc83f Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 9 Oct 2020 19:49:13 +0200 Subject: [PATCH 23/28] bootstrap: add disabled by default build-manifest dist component --- src/bootstrap/builder.rs | 1 + src/bootstrap/dist.rs | 67 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 4bc162abee6c1..73761b57a8d44 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -462,6 +462,7 @@ impl<'a> Builder<'a> { dist::LlvmTools, dist::RustDev, dist::Extended, + dist::BuildManifest, dist::HashSign ), Kind::Install => describe!( diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 8f4968d5ac69f..12533d29809cf 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2584,3 +2584,70 @@ impl Step for RustDev { Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))) } } + +/// Tarball containing a prebuilt version of the build-manifest tool, intented to be used by the +/// release process to avoid cloning the monorepo and building stuff. +/// +/// Should not be considered stable by end users. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct BuildManifest { + pub target: TargetSelection, +} + +impl Step for BuildManifest { + type Output = PathBuf; + const DEFAULT: bool = false; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/build-manifest") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(BuildManifest { target: run.target }); + } + + fn run(self, builder: &Builder<'_>) -> PathBuf { + let build_manifest = builder.tool_exe(Tool::BuildManifest); + + let name = pkgname(builder, "build-manifest"); + let tmp = tmpdir(builder); + + // Prepare the image. + let image = tmp.join("build-manifest-image"); + let image_bin = image.join("bin"); + let _ = fs::remove_dir_all(&image); + t!(fs::create_dir_all(&image_bin)); + builder.install(&build_manifest, &image_bin.join("build-manifest"), 0o755); + + // Prepare the overlay. + let overlay = tmp.join("build-manifest-overlay"); + let _ = fs::remove_dir_all(&overlay); + builder.create_dir(&overlay); + builder.create(&overlay.join("version"), &builder.rust_version()); + for file in &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"] { + builder.install(&builder.src.join(file), &overlay, 0o644); + } + + // Create the final tarball. + let mut cmd = rust_installer(builder); + cmd.arg("generate") + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=build-manifest installed.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) + .arg(format!("--package-name={}-{}", name, self.target.triple)) + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--component-name=build-manifest"); + + builder.run(&mut cmd); + distdir(builder).join(format!("{}-{}.tar.gz", name, self.target.triple)) + } +} From 60ae018bf1e0d6d372ac545b56c8992a1365e917 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 9 Oct 2020 19:51:07 +0200 Subject: [PATCH 24/28] bootstrap: add --include-default-paths to ./x.py --- src/bootstrap/builder.rs | 42 ++++++++++++++++++++-------------------- src/bootstrap/config.rs | 2 ++ src/bootstrap/flags.rs | 7 +++++++ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 73761b57a8d44..707c1ff3efad9 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -193,37 +193,37 @@ impl StepDescription { ); } - if paths.is_empty() { - for (desc, should_run) in v.iter().zip(should_runs) { + if paths.is_empty() || builder.config.include_default_paths { + for (desc, should_run) in v.iter().zip(&should_runs) { if desc.default && should_run.is_really_default { for pathset in &should_run.paths { desc.maybe_run(builder, pathset); } } } - } else { - for path in paths { - // strip CurDir prefix if present - let path = match path.strip_prefix(".") { - Ok(p) => p, - Err(_) => path, - }; + } - let mut attempted_run = false; - for (desc, should_run) in v.iter().zip(&should_runs) { - if let Some(suite) = should_run.is_suite_path(path) { - attempted_run = true; - desc.maybe_run(builder, suite); - } else if let Some(pathset) = should_run.pathset_for_path(path) { - attempted_run = true; - desc.maybe_run(builder, pathset); - } - } + for path in paths { + // strip CurDir prefix if present + let path = match path.strip_prefix(".") { + Ok(p) => p, + Err(_) => path, + }; - if !attempted_run { - panic!("error: no rules matched {}", path.display()); + let mut attempted_run = false; + for (desc, should_run) in v.iter().zip(&should_runs) { + if let Some(suite) = should_run.is_suite_path(path) { + attempted_run = true; + desc.maybe_run(builder, suite); + } else if let Some(pathset) = should_run.pathset_for_path(path) { + attempted_run = true; + desc.maybe_run(builder, pathset); } } + + if !attempted_run { + panic!("error: no rules matched {}", path.display()); + } } } } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 6265bbaf5c22c..db82155bd6ad2 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -61,6 +61,7 @@ pub struct Config { pub profiler: bool, pub ignore_git: bool, pub exclude: Vec, + pub include_default_paths: bool, pub rustc_error_format: Option, pub json_output: bool, pub test_compare_mode: bool, @@ -532,6 +533,7 @@ impl Config { let mut config = Config::default_opts(); config.exclude = flags.exclude; + config.include_default_paths = flags.include_default_paths; config.rustc_error_format = flags.rustc_error_format; config.json_output = flags.json_output; config.on_fail = flags.on_fail; diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 319a0b4e611eb..c10188875fbc4 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -30,6 +30,7 @@ pub struct Flags { pub cmd: Subcommand, pub incremental: bool, pub exclude: Vec, + pub include_default_paths: bool, pub rustc_error_format: Option, pub json_output: bool, pub dry_run: bool, @@ -137,6 +138,11 @@ To learn more about a subcommand, run `./x.py -h`", opts.optmulti("", "host", "host targets to build", "HOST"); opts.optmulti("", "target", "target targets to build", "TARGET"); opts.optmulti("", "exclude", "build paths to exclude", "PATH"); + opts.optflag( + "", + "include-default-paths", + "include default paths in addition to the provided ones", + ); opts.optopt("", "on-fail", "command to run on failure", "CMD"); opts.optflag("", "dry-run", "dry run; don't build anything"); opts.optopt( @@ -618,6 +624,7 @@ Arguments: .into_iter() .map(|p| p.into()) .collect::>(), + include_default_paths: matches.opt_present("include-default-paths"), deny_warnings: parse_deny_warnings(&matches), llvm_skip_rebuild: matches.opt_str("llvm-skip-rebuild").map(|s| s.to_lowercase()).map( |s| s.parse::().expect("`llvm-skip-rebuild` should be either true or false"), From 24d04ccd3977d4eca676439067f096de484f6fa7 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 9 Oct 2020 19:53:48 +0200 Subject: [PATCH 25/28] ci: also build the build-manifest component on dist-x86_64-linux --- src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 58e2567a58f08..14700aeea05af 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -98,7 +98,9 @@ ENV RUST_CONFIGURE_ARGS \ --set llvm.thin-lto=true \ --set llvm.ninja=false \ --set rust.jemalloc -ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS +ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS \ + --include-default-paths \ + src/tools/build-manifest ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang # This is the only builder which will create source tarballs From f3d07b36ed7609a7826200479d8d472d36f0a995 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 12 Oct 2020 17:47:37 +0200 Subject: [PATCH 26/28] build-manifest: allow configuring the number of threads --- Cargo.lock | 1 + src/tools/build-manifest/Cargo.toml | 1 + src/tools/build-manifest/src/main.rs | 19 ++++++++++++------- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bfc2d3e066a89..83ac8396a16e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,6 +243,7 @@ dependencies = [ "anyhow", "flate2", "hex 0.4.2", + "num_cpus", "rayon", "serde", "serde_json", diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index 4ae4dbfc06ede..4a2c710811f61 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -14,3 +14,4 @@ tar = "0.4.29" sha2 = "0.9.1" rayon = "1.3.1" hex = "0.4.2" +num_cpus = "1.13.0" diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 0efebe363f88f..6fda9f4e59f52 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -207,13 +207,18 @@ fn main() { // related code in this tool and ./x.py dist hash-and-sign can be removed. let legacy = env::var("BUILD_MANIFEST_LEGACY").is_ok(); - // Avoid overloading the old server in legacy mode. - if legacy { - rayon::ThreadPoolBuilder::new() - .num_threads(1) - .build_global() - .expect("failed to initialize Rayon"); - } + let num_threads = if legacy { + // Avoid overloading the old server in legacy mode. + 1 + } else if let Ok(num) = env::var("BUILD_MANIFEST_NUM_THREADS") { + num.parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS") + } else { + num_cpus::get() + }; + rayon::ThreadPoolBuilder::new() + .num_threads(num_threads) + .build_global() + .expect("failed to initialize Rayon"); let mut args = env::args().skip(1); let input = PathBuf::from(args.next().unwrap()); From cbded3e193ba7acc4611e9b8612bbc98608e7800 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 12 Oct 2020 19:34:01 +0200 Subject: [PATCH 27/28] build-manifest: use var_os instead of var to check if vars exist This will prevent the tool mistakenly ignoring the variables if they happen to contain non-utf8 data. --- src/tools/build-manifest/src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 6fda9f4e59f52..1515f46e03ac2 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -205,13 +205,13 @@ fn main() { // // Once the old release process is fully decommissioned, the environment variable, all the // related code in this tool and ./x.py dist hash-and-sign can be removed. - let legacy = env::var("BUILD_MANIFEST_LEGACY").is_ok(); + let legacy = env::var_os("BUILD_MANIFEST_LEGACY").is_some(); let num_threads = if legacy { // Avoid overloading the old server in legacy mode. 1 - } else if let Ok(num) = env::var("BUILD_MANIFEST_NUM_THREADS") { - num.parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS") + } else if let Some(num) = env::var_os("BUILD_MANIFEST_NUM_THREADS") { + num.to_str().unwrap().parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS") } else { num_cpus::get() }; From 0b7ee9d522242d6320d1066d3ba9d2314a576e8b Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 12 Oct 2020 19:40:35 +0200 Subject: [PATCH 28/28] build-manifest: bundle the rustc version in the binary --- src/bootstrap/dist.rs | 1 - src/bootstrap/run.rs | 1 - src/tools/build-manifest/src/main.rs | 3 +-- src/tools/build-manifest/src/versions.rs | 17 ++++++----------- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 12533d29809cf..dd4cf9d595323 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2353,7 +2353,6 @@ impl Step for HashSign { cmd.arg(today.trim()); cmd.arg(addr); cmd.arg(&builder.config.channel); - cmd.arg(&builder.version); cmd.env("BUILD_MANIFEST_LEGACY", "1"); builder.create_dir(&distdir(builder)); diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index d8169549c07ba..7c64e5a0aadc8 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -77,7 +77,6 @@ impl Step for BuildManifest { cmd.arg(today.trim()); cmd.arg(addr); cmd.arg(&builder.config.channel); - cmd.arg(&builder.version); builder.create_dir(&distdir(builder)); builder.run(&mut cmd); diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 1515f46e03ac2..cb04900c737e0 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -226,7 +226,6 @@ fn main() { let date = args.next().unwrap(); let s3_address = args.next().unwrap(); let channel = args.next().unwrap(); - let rustc_version = args.next().unwrap(); // Do not ask for a passphrase while manually testing let mut passphrase = String::new(); @@ -236,7 +235,7 @@ fn main() { } Builder { - versions: Versions::new(&channel, &rustc_version, &input).unwrap(), + versions: Versions::new(&channel, &input).unwrap(), input, output, diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index c2bce0f1cf39c..79f2ef8dfc450 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -7,6 +7,7 @@ use std::path::{Path, PathBuf}; use tar::Archive; const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu"; +const RUSTC_VERSION: &str = include_str!("../../../version"); #[derive(Debug, Hash, Eq, PartialEq, Clone)] pub(crate) enum PkgType { @@ -87,19 +88,13 @@ pub(crate) struct VersionInfo { pub(crate) struct Versions { channel: String, - rustc_version: String, dist_path: PathBuf, versions: HashMap, } impl Versions { - pub(crate) fn new(channel: &str, rustc_version: &str, dist_path: &Path) -> Result { - Ok(Self { - channel: channel.into(), - rustc_version: rustc_version.into(), - dist_path: dist_path.into(), - versions: HashMap::new(), - }) + pub(crate) fn new(channel: &str, dist_path: &Path) -> Result { + Ok(Self { channel: channel.into(), dist_path: dist_path.into(), versions: HashMap::new() }) } pub(crate) fn channel(&self) -> &str { @@ -177,10 +172,10 @@ impl Versions { ) -> Result { let component_name = package.tarball_component_name(); let version = match self.channel.as_str() { - "stable" => self.rustc_version.clone(), + "stable" => RUSTC_VERSION.into(), "beta" => "beta".into(), "nightly" => "nightly".into(), - _ => format!("{}-dev", self.rustc_version), + _ => format!("{}-dev", RUSTC_VERSION), }; if package.target_independent() { @@ -191,6 +186,6 @@ impl Versions { } pub(crate) fn rustc_version(&self) -> &str { - &self.rustc_version + RUSTC_VERSION } }