From 90745bd1ededab96175485b098f58ae6d26e24f8 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 15 Sep 2024 07:41:24 +0300 Subject: [PATCH 1/8] Feed `GitInfo`s from `Config` to `Build` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/config/config.rs | 22 ++++++++++++++++++++++ src/bootstrap/src/lib.rs | 19 +++++++++---------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 79c2f73161e48..928366e64d0ad 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -342,6 +342,15 @@ pub struct Config { pub out: PathBuf, pub rust_info: channel::GitInfo, + pub cargo_info: channel::GitInfo, + pub rust_analyzer_info: channel::GitInfo, + pub clippy_info: channel::GitInfo, + pub miri_info: channel::GitInfo, + pub rustfmt_info: channel::GitInfo, + pub enzyme_info: channel::GitInfo, + pub in_tree_llvm_info: channel::GitInfo, + pub in_tree_gcc_info: channel::GitInfo, + // These are either the stage0 downloaded binaries or the locally installed ones. pub initial_cargo: PathBuf, pub initial_rustc: PathBuf, @@ -1797,6 +1806,19 @@ impl Config { config.omit_git_hash = omit_git_hash.unwrap_or(default); config.rust_info = GitInfo::new(config.omit_git_hash, &config.src); + config.cargo_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/cargo")); + config.rust_analyzer_info = + GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rust-analyzer")); + config.clippy_info = + GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/clippy")); + config.miri_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/miri")); + config.rustfmt_info = + GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rustfmt")); + config.enzyme_info = + GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/enzyme")); + config.in_tree_llvm_info = GitInfo::new(false, &config.src.join("src/llvm-project")); + config.in_tree_gcc_info = GitInfo::new(false, &config.src.join("src/gcc")); + // We need to override `rust.channel` if it's manually specified when using the CI rustc. // This is because if the compiler uses a different channel than the one specified in config.toml, // tests may fail due to using a different channel than the one used by the compiler during tests. diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index df2acd8b76bd3..6467f4e35910d 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -305,18 +305,17 @@ impl Build { #[cfg(not(unix))] let is_sudo = false; - let omit_git_hash = config.omit_git_hash; - let rust_info = GitInfo::new(omit_git_hash, &src); - let cargo_info = GitInfo::new(omit_git_hash, &src.join("src/tools/cargo")); - let rust_analyzer_info = GitInfo::new(omit_git_hash, &src.join("src/tools/rust-analyzer")); - let clippy_info = GitInfo::new(omit_git_hash, &src.join("src/tools/clippy")); - let miri_info = GitInfo::new(omit_git_hash, &src.join("src/tools/miri")); - let rustfmt_info = GitInfo::new(omit_git_hash, &src.join("src/tools/rustfmt")); - let enzyme_info = GitInfo::new(omit_git_hash, &src.join("src/tools/enzyme")); + let rust_info = config.rust_info.clone(); + let cargo_info = config.cargo_info.clone(); + let rust_analyzer_info = config.rust_analyzer_info.clone(); + let clippy_info = config.clippy_info.clone(); + let miri_info = config.miri_info.clone(); + let rustfmt_info = config.rustfmt_info.clone(); + let enzyme_info = config.enzyme_info.clone(); // we always try to use git for LLVM builds - let in_tree_llvm_info = GitInfo::new(false, &src.join("src/llvm-project")); - let in_tree_gcc_info = GitInfo::new(false, &src.join("src/gcc")); + let in_tree_llvm_info = config.in_tree_llvm_info.clone(); + let in_tree_gcc_info = config.in_tree_gcc_info.clone(); let initial_target_libdir_str = if config.dry_run() { "/dummy/lib/path/to/lib/".to_string() From e7e0dc70fa8c83fcfa5ec4009a8181bc597ae9d5 Mon Sep 17 00:00:00 2001 From: Kyle J Strand Date: Sun, 15 Sep 2024 16:26:46 -0600 Subject: [PATCH 2/8] reword edge-conditions documentation on all slice 'sort' functions; resolves #130122 --- library/alloc/src/slice.rs | 67 ++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 8cdba166c9dff..4f39f731013df 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -180,10 +180,9 @@ impl [T] { /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) /// worst-case. /// - /// If the implementation of [`Ord`] for `T` does not implement a [total order] the resulting - /// order of elements in the slice is unspecified. All original elements will remain in the - /// slice and any possible modifications via interior mutability are observed in the input. Same - /// is true if the implementation of [`Ord`] for `T` panics. + /// If the implementation of [`Ord`] for `T` does not implement a [total order], the function + /// may panic; even if the function exits normally, the resulting order of elements in the slice + /// is unspecified. See also the note on panicking below. /// /// When applicable, unstable sorting is preferred because it is generally faster than stable /// sorting and it doesn't allocate auxiliary memory. See @@ -212,7 +211,15 @@ impl [T] { /// /// # Panics /// - /// May panic if the implementation of [`Ord`] for `T` does not implement a [total order]. + /// May panic if the implementation of [`Ord`] for `T` does not implement a [total order], or if + /// the [`Ord`] implementation itself panics. + /// + /// All safe functions on slices preserve the invariant that even if the function panics, all + /// original elements will remain in the slice and any possible modifications via interior + /// mutability are observed in the input. This ensures that recovery code (for instance inside + /// of a `Drop` or following a `catch_unwind`) will still have access to all the original + /// elements. For instance, if the slice belongs to a `Vec`, the `Vec::drop` method will be able + /// to dispose of all contained elements. /// /// # Examples /// @@ -241,10 +248,9 @@ impl [T] { /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) /// worst-case. /// - /// If the comparison function `compare` does not implement a [total order] the resulting order - /// of elements in the slice is unspecified. All original elements will remain in the slice and - /// any possible modifications via interior mutability are observed in the input. Same is true - /// if `compare` panics. + /// If the comparison function `compare` does not implement a [total order], the function may + /// panic; even if the function exits normally, the resulting order of elements in the slice is + /// unspecified. See also the note on panicking below. /// /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and @@ -263,7 +269,14 @@ impl [T] { /// /// # Panics /// - /// May panic if `compare` does not implement a [total order]. + /// May panic if `compare` does not implement a [total order], or if `compare` itself panics. + /// + /// All safe functions on slices preserve the invariant that even if the function panics, all + /// original elements will remain in the slice and any possible modifications via interior + /// mutability are observed in the input. This ensures that recovery code (for instance inside + /// of a `Drop` or following a `catch_unwind`) will still have access to all the original + /// elements. For instance, if the slice belongs to a `Vec`, the `Vec::drop` method will be able + /// to dispose of all contained elements. /// /// # Examples /// @@ -295,10 +308,9 @@ impl [T] { /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*)) /// worst-case, where the key function is *O*(*m*). /// - /// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting - /// order of elements in the slice is unspecified. All original elements will remain in the - /// slice and any possible modifications via interior mutability are observed in the input. Same - /// is true if the implementation of [`Ord`] for `K` panics. + /// If the implementation of [`Ord`] for `K` does not implement a [total order], the function + /// may panic; even if the function exits normally, the resulting order of elements in the slice + /// is unspecified. See also the note on panicking below. /// /// # Current implementation /// @@ -313,7 +325,15 @@ impl [T] { /// /// # Panics /// - /// May panic if the implementation of [`Ord`] for `K` does not implement a [total order]. + /// May panic if the implementation of [`Ord`] for `K` does not implement a [total order], or if + /// the [`Ord`] implementation or the key-function `f` panics. + /// + /// All safe functions on slices preserve the invariant that even if the function panics, all + /// original elements will remain in the slice and any possible modifications via interior + /// mutability are observed in the input. This ensures that recovery code (for instance inside + /// of a `Drop` or following a `catch_unwind`) will still have access to all the original + /// elements. For instance, if the slice belongs to a `Vec`, the `Vec::drop` method will be able + /// to dispose of all contained elements. /// /// # Examples /// @@ -347,10 +367,9 @@ impl [T] { /// storage to remember the results of key evaluation. The order of calls to the key function is /// unspecified and may change in future versions of the standard library. /// - /// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting - /// order of elements in the slice is unspecified. All original elements will remain in the - /// slice and any possible modifications via interior mutability are observed in the input. Same - /// is true if the implementation of [`Ord`] for `K` panics. + /// If the implementation of [`Ord`] for `K` does not implement a [total order], the function + /// may panic; even if the function exits normally, the resulting order of elements in the slice + /// is unspecified. See also the note on panicking below. /// /// For simple key functions (e.g., functions that are property accesses or basic operations), /// [`sort_by_key`](slice::sort_by_key) is likely to be faster. @@ -369,7 +388,15 @@ impl [T] { /// /// # Panics /// - /// May panic if the implementation of [`Ord`] for `K` does not implement a [total order]. + /// May panic if the implementation of [`Ord`] for `K` does not implement a [total order], or if + /// the [`Ord`] implementation panics. + /// + /// All safe functions on slices preserve the invariant that even if the function panics, all + /// original elements will remain in the slice and any possible modifications via interior + /// mutability are observed in the input. This ensures that recovery code (for instance inside + /// of a `Drop` or following a `catch_unwind`) will still have access to all the original + /// elements. For instance, if the slice belongs to a `Vec`, the `Vec::drop` method will be able + /// to dispose of all contained elements. /// /// # Examples /// From 6658c8e2449fb6a674ac606823e43c44f3caf275 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 15 Sep 2024 07:43:16 +0300 Subject: [PATCH 3/8] check if the LLVM submodule is fetched in `is_ci_llvm_modified` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/llvm.rs | 12 +++++++++++- src/bootstrap/src/lib.rs | 2 -- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 08e24ecc3401a..81a48000cf145 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -241,7 +241,17 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool { /// Returns true if we're running in CI with modified LLVM (and thus can't download it) pub(crate) fn is_ci_llvm_modified(config: &Config) -> bool { - CiEnv::is_ci() && config.rust_info.is_managed_git_subrepository() && { + // If the LLVM submodule is unavailable (which is the case when `llvm.download-ci-llvm` is set to true), + // LLVM cannot be modified which means it is unnecessary to run the git logic below. + // + // This is very unlikely to happen on our (rust-lang/rust) CI runners, as we intentionally fetch all + // submodules in CI and most of the time (probably always) prefer `llvm.download-ci-llvm` to be set + // to "if-unchanged" or true. + if config.in_tree_llvm_info.is_managed_git_subrepository() { + return false; + } + + CiEnv::is_ci() && { // We assume we have access to git, so it's okay to unconditionally pass // `true` here. let llvm_sha = detect_llvm_sha(config, true); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 6467f4e35910d..9a48b7d36d9a4 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -312,8 +312,6 @@ impl Build { let miri_info = config.miri_info.clone(); let rustfmt_info = config.rustfmt_info.clone(); let enzyme_info = config.enzyme_info.clone(); - - // we always try to use git for LLVM builds let in_tree_llvm_info = config.in_tree_llvm_info.clone(); let in_tree_gcc_info = config.in_tree_gcc_info.clone(); From e424a8c01f454ba73e4e75b9b1d648208ba9744e Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Mon, 23 Sep 2024 12:54:07 +0300 Subject: [PATCH 4/8] Clarifications for set_nonblocking methods --- library/std/src/net/tcp.rs | 2 +- library/std/src/net/udp.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index 22d2dfe65a249..ef9ccb90a91ea 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -561,7 +561,7 @@ impl TcpStream { /// Moves this TCP stream into or out of nonblocking mode. /// - /// This will result in `read`, `write`, `recv` and `send` operations + /// This will result in `read`, `write`, `recv` and `send` system operations /// becoming nonblocking, i.e., immediately returning from their calls. /// If the IO operation is successful, `Ok` is returned and no further /// action is required. If the IO operation could not be completed and needs diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs index 32e9086003d6b..14b0bee7eacb1 100644 --- a/library/std/src/net/udp.rs +++ b/library/std/src/net/udp.rs @@ -764,7 +764,7 @@ impl UdpSocket { /// Moves this UDP socket into or out of nonblocking mode. /// - /// This will result in `recv`, `recv_from`, `send`, and `send_to` + /// This will result in `recv`, `recv_from`, `send`, and `send_to` system /// operations becoming nonblocking, i.e., immediately returning from their /// calls. If the IO operation is successful, `Ok` is returned and no /// further action is required. If the IO operation could not be completed From 5ef63ec3b4cacfa21a3e7666e955cf1e7efa34d1 Mon Sep 17 00:00:00 2001 From: binarycat Date: Wed, 18 Sep 2024 18:15:42 -0400 Subject: [PATCH 5/8] rustdoc: add doc comment to DocVisitor --- src/librustdoc/visit.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index fbc18176ed850..bfa285c57fa93 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -1,11 +1,17 @@ use crate::clean::*; +/// Allows a type to traverse the cleaned ast of a crate. +/// +/// Note that like [`rustc_ast::visit::Visitor`], but +/// unlike [`rustc_lint::EarlyLintPass`], if you override a +/// `visit_*` method, you will need to manually recurse into +/// its contents. pub(crate) trait DocVisitor<'a>: Sized { fn visit_item(&mut self, item: &'a Item) { self.visit_item_recur(item) } - /// don't override! + /// Don't override! fn visit_inner_recur(&mut self, kind: &'a ItemKind) { match kind { StrippedItem(..) => unreachable!(), @@ -46,7 +52,7 @@ pub(crate) trait DocVisitor<'a>: Sized { } } - /// don't override! + /// Don't override! fn visit_item_recur(&mut self, item: &'a Item) { match &item.kind { StrippedItem(i) => self.visit_inner_recur(&*i), @@ -58,6 +64,7 @@ pub(crate) trait DocVisitor<'a>: Sized { m.items.iter().for_each(|i| self.visit_item(i)) } + /// This is the main entrypoint of [`DocVisitor`]. fn visit_crate(&mut self, c: &'a Crate) { self.visit_item(&c.module); From 2d85139f87f52f28172be61c2957d8f856b3d9ac Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 25 Sep 2024 19:48:15 +0300 Subject: [PATCH 6/8] create `CiEnv::is_rust_lang_managed_ci_job` Signed-off-by: onur-ozkan --- src/tools/build_helper/src/ci.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tools/build_helper/src/ci.rs b/src/tools/build_helper/src/ci.rs index 6d79c7c83ad8b..60f319129a0bd 100644 --- a/src/tools/build_helper/src/ci.rs +++ b/src/tools/build_helper/src/ci.rs @@ -19,6 +19,15 @@ impl CiEnv { pub fn is_ci() -> bool { Self::current() != CiEnv::None } + + /// Checks if running in rust-lang/rust managed CI job. + pub fn is_rust_lang_managed_ci_job() -> bool { + Self::is_ci() + // If both are present, we can assume it's an upstream CI job + // as they are always set unconditionally. + && std::env::var_os("CI_JOB_NAME").is_some() + && std::env::var_os("TOOLSTATE_REPO").is_some() + } } pub mod gha { From 5840d8791c1fc464e0aeca0690bff95274ddacd7 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 25 Sep 2024 19:50:42 +0300 Subject: [PATCH 7/8] in `llvm::is_ci_llvm_modified`, check if it's rust-lang/rust CI job Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/llvm.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 81a48000cf145..400297316bb43 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -241,17 +241,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool { /// Returns true if we're running in CI with modified LLVM (and thus can't download it) pub(crate) fn is_ci_llvm_modified(config: &Config) -> bool { - // If the LLVM submodule is unavailable (which is the case when `llvm.download-ci-llvm` is set to true), - // LLVM cannot be modified which means it is unnecessary to run the git logic below. - // - // This is very unlikely to happen on our (rust-lang/rust) CI runners, as we intentionally fetch all - // submodules in CI and most of the time (probably always) prefer `llvm.download-ci-llvm` to be set - // to "if-unchanged" or true. - if config.in_tree_llvm_info.is_managed_git_subrepository() { - return false; - } - - CiEnv::is_ci() && { + CiEnv::is_rust_lang_managed_ci_job() && config.rust_info.is_managed_git_subrepository() && { // We assume we have access to git, so it's okay to unconditionally pass // `true` here. let llvm_sha = detect_llvm_sha(config, true); From a78fd694d47608eb382478b038ad0e91b6f5150d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 29 Sep 2024 12:16:35 +0200 Subject: [PATCH 8/8] extend comment in global_llvm_features regarding target-cpu=native handling --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index a2a5499597c34..201cfbb1918c8 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -536,6 +536,11 @@ pub(crate) fn global_llvm_features( // -Ctarget-cpu=native match sess.opts.cg.target_cpu { Some(ref s) if s == "native" => { + // We have already figured out the actual CPU name with `LLVMRustGetHostCPUName` and set + // that for LLVM, so the features implied by that CPU name will be available everywhere. + // However, that is not sufficient: e.g. `skylake` alone is not sufficient to tell if + // some of the instructions are available or not. So we have to also explicitly ask for + // the exact set of features available on the host, and enable all of them. let features_string = unsafe { let ptr = llvm::LLVMGetHostCPUFeatures(); let features_string = if !ptr.is_null() {