Auto merge of #100100 - Dylan-DPC:rollup-llcaaq8, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #99371 (Remove synchronization from Windows `hashmap_random_keys`) - #99614 (do not claim that transmute is like memcpy) - #99738 (rustdoc: avoid inlining modules with duplicate names) - #99800 (Fix futex module imports on wasm+atomics) - #100079 (Replace `* -> vec` with `-> vec` in docs) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7308c22c6a
8 changed files with 84 additions and 83 deletions
|
@ -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
|
||||
///
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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<HashMapRng> = 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");
|
||||
}
|
||||
|
|
|
@ -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<Item> = 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(..)) {
|
||||
|
|
|
@ -816,7 +816,7 @@ function loadCss(cssFileName) {
|
|||
<code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, \
|
||||
and <code>const</code>.",
|
||||
"Search functions by type signature (e.g., <code>vec -> usize</code> or \
|
||||
<code>* -> vec</code>)",
|
||||
<code>-> vec</code>)",
|
||||
"Search multiple things at once by splitting your query with comma (e.g., \
|
||||
<code>str,u8</code> or <code>String,struct:Vec,test</code>)",
|
||||
"You can look for items with an exact name by putting double quotes around \
|
||||
|
|
11
src/test/rustdoc/auxiliary/issue-99734-aux.rs
Normal file
11
src/test/rustdoc/auxiliary/issue-99734-aux.rs
Normal file
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
14
src/test/rustdoc/issue-99734-multiple-mods-w-same-name.rs
Normal file
14
src/test/rustdoc/issue-99734-multiple-mods-w-same-name.rs
Normal file
|
@ -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 {}
|
Loading…
Add table
Reference in a new issue