Part of #24407.
# This is used by the automation to produce single-target nightlies
opt dist-host-only 0 "only install bins for the host architecture"
opt inject-std-version 1 "inject the current compiler version of libstd into programs"
-opt llvm-version-check 1 "don't check if the LLVM version is supported, build anyway"
+opt llvm-version-check 1 "check if the LLVM version is supported, build anyway"
# Optimization and debugging options. These may be overridden by the release channel, etc.
opt_nosave optimize 1 "build optimized rust code"
```rust
fn main() {
- println!("Hello, world!")
+ println!("Hello, world!");
}
```
Cargo uses the dependencies section to know what dependencies on external
crates you have, and what versions you require. In this case, we’ve used version `0.3.0`.
Cargo understands [Semantic Versioning][semver], which is a standard for writing version
-numbers. If we wanted to use the latest version we could use `*` or we could use a range
+numbers. If we wanted to use the latest version we could use `*` or we could use a range
of versions. [Cargo’s documentation][cargodoc] contains more details.
[semver]: http://semver.org
The first step to using Rust is to install it! There are a number of ways to
install Rust, but the easiest is to use the `rustup` script. If you're on Linux
-or a Mac, all you need to do is this (note that you don't need to type in the
-`$`s, they just indicate the start of each command):
+or a Mac, all you need to do is this:
+
+> Note: you don't need to type in the `$`s, they just indicate the start of
+> each command. You’ll see many tutorials and examples around the web that
+> follow this convention: `$` for commands run as your regular user, and
+> `#` for commands you should be running as an administrator.
```bash
$ curl -sf -L https://static.rust-lang.org/rustup.sh | sh
`.next()` method on repeatedly, and it gives us a sequence of things.
Because you need to call the method, this means that iterators
can be *lazy* and not generate all of the values upfront. This code,
-for example, does not actually generate the numbers `1-100`, instead
+for example, does not actually generate the numbers `1-99`, instead
creating a value that merely represents the sequence:
```rust
> * exactly one mutable reference (`&mut T`)
[ownership]: ownership.html
-[borrowing]: borrowing.html#The-Rules
+[borrowing]: references-and-borrowing.html#borrowing
So, that’s the real definition of ‘immutability’: is this safe to have two
pointers to? In `Arc<T>`’s case, yes: the mutation is entirely contained inside
///
/// Returns `None` if the `Arc<T>` is not unique.
///
+/// This function is marked **unsafe** because it is racy if weak pointers
+/// are active.
+///
/// # Examples
///
/// ```
/// # fn main() {
/// use alloc::arc::{Arc, get_mut};
///
+/// # unsafe {
/// let mut x = Arc::new(3);
/// *get_mut(&mut x).unwrap() = 4;
/// assert_eq!(*x, 4);
/// let _y = x.clone();
/// assert!(get_mut(&mut x).is_none());
/// # }
+/// # }
/// ```
#[inline]
#[unstable(feature = "alloc")]
-pub fn get_mut<T: ?Sized>(this: &mut Arc<T>) -> Option<&mut T> {
+pub unsafe fn get_mut<T: ?Sized>(this: &mut Arc<T>) -> Option<&mut T> {
+ // FIXME(#24880) potential race with upgraded weak pointers here
if strong_count(this) == 1 && weak_count(this) == 0 {
// This unsafety is ok because we're guaranteed that the pointer
// returned is the *only* pointer that will ever be returned to T. Our
// reference count is guaranteed to be 1 at this point, and we required
// the Arc itself to be `mut`, so we're returning the only possible
// reference to the inner data.
- let inner = unsafe { &mut **this._ptr };
+ let inner = &mut **this._ptr;
Some(&mut inner.data)
} else {
None
/// This is also referred to as a copy-on-write operation because the inner
/// data is cloned if the reference count is greater than one.
///
+ /// This method is marked **unsafe** because it is racy if weak pointers
+ /// are active.
+ ///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::sync::Arc;
///
+ /// # unsafe {
/// let mut five = Arc::new(5);
///
/// let mut_five = five.make_unique();
+ /// # }
/// ```
#[inline]
#[unstable(feature = "alloc")]
- pub fn make_unique(&mut self) -> &mut T {
+ pub unsafe fn make_unique(&mut self) -> &mut T {
+ // FIXME(#24880) potential race with upgraded weak pointers here
+ //
// Note that we hold a strong reference, which also counts as a weak
// reference, so we only clone if there is an additional reference of
// either kind.
}
// As with `get_mut()`, the unsafety is ok because our reference was
// either unique to begin with, or became one upon cloning the contents.
- let inner = unsafe { &mut **self._ptr };
+ let inner = &mut **self._ptr;
&mut inner.data
}
}
#[test]
fn test_arc_get_mut() {
- let mut x = Arc::new(3);
- *get_mut(&mut x).unwrap() = 4;
- assert_eq!(*x, 4);
- let y = x.clone();
- assert!(get_mut(&mut x).is_none());
- drop(y);
- assert!(get_mut(&mut x).is_some());
- let _w = x.downgrade();
- assert!(get_mut(&mut x).is_none());
+ unsafe {
+ let mut x = Arc::new(3);
+ *get_mut(&mut x).unwrap() = 4;
+ assert_eq!(*x, 4);
+ let y = x.clone();
+ assert!(get_mut(&mut x).is_none());
+ drop(y);
+ assert!(get_mut(&mut x).is_some());
+ let _w = x.downgrade();
+ assert!(get_mut(&mut x).is_none());
+ }
}
#[test]
fn test_cowarc_clone_make_unique() {
- let mut cow0 = Arc::new(75);
- let mut cow1 = cow0.clone();
- let mut cow2 = cow1.clone();
-
- assert!(75 == *cow0.make_unique());
- assert!(75 == *cow1.make_unique());
- assert!(75 == *cow2.make_unique());
-
- *cow0.make_unique() += 1;
- *cow1.make_unique() += 2;
- *cow2.make_unique() += 3;
-
- assert!(76 == *cow0);
- assert!(77 == *cow1);
- assert!(78 == *cow2);
-
- // none should point to the same backing memory
- assert!(*cow0 != *cow1);
- assert!(*cow0 != *cow2);
- assert!(*cow1 != *cow2);
+ unsafe {
+ let mut cow0 = Arc::new(75);
+ let mut cow1 = cow0.clone();
+ let mut cow2 = cow1.clone();
+
+ assert!(75 == *cow0.make_unique());
+ assert!(75 == *cow1.make_unique());
+ assert!(75 == *cow2.make_unique());
+
+ *cow0.make_unique() += 1;
+ *cow1.make_unique() += 2;
+ *cow2.make_unique() += 3;
+
+ assert!(76 == *cow0);
+ assert!(77 == *cow1);
+ assert!(78 == *cow2);
+
+ // none should point to the same backing memory
+ assert!(*cow0 != *cow1);
+ assert!(*cow0 != *cow2);
+ assert!(*cow1 != *cow2);
+ }
}
#[test]
assert!(75 == *cow1);
assert!(75 == *cow2);
- *cow0.make_unique() += 1;
+ unsafe {
+ *cow0.make_unique() += 1;
+ }
assert!(76 == *cow0);
assert!(75 == *cow1);
assert!(75 == *cow0);
assert!(75 == *cow1_weak.upgrade().unwrap());
- *cow0.make_unique() += 1;
+ unsafe {
+ *cow0.make_unique() += 1;
+ }
assert!(76 == *cow0);
assert!(cow1_weak.upgrade().is_none());
//! You can get a non-`'static` `&str` by taking a slice of a `String`:
//!
//! ```
-//! # let some_string = "Hello, world.".to_string();
+//! let some_string = "Hello, world.".to_string();
//! let s = &some_string;
//! ```
//!
///
/// ```{.should_panic}
/// let x: Option<&str> = None;
- /// x.expect("the world is ending"); // panics with `world is ending`
+ /// x.expect("the world is ending"); // panics with `the world is ending`
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
}
}
- /// Applies a function to the contained value or returns a default.
+ /// Applies a function to the contained value (if any),
+ /// or returns a `default` (if not).
///
/// # Examples
///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
+ pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
match self {
Some(t) => f(t),
- None => def
+ None => default,
}
}
- /// Applies a function to the contained value or computes a default.
+ /// Applies a function to the contained value (if any),
+ /// or computes a `default` (if not).
///
/// # Examples
///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, def: D, f: F) -> U {
+ pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
match self {
Some(t) => f(t),
- None => def()
+ None => default()
}
}
//! val: num.to_json(),
//! }).unwrap();
//! println!("data: {}", data);
-//! // data: {"uid":1,"dsc":"test","val":"0.0001+12.539j"};
+//! // data: {"uid":1,"dsc":"test","val":"0.0001+12.539i"};
//! }
//! ```
//!
// Returns a tuple of (key_offset, val_offset),
// from the start of a mallocated array.
+#[inline]
fn calculate_offsets(hashes_size: usize,
keys_size: usize, keys_align: usize,
vals_align: usize)