diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs index 9b7db11e2f29a..7b3a234cd9e8e 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("ARM64 MinGW (Windows 10+), LLVM ABI".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs index f04e3c2c2a5b0..508afd4793523 100644 --- a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs @@ -5,5 +5,11 @@ pub(crate) fn target() -> Target { base.rustc_abi = None; // overwrite the SSE2 ABI set by the base target base.cpu = "pentium".into(); base.llvm_target = "i586-unknown-linux-gnu".into(); + base.metadata = crate::spec::TargetMetadata { + description: Some("32-bit Linux (kernel 3.2, glibc 2.17+)".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(true), + }; base } diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs index 498d8182ad589..a6067f64c6860 100644 --- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("SPARC Solaris 11.4".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs index e594d187e42bd..b53bf3b7bd52b 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs @@ -63,7 +63,7 @@ pub(crate) fn target() -> Target { llvm_target: "wasm32-wasip2".into(), metadata: TargetMetadata { description: Some("WebAssembly".into()), - tier: Some(3), + tier: Some(2), host_tools: Some(false), std: Some(true), }, diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs index d417f3d48a4be..3fb1d11ef60da 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs @@ -15,6 +15,12 @@ pub(crate) fn target() -> Target { // and this may grow over time as more features are supported. let mut target = super::wasm32_wasip2::target(); target.llvm_target = "wasm32-wasip3".into(); + target.metadata = crate::spec::TargetMetadata { + description: Some("WebAssembly".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }; target.options.env = Env::P3; target } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs index 39ebe62430479..abcca352dfa33 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("64-bit Solaris 11.4".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs index 28c9e6251255c..0606d4508badc 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("64-bit x86 MinGW (Windows 10+), LLVM ABI".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index ca5b46c9b0fd0..766f4589177a8 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1434,7 +1434,8 @@ impl BTreeMap { /// /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating /// or the iteration short-circuits, then the remaining elements will be retained. - /// Use [`retain`] with a negated predicate if you do not need the returned iterator. + /// Use `extract_if().for_each(drop)` if you do not need the returned iterator, + /// or [`retain`] with a negated predicate if you also do not need to restrict the range. /// /// [`retain`]: BTreeMap::retain /// @@ -1945,7 +1946,8 @@ impl Default for Values<'_, K, V> { /// An iterator produced by calling `extract_if` on BTreeMap. #[stable(feature = "btree_extract_if", since = "1.91.0")] -#[must_use = "iterators are lazy and do nothing unless consumed"] +#[must_use = "iterators are lazy and do nothing unless consumed; \ + use `retain` or `extract_if().for_each(drop)` to remove and discard elements"] pub struct ExtractIf< 'a, K, diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index cb3e14252f8a3..28d26699d7d2c 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1189,7 +1189,8 @@ impl BTreeSet { /// /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating /// or the iteration short-circuits, then the remaining elements will be retained. - /// Use [`retain`] with a negated predicate if you do not need the returned iterator. + /// Use `extract_if().for_each(drop)` if you do not need the returned iterator, + /// or [`retain`] with a negated predicate if you also do not need to restrict the range. /// /// [`retain`]: BTreeSet::retain /// # Examples @@ -1547,7 +1548,8 @@ impl<'a, T, A: Allocator + Clone> IntoIterator for &'a BTreeSet { /// An iterator produced by calling `extract_if` on BTreeSet. #[stable(feature = "btree_extract_if", since = "1.91.0")] -#[must_use = "iterators are lazy and do nothing unless consumed"] +#[must_use = "iterators are lazy and do nothing unless consumed; \ + use `retain` or `extract_if().for_each(drop)` to remove and discard elements"] pub struct ExtractIf< 'a, T, diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 31dfe73fc7992..8bc0e08a4b26b 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1943,7 +1943,8 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { /// An iterator produced by calling `extract_if` on LinkedList. #[stable(feature = "extract_if", since = "1.87.0")] -#[must_use = "iterators are lazy and do nothing unless consumed"] +#[must_use = "iterators are lazy and do nothing unless consumed; \ + use `extract_if().for_each(drop)` to remove and discard elements"] pub struct ExtractIf< 'a, T: 'a, diff --git a/library/alloc/src/collections/vec_deque/extract_if.rs b/library/alloc/src/collections/vec_deque/extract_if.rs index bed7d46482cf4..437f0d6dd5eb3 100644 --- a/library/alloc/src/collections/vec_deque/extract_if.rs +++ b/library/alloc/src/collections/vec_deque/extract_if.rs @@ -21,7 +21,8 @@ use crate::alloc::{Allocator, Global}; /// let iter: ExtractIf<'_, _, _> = v.extract_if(.., |x| *x % 2 == 0); /// ``` #[unstable(feature = "vec_deque_extract_if", issue = "147750")] -#[must_use = "iterators are lazy and do nothing unless consumed"] +#[must_use = "iterators are lazy and do nothing unless consumed; \ + use `retain_mut` or `extract_if().for_each(drop)` to remove and discard elements"] pub struct ExtractIf< 'a, T, diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 78930364a9260..52e079d3ae8e6 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -676,7 +676,8 @@ impl VecDeque { /// /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating /// or the iteration short-circuits, then the remaining elements will be retained. - /// Use [`retain_mut`] with a negated predicate if you do not need the returned iterator. + /// Use `extract_if().for_each(drop)` if you do not need the returned iterator, + /// or [`retain_mut`] with a negated predicate if you also do not need to restrict the range. /// /// [`retain_mut`]: VecDeque::retain_mut /// diff --git a/library/alloc/src/vec/extract_if.rs b/library/alloc/src/vec/extract_if.rs index cb9e14f554d41..014219f8d461c 100644 --- a/library/alloc/src/vec/extract_if.rs +++ b/library/alloc/src/vec/extract_if.rs @@ -16,7 +16,8 @@ use crate::alloc::{Allocator, Global}; /// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(.., |x| *x % 2 == 0); /// ``` #[stable(feature = "extract_if", since = "1.87.0")] -#[must_use = "iterators are lazy and do nothing unless consumed"] +#[must_use = "iterators are lazy and do nothing unless consumed; \ + use `retain_mut` or `extract_if().for_each(drop)` to remove and discard elements"] pub struct ExtractIf< 'a, T, diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 14272c76ed54b..13d38d3c9609a 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3933,7 +3933,8 @@ impl Vec { /// /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating /// or the iteration short-circuits, then the remaining elements will be retained. - /// Use [`retain_mut`] with a negated predicate if you do not need the returned iterator. + /// Use `extract_if().for_each(drop)` if you do not need the returned iterator, + /// or [`retain_mut`] with a negated predicate if you also do not need to restrict the range. /// /// [`retain_mut`]: Vec::retain_mut /// diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs index 24efd4a204a5f..9a8824baefe4e 100644 --- a/library/core/src/range/iter.rs +++ b/library/core/src/range/iter.rs @@ -3,6 +3,7 @@ use crate::iter::{ }; use crate::num::NonZero; use crate::range::{Range, RangeFrom, RangeInclusive, legacy}; +use crate::{intrinsics, mem}; /// By-value [`Range`] iterator. #[unstable(feature = "new_range_api", issue = "125687")] @@ -168,7 +169,7 @@ impl IterRangeInclusive { } } -#[unstable(feature = "trusted_random_access", issue = "none")] +#[unstable(feature = "new_range_api", issue = "125687")] impl Iterator for IterRangeInclusive { type Item = A; @@ -293,32 +294,74 @@ range_incl_exact_iter_impl! { /// By-value [`RangeFrom`] iterator. #[unstable(feature = "new_range_api", issue = "125687")] #[derive(Debug, Clone)] -pub struct IterRangeFrom(legacy::RangeFrom); +pub struct IterRangeFrom { + start: A, + /// Whether the first element of the iterator has yielded. + /// Only used when overflow checks are enabled. + first: bool, +} -impl IterRangeFrom { +impl IterRangeFrom { /// Returns the remainder of the range being iterated over. + #[inline] + #[rustc_inherit_overflow_checks] pub fn remainder(self) -> RangeFrom { - RangeFrom { start: self.0.start } + if intrinsics::overflow_checks() { + if !self.first { + return RangeFrom { start: Step::forward(self.start, 1) }; + } + } + + RangeFrom { start: self.start } } } -#[unstable(feature = "trusted_random_access", issue = "none")] +#[unstable(feature = "new_range_api", issue = "125687")] impl Iterator for IterRangeFrom { type Item = A; #[inline] + #[rustc_inherit_overflow_checks] fn next(&mut self) -> Option { - self.0.next() + if intrinsics::overflow_checks() { + if self.first { + self.first = false; + return Some(self.start.clone()); + } + + self.start = Step::forward(self.start.clone(), 1); + return Some(self.start.clone()); + } + + let n = Step::forward(self.start.clone(), 1); + Some(mem::replace(&mut self.start, n)) } #[inline] fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() + (usize::MAX, None) } #[inline] + #[rustc_inherit_overflow_checks] fn nth(&mut self, n: usize) -> Option { - self.0.nth(n) + if intrinsics::overflow_checks() { + if self.first { + self.first = false; + + let plus_n = Step::forward(self.start.clone(), n); + self.start = plus_n.clone(); + return Some(plus_n); + } + + let plus_n = Step::forward(self.start.clone(), n); + self.start = Step::forward(plus_n.clone(), 1); + return Some(self.start.clone()); + } + + let plus_n = Step::forward(self.start.clone(), n); + self.start = Step::forward(plus_n.clone(), 1); + Some(plus_n) } } @@ -334,6 +377,6 @@ impl IntoIterator for RangeFrom { type IntoIter = IterRangeFrom; fn into_iter(self) -> Self::IntoIter { - IterRangeFrom(self.into()) + IterRangeFrom { start: self.start, first: true } } } diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index fc0fef620e3b6..ab21e3b927e20 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1685,7 +1685,8 @@ impl<'a, K, V> Drain<'a, K, V> { /// let iter = map.extract_if(|_k, v| *v % 2 == 0); /// ``` #[stable(feature = "hash_extract_if", since = "1.88.0")] -#[must_use = "iterators are lazy and do nothing unless consumed"] +#[must_use = "iterators are lazy and do nothing unless consumed; \ + use `retain` to remove and discard elements"] pub struct ExtractIf<'a, K, V, F> { base: base::ExtractIf<'a, K, V, F>, } diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 482d57b47f677..6795da80aacb6 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -1391,6 +1391,8 @@ pub struct Drain<'a, K: 'a> { /// let mut extract_ifed = a.extract_if(|v| v % 2 == 0); /// ``` #[stable(feature = "hash_extract_if", since = "1.88.0")] +#[must_use = "iterators are lazy and do nothing unless consumed; \ + use `retain` to remove and discard elements"] pub struct ExtractIf<'a, K, F> { base: base::ExtractIf<'a, K, F>, } diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 5b7b5a8ea803d..ee0c460f7dfa7 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -80,6 +80,9 @@ pub trait CommandExt: Sealed { /// or acquiring a mutex are not guaranteed to work (due to /// other threads perhaps still running when the `fork` was run). /// + /// Note that the list of allocating functions includes [`Error::new`] and + /// [`Error::other`]. To signal a non-trivial error, prefer [`panic!`]. + /// /// For further details refer to the [POSIX fork() specification] /// and the equivalent documentation for any targeted /// platform, especially the requirements around *async-signal-safety*. @@ -102,6 +105,8 @@ pub trait CommandExt: Sealed { /// [POSIX fork() specification]: /// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html /// [`std::env`]: mod@crate::env + /// [`Error::new`]: crate::io::Error::new + /// [`Error::other`]: crate::io::Error::other #[stable(feature = "process_pre_exec", since = "1.34.0")] unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command where diff --git a/library/std_detect/src/detect/os/openbsd/aarch64.rs b/library/std_detect/src/detect/os/openbsd/aarch64.rs index 2fae47b05c40a..6825a3760e485 100644 --- a/library/std_detect/src/detect/os/openbsd/aarch64.rs +++ b/library/std_detect/src/detect/os/openbsd/aarch64.rs @@ -31,7 +31,7 @@ pub(crate) fn detect_features() -> cache::Initializer { // the feature is available. let aa64pfr0 = sysctl64(&[libc::CTL_MACHDEP, CPU_ID_AA64PFR0]); - super::aarch64::parse_system_registers(aa64isar0, aa64isar1, aa64mmfr2, aa64pfr0) + crate::detect::aarch64::parse_system_registers(aa64isar0, aa64isar1, aa64mmfr2, aa64pfr0) } #[inline] diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 411d42962644d..b3f67d1b8ac53 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -22,7 +22,7 @@ use tracing::instrument; use crate::core::build_steps::compile::{get_codegen_backend_file, normalize_codegen_backend_name}; use crate::core::build_steps::doc::DocumentationFormat; use crate::core::build_steps::tool::{ - self, RustcPrivateCompilers, Tool, ToolTargetBuildMode, get_tool_target_compiler, + self, RustcPrivateCompilers, ToolTargetBuildMode, get_tool_target_compiler, }; use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor}; use crate::core::build_steps::{compile, llvm}; @@ -2695,10 +2695,14 @@ impl Step for BuildManifest { } fn run(self, builder: &Builder<'_>) -> GeneratedTarball { - let build_manifest = builder.tool_exe(Tool::BuildManifest); + // FIXME: Should BuildManifest actually be built for `self.target`? + // Today CI only builds this step where that matches the host_target so it doesn't matter + // today. + let build_manifest = + builder.ensure(tool::BuildManifest::new(builder, builder.config.host_target)); let tarball = Tarball::new(builder, "build-manifest", &self.target.triple); - tarball.add_file(&build_manifest, "bin", FileType::Executable); + tarball.add_file(&build_manifest.tool_path, "bin", FileType::Executable); tarball.generate() } diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 6ab99ae799d70..5446ec085ffd0 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -37,7 +37,9 @@ impl Step for BuildManifest { fn run(self, builder: &Builder<'_>) { // This gets called by `promote-release` // (https://github.com/rust-lang/promote-release). - let mut cmd = builder.tool_cmd(Tool::BuildManifest); + let mut cmd = command( + builder.ensure(tool::BuildManifest::new(builder, builder.config.host_target)).tool_path, + ); let sign = builder.config.dist_sign_folder.as_ref().unwrap_or_else(|| { panic!("\n\nfailed to specify `dist.sign-folder` in `bootstrap.toml`\n\n") }); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 79df9d3a49da2..0d765018d77bf 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -485,7 +485,6 @@ bootstrap_tool!( Linkchecker, "src/tools/linkchecker", "linkchecker"; CargoTest, "src/tools/cargotest", "cargotest"; Compiletest, "src/tools/compiletest", "compiletest"; - BuildManifest, "src/tools/build-manifest", "build-manifest"; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; RustInstaller, "src/tools/rust-installer", "rust-installer"; RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes"; @@ -1268,6 +1267,52 @@ impl Step for LibcxxVersionTool { } } +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct BuildManifest { + compiler: Compiler, + target: TargetSelection, +} + +impl BuildManifest { + pub fn new(builder: &Builder<'_>, target: TargetSelection) -> Self { + BuildManifest { compiler: builder.compiler(1, builder.config.host_target), target } + } +} + +impl Step for BuildManifest { + type Output = ToolBuildResult; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/build-manifest") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(BuildManifest::new(run.builder, run.target)); + } + + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { + // Building with the beta compiler will produce a broken build-manifest that doesn't support + // recently stabilized targets/hosts. + assert!(self.compiler.stage != 0); + builder.ensure(ToolBuild { + build_compiler: self.compiler, + target: self.target, + tool: "build-manifest", + mode: Mode::ToolStd, + path: "src/tools/build-manifest", + source_type: SourceType::InTree, + extra_features: vec![], + allow_features: "", + cargo_args: vec![], + artifact_kind: ToolArtifactKind::Binary, + }) + } + + fn metadata(&self) -> Option { + Some(StepMetadata::build("build-manifest", self.target).built_by(self.compiler)) + } +} + /// Represents which compilers are involved in the compilation of a tool /// that depends on compiler internals (`rustc_private`). /// Their compilation looks like this: diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index c2029f97391d4..3b7625489ad0f 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -25,9 +25,7 @@ struct Rustflags(String, TargetSelection); impl Rustflags { fn new(target: TargetSelection) -> Rustflags { - let mut ret = Rustflags(String::new(), target); - ret.propagate_cargo_env("RUSTFLAGS"); - ret + Rustflags(String::new(), target) } /// By default, cargo will pick up on various variables in the environment. However, bootstrap @@ -60,6 +58,16 @@ impl Rustflags { self.0.push_str(arg); self } + + fn propagate_rustflag_envs(&mut self, build_compiler_stage: u32) { + self.propagate_cargo_env("RUSTFLAGS"); + if build_compiler_stage != 0 { + self.env("RUSTFLAGS_NOT_BOOTSTRAP"); + } else { + self.env("RUSTFLAGS_BOOTSTRAP"); + self.arg("--cfg=bootstrap"); + } + } } /// Flags that are passed to the `rustc` shim binary. These flags will only be applied when @@ -96,6 +104,7 @@ pub struct Cargo { hostflags: HostFlags, allow_features: String, release_build: bool, + build_compiler_stage: u32, } impl Cargo { @@ -394,6 +403,28 @@ impl From for BootstrapCommand { cargo.args.insert(0, "--release".into()); } + // Propagate the envs here at the very end to make sure they override any previously set flags. + cargo.rustflags.propagate_rustflag_envs(cargo.build_compiler_stage); + cargo.rustdocflags.propagate_rustflag_envs(cargo.build_compiler_stage); + + cargo.rustdocflags.propagate_cargo_env("RUSTDOCFLAGS"); + + if cargo.build_compiler_stage == 0 { + cargo.rustdocflags.env("RUSTDOCFLAGS_BOOTSTRAP"); + if let Ok(s) = env::var("CARGOFLAGS_BOOTSTRAP") { + cargo.args(s.split_whitespace()); + } + } else { + cargo.rustdocflags.env("RUSTDOCFLAGS_NOT_BOOTSTRAP"); + if let Ok(s) = env::var("CARGOFLAGS_NOT_BOOTSTRAP") { + cargo.args(s.split_whitespace()); + } + } + + if let Ok(s) = env::var("CARGOFLAGS") { + cargo.args(s.split_whitespace()); + } + cargo.command.args(cargo.args); let rustflags = &cargo.rustflags.0; @@ -601,18 +632,6 @@ impl Builder<'_> { } let mut rustflags = Rustflags::new(target); - if build_compiler_stage != 0 { - if let Ok(s) = env::var("CARGOFLAGS_NOT_BOOTSTRAP") { - cargo.args(s.split_whitespace()); - } - rustflags.env("RUSTFLAGS_NOT_BOOTSTRAP"); - } else { - if let Ok(s) = env::var("CARGOFLAGS_BOOTSTRAP") { - cargo.args(s.split_whitespace()); - } - rustflags.env("RUSTFLAGS_BOOTSTRAP"); - rustflags.arg("--cfg=bootstrap"); - } if cmd_kind == Kind::Clippy { // clippy overwrites sysroot if we pass it to cargo. @@ -711,16 +730,6 @@ impl Builder<'_> { // but this breaks CI. At the very least, stage0 `rustdoc` needs `--cfg bootstrap`. See // #71458. let mut rustdocflags = rustflags.clone(); - rustdocflags.propagate_cargo_env("RUSTDOCFLAGS"); - if build_compiler_stage == 0 { - rustdocflags.env("RUSTDOCFLAGS_BOOTSTRAP"); - } else { - rustdocflags.env("RUSTDOCFLAGS_NOT_BOOTSTRAP"); - } - - if let Ok(s) = env::var("CARGOFLAGS") { - cargo.args(s.split_whitespace()); - } match mode { Mode::Std | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTarget => {} @@ -1374,6 +1383,7 @@ impl Builder<'_> { hostflags, allow_features, release_build, + build_compiler_stage, } } } diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 59140b9ce84c8..f243e06fecd69 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -581,4 +581,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "The `build.python` option is now respected on macOS (previously ignored and forced to be /usr/bin/python3).", }, + ChangeInfo { + change_id: 148911, + severity: ChangeSeverity::Warning, + summary: "Flags from `*FLAGS*` (such as `RUSTFLAGS`) env. vars. now have precedence over rustflags set by bootstrap. Before, it was the other way around.", + }, ]; diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index efa99f181b3a1..c0271bbc89b53 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -14,3 +14,7 @@ tar = "0.4.29" sha2 = "0.10.1" rayon = "1.5.1" hex = "0.4.2" + +[build-dependencies] +serde = "1" +serde_json = "1" diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md index 2ea1bffb35f4d..bc1992ef80cc0 100644 --- a/src/tools/build-manifest/README.md +++ b/src/tools/build-manifest/README.md @@ -2,7 +2,13 @@ This tool generates the manifests uploaded to static.rust-lang.org and used by rustup. You can see a full list of all manifests at . -This listing is updated by every 7 days. + +We auto-generate the host targets (those with full compiler toolchains) and +target targets (a superset of hosts, some of which only support std) through +`build.rs`, which internally uses a stage 1 rustc to produce the target list +and uses the `TargetMetadata` to determine whether host tools are expected and +whether artifacts are expected. This list is not currently verified against the +actually produced artifacts by CI, though that may change in the future. This gets called by `promote-release` . `promote-release` downloads a pre-built binary of `build-manifest` which is generated in the dist-x86_64-linux builder and uploaded to s3. diff --git a/src/tools/build-manifest/build.rs b/src/tools/build-manifest/build.rs new file mode 100644 index 0000000000000..c804921408a93 --- /dev/null +++ b/src/tools/build-manifest/build.rs @@ -0,0 +1,76 @@ +use std::fmt::Write; +use std::path::PathBuf; +use std::process::{Command, Stdio}; + +#[derive(Default, Debug)] +pub(crate) struct RustcTargets { + /// Targets with host tool artifacts. + pub(crate) hosts: Vec, + + /// All targets we distribute some artifacts for (superset of `hosts`). + pub(crate) targets: Vec, +} + +fn collect_rustc_targets() -> RustcTargets { + let rustc_path = std::env::var("RUSTC").expect("RUSTC set"); + let output = Command::new(&rustc_path) + .arg("--print=all-target-specs-json") + .env("RUSTC_BOOTSTRAP", "1") + .arg("-Zunstable-options") + .stderr(Stdio::inherit()) + .output() + .unwrap(); + assert!(output.status.success()); + let json: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap(); + + let mut rustc_targets = RustcTargets::default(); + for (target, json) in json.as_object().unwrap().iter() { + let Some(tier) = json["metadata"]["tier"].as_u64() else { + eprintln!("skipping {target}: no tier in metadata"); + continue; + }; + let host_tools: Option = + serde_json::from_value(json["metadata"]["host_tools"].clone()).unwrap(); + + if !(tier == 1 || tier == 2) { + eprintln!("ignoring {target}: tier {tier} insufficient for target to be in manifest"); + continue; + } + + if host_tools == Some(true) { + rustc_targets.hosts.push(target.to_owned()); + rustc_targets.targets.push(target.to_owned()); + } else { + rustc_targets.targets.push(target.to_owned()); + } + } + + rustc_targets +} + +fn main() { + let targets = collect_rustc_targets(); + + // Verify we ended up with a reasonable target list. + assert!(targets.hosts.len() >= 10); + assert!(targets.targets.len() >= 30); + assert!(targets.hosts.iter().any(|e| e == "x86_64-unknown-linux-gnu")); + assert!(targets.targets.iter().any(|e| e == "x86_64-unknown-linux-gnu")); + + let mut output = String::new(); + + writeln!(output, "static HOSTS: &[&str] = &[").unwrap(); + for host in targets.hosts { + writeln!(output, " {:?},", host).unwrap(); + } + writeln!(output, "];").unwrap(); + + writeln!(output, "static TARGETS: &[&str] = &[").unwrap(); + for target in targets.targets { + writeln!(output, " {:?},", target).unwrap(); + } + writeln!(output, "];").unwrap(); + + std::fs::write(PathBuf::from(std::env::var_os("OUT_DIR").unwrap()).join("targets.rs"), output) + .unwrap(); +} diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 3f19e1128df9d..5d9d63093860f 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -12,194 +12,7 @@ use crate::checksum::Checksums; use crate::manifest::{Component, Manifest, Package, Rename, Target}; use crate::versions::{PkgType, Versions}; -static HOSTS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-pc-windows-gnullvm", - "aarch64-pc-windows-msvc", - "aarch64-unknown-linux-gnu", - "aarch64-unknown-linux-musl", - "arm-unknown-linux-gnueabi", - "arm-unknown-linux-gnueabihf", - "armv7-unknown-linux-gnueabihf", - "i686-apple-darwin", - "i686-pc-windows-gnu", - "i686-pc-windows-msvc", - "i686-unknown-linux-gnu", - "loongarch64-unknown-linux-gnu", - "loongarch64-unknown-linux-musl", - "mips-unknown-linux-gnu", - "mips64-unknown-linux-gnuabi64", - "mips64el-unknown-linux-gnuabi64", - "mipsel-unknown-linux-gnu", - "mipsisa32r6-unknown-linux-gnu", - "mipsisa32r6el-unknown-linux-gnu", - "mipsisa64r6-unknown-linux-gnuabi64", - "mipsisa64r6el-unknown-linux-gnuabi64", - "powerpc-unknown-linux-gnu", - "powerpc64-unknown-linux-gnu", - "powerpc64le-unknown-linux-gnu", - "powerpc64le-unknown-linux-musl", - "riscv64gc-unknown-linux-gnu", - "s390x-unknown-linux-gnu", - "sparcv9-sun-solaris", - "x86_64-apple-darwin", - "x86_64-pc-solaris", - "x86_64-pc-windows-gnu", - "x86_64-pc-windows-gnullvm", - "x86_64-pc-windows-msvc", - "x86_64-unknown-freebsd", - "x86_64-unknown-illumos", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-linux-musl", - "x86_64-unknown-netbsd", -]; - -static TARGETS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-apple-ios", - "aarch64-apple-ios-macabi", - "aarch64-apple-ios-sim", - "aarch64-unknown-fuchsia", - "aarch64-linux-android", - "aarch64-pc-windows-gnullvm", - "aarch64-pc-windows-msvc", - "aarch64-unknown-hermit", - "aarch64-unknown-linux-gnu", - "aarch64-unknown-linux-musl", - "aarch64-unknown-linux-ohos", - "aarch64-unknown-none", - "aarch64-unknown-none-softfloat", - "aarch64-unknown-redox", - "aarch64-unknown-uefi", - "aarch64-unknown-managarm-mlibc", - "amdgcn-amd-amdhsa", - "arm64e-apple-darwin", - "arm64e-apple-ios", - "arm64e-apple-tvos", - "arm-linux-androideabi", - "arm-unknown-linux-gnueabi", - "arm-unknown-linux-gnueabihf", - "arm-unknown-linux-musleabi", - "arm-unknown-linux-musleabihf", - "arm64ec-pc-windows-msvc", - "armv5te-unknown-linux-gnueabi", - "armv5te-unknown-linux-musleabi", - "armv7-linux-androideabi", - "thumbv7neon-linux-androideabi", - "armv7-unknown-linux-gnueabi", - "armv7-unknown-linux-gnueabihf", - "armv7a-none-eabi", - "armv7a-none-eabihf", - "thumbv7neon-unknown-linux-gnueabihf", - "armv7-unknown-linux-musleabi", - "armv7-unknown-linux-musleabihf", - "armv7-unknown-linux-ohos", - "armebv7r-none-eabi", - "armebv7r-none-eabihf", - "armv7r-none-eabi", - "armv7r-none-eabihf", - "armv8r-none-eabihf", - "armv7s-apple-ios", - "bpfeb-unknown-none", - "bpfel-unknown-none", - "i386-apple-ios", - "i586-unknown-linux-gnu", - "i586-unknown-linux-musl", - "i586-unknown-redox", - "i686-apple-darwin", - "i686-linux-android", - "i686-pc-windows-gnu", - "i686-pc-windows-gnullvm", - "i686-pc-windows-msvc", - "i686-unknown-freebsd", - "i686-unknown-linux-gnu", - "i686-unknown-linux-musl", - "i686-unknown-uefi", - "loongarch64-unknown-linux-gnu", - "loongarch64-unknown-linux-musl", - "loongarch32-unknown-none", - "loongarch32-unknown-none-softfloat", - "loongarch64-unknown-none", - "loongarch64-unknown-none-softfloat", - "m68k-unknown-linux-gnu", - "m68k-unknown-none-elf", - "csky-unknown-linux-gnuabiv2", - "csky-unknown-linux-gnuabiv2hf", - "mips-unknown-linux-gnu", - "mips-unknown-linux-musl", - "mips64-unknown-linux-gnuabi64", - "mips64-unknown-linux-muslabi64", - "mips64el-unknown-linux-gnuabi64", - "mips64el-unknown-linux-muslabi64", - "mipsisa32r6-unknown-linux-gnu", - "mipsisa32r6el-unknown-linux-gnu", - "mipsisa64r6-unknown-linux-gnuabi64", - "mipsisa64r6el-unknown-linux-gnuabi64", - "mipsel-unknown-linux-gnu", - "mipsel-unknown-linux-musl", - "mips-mti-none-elf", - "mipsel-mti-none-elf", - "nvptx64-nvidia-cuda", - "powerpc-unknown-linux-gnu", - "powerpc64-unknown-linux-gnu", - "powerpc64le-unknown-linux-gnu", - "powerpc64le-unknown-linux-musl", - "riscv32i-unknown-none-elf", - "riscv32im-risc0-zkvm-elf", - "riscv32im-unknown-none-elf", - "riscv32ima-unknown-none-elf", - "riscv32imc-unknown-none-elf", - "riscv32imac-unknown-none-elf", - "riscv32imafc-unknown-none-elf", - "riscv32gc-unknown-linux-gnu", - "riscv64imac-unknown-none-elf", - "riscv64a23-unknown-linux-gnu", - "riscv64gc-unknown-hermit", - "riscv64gc-unknown-none-elf", - "riscv64gc-unknown-linux-gnu", - "riscv64gc-unknown-linux-musl", - "riscv64gc-unknown-managarm-mlibc", - "s390x-unknown-linux-gnu", - "sparc64-unknown-linux-gnu", - "sparcv9-sun-solaris", - "sparc-unknown-none-elf", - "thumbv6m-none-eabi", - "thumbv7em-none-eabi", - "thumbv7em-none-eabihf", - "thumbv7m-none-eabi", - "thumbv8m.base-none-eabi", - "thumbv8m.main-none-eabi", - "thumbv8m.main-none-eabihf", - "wasm32-unknown-emscripten", - "wasm32-unknown-unknown", - "wasm32-wasip1", - "wasm32-wasip1-threads", - "wasm32-wasip2", - "wasm32v1-none", - "x86_64-apple-darwin", - "x86_64-apple-ios", - "x86_64-apple-ios-macabi", - "x86_64-fortanix-unknown-sgx", - "x86_64-unknown-fuchsia", - "x86_64-linux-android", - "x86_64-pc-windows-gnu", - "x86_64-pc-windows-gnullvm", - "x86_64-pc-windows-msvc", - "x86_64-pc-solaris", - "x86_64-unikraft-linux-musl", - "x86_64-unknown-freebsd", - "x86_64-unknown-illumos", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-linux-gnux32", - "x86_64-unknown-linux-musl", - "x86_64-unknown-linux-ohos", - "x86_64-unknown-netbsd", - "x86_64-unknown-none", - "x86_64-unknown-redox", - "x86_64-unknown-hermit", - "x86_64-unknown-uefi", - "x86_64-unknown-managarm-mlibc", -]; +include!(concat!(env!("OUT_DIR"), "/targets.rs")); /// This allows the manifest to contain rust-docs for hosts that don't build /// docs. diff --git a/tests/codegen-llvm/iterrangefrom-overflow-checks.rs b/tests/codegen-llvm/iterrangefrom-overflow-checks.rs new file mode 100644 index 0000000000000..88ff5a8508c8e --- /dev/null +++ b/tests/codegen-llvm/iterrangefrom-overflow-checks.rs @@ -0,0 +1,27 @@ +// With -Coverflow-checks=yes (enabled by default by -Cdebug-assertions=yes) we will produce a +// runtime check that panics after yielding the maximum value of the range bound type. That is +// tested for by tests/ui/iterators/rangefrom-overflow-overflow-checks.rs +// +// This test ensures that such a runtime check is *not* emitted when debug-assertions are +// enabled, but overflow-checks are explicitly disabled. + +//@ revisions: DEBUG NOCHECKS +//@ compile-flags: -O -Cdebug-assertions=yes +//@ [NOCHECKS] compile-flags: -Coverflow-checks=no + +#![crate_type = "lib"] +#![feature(new_range_api)] +use std::range::{IterRangeFrom, RangeFrom}; + +// CHECK-LABEL: @iterrangefrom_remainder( +#[no_mangle] +pub unsafe fn iterrangefrom_remainder(x: IterRangeFrom) -> RangeFrom { + // DEBUG: i32 noundef %x + // NOCHECKS: i32 noundef returned %x + // DEBUG: br i1 + // DEBUG: call core::panicking::panic_const::panic_const_add_overflow + // DEBUG: unreachable + // NOCHECKS-NOT: unreachable + // NOCHECKS: ret i32 %x + x.remainder() +} diff --git a/tests/codegen-llvm/naked-fn/naked-functions.rs b/tests/codegen-llvm/naked-fn/naked-functions.rs index 76c9b90e92ef9..8cf643de7db01 100644 --- a/tests/codegen-llvm/naked-fn/naked-functions.rs +++ b/tests/codegen-llvm/naked-fn/naked-functions.rs @@ -62,11 +62,14 @@ use minicore::*; #[no_mangle] #[unsafe(naked)] pub extern "C" fn naked_empty() { - #[cfg(not(all(target_arch = "arm", target_feature = "thumb-mode")))] - naked_asm!("ret"); - - #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] - naked_asm!("bx lr"); + cfg_select! { + all(target_arch = "arm", target_feature = "thumb-mode") => { + naked_asm!("bx lr"); + } + _ => { + naked_asm!("ret"); + } + } } // linux,win: .intel_syntax @@ -116,19 +119,16 @@ pub extern "C" fn naked_empty() { #[no_mangle] #[unsafe(naked)] pub extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize { - #[cfg(any(target_os = "windows", target_os = "linux"))] - { - naked_asm!("lea rax, [rdi + rsi]", "ret") - } - - #[cfg(target_os = "macos")] - { - naked_asm!("add x0, x0, x1", "ret") - } - - #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] - { - naked_asm!("adds r0, r0, r1", "bx lr") + cfg_select! { + any(target_arch = "x86_64", target_arch = "x86") => { + naked_asm!("lea rax, [rdi + rsi]", "ret") + } + target_arch = "aarch64" => { + naked_asm!("add x0, x0, x1", "ret") + } + all(target_arch = "arm", target_feature = "thumb-mode") => { + naked_asm!("adds r0, r0, r1", "bx lr") + } } } @@ -141,11 +141,14 @@ pub extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize { #[unsafe(naked)] #[link_section = ".text.some_different_name"] pub extern "C" fn test_link_section() { - #[cfg(not(all(target_arch = "arm", target_feature = "thumb-mode")))] - naked_asm!("ret"); - - #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] - naked_asm!("bx lr"); + cfg_select! { + all(target_arch = "arm", target_feature = "thumb-mode") => { + naked_asm!("bx lr"); + } + _ => { + naked_asm!("ret"); + } + } } // win_x86: .def fastcall_cc diff --git a/tests/ui/iterators/iterrangefrom.rs b/tests/ui/iterators/iterrangefrom.rs new file mode 100644 index 0000000000000..54d8f522a2c88 --- /dev/null +++ b/tests/ui/iterators/iterrangefrom.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -C overflow-checks=yes + +#![feature(new_range_api)] + +use std::{iter, range}; + +fn main() { + for (a, b) in iter::zip(0_u32..256, range::RangeFrom::from(0_u8..)) { + assert_eq!(a, u32::from(b)); + } + + let mut a = range::RangeFrom::from(0_u8..).into_iter(); + let mut b = 0_u8..; + assert_eq!(a.next(), b.next()); + assert_eq!(a.nth(5), b.nth(5)); + assert_eq!(a.nth(0), b.next()); + + let mut a = range::RangeFrom::from(0_u8..).into_iter(); + let mut b = 0_u8..; + assert_eq!(a.nth(5), b.nth(5)); + assert_eq!(a.nth(0), b.next()); +} diff --git a/tests/ui/iterators/rangefrom-overflow-debug.rs b/tests/ui/iterators/rangefrom-overflow-debug.rs new file mode 100644 index 0000000000000..9a1bc6910a044 --- /dev/null +++ b/tests/ui/iterators/rangefrom-overflow-debug.rs @@ -0,0 +1,17 @@ +//@ run-pass +//@ needs-unwind +//@ compile-flags: -O -C debug_assertions=yes + +#![feature(new_range_api)] + +use std::panic; + +fn main() { + let mut it = core::range::RangeFrom::from(u8::MAX..).into_iter(); + assert_eq!(it.next().unwrap(), 255); + + let r = panic::catch_unwind(|| { + let _ = it.remainder(); + }); + assert!(r.is_err()); +} diff --git a/tests/ui/iterators/rangefrom-overflow-ndebug.rs b/tests/ui/iterators/rangefrom-overflow-ndebug.rs new file mode 100644 index 0000000000000..4ce9b0636383c --- /dev/null +++ b/tests/ui/iterators/rangefrom-overflow-ndebug.rs @@ -0,0 +1,10 @@ +//@ run-pass +//@ compile-flags: -O -C debug_assertions=no + +#![feature(new_range_api)] + +fn main() { + let mut it = core::range::RangeFrom::from(u8::MAX..).into_iter(); + assert_eq!(it.next().unwrap(), 255); + assert_eq!(it.remainder().start, u8::MIN); +} diff --git a/tests/ui/iterators/rangefrom-overflow-overflow-checks.rs b/tests/ui/iterators/rangefrom-overflow-overflow-checks.rs new file mode 100644 index 0000000000000..7e3b0fc308405 --- /dev/null +++ b/tests/ui/iterators/rangefrom-overflow-overflow-checks.rs @@ -0,0 +1,48 @@ +//@ run-pass +//@ needs-unwind +//@ compile-flags: -O -C overflow-checks=yes + +#![feature(new_range_api)] + +use std::panic; + +fn main() { + let mut it = core::range::RangeFrom::from(u8::MAX..).into_iter(); + assert_eq!(it.next().unwrap(), 255); + + let r = panic::catch_unwind(move || { + let _ = it.remainder(); + }); + assert!(r.is_err()); + + let mut it = core::range::RangeFrom::from(u8::MAX..).into_iter(); + assert_eq!(it.next().unwrap(), 255); + + let r = panic::catch_unwind(move || { + let _ = it.next(); + }); + assert!(r.is_err()); + + let mut it = core::range::RangeFrom::from(u8::MAX..).into_iter(); + assert_eq!(it.next().unwrap(), 255); + + let r = panic::catch_unwind(move || { + let _ = it.nth(0); + }); + assert!(r.is_err()); + + let mut it = core::range::RangeFrom::from(u8::MAX-1..).into_iter(); + assert_eq!(it.nth(1).unwrap(), 255); + + let r = panic::catch_unwind(move || { + let _ = it.next(); + }); + assert!(r.is_err()); + + let mut it = core::range::RangeFrom::from(u8::MAX-1..).into_iter(); + + let r = panic::catch_unwind(move || { + let _ = it.nth(2); + }); + assert!(r.is_err()); +}