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 7 pull requests #34819

Merged
merged 14 commits into from
Jul 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
58 changes: 56 additions & 2 deletions src/doc/book/ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,62 @@ pub fn uncompress(src: &[u8]) -> Option<Vec<u8>> {
}
```

For reference, the examples used here are also available as a [library on
GitHub](https://github.com/thestinger/rust-snappy).
Then, we can add some tests to show how to use them.

```rust
# #![feature(libc)]
# extern crate libc;
# use libc::{c_int, size_t};
# unsafe fn snappy_compress(input: *const u8,
# input_length: size_t,
# compressed: *mut u8,
# compressed_length: *mut size_t)
# -> c_int { 0 }
# unsafe fn snappy_uncompress(compressed: *const u8,
# compressed_length: size_t,
# uncompressed: *mut u8,
# uncompressed_length: *mut size_t)
# -> c_int { 0 }
# unsafe fn snappy_max_compressed_length(source_length: size_t) -> size_t { 0 }
# unsafe fn snappy_uncompressed_length(compressed: *const u8,
# compressed_length: size_t,
# result: *mut size_t)
# -> c_int { 0 }
# unsafe fn snappy_validate_compressed_buffer(compressed: *const u8,
# compressed_length: size_t)
# -> c_int { 0 }
# fn main() { }

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn valid() {
let d = vec![0xde, 0xad, 0xd0, 0x0d];
let c: &[u8] = &compress(&d);
assert!(validate_compressed_buffer(c));
assert!(uncompress(c) == Some(d));
}

#[test]
fn invalid() {
let d = vec![0, 0, 0, 0];
assert!(!validate_compressed_buffer(&d));
assert!(uncompress(&d).is_none());
}

#[test]
fn empty() {
let d = vec![];
assert!(!validate_compressed_buffer(&d));
assert!(uncompress(&d).is_none());
let c = compress(&d);
assert!(validate_compressed_buffer(&c));
assert!(uncompress(&c) == Some(d));
}
}
```

# Destructors

Expand Down
89 changes: 46 additions & 43 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,11 @@

//! Threadsafe reference-counted boxes (the `Arc<T>` type).
//!
//! The `Arc<T>` type provides shared ownership of an immutable value.
//! Destruction is deterministic, and will occur as soon as the last owner is
//! gone. It is marked as `Send` because it uses atomic reference counting.
//!
//! If you do not need thread-safety, and just need shared ownership, consider
//! the [`Rc<T>` type](../rc/struct.Rc.html). It is the same as `Arc<T>`, but
//! does not use atomics, making it both thread-unsafe as well as significantly
//! faster when updating the reference count.
//!
//! The `downgrade` method can be used to create a non-owning `Weak<T>` pointer
//! to the box. A `Weak<T>` pointer can be upgraded to an `Arc<T>` pointer, but
//! will return `None` if the value has already been dropped.
//!
//! For example, a tree with parent pointers can be represented by putting the
//! nodes behind strong `Arc<T>` pointers, and then storing the parent pointers
//! as `Weak<T>` pointers.
//! The `Arc<T>` type provides shared ownership of an immutable value through
//! atomic reference counting.
//!
//! `Weak<T>` is a weak reference to the `Arc<T>` box, and it is created by
//! the `downgrade` method.
//! # Examples
//!
//! Sharing some immutable data between threads:
Expand All @@ -47,27 +35,6 @@
//! });
//! }
//! ```
//!
//! Sharing mutable data safely between threads with a `Mutex`:
//!
//! ```no_run
//! use std::sync::{Arc, Mutex};
//! use std::thread;
//!
//! let five = Arc::new(Mutex::new(5));
//!
//! for _ in 0..10 {
//! let five = five.clone();
//!
//! thread::spawn(move || {
//! let mut number = five.lock().unwrap();
//!
//! *number += 1;
//!
//! println!("{}", *number); // prints 6
//! });
//! }
//! ```

use boxed::Box;

Expand All @@ -92,15 +59,19 @@ use heap::deallocate;
const MAX_REFCOUNT: usize = (isize::MAX) as usize;

