@@ -287,12 +287,12 @@ extern "rust-intrinsic" {
287
287
///
288
288
/// ```
289
289
/// // assuming that T and U are the same size
290
- /// fn transmute<T, U>(t: T) -> U {
291
- /// let u: U = std:: mem::uninitialized();
290
+ /// unsafe fn transmute<T, U>(t: T) -> U {
291
+ /// let u: U = mem::uninitialized();
292
292
/// std::ptr::copy_nonoverlapping(&t as *const T as *const u8,
293
293
/// &mut u as *mut U as *mut u8,
294
- /// std:: mem::size_of::<T>());
295
- /// std:: mem::forget(t);
294
+ /// mem::size_of::<T>());
295
+ /// mem::forget(t);
296
296
/// u
297
297
/// }
298
298
/// ```
@@ -314,76 +314,85 @@ extern "rust-intrinsic" {
314
314
/// use std::mem;
315
315
///
316
316
/// // turning a pointer into a usize
317
- /// let ptr = &0;
318
- /// let ptr_num_transmute = std::mem::transmute::<&i32, usize>(ptr);
319
- /// // Use `as` casts instead
320
- /// let ptr_num_cast = ptr as *const i32 as usize;
321
- ///
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
+ /// }
322
323
///
323
324
/// // Turning a *mut T into an &mut T
324
- /// let ptr: *mut i32 = &mut 0;
325
- /// let ref_transmuted = std::mem::transmute::<*mut i32, &mut i32>(ptr);
326
- /// // Use reborrows
327
- /// let ref_casted = &mut *ptr;
328
- ///
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
+ /// }
329
331
///
330
332
/// // Turning an &mut T into an &mut U
331
- /// let ptr = &mut 0;
332
- /// let val_transmuted = std::mem::transmute::<&mut i32, &mut u32>(ptr);
333
- /// // Now let's put together `as` and reborrowing
334
- /// let val_casts = &mut *(ptr as *mut i32 as *mut u32);
335
- ///
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
+ /// }
336
339
///
337
340
/// // Turning an `&str` into an `&[u8]`
338
- /// // this is not a good way to do this.
339
- /// let slice = unsafe { mem::transmute::<&str, &[u8]>("Rust") };
340
- /// assert_eq!(slice, [82, 117, 115, 116]);
341
- /// // You could use `str::as_bytes`
342
- /// let slice = "Rust".as_bytes();
343
- /// assert_eq!(slice, [82, 117, 115, 116]);
344
- /// // Or, just use a byte string, if you have control over the string
345
- /// // literal
346
- /// assert_eq!(b"Rust", [82, 117, 116, 116]);
347
- ///
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
+ /// }
348
352
///
349
353
/// // Turning a Vec<&T> into a Vec<Option<&T>>
350
- /// let store = [0, 1, 2, 3];
351
- /// let v_orig = store.iter().collect::<Vec<&i32>>();
352
- /// // Using transmute; Undefined Behavior
353
- /// let v_transmuted = mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
354
- /// v_orig);
355
- /// // The suggested, safe way
356
- /// let v_collected = v_orig.into_iter()
357
- /// .map(|r| Some(r))
358
- /// .collect::<Vec<Option<&i32>>>();
359
- /// // The no-copy, unsafe way, still using transmute, but not UB
360
- /// let v_no_copy = Vec::from_raw_parts(v_orig.as_mut_ptr(),
361
- /// v_orig.len(),
362
- /// v_orig.capacity());
363
- /// mem::forget(v_orig);
364
- /// // This is equivalent to the original, but safer, and reuses the same
365
- /// // Vec internals. Therefore the new inner type must have the exact same
366
- /// // size, and the same or lesser alignment, as the old type.
367
- /// // The same caveats exist for this method as transmute, for the original
368
- /// // inner type (`&i32`) to the converted inner type (`Option<&i32>`), so
369
- /// // read the nomicon page linked above.
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
+ /// }
370
377
///
371
378
///
372
379
/// // Copying an `&mut T` to reslice:
373
- /// fn split_at_mut_transmute<T>(slice: &mut [T], index: usize)
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);
385
+ /// let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
386
+ /// (slice[0..index], slice2[index..len])
387
+ /// }
388
+ /// // Again, use `as` and reborrowing
389
+ /// fn split_at_mut_casts<T>(slice: &mut [T], index: usize)
374
390
/// -> (&mut [T], &mut [T]) {
375
- /// let len = slice.len();
376
- /// assert!(index < len);
377
- /// let slice2 = std::mem::transmute::<&mut [T], &mut [T]>(slice);
378
- /// (slice[0..index], slice2[index..len])
379
- /// }
380
- /// // Again, use `as` and reborrowing
381
- /// fn split_at_mut_casts<T>(slice: &mut [T], index: usize)
382
- /// -> (&mut [T], &mut [T]) {
383
- /// let len = slice.len();
384
- /// assert!(index < len);
385
- /// let slice2 = &mut *(slice as *mut [T]); // actually typesafe!
386
- /// (slice[0..index], slice2[index..len])
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])
395
+ /// }
387
396
/// }
388
397
/// ```
389
398
///
@@ -393,27 +402,33 @@ extern "rust-intrinsic" {
393
402
///
394
403
/// ```
395
404
/// // getting the bitpattern of a floating point type
396
- /// let x = std::mem::transmute::<f32, u32>(0.0/0.0)
405
+ /// {
406
+ /// let x = mem::transmute::<f32, u32>(0.0/0.0)
407
+ /// }
397
408
///
398
409
///
399
410
/// // turning a pointer into a function pointer
400
- /// // in file.c: `int foo(void) { ... }`
401
- /// let handle: *mut libc::c_void = libc::dlopen(
402
- /// b"file.so\0".as_ptr() as *const libc::c_char, libc::RTLD_LAZY);
403
- /// let foo: *mut libc::c_void = libc::dlsym(
404
- /// handle,
405
- /// b"foo\0".as_ptr() as *const libc::c_char);
406
- /// let foo = std::mem::transmute::<*mut libc::c_void,
407
- /// extern fn() -> libc::c_int>(foo);
408
- /// println!("{}", foo());
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());
421
+ /// }
409
422
///
410
423
///
411
424
/// // extending an invariant lifetime; this is advanced, very unsafe rust
412
- /// struct T<'a>(&'a i32);
413
- /// let value = 0;
414
- /// let t = T::new(&value);
415
- /// let ptr = &mut t;
416
- /// let ptr_extended = std::mem::transmute::<&mut T, &mut T<'static>>(ptr);
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);
431
+ /// }
417
432
/// ```
418
433
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
419
434
pub fn transmute < T , U > ( e : T ) -> U ;
0 commit comments