Skip to content

Commit 58450c0

Browse files
authored
Auto merge of #36446 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 5 pull requests - Successful merges: #36357, #36380, #36389, #36397, #36402 - Failed merges:
2 parents 09905b1 + c05424f commit 58450c0

File tree

7 files changed

+306
-137
lines changed

7 files changed

+306
-137
lines changed

src/doc/book/references-and-borrowing.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ the thing `y` points at. You’ll notice that `x` had to be marked `mut` as well
152152
If it wasn’t, we couldn’t take a mutable borrow to an immutable value.
153153

154154
You'll also notice we added an asterisk (`*`) in front of `y`, making it `*y`,
155-
this is because `y` is a `&mut` reference. You'll need to use astrisks to
155+
this is because `y` is a `&mut` reference. You'll need to use asterisks to
156156
access the contents of a reference as well.
157157

158158
Otherwise, `&mut` references are like references. There _is_ a large

src/libcore/intrinsics.rs

+30-17
Original file line numberDiff line numberDiff line change
@@ -262,22 +262,25 @@ extern "rust-intrinsic" {
262262
/// Moves a value out of scope without running drop glue.
263263
pub fn forget<T>(_: T) -> ();
264264

265-
/// Reinterprets the bits of a value of one type as another type; both types
266-
/// must have the same size. Neither the original, nor the result, may be an
267-
/// [invalid value] (../../nomicon/meet-safe-and-unsafe.html).
265+
/// Reinterprets the bits of a value of one type as another type.
266+
///
267+
/// Both types must have the same size. Neither the original, nor the result,
268+
/// may be an [invalid value](../../nomicon/meet-safe-and-unsafe.html).
268269
///
269270
/// `transmute` is semantically equivalent to a bitwise move of one type
270-
/// into another. It copies the bits from the destination type into the
271-
/// source type, then forgets the original. It's equivalent to C's `memcpy`
272-
/// under the hood, just like `transmute_copy`.
271+
/// into another. It copies the bits from the source value into the
272+
/// destination value, then forgets the original. It's equivalent to C's
273+
/// `memcpy` under the hood, just like `transmute_copy`.
273274
///
274-
/// `transmute` is incredibly unsafe. There are a vast number of ways to
275-
/// cause undefined behavior with this function. `transmute` should be
275+
/// `transmute` is **incredibly** unsafe. There are a vast number of ways to
276+
/// cause [undefined behavior][ub] with this function. `transmute` should be
276277
/// the absolute last resort.
277278
///
278279
/// The [nomicon](../../nomicon/transmutes.html) has additional
279280
/// documentation.
280281
///
282+
/// [ub]: ../../reference.html#behavior-considered-undefined
283+
///
281284
/// # Examples
282285
///
283286
/// There are a few things that `transmute` is really useful for.
@@ -292,7 +295,8 @@ extern "rust-intrinsic" {
292295
/// assert_eq!(bitpattern, 0x3F800000);
293296
/// ```
294297
///
295-
/// Turning a pointer into a function pointer:
298+
/// Turning a pointer into a function pointer. This is *not* portable to
299+
/// machines where function pointers and data pointers have different sizes.
296300
///
297301
/// ```
298302
/// fn foo() -> i32 {
@@ -305,8 +309,8 @@ extern "rust-intrinsic" {
305309
/// assert_eq!(function(), 0);
306310
/// ```
307311
///
308-
/// Extending a lifetime, or shortening an invariant lifetime; this is
309-
/// advanced, very unsafe rust:
312+
/// Extending a lifetime, or shortening an invariant lifetime. This is
313+
/// advanced, very unsafe Rust!
310314
///
311315
/// ```
312316
/// struct R<'a>(&'a i32);
@@ -322,11 +326,9 @@ extern "rust-intrinsic" {
322326
///
323327
/// # Alternatives
324328
///
325-
/// However, many uses of `transmute` can be achieved through other means.
326-
/// `transmute` can transform any type into any other, with just the caveat
327-
/// that they're the same size, and often interesting results occur. Below
328-
/// are common applications of `transmute` which can be replaced with safe
329-
/// applications of `as`:
329+
/// Don't despair: many uses of `transmute` can be achieved through other means.
330+
/// Below are common applications of `transmute` which can be replaced with safer
331+
/// constructs.
330332
///
331333
/// Turning a pointer into a `usize`:
332334
///
@@ -335,6 +337,7 @@ extern "rust-intrinsic" {
335337
/// let ptr_num_transmute = unsafe {
336338
/// std::mem::transmute::<&i32, usize>(ptr)
337339
/// };
340+
///
338341
/// // Use an `as` cast instead
339342
/// let ptr_num_cast = ptr as *const i32 as usize;
340343
/// ```
@@ -346,6 +349,7 @@ extern "rust-intrinsic" {
346349
/// let ref_transmuted = unsafe {
347350
/// std::mem::transmute::<*mut i32, &mut i32>(ptr)
348351
/// };
352+
///
349353
/// // Use a reborrow instead
350354
/// let ref_casted = unsafe { &mut *ptr };
351355
/// ```
@@ -357,6 +361,7 @@ extern "rust-intrinsic" {
357361
/// let val_transmuted = unsafe {
358362
/// std::mem::transmute::<&mut i32, &mut u32>(ptr)
359363
/// };
364+
///
360365
/// // Now, put together `as` and reborrowing - note the chaining of `as`
361366
/// // `as` is not transitive
362367
/// let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
@@ -368,9 +373,11 @@ extern "rust-intrinsic" {
368373
/// // this is not a good way to do this.
369374
/// let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
370375
/// assert_eq!(slice, &[82, 117, 115, 116]);
376+
///
371377
/// // You could use `str::as_bytes`
372378
/// let slice = "Rust".as_bytes();
373379
/// assert_eq!(slice, &[82, 117, 115, 116]);
380+
///
374381
/// // Or, just use a byte string, if you have control over the string
375382
/// // literal
376383
/// assert_eq!(b"Rust", &[82, 117, 115, 116]);
@@ -381,18 +388,21 @@ extern "rust-intrinsic" {
381388
/// ```
382389
/// let store = [0, 1, 2, 3];
383390
/// let mut v_orig = store.iter().collect::<Vec<&i32>>();
391+
///
384392
/// // Using transmute: this is Undefined Behavior, and a bad idea.
385393
/// // However, it is no-copy.
386394
/// let v_transmuted = unsafe {
387395
/// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
388396
/// v_orig.clone())
389397
/// };
398+
///
390399
/// // This is the suggested, safe way.
391-
/// // It does copy the entire Vector, though, into a new array.
400+
/// // It does copy the entire vector, though, into a new array.
392401
/// let v_collected = v_orig.clone()
393402
/// .into_iter()
394403
/// .map(|r| Some(r))
395404
/// .collect::<Vec<Option<&i32>>>();
405+
///
396406
/// // The no-copy, unsafe way, still using transmute, but not UB.
397407
/// // This is equivalent to the original, but safer, and reuses the
398408
/// // same Vec internals. Therefore the new inner type must have the
@@ -412,6 +422,7 @@ extern "rust-intrinsic" {
412422
///
413423
/// ```
414424
/// use std::{slice, mem};
425+
///
415426
/// // There are multiple ways to do this; and there are multiple problems
416427
/// // with the following, transmute, way.
417428
/// fn split_at_mut_transmute<T>(slice: &mut [T], mid: usize)
@@ -426,6 +437,7 @@ extern "rust-intrinsic" {
426437
/// (&mut slice[0..mid], &mut slice2[mid..len])
427438
/// }
428439
/// }
440+
///
429441
/// // This gets rid of the typesafety problems; `&mut *` will *only* give
430442
/// // you an `&mut T` from an `&mut T` or `*mut T`.
431443
/// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
@@ -439,6 +451,7 @@ extern "rust-intrinsic" {
439451
/// (&mut slice[0..mid], &mut slice2[mid..len])
440452
/// }
441453
/// }
454+
///
442455
/// // This is how the standard library does it. This is the best method, if
443456
/// // you need to do something like this
444457
/// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)

0 commit comments

Comments
 (0)