Skip to content

Commit

Permalink
Auto merge of #35908 - jonathandturner:rollup, r=jonathandturner
Browse files Browse the repository at this point in the history
Rollup of 20 pull requests

- Successful merges: #35360, #35526, #35809, #35817, #35820, #35824, #35835, #35841, #35842, #35858, #35860, #35861, #35864, #35878, #35879, #35881, #35882, #35889, #35891, #35901
- Failed merges: #35395
  • Loading branch information
bors authored Aug 22, 2016
2 parents 3c5a0fa + 8ea2936 commit d0da7f6
Show file tree
Hide file tree
Showing 65 changed files with 639 additions and 139 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ To find documentation-related issues, sort by the [A-docs label][adocs].
In many cases, you don't need a full `make doc`. You can use `rustdoc` directly
to check small fixes. For example, `rustdoc src/doc/reference.md` will render
reference to `doc/reference.html`. The CSS might be messed up, but you can
verify that HTML is right.
verify that the HTML is right.

## Issue Triage

Expand Down
28 changes: 28 additions & 0 deletions src/doc/book/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,34 @@ As you can see, the `trait` block looks very similar to the `impl` block,
but we don’t define a body, only a type signature. When we `impl` a trait,
we use `impl Trait for Item`, rather than only `impl Item`.

`Self` may be used in a type annotation to refer to an instance of the type
implementing this trait passed as a parameter. `Self`, `&Self` or `&mut Self`
may be used depending on the level of ownership required.

```rust
struct Circle {
x: f64,
y: f64,
radius: f64,
}

trait HasArea {
fn area(&self) -> f64;

fn is_larger(&self, &Self) -> bool;
}

impl HasArea for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * (self.radius * self.radius)
}

fn is_larger(&self, other: &Self) -> bool {
self.area() > other.area()
}
}
```

## Trait bounds on generic functions

Traits are useful because they allow a type to make certain promises about its
Expand Down
1 change: 1 addition & 0 deletions src/etc/CONFIGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ These are some links to repos with configs which ease the use of rust.