/// An atomically reference counted wrapper for shared state.
/// Destruction is deterministic, and will occur as soon as the last owner is
/// gone. It is marked as `Send` because it uses atomic reference counting.
///
/// # Examples
/// If you do not need thread-safety, and just need shared ownership, consider
/// the [`Rc<T>` type](../rc/struct.Rc.html). It is the same as `Arc<T>`, but
/// does not use atomics, making it both thread-unsafe as well as significantly
/// faster when updating the reference count.
///
/// In this example, a large vector is shared between several threads.
/// With simple pipes, without `Arc`, a copy would have to be made for each
/// thread.
/// # Examples
///
/// When you clone an `Arc<T>`, it will create another pointer to the data and
/// increase the reference counter.
/// In this example, a large vector of data will be shared by several threads. First we
/// wrap it with a `Arc::new` and then clone the `Arc<T>` reference for every thread (which will
/// increase the reference count atomically).
///
/// ```
/// use std::sync::Arc;
Expand All @@ -111,6 +82,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
/// let shared_numbers = Arc::new(numbers);
///
/// for _ in 0..10 {
/// // prepare a copy of reference here and it will be moved to the thread
/// let child_numbers = shared_numbers.clone();
///
/// thread::spawn(move || {
Expand All @@ -121,6 +93,29 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
/// }
/// }
/// ```
/// You can also share mutable data between threads safely
/// by putting it inside `Mutex` and then share `Mutex` immutably
/// with `Arc<T>` as shown below.
///
/// ```
/// use std::sync::{Arc, Mutex};
/// use std::thread;
///
/// let five = Arc::new(Mutex::new(5));
///
/// for _ in 0..10 {
/// let five = five.clone();
///
/// thread::spawn(move || {
/// let mut number = five.lock().unwrap();
///
/// *number += 1;
///
/// println!("{}", *number); // prints 6
/// });
/// }
/// ```

#[unsafe_no_drop_flag]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Arc<T: ?Sized> {
Expand All @@ -139,6 +134,14 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
///
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
/// used to break cycles between `Arc` pointers.
///
/// A `Weak<T>` pointer can be upgraded to an `Arc<T>` pointer, but
/// will return `None` if the value has already been dropped.
///
/// For example, a tree with parent pointers can be represented by putting the
/// nodes behind strong `Arc<T>` pointers, and then storing the parent pointers
/// as `Weak<T>` pointers.

#[unsafe_no_drop_flag]
#[stable(feature = "arc_weak", since = "1.4.0")]
pub struct Weak<T: ?Sized> {
Expand Down
11 changes: 11 additions & 0 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,12 @@ impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
////////////////////////////////////////////////////////////////////////////////

/// An iterator that moves out of a vector.
///
/// This `struct` is created by the `into_iter` method on [`Vec`][`Vec`] (provided
/// by the [`IntoIterator`] trait).
///
/// [`Vec`]: struct.Vec.html
/// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> {
_buf: RawVec<T>,
Expand Down Expand Up @@ -1710,6 +1716,11 @@ impl<T> Drop for IntoIter<T> {
}

/// A draining iterator for `Vec<T>`.
///
/// This `struct` is created by the [`drain`] method on [`Vec`].
///
/// [`drain`]: struct.Vec.html#method.drain
/// [`Vec`]: struct.Vec.html
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, T: 'a> {
/// Index of tail to preserve
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ macro_rules! write {
}

/// Use the `format!` syntax to write data into a buffer, appending a newline.
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`)
/// alone (no additional CARRIAGE RETURN (`\r`/`U+000D`).
///
/// This macro is typically used with a buffer of `&mut `[`Write`][write].
///
Expand Down
29 changes: 24 additions & 5 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2308,26 +2308,45 @@ impl usize {
///
/// [`f32::classify()`]: ../../std/primitive.f32.html#method.classify
/// [`f64::classify()`]: ../../std/primitive.f64.html#method.classify
///
/// # Examples
///
/// ```
/// use std::num::FpCategory;
/// use std::f32;
///
/// let num = 12.4_f32;
/// let inf = f32::INFINITY;
/// let zero = 0f32;
/// let sub: f32 = 0.000000000000000000000000000000000000011754942;
/// let nan = f32::NAN;
///
/// assert_eq!(num.classify(), FpCategory::Normal);
/// assert_eq!(inf.classify(), FpCategory::Infinite);
/// assert_eq!(zero.classify(), FpCategory::Zero);
/// assert_eq!(nan.classify(), FpCategory::Nan);
/// assert_eq!(sub.classify(), FpCategory::Subnormal);
/// ```
#[derive(Copy, Clone, PartialEq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum FpCategory {
/// "Not a Number", often obtained by dividing by zero
/// "Not a Number", often obtained by dividing by zero.
#[stable(feature = "rust1", since = "1.0.0")]
Nan,

/// Positive or negative infinity
/// Positive or negative infinity.
#[stable(feature = "rust1", since = "1.0.0")]
Infinite ,

/// Positive or negative zero
/// Positive or negative zero.
#[stable(feature = "rust1", since = "1.0.0")]
Zero,

/// De-normalized floating point representation (less precise than `Normal`)
/// De-normalized floating point representation (less precise than `Normal`).
#[stable(feature = "rust1", since = "1.0.0")]
Subnormal,

/// A regular floating point number
/// A regular floating point number.
#[stable(feature = "rust1", since = "1.0.0")]
Normal,
}
Expand Down
3 changes: 2 additions & 1 deletion src/libpanic_unwind/gcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#![allow(private_no_mangle_fns)]

