Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 13 pull requests #35036

Closed
wants to merge 42 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
dbe6a09
First commit, fix ABI string docs in reference.md
ubsan Jun 24, 2016
1e899fd
Add vectorcall and fastcall explanation
ubsan Jun 25, 2016
3d03f75
Add more docs - mostly warnings - to std::mem::transmute
ubsan Jul 2, 2016
233b45f
Fix up some things which scott mentioned
ubsan Jul 2, 2016
6928bbb
Fix some other small nits
ubsan Jul 2, 2016
2413b52
More nits :P
ubsan Jul 2, 2016
377bbfe
Add a new alternative
ubsan Jul 2, 2016
9e94ebf
Make sure the documentation compiles
ubsan Jul 3, 2016
7ec44e6
Fix tests
ubsan Jul 5, 2016
8c7668a
Fix nits
ubsan Jul 5, 2016
15a49fe
Tone it down a little
ubsan Jul 5, 2016
451af79
Fix links, change example to english
ubsan Jul 5, 2016
297e396
Merge upstream/master: Fix a weird bug
ubsan Jul 6, 2016
7eabff5
Hopefully, it now works
ubsan Jul 6, 2016
b4ff6b0
document DoubleEndedIterator::next_back
durka Jul 9, 2016
97003e5
Switch around Examples and Alternatives
ubsan Jul 10, 2016
c0bee60
Make it nicer from @alexandermerritt
ubsan Jul 10, 2016
010e479
Merge guidelines from RFC 1567 into UX Guidelines.
Havvy Jul 17, 2016
b0de620
doc: add missing pause
tshepang Jul 16, 2016
24f8589
Fix nits
ubsan Jul 21, 2016
0d192c3
Update VecDeque documentation to specify direction of index 0 (#34920)
abhijeetbhagat Jul 22, 2016
ec33dab
Add HashMap Entry enums examples
GuillaumeGomez Jul 20, 2016
90bb8d4
Add DirBuilder doc examples
GuillaumeGomez Jul 22, 2016
6ebe6e8
Update underscore usage (#34903)
abhijeetbhagat Jul 23, 2016
ccc955c
Fix HashMap's values_mut example to use println!
rdwilliamson Jul 23, 2016
dad29a6
Add missing links
GuillaumeGomez Jul 24, 2016
1669963
Add DirEntry doc examples
GuillaumeGomez Jul 24, 2016
debb2ac
Improve Open doc
GuillaumeGomez Jul 24, 2016
96932cf
Remove no_stack_check tests (#34915)
abhijeetbhagat Jul 25, 2016
48fda61
Rollup merge of #34461 - ubsan:master, r=steveklabnik
steveklabnik Jul 25, 2016
ee771bf
Rollup merge of #34609 - ubsan:transmute_docs, r=steveklabnik
steveklabnik Jul 25, 2016
3f359d9
Rollup merge of #34732 - durka:patch-27, r=steveklabnik
steveklabnik Jul 25, 2016
31ffb92
Rollup merge of #34850 - tshepang:patch-3, r=steveklabnik
steveklabnik Jul 25, 2016
017517d
Rollup merge of #34894 - Havvy:patch-2, r=steveklabnik
steveklabnik Jul 25, 2016
637b63a
Rollup merge of #34935 - GuillaumeGomez:hash_map_doc, r=steveklabnik
steveklabnik Jul 25, 2016
7027fd9
Rollup merge of #34974 - abhijeetbhagat:patch-2, r=GuillaumeGomez
steveklabnik Jul 25, 2016
4d44503
Rollup merge of #34990 - abhijeetbhagat:patch-3, r=steveklabnik
steveklabnik Jul 25, 2016
8c810ef
Rollup merge of #34995 - GuillaumeGomez:dir_builder_doc, r=steveklabnik
steveklabnik Jul 25, 2016
c61da08
Rollup merge of #35001 - rdwilliamson:patch-1, r=alexcrichton
steveklabnik Jul 25, 2016
181d39d
Rollup merge of #35009 - GuillaumeGomez:dir_entry_doc, r=steveklabnik
steveklabnik Jul 25, 2016
dafbe97
Rollup merge of #35010 - GuillaumeGomez:file_doc, r=steveklabnik
steveklabnik Jul 25, 2016
e3e138b
Rollup merge of #35028 - abhijeetbhagat:patch-6, r=alexcrichton
steveklabnik Jul 25, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Make sure the documentation compiles
  • Loading branch information
ubsan committed Jul 3, 2016
commit 9e94ebf268385686299b6838b41e8e04a874259f
169 changes: 92 additions & 77 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,12 @@ extern "rust-intrinsic" {
///
/// ```
/// // assuming that T and U are the same size
/// fn transmute<T, U>(t: T) -> U {
/// let u: U = std::mem::uninitialized();
/// unsafe fn transmute<T, U>(t: T) -> U {
/// let u: U = mem::uninitialized();
/// std::ptr::copy_nonoverlapping(&t as *const T as *const u8,
/// &mut u as *mut U as *mut u8,
/// std::mem::size_of::<T>());
/// std::mem::forget(t);
/// mem::size_of::<T>());
/// mem::forget(t);
/// u
/// }
/// ```
Expand All @@ -314,76 +314,85 @@ extern "rust-intrinsic" {
/// use std::mem;
///
/// // turning a pointer into a usize
/// let ptr = &0;
/// let ptr_num_transmute = std::mem::transmute::<&i32, usize>(ptr);
/// // Use `as` casts instead
/// let ptr_num_cast = ptr as *const i32 as usize;
///
/// {
/// let ptr = &0;
/// let ptr_num_transmute = mem::transmute::<&i32, usize>(ptr);
/// // Use `as` casts instead
/// let ptr_num_cast = ptr as *const i32 as usize;
/// }
///
/// // Turning a *mut T into an &mut T
/// let ptr: *mut i32 = &mut 0;
/// let ref_transmuted = std::mem::transmute::<*mut i32, &mut i32>(ptr);
/// // Use reborrows
/// let ref_casted = &mut *ptr;
///
/// {
/// let ptr: *mut i32 = &mut 0;
/// let ref_transmuted = mem::transmute::<*mut i32, &mut i32>(ptr);
/// // Use reborrows
/// let ref_casted = &mut *ptr;
/// }
///
/// // Turning an &mut T into an &mut U
/// let ptr = &mut 0;
/// let val_transmuted = std::mem::transmute::<&mut i32, &mut u32>(ptr);
/// // Now let's put together `as` and reborrowing
/// let val_casts = &mut *(ptr as *mut i32 as *mut u32);
///
/// {
/// let ptr = &mut 0;
/// let val_transmuted = mem::transmute::<&mut i32, &mut u32>(ptr);
/// // Now let's put together `as` and reborrowing
/// let val_casts = &mut *(ptr as *mut i32 as *mut u32);
/// }
///
/// // Turning an `&str` into an `&[u8]`
/// // this is not a good way to do this.
/// let slice = unsafe { mem::transmute::<&str, &[u8]>("Rust") };
/// assert_eq!(slice, [82, 117, 115, 116]);
/// // You could use `str::as_bytes`
/// let slice = "Rust".as_bytes();
/// assert_eq!(slice, [82, 117, 115, 116]);
/// // Or, just use a byte string, if you have control over the string
/// // literal
/// assert_eq!(b"Rust", [82, 117, 116, 116]);
///
/// {
/// // this is not a good way to do this.
/// let slice = unsafe { mem::transmute::<&str, &[u8]>("Rust") };
/// assert_eq!(slice, [82, 117, 115, 116]);
/// // You could use `str::as_bytes`
/// let slice = "Rust".as_bytes();
/// assert_eq!(slice, [82, 117, 115, 116]);
/// // Or, just use a byte string, if you have control over the string
/// // literal
/// assert_eq!(b"Rust", [82, 117, 116, 116]);
/// }
///
/// // Turning a Vec<&T> into a Vec<Option<&T>>
/// let store = [0, 1, 2, 3];
/// let v_orig = store.iter().collect::<Vec<&i32>>();
/// // Using transmute; Undefined Behavior
/// let v_transmuted = mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
/// v_orig);
/// // The suggested, safe way
/// let v_collected = v_orig.into_iter()
/// .map(|r| Some(r))
/// .collect::<Vec<Option<&i32>>>();
/// // The no-copy, unsafe way, still using transmute, but not UB
/// let v_no_copy = Vec::from_raw_parts(v_orig.as_mut_ptr(),
/// v_orig.len(),
/// v_orig.capacity());
/// mem::forget(v_orig);
/// // This is equivalent to the original, but safer, and reuses the same
/// // Vec internals. Therefore the new inner type must have the exact same
/// // size, and the same or lesser alignment, as the old type.
/// // The same caveats exist for this method as transmute, for the original
/// // inner type (`&i32`) to the converted inner type (`Option<&i32>`), so
/// // read the nomicon page linked above.
/// {
/// let store = [0, 1, 2, 3];
/// let v_orig = store.iter().collect::<Vec<&i32>>();
/// // Using transmute; Undefined Behavior
/// let v_transmuted = mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
/// v_orig.clone());
/// // The suggested, safe way
/// let v_collected = v_orig.clone()
/// .into_iter()
/// .map(|r| Some(r))
/// .collect::<Vec<Option<&i32>>>();
/// // The no-copy, unsafe way, still using transmute, but not UB
/// // This is equivalent to the original, but safer, and reuses the
/// // same Vec internals. Therefore the new inner type must have the
/// // exact same size, and the same or lesser alignment, as the old
/// // type. The same caveats exist for this method as transmute, for
/// // the original inner type (`&i32`) to the converted inner type
/// // (`Option<&i32>`), so read the nomicon page linked above.
/// let v_no_copy = Vec::from_raw_parts(v_orig.as_mut_ptr(),
/// v_orig.len(),
/// v_orig.capacity());
/// mem::forget(v_orig);
/// }
///
///
/// // Copying an `&mut T` to reslice:
/// fn split_at_mut_transmute<T>(slice: &mut [T], index: usize)
/// {
/// fn split_at_mut_transmute<T>(slice: &mut [T], index: usize)
/// -> (&mut [T], &mut [T]) {
/// let len = slice.len();
/// assert!(index < len);
/// let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
/// (slice[0..index], slice2[index..len])
/// }
/// // Again, use `as` and reborrowing
/// fn split_at_mut_casts<T>(slice: &mut [T], index: usize)
/// -> (&mut [T], &mut [T]) {
/// let len = slice.len();
/// assert!(index < len);
/// let slice2 = std::mem::transmute::<&mut [T], &mut [T]>(slice);
/// (slice[0..index], slice2[index..len])
/// }
/// // Again, use `as` and reborrowing
/// fn split_at_mut_casts<T>(slice: &mut [T], index: usize)
/// -> (&mut [T], &mut [T]) {
/// let len = slice.len();
/// assert!(index < len);
/// let slice2 = &mut *(slice as *mut [T]); // actually typesafe!
/// (slice[0..index], slice2[index..len])
/// let len = slice.len();
/// assert!(index < len);
/// let slice2 = &mut *(slice as *mut [T]); // actually typesafe!
/// (slice[0..index], slice2[index..len])
/// }
/// }
/// ```
///
Expand All @@ -393,27 +402,33 @@ extern "rust-intrinsic" {
///
/// ```
/// // getting the bitpattern of a floating point type
/// let x = std::mem::transmute::<f32, u32>(0.0/0.0)
/// {
/// let x = mem::transmute::<f32, u32>(0.0/0.0)
/// }
///
///
/// // turning a pointer into a function pointer
/// // in file.c: `int foo(void) { ... }`
/// let handle: *mut libc::c_void = libc::dlopen(
/// b"file.so\0".as_ptr() as *const libc::c_char, libc::RTLD_LAZY);
/// let foo: *mut libc::c_void = libc::dlsym(
/// handle,
/// b"foo\0".as_ptr() as *const libc::c_char);
/// let foo = std::mem::transmute::<*mut libc::c_void,
/// extern fn() -> libc::c_int>(foo);
/// println!("{}", foo());
/// {
/// // in file.c: `int foo(void) { ... }`
/// let handle: *mut libc::c_void = libc::dlopen(
/// b"file.so\0".as_ptr() as *const libc::c_char, libc::RTLD_LAZY);
/// let foo: *mut libc::c_void = libc::dlsym(
/// handle,
/// b"foo\0".as_ptr() as *const libc::c_char);
/// let foo = mem::transmute::<*mut libc::c_void,
/// extern fn() -> libc::c_int>(foo);
/// println!("{}", foo());
/// }
///
///
/// // extending an invariant lifetime; this is advanced, very unsafe rust
/// struct T<'a>(&'a i32);
/// let value = 0;
/// let t = T::new(&value);
/// let ptr = &mut t;
/// let ptr_extended = std::mem::transmute::<&mut T, &mut T<'static>>(ptr);
/// {
/// struct T<'a>(&'a i32);
/// let value = 0;
/// let t = T::new(&value);
/// let ptr = &mut t;
/// let ptr_extended = mem::transmute::<&mut T, &mut T<'static>>(ptr);
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn transmute<T, U>(e: T) -> U;
Expand Down