@@ -286,12 +286,13 @@ extern "rust-intrinsic" {
286
286
/// `transmute::<T, U>(t)` is semantically equivalent to the following:
287
287
///
288
288
/// ```
289
+ /// use std::{mem, ptr};
289
290
/// // assuming that T and U are the same size
290
291
/// unsafe fn transmute<T, U>(t: T) -> U {
291
- /// let u: U = mem::uninitialized();
292
- /// std:: ptr::copy_nonoverlapping(&t as *const T as *const u8,
293
- /// &mut u as *mut U as *mut u8,
294
- /// mem::size_of::<T>());
292
+ /// let mut u: U = mem::uninitialized();
293
+ /// ptr::copy_nonoverlapping(&t as *const T as *const u8,
294
+ /// &mut u as *mut U as *mut u8,
295
+ /// mem::size_of::<T>());
295
296
/// mem::forget(t);
296
297
/// u
297
298
/// }
@@ -310,88 +311,115 @@ extern "rust-intrinsic" {
310
311
/// through other means. Some more or less common uses, and a better way,
311
312
/// are as follows:
312
313
///
314
+ /// Turning a pointer into a `usize`:
315
+ /// ```
316
+ /// let ptr = &0;
317
+ /// let ptr_num_transmute = mem::transmute::<&i32, usize>(ptr);
318
+ /// // Use `as` casts instead
319
+ /// let ptr_num_cast = ptr as *const i32 as usize;
313
320
/// ```
314
- /// use std::mem;
315
- ///
316
- /// // turning a pointer into a usize
317
- /// {
318
- /// let ptr = &0;
319
- /// let ptr_num_transmute = mem::transmute::<&i32, usize>(ptr);
320
- /// // Use `as` casts instead
321
- /// let ptr_num_cast = ptr as *const i32 as usize;
322
- /// }
323
- ///
324
- /// // Turning a *mut T into an &mut T
325
- /// {
326
- /// let ptr: *mut i32 = &mut 0;
327
- /// let ref_transmuted = mem::transmute::<*mut i32, &mut i32>(ptr);
328
- /// // Use reborrows
329
- /// let ref_casted = &mut *ptr;
330
- /// }
331
321
///
332
- /// // Turning an & mut T into an &mut U
333
- /// {
334
- /// let ptr = &mut 0;
335
- /// let val_transmuted = mem::transmute::<& mut i32, &mut u32 >(ptr);
336
- /// // Now let's put together `as` and reborrowing
337
- /// let val_casts = &mut *( ptr as *mut i32 as *mut u32) ;
338
- /// }
322
+ /// Turning a `* mut T` into an ` &mut T`:
323
+ /// ```
324
+ /// let ptr: *mut i32 = &mut 0;
325
+ /// let ref_transmuted = mem::transmute::<* mut i32, &mut i32 >(ptr);
326
+ /// // Use reborrows
327
+ /// let ref_casted = &mut *ptr;
328
+ /// ```
339
329
///
340
- /// // Turning an `&str` into an `&[u8]`
341
- /// {
342
- /// // this is not a good way to do this.
343
- /// let slice = unsafe { mem::transmute::<&str, &[u8]>("Rust") };
344
- /// assert_eq!(slice, [82, 117, 115, 116]);
345
- /// // You could use `str::as_bytes`
346
- /// let slice = "Rust".as_bytes();
347
- /// assert_eq!(slice, [82, 117, 115, 116]);
348
- /// // Or, just use a byte string, if you have control over the string
349
- /// // literal
350
- /// assert_eq!(b"Rust", [82, 117, 116, 116]);
351
- /// }
330
+ /// Turning an `&mut T` into an `&mut U`:
331
+ /// ```
332
+ /// let ptr = &mut 0;
333
+ /// let val_transmuted = mem::transmute::<&mut i32, &mut u32>(ptr);
334
+ /// // Now let's put together `as` and reborrowing
335
+ /// let val_casts = &mut *(ptr as *mut i32 as *mut u32);
336
+ /// ```
352
337
///
353
- /// // Turning a Vec<&T> into a Vec<Option<&T>>
354
- /// {
355
- /// let store = [0, 1, 2, 3];
356
- /// let v_orig = store.iter().collect::<Vec<&i32>>();
357
- /// // Using transmute; Undefined Behavior
358
- /// let v_transmuted = mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
359
- /// v_orig.clone());
360
- /// // The suggested, safe way
361
- /// let v_collected = v_orig.clone()
362
- /// .into_iter()
363
- /// .map(|r| Some(r))
364
- /// .collect::<Vec<Option<&i32>>>();
365
- /// // The no-copy, unsafe way, still using transmute, but not UB
366
- /// // This is equivalent to the original, but safer, and reuses the
367
- /// // same Vec internals. Therefore the new inner type must have the
368
- /// // exact same size, and the same or lesser alignment, as the old
369
- /// // type. The same caveats exist for this method as transmute, for
370
- /// // the original inner type (`&i32`) to the converted inner type
371
- /// // (`Option<&i32>`), so read the nomicon page linked above.
372
- /// let v_no_copy = Vec::from_raw_parts(v_orig.as_mut_ptr(),
373
- /// v_orig.len(),
374
- /// v_orig.capacity());
375
- /// mem::forget(v_orig);
376
- /// }
338
+ /// Turning an `&str` into an `&[u8]`:
339
+ /// ```
340
+ /// // this is not a good way to do this.
341
+ /// let slice = unsafe { mem::transmute::<&str, &[u8]>("Rust") };
342
+ /// assert_eq!(slice, [82, 117, 115, 116]);
343
+ /// // You could use `str::as_bytes`
344
+ /// let slice = "Rust".as_bytes();
345
+ /// assert_eq!(slice, [82, 117, 115, 116]);
346
+ /// // Or, just use a byte string, if you have control over the string
347
+ /// // literal
348
+ /// assert_eq!(b"Rust", [82, 117, 116, 116]);
349
+ /// ```
377
350
///
351
+ /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`:
352
+ /// ```
353
+ /// let store = [0, 1, 2, 3];
354
+ /// let v_orig = store.iter().collect::<Vec<&i32>>();
355
+ /// // Using transmute: this is Undefined Behavior, and a bad idea
356
+ /// // However, it is no-copy
357
+ /// let v_transmuted = mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
358
+ /// v_orig.clone());
359
+ /// // This is the suggested, safe way
360
+ /// // It does copy the entire Vector, though, into a new array
361
+ /// let v_collected = v_orig.clone()
362
+ /// .into_iter()
363
+ /// .map(|r| Some(r))
364
+ /// .collect::<Vec<Option<&i32>>>();
365
+ /// // The no-copy, unsafe way, still using transmute, but not UB
366
+ /// // This is equivalent to the original, but safer, and reuses the
367
+ /// // same Vec internals. Therefore the new inner type must have the
368
+ /// // exact same size, and the same or lesser alignment, as the old
369
+ /// // type. The same caveats exist for this method as transmute, for
370
+ /// // the original inner type (`&i32`) to the converted inner type
371
+ /// // (`Option<&i32>`), so read the nomicon page linked above.
372
+ /// let v_from_raw = Vec::from_raw_parts(v_orig.as_mut_ptr(),
373
+ /// v_orig.len(),
374
+ /// v_orig.capacity());
375
+ /// mem::forget(v_orig);
376
+ /// ```
378
377
///
379
- /// // Copying an `&mut T` to reslice:
380
- /// {
381
- /// fn split_at_mut_transmute<T>(slice: &mut [T], index: usize)
382
- /// -> (&mut [T], &mut [T]) {
383
- /// let len = slice.len();
384
- /// assert!(index < len);
378
+ /// Implemententing `split_at_mut`:
379
+ /// ```
380
+ /// use std::{slice, mem};
381
+ /// // There are multiple ways to do this; and there are multiple problems
382
+ /// // with the following, transmute, way
383
+ /// fn split_at_mut_transmute<T>(slice: &mut [T], index: usize)
384
+ /// -> (&mut [T], &mut [T]) {
385
+ /// let len = slice.len();
386
+ /// assert!(index < len);
387
+ /// unsafe {
385
388
/// let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
386
- /// (slice[0..index], slice2[index..len])
389
+ /// // first: transmute is not typesafe; all it checks is that T and
390
+ /// // U are of the same size. Second, right here, you have two
391
+ /// // mutable references pointing to the same memory
392
+ /// (&mut slice[0..index], &mut slice2[index..len])
387
393
/// }
388
- /// // Again, use `as` and reborrowing
389
- /// fn split_at_mut_casts<T>(slice: &mut [T], index: usize)
390
- /// -> (&mut [T], &mut [T]) {
391
- /// let len = slice.len();
392
- /// assert!(index < len);
393
- /// let slice2 = &mut *(slice as *mut [T]); // actually typesafe!
394
- /// (slice[0..index], slice2[index..len])
394
+ /// }
395
+ /// // This gets rid of the typesafety problems; `&mut *` will *only* give
396
+ /// // you an &mut T from an &mut T or *mut T
397
+ /// fn split_at_mut_casts<T>(slice: &mut [T], index: usize)
398
+ /// -> (&mut [T], &mut [T]) {
399
+ /// let len = slice.len();
400
+ /// assert!(index < len);
401
+ /// unsafe {
402
+ /// let slice2 = &mut *(slice as *mut [T]);
403
+ /// // however, you still have two mutable references pointing to
404
+ /// // the same memory
405
+ /// (&mut slice[0..index], &mut slice2[index..len])
406
+ /// }
407
+ /// }
408
+ /// // This is how the standard library does it. This is the best method, if
409
+ /// // you need to do something like this
410
+ /// fn split_at_stdlib<T>(slice: &mut [T], index: usize)
411
+ /// -> (&mut [T], &mut [T]) {
412
+ /// let len = self.len();
413
+ /// let ptr = self.as_mut_ptr();
414
+ /// unsafe {
415
+ /// assert!(mid <= len);
416
+ /// // This now has three mutable references pointing at the same
417
+ /// // memory. `slice`, the rvalue ret.0, and the rvalue ret.1.
418
+ /// // However, `slice` is never used after `let ptr = ...`, and so
419
+ /// // one can treat it as "dead", and therefore, you only have two
420
+ /// // real mutable slices.
421
+ /// (slice::from_raw_parts_mut(ptr, mid),
422
+ /// slice::from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
395
423
/// }
396
424
/// }
397
425
/// ```
@@ -400,39 +428,49 @@ extern "rust-intrinsic" {
400
428
///
401
429
/// There are valid uses of transmute, though they are few and far between.
402
430
///
431
+ /// Getting the bitpattern of a floating point type:
432
+ /// ```
433
+ /// let bitpattern = std::mem::transmute::<f32, u32>(1.0);
434
+ /// assert_eq!(bitpattern, 0x3F800000);
403
435
/// ```
404
- /// // getting the bitpattern of a floating point type
405
- /// {
406
- /// let x = mem::transmute::<f32, u32>(0.0/0.0)
436
+ ///
437
+ /// Turning a pointer into a function pointer (this isn't guaranteed to
438
+ /// work in Rust, although, for example, Linux does make this guarantee):
439
+ /// ```
440
+ /// fn foo() -> i32 {
441
+ /// 0
407
442
/// }
443
+ /// let pointer = foo as *const ();
444
+ /// let function = std::mem::transmute::<*const (), fn() -> i32>(pointer)
445
+ /// assert_eq!(function(), 0);
446
+ /// ```
408
447
///
448
+ /// Extending a lifetime, or shortening an invariant an invariant lifetime;
449
+ /// this is advanced, very unsafe rust:
450
+ /// ```
451
+ /// use std::mem;
409
452
///
410
- /// // turning a pointer into a function pointer
411
- /// {
412
- /// // in file.c: `int foo(void) { ... }`
413
- /// let handle: *mut libc::c_void = libc::dlopen(
414
- /// b"file.so\0".as_ptr() as *const libc::c_char, libc::RTLD_LAZY);
415
- /// let foo: *mut libc::c_void = libc::dlsym(
416
- /// handle,
417
- /// b"foo\0".as_ptr() as *const libc::c_char);
418
- /// let foo = mem::transmute::<*mut libc::c_void,
419
- /// extern fn() -> libc::c_int>(foo);
420
- /// println!("{}", foo());
453
+ /// struct R<'a>(&'a i32);
454
+ /// unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
455
+ /// mem::transmute::<R<'b>, R<'static>>(ptr);
421
456
/// }
422
457
///
423
- ///
424
- /// // extending an invariant lifetime; this is advanced, very unsafe rust
425
- /// {
426
- /// struct T<'a>(&'a i32);
427
- /// let value = 0;
428
- /// let t = T::new(&value);
429
- /// let ptr = &mut t;
430
- /// let ptr_extended = mem::transmute::<&mut T, &mut T<'static>>(ptr);
458
+ /// unsafe fn shorten_invariant<'b, 'c>(r: &'b mut R<'static>)
459
+ /// -> &'b R<'c> {
460
+ /// let ref_to_original =
461
+ /// mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(
462
+ /// ref_to_extended);
431
463
/// }
432
464
/// ```
433
465
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
434
466
pub fn transmute < T , U > ( e : T ) -> U ;
435
467
468
+ /// Gives the address for the return value of the enclosing function.
469
+ ///
470
+ /// Using this intrinsic in a function that does not use an out pointer
471
+ /// will trigger a compiler error.
472
+ pub fn return_address ( ) -> * const u8 ;
473
+
436
474
/// Returns `true` if the actual type given as `T` requires drop
437
475
/// glue; returns `false` if the actual type provided for `T`
438
476
/// implements `Copy`.
0 commit comments