From 46673bb08ffa22f21287349d966d875038e41b37 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sun, 17 Jul 2022 11:11:05 +0100 Subject: [PATCH 1/9] Simplify Windows `hashmap_random_keys` --- library/std/src/sys/windows/rand.rs | 68 ++++------------------------- 1 file changed, 8 insertions(+), 60 deletions(-) diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs index 57248e3651ba2..f8fd93a7398e1 100644 --- a/library/std/src/sys/windows/rand.rs +++ b/library/std/src/sys/windows/rand.rs @@ -1,62 +1,9 @@ use crate::io; use crate::mem; -use crate::sync; +use crate::ptr; use crate::sys::c; -/// The kinds of HashMap RNG that may be available -#[derive(Clone, Copy, Debug, PartialEq)] -enum HashMapRng { - Preferred, - Fallback, -} - pub fn hashmap_random_keys() -> (u64, u64) { - match get_hashmap_rng() { - HashMapRng::Preferred => { - preferred_rng().expect("couldn't generate random bytes with preferred RNG") - } - HashMapRng::Fallback => { - fallback_rng().expect("couldn't generate random bytes with fallback RNG") - } - } -} - -/// Returns the HashMap RNG that should be used -/// -/// Panics if they are both broken -fn get_hashmap_rng() -> HashMapRng { - // Assume that if the preferred RNG is broken the first time we use it, it likely means - // that: the DLL has failed to load, there is no point to calling it over-and-over again, - // and we should cache the result - static VALUE: sync::OnceLock = sync::OnceLock::new(); - *VALUE.get_or_init(choose_hashmap_rng) -} - -/// Test whether we should use the preferred or fallback RNG -/// -/// If the preferred RNG is successful, we choose it. Otherwise, if the fallback RNG is successful, -/// we choose that -/// -/// Panics if both the preferred and the fallback RNG are both non-functional -fn choose_hashmap_rng() -> HashMapRng { - let preferred_error = match preferred_rng() { - Ok(_) => return HashMapRng::Preferred, - Err(e) => e, - }; - - match fallback_rng() { - Ok(_) => return HashMapRng::Fallback, - Err(fallback_error) => panic!( - "preferred RNG broken: `{}`, fallback RNG broken: `{}`", - preferred_error, fallback_error - ), - } -} - -/// Generate random numbers using the preferred RNG function (BCryptGenRandom) -fn preferred_rng() -> Result<(u64, u64), io::Error> { - use crate::ptr; - let mut v = (0, 0); let ret = unsafe { c::BCryptGenRandom( @@ -66,22 +13,23 @@ fn preferred_rng() -> Result<(u64, u64), io::Error> { c::BCRYPT_USE_SYSTEM_PREFERRED_RNG, ) }; - - if ret == 0 { Ok(v) } else { Err(io::Error::last_os_error()) } + if ret != 0 { fallback_rng() } else { v } } /// Generate random numbers using the fallback RNG function (RtlGenRandom) #[cfg(not(target_vendor = "uwp"))] -fn fallback_rng() -> Result<(u64, u64), io::Error> { +#[inline(never)] +fn fallback_rng() -> (u64, u64) { let mut v = (0, 0); let ret = unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut u8, mem::size_of_val(&v) as c::ULONG) }; - if ret != 0 { Ok(v) } else { Err(io::Error::last_os_error()) } + if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) } } /// We can't use RtlGenRandom with UWP, so there is no fallback #[cfg(target_vendor = "uwp")] -fn fallback_rng() -> Result<(u64, u64), io::Error> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "RtlGenRandom() not supported on UWP")) +#[inline(never)] +fn fallback_rng() -> (u64, u64) { + panic!("fallback RNG broken: RtlGenRandom() not supported on UWP"); } From 5d95a36244f60bbbc5134310460e7597e82e41b1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 22 Jul 2022 14:51:23 -0400 Subject: [PATCH 2/9] do not claim that transmute is like memcpy --- library/core/src/intrinsics.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index dc82b32214c37..6bf95a1b008e1 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1212,8 +1212,9 @@ extern "rust-intrinsic" { /// /// `transmute` is semantically equivalent to a bitwise move of one type /// into another. It copies the bits from the source value into the - /// destination value, then forgets the original. It's equivalent to C's - /// `memcpy` under the hood, just like `transmute_copy`. + /// destination value, then forgets the original. Note that source and destination + /// are passed by-value, which means if `T` or `U` contains padding, that padding + /// might *not* be preserved by `transmute`. /// /// Because `transmute` is a by-value operation, alignment of the *transmuted values /// themselves* is not a concern. As with any other function, the compiler already ensures From aed5cf3f8ccd42ce455b8d7adbc4a2acfe013f85 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 23 Jul 2022 08:14:46 -0400 Subject: [PATCH 3/9] say some more things about how transmute is UB --- library/core/src/intrinsics.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 6bf95a1b008e1..d043c61a47a39 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1207,8 +1207,7 @@ extern "rust-intrinsic" { /// Reinterprets the bits of a value of one type as another type. /// - /// Both types must have the same size. Neither the original, nor the result, - /// may be an [invalid value](../../nomicon/what-unsafe-does.html). + /// Both types must have the same size. Compilation will fail if this is not guaranteed. /// /// `transmute` is semantically equivalent to a bitwise move of one type /// into another. It copies the bits from the source value into the @@ -1216,21 +1215,24 @@ extern "rust-intrinsic" { /// are passed by-value, which means if `T` or `U` contains padding, that padding /// might *not* be preserved by `transmute`. /// + /// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at + /// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler + /// will generate code *assuming that you, the programmer, ensure that there will never be + /// undefined behavior*. It is therefore your responsibility to guarantee that every value + /// passed to `transmute` is valid at both types `T` and `U`. Failing to uphold this condition + /// may lead to unexpeced and unstable compilation results. This makes `transmute` **incredibly + /// unsafe**. `transmute` should be the absolute last resort. + /// + /// Transmuting pointers to integers in a `const` context is [undefined behavior][ub]. + /// Any attempt to use the resulting value for integer operations will abort const-evaluation. + /// /// Because `transmute` is a by-value operation, alignment of the *transmuted values /// themselves* is not a concern. As with any other function, the compiler already ensures /// both `T` and `U` are properly aligned. However, when transmuting values that *point /// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper /// alignment of the pointed-to values. /// - /// `transmute` is **incredibly** unsafe. There are a vast number of ways to - /// cause [undefined behavior][ub] with this function. `transmute` should be - /// the absolute last resort. - /// - /// Transmuting pointers to integers in a `const` context is [undefined behavior][ub]. - /// Any attempt to use the resulting value for integer operations will abort const-evaluation. - /// - /// The [nomicon](../../nomicon/transmutes.html) has additional - /// documentation. + /// The [nomicon](../../nomicon/transmutes.html) has additional documentation. /// /// [ub]: ../../reference/behavior-considered-undefined.html /// From 225ac9efc10bfd4149fd6de3d09e70d6c2387a8b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 25 Jul 2022 16:35:12 -0700 Subject: [PATCH 4/9] rustdoc: avoid inlining modules with duplicate names Fixes rust-lang/rust#99734 --- src/librustdoc/clean/mod.rs | 7 +++++-- src/test/rustdoc/auxiliary/issue-99734-aux.rs | 7 +++++++ .../issue-99734-multiple-mods-w-same-name.rs | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc/auxiliary/issue-99734-aux.rs create mode 100644 src/test/rustdoc/issue-99734-multiple-mods-w-same-name.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c9ef4748a4845..cf03979a934fb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -51,19 +51,22 @@ pub(crate) trait Clean<'tcx, T> { impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let mut items: Vec = vec![]; + let mut inserted = FxHashSet::default(); items.extend( self.foreigns .iter() .map(|(item, renamed)| clean_maybe_renamed_foreign_item(cx, item, *renamed)), ); - items.extend(self.mods.iter().map(|x| x.clean(cx))); + items.extend(self.mods.iter().map(|x| { + inserted.insert((ItemType::Module, x.name)); + x.clean(cx) + })); // Split up imports from all other items. // // This covers the case where somebody does an import which should pull in an item, // but there's already an item with the same namespace and same name. Rust gives // priority to the not-imported one, so we should, too. - let mut inserted = FxHashSet::default(); items.extend(self.items.iter().flat_map(|(item, renamed)| { // First, lower everything other than imports. if matches!(item.kind, hir::ItemKind::Use(..)) { diff --git a/src/test/rustdoc/auxiliary/issue-99734-aux.rs b/src/test/rustdoc/auxiliary/issue-99734-aux.rs new file mode 100644 index 0000000000000..8f1f1ec89674f --- /dev/null +++ b/src/test/rustdoc/auxiliary/issue-99734-aux.rs @@ -0,0 +1,7 @@ +pub struct Option; +impl Option { + pub fn unwrap(self) {} +} + +/// [`Option::unwrap`] +pub mod task {} diff --git a/src/test/rustdoc/issue-99734-multiple-mods-w-same-name.rs b/src/test/rustdoc/issue-99734-multiple-mods-w-same-name.rs new file mode 100644 index 0000000000000..b2f9b8b46578b --- /dev/null +++ b/src/test/rustdoc/issue-99734-multiple-mods-w-same-name.rs @@ -0,0 +1,14 @@ +// aux-build:issue-99734-aux.rs +// build-aux-docs +// ignore-cross-compile + +#![crate_name = "foo"] + +#[macro_use] +extern crate issue_99734_aux; + +pub use issue_99734_aux::*; + +// @count foo/index.html '//a[@class="mod"][@title="foo::task mod"]' 1 + +pub mod task {} From e3afce8c70ab085ae84da0ed6d42e19f9736667d Mon Sep 17 00:00:00 2001 From: sandydoo Date: Wed, 27 Jul 2022 12:32:34 +0400 Subject: [PATCH 5/9] Fix futex module imports on wasm+atomics --- library/std/src/sys/wasm/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs index 55b5ad314daf0..4159efe2a0523 100644 --- a/library/std/src/sys/wasm/mod.rs +++ b/library/std/src/sys/wasm/mod.rs @@ -52,9 +52,11 @@ cfg_if::cfg_if! { #[path = "../unix/locks"] pub mod locks { #![allow(unsafe_op_in_unsafe_fn)] - mod futex; + mod futex_condvar; + mod futex_mutex; mod futex_rwlock; - pub(crate) use futex::{Mutex, MovableMutex, Condvar, MovableCondvar}; + pub(crate) use futex_condvar::{Condvar, MovableCondvar}; + pub(crate) use futex_mutex::{Mutex, MovableMutex}; pub(crate) use futex_rwlock::{RwLock, MovableRwLock}; } #[path = "atomics/futex.rs"] From c4aca2bc889a657825ea74db2b0dca1d7ea87a44 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 31 Jul 2022 09:00:49 -0400 Subject: [PATCH 6/9] typo Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index d043c61a47a39..f4234105ac649 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1220,7 +1220,7 @@ extern "rust-intrinsic" { /// will generate code *assuming that you, the programmer, ensure that there will never be /// undefined behavior*. It is therefore your responsibility to guarantee that every value /// passed to `transmute` is valid at both types `T` and `U`. Failing to uphold this condition - /// may lead to unexpeced and unstable compilation results. This makes `transmute` **incredibly + /// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly /// unsafe**. `transmute` should be the absolute last resort. /// /// Transmuting pointers to integers in a `const` context is [undefined behavior][ub]. From 234bfc04b0cedc115395ccdce7e84bfadccc1bf7 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 2 Aug 2022 13:59:18 -0700 Subject: [PATCH 7/9] Replace `* -> vec` with `-> vec` in docs Rustdoc's current syntax is `-> vec`. --- src/librustdoc/html/static/js/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 2aef978a072d2..0702b2b0b7caf 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -816,7 +816,7 @@ function loadCss(cssFileName) { enum, trait, type, macro, \ and const.", "Search functions by type signature (e.g., vec -> usize or \ - * -> vec)", + -> vec)", "Search multiple things at once by splitting your query with comma (e.g., \ str,u8 or String,struct:Vec,test)", "You can look for items with an exact name by putting double quotes around \ From 8724ca3114f2babefeee7989eadbb7d156503f37 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 2 Aug 2022 14:48:23 -0700 Subject: [PATCH 8/9] rustdoc: avoid inlining foreigns with duplicate names --- src/librustdoc/clean/mod.rs | 12 +++++++----- src/test/rustdoc/auxiliary/issue-99734-aux.rs | 4 ++++ .../issue-99734-multiple-foreigns-w-same-name.rs | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 src/test/rustdoc/issue-99734-multiple-foreigns-w-same-name.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index cf03979a934fb..9251a7487a7d3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -52,11 +52,13 @@ impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let mut items: Vec = vec![]; let mut inserted = FxHashSet::default(); - items.extend( - self.foreigns - .iter() - .map(|(item, renamed)| clean_maybe_renamed_foreign_item(cx, item, *renamed)), - ); + items.extend(self.foreigns.iter().map(|(item, renamed)| { + let item = clean_maybe_renamed_foreign_item(cx, item, *renamed); + if let Some(name) = item.name { + inserted.insert((item.type_(), name)); + } + item + })); items.extend(self.mods.iter().map(|x| { inserted.insert((ItemType::Module, x.name)); x.clean(cx) diff --git a/src/test/rustdoc/auxiliary/issue-99734-aux.rs b/src/test/rustdoc/auxiliary/issue-99734-aux.rs index 8f1f1ec89674f..234d55efb554d 100644 --- a/src/test/rustdoc/auxiliary/issue-99734-aux.rs +++ b/src/test/rustdoc/auxiliary/issue-99734-aux.rs @@ -5,3 +5,7 @@ impl Option { /// [`Option::unwrap`] pub mod task {} + +extern "C" { + pub fn main() -> std::ffi::c_int; +} diff --git a/src/test/rustdoc/issue-99734-multiple-foreigns-w-same-name.rs b/src/test/rustdoc/issue-99734-multiple-foreigns-w-same-name.rs new file mode 100644 index 0000000000000..3208fea05b376 --- /dev/null +++ b/src/test/rustdoc/issue-99734-multiple-foreigns-w-same-name.rs @@ -0,0 +1,16 @@ +// aux-build:issue-99734-aux.rs +// build-aux-docs +// ignore-cross-compile + +#![crate_name = "foo"] + +#[macro_use] +extern crate issue_99734_aux; + +pub use issue_99734_aux::*; + +// @count foo/index.html '//a[@class="fn"][@title="foo::main fn"]' 1 + +extern "C" { + pub fn main() -> std::ffi::c_int; +} From da3e11fc4298e6e832eba0575b77a21493a7adfe Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Aug 2022 20:43:28 -0400 Subject: [PATCH 9/9] wordsmithing --- library/core/src/intrinsics.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index f4234105ac649..37940c7921360 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1212,8 +1212,8 @@ extern "rust-intrinsic" { /// `transmute` is semantically equivalent to a bitwise move of one type /// into another. It copies the bits from the source value into the /// destination value, then forgets the original. Note that source and destination - /// are passed by-value, which means if `T` or `U` contains padding, that padding - /// might *not* be preserved by `transmute`. + /// are passed by-value, which means if `T` or `U` contain padding, that padding + /// is *not* guaranteed to be preserved by `transmute`. /// /// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at /// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler @@ -1225,6 +1225,8 @@ extern "rust-intrinsic" { /// /// Transmuting pointers to integers in a `const` context is [undefined behavior][ub]. /// Any attempt to use the resulting value for integer operations will abort const-evaluation. + /// (And even outside `const`, such transmutation is touching on many unspecified aspects of the + /// Rust memory model and should be avoided. See below for alternatives.) /// /// Because `transmute` is a by-value operation, alignment of the *transmuted values /// themselves* is not a concern. As with any other function, the compiler already ensures