@@ -262,22 +262,25 @@ extern "rust-intrinsic" {
262
262
/// Moves a value out of scope without running drop glue.
263
263
pub fn forget < T > ( _: T ) -> ( ) ;
264
264
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).
268
269
///
269
270
/// `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`.
273
274
///
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
276
277
/// the absolute last resort.
277
278
///
278
279
/// The [nomicon](../../nomicon/transmutes.html) has additional
279
280
/// documentation.
280
281
///
282
+ /// [ub]: ../../reference.html#behavior-considered-undefined
283
+ ///
281
284
/// # Examples
282
285
///
283
286
/// There are a few things that `transmute` is really useful for.
@@ -292,7 +295,8 @@ extern "rust-intrinsic" {
292
295
/// assert_eq!(bitpattern, 0x3F800000);
293
296
/// ```
294
297
///
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.
296
300
///
297
301
/// ```
298
302
/// fn foo() -> i32 {
@@ -305,8 +309,8 @@ extern "rust-intrinsic" {
305
309
/// assert_eq!(function(), 0);
306
310
/// ```
307
311
///
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!
310
314
///
311
315
/// ```
312
316
/// struct R<'a>(&'a i32);
@@ -322,11 +326,9 @@ extern "rust-intrinsic" {
322
326
///
323
327
/// # Alternatives
324
328
///
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.
330
332
///
331
333
/// Turning a pointer into a `usize`:
332
334
///
@@ -335,6 +337,7 @@ extern "rust-intrinsic" {
335
337
/// let ptr_num_transmute = unsafe {
336
338
/// std::mem::transmute::<&i32, usize>(ptr)
337
339
/// };
340
+ ///
338
341
/// // Use an `as` cast instead
339
342
/// let ptr_num_cast = ptr as *const i32 as usize;
340
343
/// ```
@@ -346,6 +349,7 @@ extern "rust-intrinsic" {
346
349
/// let ref_transmuted = unsafe {
347
350
/// std::mem::transmute::<*mut i32, &mut i32>(ptr)
348
351
/// };
352
+ ///
349
353
/// // Use a reborrow instead
350
354
/// let ref_casted = unsafe { &mut *ptr };
351
355
/// ```
@@ -357,6 +361,7 @@ extern "rust-intrinsic" {
357
361
/// let val_transmuted = unsafe {
358
362
/// std::mem::transmute::<&mut i32, &mut u32>(ptr)
359
363
/// };
364
+ ///
360
365
/// // Now, put together `as` and reborrowing - note the chaining of `as`
361
366
/// // `as` is not transitive
362
367
/// let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
@@ -368,9 +373,11 @@ extern "rust-intrinsic" {
368
373
/// // this is not a good way to do this.
369
374
/// let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
370
375
/// assert_eq!(slice, &[82, 117, 115, 116]);
376
+ ///
371
377
/// // You could use `str::as_bytes`
372
378
/// let slice = "Rust".as_bytes();
373
379
/// assert_eq!(slice, &[82, 117, 115, 116]);
380
+ ///
374
381
/// // Or, just use a byte string, if you have control over the string
375
382
/// // literal
376
383
/// assert_eq!(b"Rust", &[82, 117, 115, 116]);
@@ -381,18 +388,21 @@ extern "rust-intrinsic" {
381
388
/// ```
382
389
/// let store = [0, 1, 2, 3];
383
390
/// let mut v_orig = store.iter().collect::<Vec<&i32>>();
391
+ ///
384
392
/// // Using transmute: this is Undefined Behavior, and a bad idea.
385
393
/// // However, it is no-copy.
386
394
/// let v_transmuted = unsafe {
387
395
/// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
388
396
/// v_orig.clone())
389
397
/// };
398
+ ///
390
399
/// // 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.
392
401
/// let v_collected = v_orig.clone()
393
402
/// .into_iter()
394
403
/// .map(|r| Some(r))
395
404
/// .collect::<Vec<Option<&i32>>>();
405
+ ///
396
406
/// // The no-copy, unsafe way, still using transmute, but not UB.
397
407
/// // This is equivalent to the original, but safer, and reuses the
398
408
/// // same Vec internals. Therefore the new inner type must have the
@@ -412,6 +422,7 @@ extern "rust-intrinsic" {
412
422
///
413
423
/// ```
414
424
/// use std::{slice, mem};
425
+ ///
415
426
/// // There are multiple ways to do this; and there are multiple problems
416
427
/// // with the following, transmute, way.
417
428
/// fn split_at_mut_transmute<T>(slice: &mut [T], mid: usize)
@@ -426,6 +437,7 @@ extern "rust-intrinsic" {
426
437
/// (&mut slice[0..mid], &mut slice2[mid..len])
427
438
/// }
428
439
/// }
440
+ ///
429
441
/// // This gets rid of the typesafety problems; `&mut *` will *only* give
430
442
/// // you an `&mut T` from an `&mut T` or `*mut T`.
431
443
/// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
@@ -439,6 +451,7 @@ extern "rust-intrinsic" {
439
451
/// (&mut slice[0..mid], &mut slice2[mid..len])
440
452
/// }
441
453
/// }
454
+ ///
442
455
/// // This is how the standard library does it. This is the best method, if
443
456
/// // you need to do something like this
444
457
/// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)
0 commit comments