about summary refs log tree commit diff
path: root/library
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2024-04-25 05:04:32 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2024-04-25 05:04:32 +0000
commitff6fc757815055923e7f7ff73eaed8f9cbcfba75 (patch)
treebfd3766e077a0f447004b74063ad40ec02cd00e3 /library
parentbed7caf20638dde1822553d432f6fe213baf4eae (diff)
parentcb3752d20e0f5d24348062211102a08d46fbecff (diff)
downloadrust-ff6fc757815055923e7f7ff73eaed8f9cbcfba75.tar.gz
rust-ff6fc757815055923e7f7ff73eaed8f9cbcfba75.zip
Merge from rustc
Diffstat (limited to 'library')
-rw-r--r--library/alloc/src/collections/binary_heap/mod.rs2
-rw-r--r--library/alloc/src/lib.rs2
-rw-r--r--library/core/src/iter/adapters/enumerate.rs1
-rw-r--r--library/core/src/iter/sources/from_coroutine.rs2
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/ops/coroutine.rs3
-rw-r--r--library/core/src/pin.rs2
-rw-r--r--library/core/src/sync/atomic.rs9
-rw-r--r--library/core/tests/lib.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/lib.rs1
-rw-r--r--library/std/src/path.rs4
-rw-r--r--library/std/src/sys/pal/windows/mod.rs17
-rw-r--r--library/std/src/sys/pal/windows/os.rs2
-rw-r--r--library/std/src/sys/pal/windows/thread_local_key.rs26
14 files changed, 52 insertions, 23 deletions
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index c54f0062824..846b9a1404d 100644
--- a/library/alloc/src/collections/binary_heap/mod.rs
+++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -31,7 +31,7 @@
 //! // instead of a max-heap.
 //! impl Ord for State {
 //!     fn cmp(&self, other: &Self) -> Ordering {
-//!         // Notice that the we flip the ordering on costs.
+//!         // Notice that we flip the ordering on costs.
 //!         // In case of a tie we compare positions - this step is necessary
 //!         // to make implementations of `PartialEq` and `Ord` consistent.
 //!         other.cost.cmp(&self.cost)
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 88faf5a9c7d..b417513aaa2 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -128,7 +128,6 @@
 #![feature(fn_traits)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hint_assert_unchecked)]
-#![feature(inline_const)]
 #![feature(inplace_iteration)]
 #![feature(iter_advance_by)]
 #![feature(iter_next_chunk)]
@@ -169,6 +168,7 @@
 // Language features:
 // tidy-alphabetical-start
 #![cfg_attr(bootstrap, feature(associated_type_bounds))]
+#![cfg_attr(bootstrap, feature(inline_const))]
 #![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)]
 #![cfg_attr(not(test), feature(coroutine_trait))]
 #![cfg_attr(test, feature(panic_update_hook))]
diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs
index ef46040f0a7..7adbabf69e4 100644
--- a/library/core/src/iter/adapters/enumerate.rs
+++ b/library/core/src/iter/adapters/enumerate.rs
@@ -15,6 +15,7 @@ use crate::ops::Try;
 #[derive(Clone, Debug)]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Enumerate")]
 pub struct Enumerate<I> {
     iter: I,
     count: usize,
diff --git a/library/core/src/iter/sources/from_coroutine.rs b/library/core/src/iter/sources/from_coroutine.rs
index bf413b24d41..9bac9037a02 100644
--- a/library/core/src/iter/sources/from_coroutine.rs
+++ b/library/core/src/iter/sources/from_coroutine.rs
@@ -14,7 +14,7 @@ use crate::pin::Pin;
 /// #![feature(coroutines)]
 /// #![feature(iter_from_coroutine)]
 ///
-/// let it = std::iter::from_coroutine(|| {
+/// let it = std::iter::from_coroutine(#[cfg_attr(not(bootstrap), coroutine)] || {
 ///     yield 1;
 ///     yield 2;
 ///     yield 3;
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 154565b6fee..6925a7d1da1 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -201,6 +201,7 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(inline_const))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
 #![feature(allow_internal_unsafe)]
@@ -231,7 +232,6 @@
 #![feature(fundamental)]
 #![feature(generic_arg_infer)]
 #![feature(if_let_guard)]
-#![feature(inline_const)]
 #![feature(intra_doc_pointers)]
 #![feature(intrinsics)]
 #![feature(lang_items)]