use core::any::Any;
use core::ptr;
use alloc::boxed::Box;

use unwind as uw;
Expand Down Expand Up @@ -88,7 +89,7 @@ pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
}

pub fn payload() -> *mut u8 {
0 as *mut u8
ptr::null_mut()
}

pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
Expand Down
3 changes: 2 additions & 1 deletion src/libpanic_unwind/seh64_gnu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use alloc::boxed::Box;

use core::any::Any;
use core::intrinsics;
use core::ptr;
use dwarf::eh;
use windows as c;

Expand Down Expand Up @@ -50,7 +51,7 @@ pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
}

pub fn payload() -> *mut u8 {
0 as *mut u8
ptr::null_mut()
}

pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ use libc::c_uint;
use std::ffi::{CStr, CString};
use std::cell::{Cell, RefCell};
use std::collections::{HashMap, HashSet};
use std::ptr;
use std::rc::Rc;
use std::str;
use std::{i8, i16, i32, i64};
Expand Down Expand Up @@ -2201,7 +2202,7 @@ pub fn maybe_create_entry_wrapper(ccx: &CrateContext) {
start_fn,
args.as_ptr(),
args.len() as c_uint,
0 as *mut _,
ptr::null_mut(),
noname());

llvm::LLVMBuildRet(bld, result);
Expand Down
14 changes: 7 additions & 7 deletions src/librustc_trans/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

check_call("invoke", llfn, args);

let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(0 as *mut _);
let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut());

unsafe {
llvm::LLVMRustBuildInvoke(self.llbuilder,
Expand Down Expand Up @@ -859,7 +859,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

check_call("call", llfn, args);

let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(0 as *mut _);
let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut());

unsafe {
llvm::LLVMRustBuildCall(self.llbuilder, llfn, args.as_ptr(),
Expand Down Expand Up @@ -961,7 +961,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.count_insn("trap");
llvm::LLVMRustBuildCall(self.llbuilder, t,
args.as_ptr(), args.len() as c_uint,
0 as *mut _,
ptr::null_mut(),
noname());
}
}
Expand Down Expand Up @@ -1000,7 +1000,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
parent: Option<ValueRef>,
args: &[ValueRef]) -> ValueRef {
self.count_insn("cleanuppad");
let parent = parent.unwrap_or(0 as *mut _);
let parent = parent.unwrap_or(ptr::null_mut());
let name = CString::new("cleanuppad").unwrap();
let ret = unsafe {
llvm::LLVMRustBuildCleanupPad(self.llbuilder,
Expand All @@ -1016,7 +1016,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub fn cleanup_ret(&self, cleanup: ValueRef,
unwind: Option<BasicBlockRef>) -> ValueRef {
self.count_insn("cleanupret");
let unwind = unwind.unwrap_or(0 as *mut _);
let unwind = unwind.unwrap_or(ptr::null_mut());
let ret = unsafe {
llvm::LLVMRustBuildCleanupRet(self.llbuilder, cleanup, unwind)
};
Expand Down Expand Up @@ -1052,8 +1052,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
unwind: Option<BasicBlockRef>,
num_handlers: usize) -> ValueRef {
self.count_insn("catchswitch");
let parent = parent.unwrap_or(0 as *mut _);
let unwind = unwind.unwrap_or(0 as *mut _);
let parent = parent.unwrap_or(ptr::null_mut());
let unwind = unwind.unwrap_or(ptr::null_mut());
let name = CString::new("catchswitch").unwrap();
let ret = unsafe {
llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind,
Expand Down
Loading