Skip to content

Commit 9e94ebf

Browse files
committed
Make sure the documentation compiles
1 parent 377bbfe commit 9e94ebf

File tree

1 file changed

+92
-77
lines changed

1 file changed

+92
-77
lines changed

src/libcore/intrinsics.rs

Lines changed: 92 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,12 @@ extern "rust-intrinsic" {
287287
///
288288
/// ```
289289
/// // 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();
292292
/// std::ptr::copy_nonoverlapping(&t as *const T as *const u8,
293293
/// &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);
296296
/// u
297297
/// }
298298
/// ```
@@ -314,76 +314,85 @@ extern "rust-intrinsic" {
314314
/// use std::mem;
315315
///
316316
/// // 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+
/// }
322323
///
323324
/// // 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+
/// }
329331
///
330332
/// // 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+
/// }
336339
///
337340
/// // 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+
/// }
348352
///
349353
/// // 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+
/// }
370377
///
371378
///
372379
/// // 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)
374390
/// -> (&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+
/// }
387396
/// }
388397
/// ```
389398
///
@@ -393,27 +402,33 @@ extern "rust-intrinsic" {
393402
///
394403
/// ```
395404
/// // 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+
/// }
397408
///
398409
///
399410
/// // 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+
/// }
409422
///
410423
///
411424
/// // 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+
/// }
417432
/// ```
418433
#[stable(feature = "rust1", since = "1.0.0")]
419434
pub fn transmute<T, U>(e: T) -> U;

0 commit comments

Comments
 (0)