diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index bf881feb60158..51a4186658c62 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -816,6 +816,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub(super) fn apply_do_not_recommend( &self, obligation: &mut PredicateObligation<'tcx>, + root_obligation: &PredicateObligation<'tcx>, ) -> bool { let mut base_cause = obligation.cause.code().clone(); let mut applied_do_not_recommend = false; @@ -823,6 +824,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let ObligationCauseCode::ImplDerived(ref c) = base_cause { if self.tcx.do_not_recommend_impl(c.impl_or_alias_def_id) { let code = (*c.derived.parent_code).clone(); + // Keep more precise spans that still point within the parent obligation, + // but do not let hidden impl details move the span outside of it. + if code == *root_obligation.cause.code() + && !root_obligation.cause.span.contains(obligation.cause.span) + { + obligation.cause.span = root_obligation.cause.span; + } obligation.cause.map_code(|_| code); obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx); applied_do_not_recommend = true; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 990a703409d17..e38ac4c447fcc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -298,7 +298,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { error.code, FulfillmentErrorCode::Select(crate::traits::SelectionError::Unimplemented) | FulfillmentErrorCode::Project(_) - ) && self.apply_do_not_recommend(&mut error.obligation) + ) && self.apply_do_not_recommend(&mut error.obligation, &error.root_obligation) { error.code = FulfillmentErrorCode::Select(SelectionError::Unimplemented); } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index a08e99a277d70..27f85666d719a 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1740,6 +1740,27 @@ impl Vec { } } + /// Converts the Vec into a boxed array. This conversion will discard any spare capacity, if there is any, see [`Vec::shrink_to_fit`]. + /// If you merely wish for a reference to an array, use [`as_array`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_array). + /// + /// If `N` is not exactly equal to [`Vec::len`], then this method returns `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(alloc_slice_into_array)] + /// let vec: Vec = vec![1, 2, 3]; + /// let box_array: Box<[i32; 3]> = vec.clone().into_array().unwrap(); + /// let not_enough_elements: Result, Vec> = vec.into_array::<4>(); + /// assert_eq!(not_enough_elements, Err(vec![1, 2, 3])); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "alloc_slice_into_array", issue = "148082")] + #[must_use] + pub fn into_array(self) -> Result, Self> { + if self.len() == N { Ok(self.into_boxed_slice().into_array().unwrap()) } else { Err(self) } + } + /// Shortens the vector, keeping the first `len` elements and dropping /// the rest. /// diff --git a/library/alloctests/tests/str.rs b/library/alloctests/tests/str.rs index f1bd5325da587..dca2c49249aff 100644 --- a/library/alloctests/tests/str.rs +++ b/library/alloctests/tests/str.rs @@ -2348,6 +2348,7 @@ fn utf8_char_counts() { .flat_map(|n| n - spread..=n + spread) .collect::>(); if cfg!(not(miri)) { + // Miri is too slow reps.extend([1024, 1 << 16].iter().copied().flat_map(|n| n - spread..=n + spread)); } let counts = if cfg!(miri) { 0..1 } else { 0..8 }; diff --git a/library/alloctests/tests/sync.rs b/library/alloctests/tests/sync.rs index 6d3ab1b1d11e1..5742855768c70 100644 --- a/library/alloctests/tests/sync.rs +++ b/library/alloctests/tests/sync.rs @@ -469,8 +469,6 @@ fn test_weak_count_locked() { while !a2.load(SeqCst) { let n = Arc::weak_count(&a2); assert!(n < 2, "bad weak count: {}", n); - #[cfg(miri)] // Miri's scheduler does not guarantee liveness, and thus needs this hint. - std::hint::spin_loop(); } t.join().unwrap(); } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 2051a806af642..4e6cddc77e0e1 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -280,8 +280,9 @@ pub macro PartialEq($item:item) { /// The primary difference to [`PartialEq`] is the additional requirement for reflexivity. A type /// that implements [`PartialEq`] guarantees that for all `a`, `b` and `c`: /// -/// - symmetric: `a == b` implies `b == a` and `a != b` implies `!(a == b)` +/// - symmetric: `a == b` implies `b == a` /// - transitive: `a == b` and `b == c` implies `a == c` +/// - consistent: `a != b` if and only if `!(a == b)` /// /// `Eq`, which builds on top of [`PartialEq`] also implies: /// diff --git a/library/core/src/ffi/c_short.md b/library/core/src/ffi/c_short.md index 3d1e53d1325f3..29415129b50a7 100644 --- a/library/core/src/ffi/c_short.md +++ b/library/core/src/ffi/c_short.md @@ -1,5 +1,3 @@ Equivalent to C's `signed short` (`short`) type. This type will almost always be [`i16`], but may differ on some esoteric systems. The C standard technically only requires that this type be a signed integer with at least 16 bits; some systems may define it as `i32`, for example. - -[`char`]: c_char diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index e9302a6127f5c..d395d0ab58354 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -299,8 +299,8 @@ macro_rules! impl_Display { } impl $Unsigned { - /// Allows users to write an integer (in signed decimal format) into a variable `buf` of - /// type [`NumBuffer`] that is passed by the caller by mutable reference. + /// Allows users to write an integer (in unsigned decimal format) into a variable `buf` + /// of type [`NumBuffer`] that is passed by the caller by mutable reference. /// /// # Examples /// @@ -738,7 +738,7 @@ impl u128 { offset } - /// Allows users to write an integer (in signed decimal format) into a variable `buf` of + /// Allows users to write an integer (in unsigned decimal format) into a variable `buf` of /// type [`NumBuffer`] that is passed by the caller by mutable reference. /// /// # Examples diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 6dc748c568fcd..c5182cb3d0720 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -3674,7 +3674,7 @@ pub const trait Iterator { Sum::sum(self) } - /// Iterates over the entire iterator, multiplying all the elements + /// Iterates over the entire iterator, multiplying all the elements. /// /// An empty iterator returns the one value of the type. /// diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index c17f55a25896a..d381402b469f4 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -977,7 +977,7 @@ impl f128 { #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn midpoint(self, other: f128) -> f128 { - const HI: f128 = f128::MAX / 2.; + const HI: f128 = f128::MAX * 0.5; let (a, b) = (self, other); let abs_a = a.abs(); @@ -985,9 +985,9 @@ impl f128 { if abs_a <= HI && abs_b <= HI { // Overflow is impossible - (a + b) / 2. + (a + b) * 0.5 } else { - (a / 2.) + (b / 2.) + (a * 0.5) + (b * 0.5) } } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 110465068b8f6..c26ae17d870cc 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -973,7 +973,7 @@ impl f16 { #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn midpoint(self, other: f16) -> f16 { - const HI: f16 = f16::MAX / 2.; + const HI: f16 = f16::MAX * 0.5; let (a, b) = (self, other); let abs_a = a.abs(); @@ -981,9 +981,9 @@ impl f16 { if abs_a <= HI && abs_b <= HI { // Overflow is impossible - (a + b) / 2. + (a + b) * 0.5 } else { - (a / 2.) + (b / 2.) + (a * 0.5) + (b * 0.5) } } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index f9cb7cc650f4f..24c97a6491c11 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1164,10 +1164,10 @@ impl f32 { target_arch = "wasm32", target_arch = "wasm64", ) => { - ((self as f64 + other as f64) / 2.0) as f32 + ((self as f64 + other as f64) * 0.5) as f32 } _ => { - const HI: f32 = f32::MAX / 2.; + const HI: f32 = f32::MAX * 0.5; let (a, b) = (self, other); let abs_a = a.abs(); @@ -1175,9 +1175,9 @@ impl f32 { if abs_a <= HI && abs_b <= HI { // Overflow is impossible - (a + b) / 2. + (a + b) * 0.5 } else { - (a / 2.) + (b / 2.) + (a * 0.5) + (b * 0.5) } } } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 87f5505ce2b33..be045033a3553 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1150,7 +1150,7 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn midpoint(self, other: f64) -> f64 { - const HI: f64 = f64::MAX / 2.; + const HI: f64 = f64::MAX * 0.5; let (a, b) = (self, other); let abs_a = a.abs(); @@ -1158,9 +1158,9 @@ impl f64 { if abs_a <= HI && abs_b <= HI { // Overflow is impossible - (a + b) / 2. + (a + b) * 0.5 } else { - (a / 2.) + (b / 2.) + (a * 0.5) + (b * 0.5) } } diff --git a/library/std/src/env.rs b/library/std/src/env.rs index f60c8392785c1..540dcfd204e9a 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -303,12 +303,12 @@ impl Error for VarError {} /// /// # Safety /// -/// This function is safe to call in a single-threaded program. +/// This function is sound to call in a single-threaded program. /// -/// This function is also always safe to call on Windows, in single-threaded +/// This function is also always sound to call on Windows, in single-threaded /// and multi-threaded programs. /// -/// In multi-threaded programs on other operating systems, the only safe option is +/// In multi-threaded programs on other operating systems, the only sound option is /// to not use `set_var` or `remove_var` at all. /// /// The exact requirement is: you @@ -322,7 +322,7 @@ impl Error for VarError {} /// lookups from [`std::net::ToSocketAddrs`]. No stable guarantee is made about /// which functions may read from the environment in future versions of a /// library. All this makes it not practically possible for you to guarantee -/// that no other thread will read the environment, so the only safe option is +/// that no other thread will read the environment, so the only sound option is /// to not use `set_var` or `remove_var` in multi-threaded programs at all. /// /// Discussion of this unsafety on Unix may be found in: @@ -366,12 +366,12 @@ pub unsafe fn set_var, V: AsRef>(key: K, value: V) { /// /// # Safety /// -/// This function is safe to call in a single-threaded program. +/// This function is sound to call in a single-threaded program. /// -/// This function is also always safe to call on Windows, in single-threaded +/// This function is also always sound to call on Windows, in single-threaded /// and multi-threaded programs. /// -/// In multi-threaded programs on other operating systems, the only safe option is +/// In multi-threaded programs on other operating systems, the only sound option is /// to not use `set_var` or `remove_var` at all. /// /// The exact requirement is: you @@ -385,7 +385,7 @@ pub unsafe fn set_var, V: AsRef>(key: K, value: V) { /// lookups from [`std::net::ToSocketAddrs`]. No stable guarantee is made about /// which functions may read from the environment in future versions of a /// library. All this makes it not practically possible for you to guarantee -/// that no other thread will read the environment, so the only safe option is +/// that no other thread will read the environment, so the only sound option is /// to not use `set_var` or `remove_var` in multi-threaded programs at all. /// /// Discussion of this unsafety on Unix may be found in: diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index e1dedad313ddc..5f94a13dad22a 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -238,7 +238,7 @@ mod break_keyword {} /// /// Turning a `fn` into a `const fn` has no effect on run-time uses of that function. /// -/// ## Other uses of `const` +/// ## raw pointers /// /// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const /// T` and `*mut T`. More about `const` as used in raw pointers can be read at the Rust docs for the [pointer primitive]. diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index a0defc39ac82e..71896d73670fd 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -494,9 +494,18 @@ impl ChildExt for process::Child { self.handle.send_process_group_signal(signal) } + #[cfg(not(target_os = "espidf"))] fn kill_process_group(&mut self) -> io::Result<()> { self.handle.send_process_group_signal(libc::SIGKILL) } + + #[cfg(target_os = "espidf")] + fn kill_process_group(&mut self) -> io::Result<()> { + Err(io::Error::new( + io::ErrorKind::Unsupported, + "process groups are not supported on espidf", + )) + } } #[stable(feature = "process_extensions", since = "1.2.0")] diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 5d2cfdf6718a1..a7cb9ebad314e 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1090,7 +1090,7 @@ impl DirEntry { target_os = "illumos", target_vendor = "apple", )), - miri + miri // no dirfd on Miri ))] pub fn metadata(&self) -> io::Result { run_path_with_cstr(&self.path(), &lstat) diff --git a/library/std/src/sys/pal/unix/conf.rs b/library/std/src/sys/pal/unix/conf.rs index a97173a1a35a1..4c00379a88439 100644 --- a/library/std/src/sys/pal/unix/conf.rs +++ b/library/std/src/sys/pal/unix/conf.rs @@ -12,9 +12,7 @@ pub fn page_size() -> usize { /// /// [posix_confstr]: /// https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html -// -// FIXME: Support `confstr` in Miri. -#[cfg(all(target_vendor = "apple", not(miri)))] +#[cfg(target_vendor = "apple")] pub fn confstr( key: crate::ffi::c_int, size_hint: Option, diff --git a/library/std/src/sys/pal/unix/conf/tests.rs b/library/std/src/sys/pal/unix/conf/tests.rs index 63a1cc1e94a1d..a84086037ce0b 100644 --- a/library/std/src/sys/pal/unix/conf/tests.rs +++ b/library/std/src/sys/pal/unix/conf/tests.rs @@ -25,7 +25,7 @@ fn test_parse_glibc_version() { // Smoke check `confstr`, do it for several hint values, to ensure our resizing // logic is correct. #[test] -#[cfg(all(target_vendor = "apple", not(miri)))] +#[cfg(target_vendor = "apple")] fn test_confstr() { for key in [libc::_CS_DARWIN_USER_TEMP_DIR, libc::_CS_PATH] { let value_nohint = super::confstr(key, None).unwrap_or_else(|e| { diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 0be150a0bfaa8..cfd7acdb08ab2 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -78,7 +78,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { // fast path with a single syscall for systems with poll() #[cfg(not(any( - miri, + miri, // no `poll` target_os = "emscripten", target_os = "fuchsia", target_os = "vxworks", @@ -125,8 +125,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { // fallback in case poll isn't available or limited by RLIMIT_NOFILE #[cfg(not(any( - // The standard fds are always available in Miri. - miri, target_os = "emscripten", target_os = "fuchsia", target_os = "vxworks", diff --git a/library/std/src/sys/paths/unix.rs b/library/std/src/sys/paths/unix.rs index 616456c6d4a47..e0b1aafda6eb0 100644 --- a/library/std/src/sys/paths/unix.rs +++ b/library/std/src/sys/paths/unix.rs @@ -393,7 +393,7 @@ pub fn current_exe() -> io::Result { if !path.is_absolute() { getcwd().map(|cwd| cwd.join(path)) } else { Ok(path) } } -#[cfg(all(target_vendor = "apple", not(miri)))] +#[cfg(target_vendor = "apple")] fn darwin_temp_dir() -> PathBuf { crate::sys::pal::conf::confstr(libc::_CS_DARWIN_USER_TEMP_DIR, Some(64)) .map(PathBuf::from) @@ -407,7 +407,7 @@ fn darwin_temp_dir() -> PathBuf { pub fn temp_dir() -> PathBuf { crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| { cfg_select! { - all(target_vendor = "apple", not(miri)) => darwin_temp_dir(), + target_vendor = "apple" => darwin_temp_dir(), target_os = "android" => PathBuf::from("/data/local/tmp"), _ => PathBuf::from("/tmp"), } diff --git a/library/std/tests/pipe_subprocess.rs b/library/std/tests/pipe_subprocess.rs index c51a4459e718b..dad1ea6c57377 100644 --- a/library/std/tests/pipe_subprocess.rs +++ b/library/std/tests/pipe_subprocess.rs @@ -1,4 +1,5 @@ fn main() { + // No `Command` on Miri and emscripten #[cfg(all(not(miri), any(unix, windows), not(target_os = "emscripten")))] { use std::io::{Read, pipe}; diff --git a/library/std/tests/windows_unix_socket.rs b/library/std/tests/windows_unix_socket.rs index 1d16ec9ed8414..dd71b1f135dce 100644 --- a/library/std/tests/windows_unix_socket.rs +++ b/library/std/tests/windows_unix_socket.rs @@ -1,5 +1,5 @@ #![cfg(windows)] -#![cfg(not(miri))] // no socket support in Miri +#![cfg(not(miri))] // no Windows socket support in Miri #![feature(windows_unix_domain_sockets)] // Now only test windows_unix_domain_sockets feature // in the future, will test both unix and windows uds diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 222b982073280..360b8418d2194 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -27,7 +27,7 @@ use crate::core::build_steps::gcc::GccTargetPair; use crate::core::build_steps::tool::{ self, RustcPrivateCompilers, ToolTargetBuildMode, get_tool_target_compiler, }; -use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor}; +use crate::core::build_steps::vendor::Vendor; use crate::core::build_steps::{compile, llvm}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata}; use crate::core::config::{GccCiMode, TargetSelection}; @@ -1211,6 +1211,19 @@ impl Step for Src { &dst_src, ); + // Vendor all Cargo dependencies + let vendor = builder.ensure(Vendor { + sync_args: vec![], + versioned_dirs: true, + root_dir: dst_src.clone(), + output_dir: None, + only_library_workspace: true, + }); + + let library_cargo_config_dir = dst_src.join("library").join(".cargo"); + builder.create_dir(&library_cargo_config_dir); + builder.create(&library_cargo_config_dir.join("config.toml"), &vendor.config_library); + tarball.generate() } @@ -1376,12 +1389,17 @@ fn prepare_source_tarball<'a>( sync_args: pkgs_for_pgo_training.collect(), versioned_dirs: true, root_dir: plain_dst_src.into(), - output_dir: VENDOR_DIR.into(), + output_dir: None, + only_library_workspace: false, }); let cargo_config_dir = plain_dst_src.join(".cargo"); builder.create_dir(&cargo_config_dir); builder.create(&cargo_config_dir.join("config.toml"), &vendor.config); + + let library_cargo_config_dir = plain_dst_src.join("library").join(".cargo"); + builder.create_dir(&library_cargo_config_dir); + builder.create(&library_cargo_config_dir.join("config.toml"), &vendor.config_library); } // Delete extraneous directories diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 897e03ce71813..2329bb93b4d3d 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -12,7 +12,7 @@ use clap_complete::{Generator, shells}; use crate::core::build_steps::dist::distdir; use crate::core::build_steps::test; use crate::core::build_steps::tool::{self, RustcPrivateCompilers, SourceType, Tool}; -use crate::core::build_steps::vendor::{Vendor, default_paths_to_vendor}; +use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor, default_paths_to_vendor}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata}; use crate::core::config::TargetSelection; use crate::core::config::flags::{get_completion, top_level_help}; @@ -275,9 +275,10 @@ impl Step for GenerateCopyright { sync_args: Vec::new(), versioned_dirs: true, root_dir: builder.src.clone(), - output_dir: cache_dir.clone(), + output_dir: Some(cache_dir.clone()), + only_library_workspace: false, }); - cache_dir + cache_dir.join(VENDOR_DIR) }; let _guard = builder.group("generate-copyright"); diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 36a740c6f35fc..246598550553a 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -46,9 +46,15 @@ pub(crate) struct Vendor { /// Determines whether vendored dependencies use versioned directories. pub(crate) versioned_dirs: bool, /// The root directory of the source code. + /// + /// Vendored dependencies will be stored in /vendor and + /// /library/vendor unless overridden by `output_dir`. pub(crate) root_dir: PathBuf, - /// The target directory for storing vendored dependencies. - pub(crate) output_dir: PathBuf, + /// The root directory for storing vendored dependencies in /vendor + /// and /library/vendor. + pub(crate) output_dir: Option, + /// Only vendor crates necessary by the library workspace. + pub(crate) only_library_workspace: bool, } impl Step for Vendor { @@ -68,7 +74,8 @@ impl Step for Vendor { sync_args: run.builder.config.cmd.vendor_sync_args(), versioned_dirs: run.builder.config.cmd.vendor_versioned_dirs(), root_dir: run.builder.src.clone(), - output_dir: run.builder.src.join(VENDOR_DIR), + output_dir: None, + only_library_workspace: false, }); } @@ -79,29 +86,53 @@ impl Step for Vendor { fn run(self, builder: &Builder<'_>) -> Self::Output { let _guard = builder.group(&format!("Vendoring sources to {:?}", self.root_dir)); - let mut cmd = command(&builder.initial_cargo); - cmd.arg("vendor"); + let config = if self.only_library_workspace { + String::new() + } else { + let mut cmd = command(&builder.initial_cargo); + cmd.arg("vendor"); - if self.versioned_dirs { - cmd.arg("--versioned-dirs"); - } + if self.versioned_dirs { + cmd.arg("--versioned-dirs"); + } - let to_vendor = default_paths_to_vendor(builder); - // These submodules must be present for `x vendor` to work. - for (_, submodules) in &to_vendor { - for submodule in submodules { - builder.build.require_submodule(submodule, None); + let to_vendor = default_paths_to_vendor(builder); + // These submodules must be present for `x vendor` to work. + for (_, submodules) in &to_vendor { + for submodule in submodules { + builder.build.require_submodule(submodule, None); + } } - } - // Sync these paths by default. - for (p, _) in &to_vendor { - cmd.arg("--sync").arg(p); - } + // Sync these paths by default. + for (p, _) in &to_vendor { + cmd.arg("--sync").arg(p); + } - // Also sync explicitly requested paths. - for sync_arg in self.sync_args { - cmd.arg("--sync").arg(sync_arg); + // Also sync explicitly requested paths. + for sync_arg in self.sync_args { + cmd.arg("--sync").arg(sync_arg); + } + + // Will read the libstd Cargo.toml + // which uses the unstable `public-dependency` feature. + cmd.env("RUSTC_BOOTSTRAP", "1"); + cmd.env("RUSTC", &builder.initial_rustc); + + cmd.current_dir(&self.root_dir); + match &self.output_dir { + None => cmd.arg(VENDOR_DIR), + Some(output_dir) => cmd.arg(output_dir.join(VENDOR_DIR)), + }; + + cmd.run_capture_stdout(builder).stdout() + }; + + let mut cmd = command(&builder.initial_cargo); + cmd.arg("vendor"); + + if self.versioned_dirs { + cmd.arg("--versioned-dirs"); } // Will read the libstd Cargo.toml @@ -109,10 +140,15 @@ impl Step for Vendor { cmd.env("RUSTC_BOOTSTRAP", "1"); cmd.env("RUSTC", &builder.initial_rustc); - cmd.current_dir(self.root_dir).arg(&self.output_dir); + cmd.current_dir(self.root_dir.join("library")); + match &self.output_dir { + None => cmd.arg(VENDOR_DIR), + Some(output_dir) => cmd.arg(output_dir.join("library").join(VENDOR_DIR)), + }; + + let config_library = cmd.run_capture_stdout(builder).stdout(); - let config = cmd.run_capture_stdout(builder); - VendorOutput { config: config.stdout() } + VendorOutput { config, config_library } } } @@ -120,4 +156,5 @@ impl Step for Vendor { #[derive(Debug, Clone)] pub(crate) struct VendorOutput { pub(crate) config: String, + pub(crate) config_library: String, } diff --git a/tests/run-make/macos-deployment-target-warning/rmake.rs b/tests/run-make/macos-deployment-target-warning/rmake.rs index e109b2adcc17a..f48719ebd3b3d 100644 --- a/tests/run-make/macos-deployment-target-warning/rmake.rs +++ b/tests/run-make/macos-deployment-target-warning/rmake.rs @@ -1,19 +1,16 @@ -//@ only-apple //! Tests that deployment target linker warnings are shown as `linker-info`, not `linker-messages` +//@ only-macos + use run_make_support::external_deps::c_cxx_compiler::cc; use run_make_support::external_deps::llvm::llvm_ar; -use run_make_support::{bare_rustc, diff}; +use run_make_support::{diff, rustc}; fn main() { - let cwd = std::env::current_dir().unwrap().to_str().unwrap().to_owned(); - cc().arg("-c").arg("-mmacosx-version-min=15.5").output("foo.o").input("foo.c").run(); llvm_ar().obj_to_ar().output_input("libfoo.a", "foo.o").run(); - let warnings = bare_rustc() - .arg("-L") - .arg(format!("native={cwd}")) + let warnings = rustc() .arg("-lstatic=foo") .link_arg("-mmacosx-version-min=11.2") .input("main.rs") diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr index 46dd21ceb00a0..0cb117d3fc4c3 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr @@ -12,6 +12,26 @@ LL | impl AsExpression for &'_ str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: for that trait implementation, expected `Text`, found `Integer` -error: aborting due to 1 previous error +error[E0277]: the trait bound `X: A` is not satisfied + --> $DIR/as_expression.rs:60:15 + | +LL | X.start().foo().finish(); + | ^^^ unsatisfied trait bound + | +help: the trait `A` is not implemented for `X` + --> $DIR/as_expression.rs:70:1 + | +LL | struct X; + | ^^^^^^^^ +note: required by a bound in `Ext::foo` + --> $DIR/as_expression.rs:79:23 + | +LL | fn foo(self) -> Self + | --- required by a bound in this associated function +LL | where +LL | Self: Sized + A; + | ^ required by this bound in `Ext::foo` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr index c43b4cd8defe3..d47424abcf10d 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr @@ -22,6 +22,26 @@ LL | where LL | T: AsExpression, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::check` -error: aborting due to 1 previous error +error[E0277]: the trait bound `X: A` is not satisfied + --> $DIR/as_expression.rs:60:15 + | +LL | X.start().foo().finish(); + | ^^^ unsatisfied trait bound + | +help: the trait `A` is not implemented for `X` + --> $DIR/as_expression.rs:70:1 + | +LL | struct X; + | ^^^^^^^^ +note: required by a bound in `Ext::foo` + --> $DIR/as_expression.rs:79:23 + | +LL | fn foo(self) -> Self + | --- required by a bound in this associated function +LL | where +LL | Self: Sized + A; + | ^ required by this bound in `Ext::foo` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs index ca8b95f79bbee..c92c78f91ea45 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs @@ -55,4 +55,49 @@ impl Foo for T where T: Expression {} fn main() { SelectInt.check("bar"); //~^ ERROR the trait bound `&str: AsExpression` is not satisfied + + // Regression test for https://github.com/rust-lang/rust/issues/156475. + X.start().foo().finish(); + //~^ ERROR the trait bound `X: A` is not satisfied +} + +trait A {} +trait B {} + +#[diagnostic::do_not_recommend] +impl A for T {} + +struct X; + +trait Start { + fn start(self) -> Self; +} + +trait Ext { + fn foo(self) -> Self + where + Self: Sized + A; +} + +trait Finish { + fn finish(self); +} + +impl Start for T { + fn start(self) -> Self { + self + } +} + +impl Ext for T { + fn foo(self) -> Self + where + Self: Sized + A, + { + self + } +} + +impl Finish for T { + fn finish(self) {} }