* [rust.vim](https://github.com/rust-lang/rust.vim)
* [emacs rust-mode](https://github.com/rust-lang/rust-mode)
* [sublime-rust](https://github.com/rust-lang/sublime-rust)
* [gedit-config](https://github.com/rust-lang/gedit-config)
* [kate-config](https://github.com/rust-lang/kate-config)
* [nano-config](https://github.com/rust-lang/nano-config)
Expand Down
17 changes: 17 additions & 0 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,23 @@ impl<T> Rc<T> {
}

/// Checks if `Rc::try_unwrap` would return `Ok`.
///
/// # Examples
///
/// ```
/// #![feature(rc_would_unwrap)]
///
/// use std::rc::Rc;
///
/// let x = Rc::new(3);
/// assert!(Rc::would_unwrap(&x));
/// assert_eq!(Rc::try_unwrap(x), Ok(3));
///
/// let x = Rc::new(4);
/// let _y = x.clone();
/// assert!(!Rc::would_unwrap(&x));
/// assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4)));
/// ```
#[unstable(feature = "rc_would_unwrap",
reason = "just added for niche usecase",
issue = "28356")]
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ use boxed::Box;
/// [`OsString`]: ../../std/ffi/struct.OsString.html
///
/// Indexing is intended to be a constant-time operation, but UTF-8 encoding
/// does not allow us to do this. Furtheremore, it's not clear what sort of
/// does not allow us to do this. Furthermore, it's not clear what sort of
/// thing the index should return: a byte, a codepoint, or a grapheme cluster.
/// The [`as_bytes()`] and [`chars()`] methods return iterators over the first
/// two, respectively.
Expand Down
168 changes: 122 additions & 46 deletions src/libcore/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,26 +299,63 @@ sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
///
/// # Examples
///
/// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
/// calling `mul`, and therefore, `main` prints `Multiplying!`.
/// Implementing a `Mul`tipliable rational number struct:
///
/// ```
/// use std::ops::Mul;
///
/// struct Foo;
/// // The uniqueness of rational numbers in lowest terms is a consequence of
/// // the fundamental theorem of arithmetic.
/// #[derive(Eq)]
/// #[derive(PartialEq, Debug)]
/// struct Rational {
/// nominator: usize,
/// denominator: usize,
/// }
///
/// impl Mul for Foo {
/// type Output = Foo;
/// impl Rational {
/// fn new(nominator: usize, denominator: usize) -> Self {
/// if denominator == 0 {
/// panic!("Zero is an invalid denominator!");
/// }
///
/// fn mul(self, _rhs: Foo) -> Foo {
/// println!("Multiplying!");
/// self
/// // Reduce to lowest terms by dividing by the greatest common
/// // divisor.
/// let gcd = gcd(nominator, denominator);
/// Rational {
/// nominator: nominator / gcd,
/// denominator: denominator / gcd,
/// }
/// }
/// }
///
/// fn main() {
/// Foo * Foo;
/// impl Mul for Rational {
/// // The multiplication of rational numbers is a closed operation.
/// type Output = Self;
///
/// fn mul(self, rhs: Self) -> Self {
/// let nominator = self.nominator * rhs.nominator;
/// let denominator = self.denominator * rhs.denominator;
/// Rational::new(nominator, denominator)
/// }
/// }
///
/// // Euclid's two-thousand-year-old algorithm for finding the greatest common
/// // divisor.
/// fn gcd(x: usize, y: usize) -> usize {
/// let mut x = x;
/// let mut y = y;
/// while y != 0 {
/// let t = y;
/// y = x % y;
/// x = t;
/// }
/// x
/// }
///
/// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
/// assert_eq!(Rational::new(2, 3) * Rational::new(3, 4),
/// Rational::new(1, 2));
/// ```
///
/// Note that `RHS = Self` by default, but this is not mandatory. Here is an
Expand Down Expand Up @@ -486,26 +523,34 @@ div_impl_float! { f32 f64 }
///
/// # Examples
///
/// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
/// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
/// This example implements `Rem` on a `SplitSlice` object. After `Rem` is
/// implemented, one can use the `%` operator to find out what the remaining
/// elements of the slice would be after splitting it into equal slices of a
/// given length.
///
/// ```
/// use std::ops::Rem;
///
/// struct Foo;
/// #[derive(PartialEq, Debug)]
/// struct SplitSlice<'a, T: 'a> {
/// slice: &'a [T],
/// }
///
/// impl Rem for Foo {
/// type Output = Foo;
/// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
/// type Output = SplitSlice<'a, T>;
///
/// fn rem(self, _rhs: Foo) -> Foo {
/// println!("Remainder-ing!");
/// self
/// fn rem(self, modulus: usize) -> Self {
/// let len = self.slice.len();
/// let rem = len % modulus;
/// let start = len - rem;
/// SplitSlice {slice: &self.slice[start..]}
/// }
/// }
///
/// fn main() {
/// Foo % Foo;
/// }
/// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
/// // the remainder would be &[6, 7]
/// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
/// SplitSlice { slice: &[6, 7] });
/// ```
#[lang = "rem"]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -694,26 +739,41 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
///
/// # Examples
///
/// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
/// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
/// In this example, the `BitAnd` trait is implemented for a `BooleanVector`
/// struct.
///
/// ```
/// use std::ops::BitAnd;
///
/// struct Foo;
///
/// impl BitAnd for Foo {
/// type Output = Foo;
///
/// fn bitand(self, _rhs: Foo) -> Foo {
/// println!("Bitwise And-ing!");
/// self
/// #[derive(Debug)]
/// struct BooleanVector {
/// value: Vec<bool>,
/// };
///
/// impl BitAnd for BooleanVector {
/// type Output = Self;
///
/// fn bitand(self, rhs: Self) -> Self {
/// BooleanVector {
/// value: self.value
/// .iter()
/// .zip(rhs.value.iter())
/// .map(|(x, y)| *x && *y)
/// .collect(),
/// }
/// }
/// }
///
/// fn main() {
/// Foo & Foo;
/// impl PartialEq for BooleanVector {
/// fn eq(&self, other: &Self) -> bool {
/// self.value == other.value
/// }
/// }
///
/// let bv1 = BooleanVector { value: vec![true, true, false, false] };
/// let bv2 = BooleanVector { value: vec![true, false, true, false] };
/// let expected = BooleanVector { value: vec![true, false, false, false] };
/// assert_eq!(bv1 & bv2, expected);
/// ```
#[lang = "bitand"]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -1490,28 +1550,44 @@ shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
///
/// # Examples
///
/// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up
/// calling `index`, and therefore, `main` prints `Indexing!`.
/// This example implements `Index` on a read-only `NucleotideCount` container,
/// enabling individual counts to be retrieved with index syntax.
///
/// ```
/// use std::ops::Index;
///
/// #[derive(Copy, Clone)]
/// struct Foo;
/// struct Bar;
/// enum Nucleotide {
/// A,
/// C,
/// G,
/// T,
/// }
///
/// impl Index<Bar> for Foo {
/// type Output = Foo;
/// struct NucleotideCount {
/// a: usize,
/// c: usize,
/// g: usize,
/// t: usize,
/// }
///
/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
/// println!("Indexing!");
/// self
/// impl Index<Nucleotide> for NucleotideCount {
/// type Output = usize;
///
/// fn index(&self, nucleotide: Nucleotide) -> &usize {
/// match nucleotide {
/// Nucleotide::A => &self.a,
/// Nucleotide::C => &self.c,
/// Nucleotide::G => &self.g,
/// Nucleotide::T => &self.t,
/// }
/// }
/// }
///
/// fn main() {
/// Foo[Bar];
/// }
/// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12};
/// assert_eq!(nucleotide_count[Nucleotide::A], 14);
/// assert_eq!(nucleotide_count[Nucleotide::C], 9);
/// assert_eq!(nucleotide_count[Nucleotide::G], 10);
/// assert_eq!(nucleotide_count[Nucleotide::T], 12);
/// ```
#[lang = "index"]
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
Expand Down
12 changes: 8 additions & 4 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
/// let x = 12;
/// let y = &x as *const i32;
///
/// unsafe { println!("{}", std::ptr::read(y)); }
/// unsafe {
/// assert_eq!(std::ptr::read(y), 12);
/// }
/// ```
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -178,7 +180,7 @@ pub unsafe fn read_and_drop<T>(dest: *mut T) -> T {
///
/// unsafe {
/// std::ptr::write(y, z);
/// println!("{}", std::ptr::read(y));
/// assert_eq!(std::ptr::read(y), 12);
/// }
/// ```
#[inline]
Expand Down Expand Up @@ -220,7 +222,9 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
/// let x = 12;
/// let y = &x as *const i32;
///
/// unsafe { println!("{}", std::ptr::read_volatile(y)); }
/// unsafe {
/// assert_eq!(std::ptr::read_volatile(y), 12);
/// }
/// ```
#[inline]
#[stable(feature = "volatile", since = "1.9.0")]
Expand Down Expand Up @@ -266,7 +270,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
///
/// unsafe {
/// std::ptr::write_volatile(y, z);
/// println!("{}", std::ptr::read_volatile(y));
/// assert_eq!(std::ptr::read_volatile(y), 12);
/// }
/// ```
#[inline]
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/middle/privacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ use syntax::ast::NodeId;
pub enum AccessLevel {
// Exported items + items participating in various kinds of public interfaces,
// but not directly nameable. For example, if function `fn f() -> T {...}` is
// public, then type `T` is exported. Its values can be obtained by other crates
// even if the type itseld is not nameable.
// FIXME: Mostly unimplemented. Only `type` aliases export items currently.
// public, then type `T` is reachable. Its values can be obtained by other crates
// even if the type itself is not nameable.
Reachable,
// Public items + items accessible to other crates with help of `pub use` reexports
Exported,
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_borrowck/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,10 +647,13 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
struct_span_err!(self.bccx, span, E0503,
"cannot use `{}` because it was mutably borrowed",
&self.bccx.loan_path_to_string(copy_path))
.span_note(loan_span,
.span_label(loan_span,
&format!("borrow of `{}` occurs here",
&self.bccx.loan_path_to_string(&loan_path))
)
.span_label(span,
&format!("use of borrowed `{}`",
&self.bccx.loan_path_to_string(&loan_path)))
.emit();
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/librustc_borrowck/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,9 +914,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
mc::AliasableStatic |
mc::AliasableStaticMut => {
struct_span_err!(
let mut err = struct_span_err!(
self.tcx.sess, span, E0388,
"{} in a static location", prefix)
"{} in a static location", prefix);
err.span_label(span, &format!("cannot write data in a static definition"));
err
}
mc::AliasableBorrowed => {
struct_span_err!(
Expand Down
Loading

0 comments on commit d0da7f6

Please sign in to comment.