diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 7e65f4ebdad..cabc5017f1d 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1207,13 +1207,26 @@ 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 - /// 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` 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 + /// 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 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]. + /// 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 @@ -1221,15 +1234,7 @@ extern "rust-intrinsic" { /// 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 /// diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs index 55b5ad314da..4159efe2a05 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"] diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs index 57248e3651b..f8fd93a7398 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"); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4777f9c96e6..116b1f16f7f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -51,19 +51,24 @@ 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![]; - 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))); + let mut inserted = FxHashSet::default(); + 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) + })); // 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/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 2aef978a072..0702b2b0b7c 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 \ 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 00000000000..234d55efb55 --- /dev/null +++ b/src/test/rustdoc/auxiliary/issue-99734-aux.rs @@ -0,0 +1,11 @@ +pub struct Option; +impl Option { + pub fn unwrap(self) {} +} + +/// [`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 00000000000..3208fea05b3 --- /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; +} 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 00000000000..b2f9b8b4657 --- /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 {}