Skip to content

Commit 7eabff5

Browse files
committed
Hopefully, it now works
1 parent 297e396 commit 7eabff5

File tree

1 file changed

+42
-31
lines changed

1 file changed

+42
-31
lines changed

src/libcore/intrinsics.rs

+42-31
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,9 @@ extern "rust-intrinsic" {
304304
///
305305
/// ```
306306
/// let ptr = &0;
307-
/// let ptr_num_transmute = mem::transmute::<&i32, usize>(ptr);
307+
/// let ptr_num_transmute = unsafe {
308+
/// std::mem::transmute::<&i32, usize>(ptr)
309+
/// };
308310
/// // Use an `as` cast instead
309311
/// let ptr_num_cast = ptr as *const i32 as usize;
310312
/// ```
@@ -313,43 +315,49 @@ extern "rust-intrinsic" {
313315
///
314316
/// ```
315317
/// let ptr: *mut i32 = &mut 0;
316-
/// let ref_transmuted = mem::transmute::<*mut i32, &mut i32>(ptr);
318+
/// let ref_transmuted = unsafe {
319+
/// std::mem::transmute::<*mut i32, &mut i32>(ptr)
320+
/// };
317321
/// // Use a reborrow instead
318-
/// let ref_casted = &mut *ptr;
322+
/// let ref_casted = unsafe { &mut *ptr };
319323
/// ```
320324
///
321325
/// Turning an `&mut T` into an `&mut U`:
322326
///
323327
/// ```
324328
/// let ptr = &mut 0;
325-
/// let val_transmuted = mem::transmute::<&mut i32, &mut u32>(ptr);
329+
/// let val_transmuted = unsafe {
330+
/// std::mem::transmute::<&mut i32, &mut u32>(ptr)
331+
/// };
326332
/// // Now, put together `as` and reborrowing
327-
/// let val_casts = &mut *(ptr as *mut i32 as *mut u32);
333+
/// let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
328334
/// ```
329335
///
330336
/// Turning an `&str` into an `&[u8]`:
331337
///
332338
/// ```
333339
/// // this is not a good way to do this.
334-
/// let slice = unsafe { mem::transmute::<&str, &[u8]>("Rust") };
340+
/// let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
335341
/// assert_eq!(slice, &[82, 117, 115, 116]);
336342
/// // You could use `str::as_bytes`
337343
/// let slice = "Rust".as_bytes();
338344
/// assert_eq!(slice, &[82, 117, 115, 116]);
339345
/// // Or, just use a byte string, if you have control over the string
340346
/// // literal
341-
/// assert_eq!(b"Rust", &[82, 117, 116, 116]);
347+
/// assert_eq!(b"Rust", &[82, 117, 115, 116]);
342348
/// ```
343349
///
344350
/// Turning a `Vec<&T>` into a `Vec<Option<&T>>`:
345351
///
346352
/// ```
347353
/// let store = [0, 1, 2, 3];
348-
/// let v_orig = store.iter().collect::<Vec<&i32>>();
354+
/// let mut v_orig = store.iter().collect::<Vec<&i32>>();
349355
/// // Using transmute: this is Undefined Behavior, and a bad idea.
350356
/// // However, it is no-copy.
351-
/// let v_transmuted = mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
352-
/// v_orig.clone());
357+
/// let v_transmuted = unsafe {
358+
/// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
359+
/// v_orig.clone())
360+
/// };
353361
/// // This is the suggested, safe way.
354362
/// // It does copy the entire Vector, though, into a new array.
355363
/// let v_collected = v_orig.clone()
@@ -363,10 +371,12 @@ extern "rust-intrinsic" {
363371
/// // type. The same caveats exist for this method as transmute, for
364372
/// // the original inner type (`&i32`) to the converted inner type
365373
/// // (`Option<&i32>`), so read the nomicon pages linked above.
366-
/// let v_from_raw = Vec::from_raw_parts(v_orig.as_mut_ptr(),
367-
/// v_orig.len(),
368-
/// v_orig.capacity());
369-
/// mem::forget(v_orig);
374+
/// let v_from_raw = unsafe {
375+
/// Vec::from_raw_parts(v_orig.as_mut_ptr(),
376+
/// v_orig.len(),
377+
/// v_orig.capacity())
378+
/// };
379+
/// std::mem::forget(v_orig);
370380
/// ```
371381
///
372382
/// Implementing `split_at_mut`:
@@ -375,39 +385,39 @@ extern "rust-intrinsic" {
375385
/// use std::{slice, mem};
376386
/// // There are multiple ways to do this; and there are multiple problems
377387
/// // with the following, transmute, way.
378-
/// fn split_at_mut_transmute<T>(slice: &mut [T], index: usize)
388+
/// fn split_at_mut_transmute<T>(slice: &mut [T], mid: usize)
379389
/// -> (&mut [T], &mut [T]) {
380390
/// let len = slice.len();
381-
/// assert!(index < len);
391+
/// assert!(mid <= len);
382392
/// unsafe {
383393
/// let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
384394
/// // first: transmute is not typesafe; all it checks is that T and
385395
/// // U are of the same size. Second, right here, you have two
386396
/// // mutable references pointing to the same memory.
387-
/// (&mut slice[0..index], &mut slice2[index..len])
397+
/// (&mut slice[0..mid], &mut slice2[mid..len])
388398
/// }
389399
/// }
390400
/// // This gets rid of the typesafety problems; `&mut *` will *only* give
391401
/// // you an `&mut T` from an `&mut T` or `*mut T`.
392-
/// fn split_at_mut_casts<T>(slice: &mut [T], index: usize)
402+
/// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
393403
/// -> (&mut [T], &mut [T]) {
394404
/// let len = slice.len();
395-
/// assert!(index < len);
405+
/// assert!(mid <= len);
396406
/// unsafe {
397407
/// let slice2 = &mut *(slice as *mut [T]);
398408
/// // however, you still have two mutable references pointing to
399409
/// // the same memory.
400-
/// (&mut slice[0..index], &mut slice2[index..len])
410+
/// (&mut slice[0..mid], &mut slice2[mid..len])
401411
/// }
402412
/// }
403413
/// // This is how the standard library does it. This is the best method, if
404414
/// // you need to do something like this
405-
/// fn split_at_stdlib<T>(slice: &mut [T], index: usize)
415+
/// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)
406416
/// -> (&mut [T], &mut [T]) {
407-
/// let len = self.len();
408-
/// let ptr = self.as_mut_ptr();
417+
/// let len = slice.len();
418+
/// assert!(mid <= len);
409419
/// unsafe {
410-
/// assert!(mid <= len);
420+
/// let ptr = slice.as_mut_ptr();
411421
/// // This now has three mutable references pointing at the same
412422
/// // memory. `slice`, the rvalue ret.0, and the rvalue ret.1.
413423
/// // `slice` is never used after `let ptr = ...`, and so one can
@@ -426,7 +436,9 @@ extern "rust-intrinsic" {
426436
/// Getting the bitpattern of a floating point type:
427437
///
428438
/// ```
429-
/// let bitpattern = std::mem::transmute::<f32, u32>(1.0);
439+
/// let bitpattern = unsafe {
440+
/// std::mem::transmute::<f32, u32>(1.0)
441+
/// };
430442
/// assert_eq!(bitpattern, 0x3F800000);
431443
/// ```
432444
///
@@ -438,25 +450,24 @@ extern "rust-intrinsic" {
438450
/// 0
439451
/// }
440452
/// let pointer = foo as *const ();
441-
/// let function = std::mem::transmute::<*const (), fn() -> i32>(pointer)
453+
/// let function = unsafe {
454+
/// std::mem::transmute::<*const (), fn() -> i32>(pointer)
455+
/// };
442456
/// assert_eq!(function(), 0);
443457
/// ```
444458
///
445459
/// Extending a lifetime, or shortening an invariant lifetime; this is
446460
/// advanced, very unsafe rust:
447461
///
448462
/// ```
449-
/// use std::mem;
450-
///
451463
/// struct R<'a>(&'a i32);
452464
/// unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
453-
/// mem::transmute::<R<'b>, R<'static>>(ptr);
465+
/// std::mem::transmute::<R<'b>, R<'static>>(r)
454466
/// }
455467
///
456468
/// unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>)
457469
/// -> &'b mut R<'c> {
458-
/// mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(
459-
/// ref_to_extended)
470+
/// std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
460471
/// }
461472
/// ```
462473
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)