diff --git a/library/core/src/ops/coroutine.rs b/library/core/src/ops/coroutine.rs
index 6e067f95da9..5250be15fe4 100644
--- a/library/core/src/ops/coroutine.rs
+++ b/library/core/src/ops/coroutine.rs
@@ -40,12 +40,13 @@ pub enum CoroutineState<Y, R> {
 /// ```rust
 /// #![feature(coroutines)]
 /// #![feature(coroutine_trait)]
+/// #![feature(stmt_expr_attributes)]
 ///
 /// use std::ops::{Coroutine, CoroutineState};
 /// use std::pin::Pin;
 ///
 /// fn main() {
-///     let mut coroutine = || {
+///     let mut coroutine = #[cfg_attr(not(bootstrap), coroutine)] || {
 ///         yield 1;
 ///         "foo"
 ///     };
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index efd525aeb3b..a11c6c742d7 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -1809,7 +1809,7 @@ impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr> where Ptr: DispatchFromDyn<U>
 /// fn coroutine_fn() -> impl Coroutine<Yield = usize, Return = ()> /* not Unpin */ {
 ///  // Allow coroutine to be self-referential (not `Unpin`)
 ///  // vvvvvv        so that locals can cross yield points.
-///     static || {
+///     #[cfg_attr(not(bootstrap), coroutine)] static || {
 ///         let foo = String::from("foo");
 ///         let foo_ref = &foo; // ------+
 ///         yield 0;                  // | <- crosses yield point!
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index c8fd997a5da..073459fcb00 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -511,7 +511,8 @@ impl AtomicBool {
     /// # Examples
     ///
     /// ```
-    /// #![feature(atomic_from_mut, inline_const)]
+    /// #![feature(atomic_from_mut)]
+    /// # #![cfg_attr(bootstrap, feature(inline_const))]
     /// use std::sync::atomic::{AtomicBool, Ordering};
     ///
     /// let mut some_bools = [const { AtomicBool::new(false) }; 10];
@@ -1313,7 +1314,8 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(atomic_from_mut, inline_const)]
+    /// #![feature(atomic_from_mut)]
+    /// # #![cfg_attr(bootstrap, feature(inline_const))]
     /// use std::ptr::null_mut;
     /// use std::sync::atomic::{AtomicPtr, Ordering};
     ///
@@ -2303,7 +2305,8 @@ macro_rules! atomic_int {
             /// # Examples
             ///
             /// ```
-            /// #![feature(atomic_from_mut, inline_const)]
+            /// #![feature(atomic_from_mut)]
+            /// # #![cfg_attr(bootstrap, feature(inline_const))]
             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
             ///
             #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 7bd962fa260..d6e705a37a7 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -46,7 +46,7 @@
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
 #![feature(try_find)]
-#![feature(inline_const)]
+#![cfg_attr(bootstrap, feature(inline_const))]
 #![feature(is_sorted)]
 #![feature(layout_for_ptr)]
 #![feature(pattern)]
diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs
index 48514e52587..331b6626249 100644
--- a/library/portable-simd/crates/core_simd/src/lib.rs
+++ b/library/portable-simd/crates/core_simd/src/lib.rs
@@ -7,7 +7,6 @@
     convert_float_to_int,
     core_intrinsics,
     decl_macro,
-    inline_const,
     intra_doc_pointers,
     repr_simd,
     simd_ffi,
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 0636f55771e..1c58671a0cf 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -3332,7 +3332,6 @@ impl Error for StripPrefixError {
 /// ## Posix paths
 ///
 /// ```
-/// #![feature(absolute_path)]
 /// # #[cfg(unix)]
 /// fn main() -> std::io::Result<()> {
 ///   use std::path::{self, Path};
@@ -3357,7 +3356,6 @@ impl Error for StripPrefixError {
 /// ## Windows paths
 ///
 /// ```
-/// #![feature(absolute_path)]
 /// # #[cfg(windows)]
 /// fn main() -> std::io::Result<()> {
 ///   use std::path::{self, Path};
@@ -3382,7 +3380,7 @@ impl Error for StripPrefixError {
 ///
 /// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
 /// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
-#[unstable(feature = "absolute_path", issue = "92750")]
+#[stable(feature = "absolute_path", since = "CURRENT_RUSTC_VERSION")]
 pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
     let path = path.as_ref();
     if path.as_os_str().is_empty() {
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index b49585599cb..ff41f6e77be 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -201,14 +201,21 @@ pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
 // currently reside in the buffer. This function is an abstraction over these
 // functions by making them easier to call.
 //
-// The first callback, `f1`, is yielded a (pointer, len) pair which can be
+// The first callback, `f1`, is passed a (pointer, len) pair which can be
 // passed to a syscall. The `ptr` is valid for `len` items (u16 in this case).
-// The closure is expected to return what the syscall returns which will be
-// interpreted by this function to determine if the syscall needs to be invoked
-// again (with more buffer space).
+// The closure is expected to:
+// - On success, return the actual length of the written data *without* the null terminator.
+//   This can be 0. In this case the last_error must be left unchanged.
+// - On insufficient buffer space,
+//   - either return the required length *with* the null terminator,
+//   - or set the last-error to ERROR_INSUFFICIENT_BUFFER and return `len`.
+// - On other failure, return 0 and set last_error.
+//
+// This is how most but not all syscalls indicate the required buffer space.
+// Other syscalls may need translation to match this protocol.
 //
 // Once the syscall has completed (errors bail out early) the second closure is
-// yielded the data which has been read from the syscall. The return value
+// passed the data which has been read from the syscall. The return value
 // from this closure is then the return value of the function.
 pub fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> crate::io::Result<T>
 where
diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs
index 374c9845ea4..64d8b72aed2 100644
--- a/library/std/src/sys/pal/windows/os.rs
+++ b/library/std/src/sys/pal/windows/os.rs
@@ -326,6 +326,8 @@ fn home_dir_crt() -> Option<PathBuf> {
 
         super::fill_utf16_buf(
             |buf, mut sz| {
+                // GetUserProfileDirectoryW does not quite use the usual protocol for
+                // negotiating the buffer size, so we have to translate.
                 match c::GetUserProfileDirectoryW(
                     ptr::without_provenance_mut(CURRENT_PROCESS_TOKEN),
                     buf,
diff --git a/library/std/src/sys/pal/windows/thread_local_key.rs b/library/std/src/sys/pal/windows/thread_local_key.rs
index 4c00860dae3..e5ba619fc6b 100644
--- a/library/std/src/sys/pal/windows/thread_local_key.rs
+++ b/library/std/src/sys/pal/windows/thread_local_key.rs
@@ -141,9 +141,15 @@ impl StaticKey {
                     panic!("out of TLS indexes");
                 }
 
-                self.key.store(key + 1, Release);
                 register_dtor(self);
 
+                // Release-storing the key needs to be the last thing we do.
+                // This is because in `fn key()`, other threads will do an acquire load of the key,
+                // and if that sees this write then it will entirely bypass the `InitOnce`. We thus
+                // need to establish synchronization through `key`. In particular that acquire load
+                // must happen-after the register_dtor above, to ensure the dtor actually runs!
+                self.key.store(key + 1, Release);
+
                 let r = c::InitOnceComplete(self.once.get(), 0, ptr::null_mut());
                 debug_assert_eq!(r, c::TRUE);
 
@@ -313,8 +319,22 @@ unsafe fn run_dtors() {
         // Use acquire ordering to observe key initialization.
         let mut cur = DTORS.load(Acquire);
         while !cur.is_null() {
-            let key = (*cur).key.load(Relaxed) - 1;
+            let pre_key = (*cur).key.load(Acquire);
             let dtor = (*cur).dtor.unwrap();
+            cur = (*cur).next.load(Relaxed);
+
+            // In StaticKey::init, we register the dtor before setting `key`.
+            // So if one thread's `run_dtors` races with another thread executing `init` on the same
+            // `StaticKey`, we can encounter a key of 0 here. That means this key was never
+            // initialized in this thread so we can safely skip it.
+            if pre_key == 0 {
+                continue;
+            }
+            // If this is non-zero, then via the `Acquire` load above we synchronized with
+            // everything relevant for this key. (It's not clear that this is needed, since the
+            // release-acquire pair on DTORS also establishes synchronization, but better safe than
+            // sorry.)
+            let key = pre_key - 1;
 
             let ptr = c::TlsGetValue(key);
             if !ptr.is_null() {
@@ -322,8 +342,6 @@ unsafe fn run_dtors() {
                 dtor(ptr as *mut _);
                 any_run = true;
             }
-
-            cur = (*cur).next.load(Relaxed);
         }
 
         if !any_run {