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/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 325af56f3cd8c..9c309345000bb 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -154,7 +154,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 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..fb5f8ce322462 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -23,18 +23,17 @@ 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; -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 { @@ -249,11 +248,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>( @@ -274,47 +273,27 @@ impl CodegenBackend for LlvmCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - dep_graph: &DepGraph, - ) -> Result, ErrorReported> { + ) -> Result<(CodegenResults, FxHashMap), ErrorReported> { let (codegen_results, work_products) = ongoing_codegen .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("serialize_work_products", move || { - rustc_incremental::save_work_product_index(sess, &dep_graph, work_products) + sess.time("llvm_dump_timing_file", || { + if sess.opts.debugging_opts.llvm_time_trace { + llvm_util::time_trace_profiler_finish("llvm_timings.json"); + } }); - sess.compile_status()?; - - Ok(Box::new(codegen_results)) + 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", || { @@ -331,16 +310,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"); - } - }); - Ok(()) } } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 0edf0fcd1a264..2ff78898fb268 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, @@ -658,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), @@ -1720,7 +1708,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 +1753,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 e34371ef59ac4..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, @@ -144,6 +142,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() + } + }; +} diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 48c07b0089420..c6fbca39ee451 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -1,10 +1,11 @@ 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; 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<(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 575c2e627ed73..c7fb6a55d5ae0 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -642,7 +642,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 8b82217a91ac6..1de7350a3e21c 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; @@ -13,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; @@ -331,6 +333,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 +343,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,18 +354,31 @@ pub struct Linker { sess: Lrc, dep_graph: DepGraph, prepare_outputs: OutputFilenames, + crate_hash: Svh, ongoing_codegen: Box, codegen_backend: Lrc>, } 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)); + // 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 @@ -371,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) } } 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 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 { diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 4bc162abee6c1..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()); + } } } } @@ -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/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") 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/dist.rs b/src/bootstrap/dist.rs index 3a0743da7a415..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.src); cmd.env("BUILD_MANIFEST_LEGACY", "1"); builder.create_dir(&distdir(builder)); @@ -2584,3 +2583,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)) + } +} 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"), diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 80c093e713eff..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.src); builder.create_dir(&distdir(builder)); builder.run(&mut cmd); diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index 512224156d857..2a9507cfc4c18 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)), @@ -108,7 +108,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" ); 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) && \ 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 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 501891da573a6..776b131a07611 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 }), @@ -914,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 { @@ -1023,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), @@ -1047,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), @@ -1832,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, @@ -1852,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, @@ -1882,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(), @@ -1900,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) }), @@ -2049,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), } @@ -2064,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), @@ -2092,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), @@ -2113,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), @@ -2167,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, @@ -2349,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, } @@ -2364,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 { @@ -2389,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) }), @@ -2397,27 +2396,6 @@ 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::Deprecation { fn clean(&self, _: &DocContext<'_>) -> Deprecation { Deprecation { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 76efdfc1675b2..3b72cf5c4f97a 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 { @@ -1698,15 +1700,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 cdea5a7af203d..9a7f1964a1157 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}; @@ -102,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 { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 76334f0213d15..f81ea0f6d46ac 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; @@ -1983,10 +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(stability::Unstable), Some(stability::Stable)) => return Ordering::Greater, - (Some(stability::Stable), Some(stability::Unstable)) => return Ordering::Less, - _ => {} + 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); @@ -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, diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 4bca3996eb48f..ced26fcf5b0e9 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -1,10 +1,12 @@ 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_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 } @@ -41,8 +43,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; @@ -94,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 { @@ -108,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 { @@ -124,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; @@ -178,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() => { @@ -245,11 +252,18 @@ 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); + // `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::Default); 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..686ec51fb0604 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::Default) } 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/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)); 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..c077be31b209d --- /dev/null +++ b/src/test/rustdoc-ui/coverage/allow_missing_docs.rs @@ -0,0 +1,41 @@ +// 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, +} + +#[allow(missing_docs)] +pub mod bar { + #[warn(missing_docs)] + pub struct Bar { //~ WARN + pub f: u32, //~ WARN + } + + pub struct NeedsNoDocs; +} 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 + 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..17e8ee9e23dcc --- /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 | 71.4% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 5 | 71.4% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ 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/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..cb04900c737e0 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -205,15 +205,20 @@ 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(); - - // Avoid overloading the old server in legacy mode. - if legacy { - rayon::ThreadPoolBuilder::new() - .num_threads(1) - .build_global() - .expect("failed to initialize Rayon"); - } + 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 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() + }; + 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()); @@ -221,7 +226,6 @@ fn main() { let date = args.next().unwrap(); let s3_address = args.next().unwrap(); let channel = args.next().unwrap(); - let monorepo_path = args.next().unwrap(); // Do not ask for a passphrase while manually testing let mut passphrase = String::new(); @@ -231,7 +235,7 @@ fn main() { } Builder { - versions: Versions::new(&channel, &input, Path::new(&monorepo_path)).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 75b6979b54a78..79f2ef8dfc450 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; @@ -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,26 +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, - dist_path: &Path, - monorepo_root: &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(), - 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 { @@ -184,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() { @@ -198,6 +186,6 @@ impl Versions { } pub(crate) fn rustc_version(&self) -> &str { - &self.rustc_version + RUSTC_VERSION } }