@@ -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