diff --git a/src/doc/book/compiler-plugins.md b/src/doc/book/compiler-plugins.md index 8426d5a626549..a9a81843ab199 100644 --- a/src/doc/book/compiler-plugins.md +++ b/src/doc/book/compiler-plugins.md @@ -46,10 +46,10 @@ extern crate rustc; extern crate rustc_plugin; use syntax::parse::token; -use syntax::ast::TokenTree; +use syntax::tokenstream::TokenTree; use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; use syntax::ext::build::AstBuilder; // trait for expr_usize -use syntax_pos::Span; +use syntax::ext::quote::rt::Span; use rustc_plugin::Registry; fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) @@ -69,7 +69,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) } let text = match args[0] { - TokenTree::Token(_, token::Ident(s, _)) => s.to_string(), + TokenTree::Token(_, token::Ident(s)) => s.to_string(), _ => { cx.span_err(sp, "argument should be a single identifier"); return DummyResult::any(sp); diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 9c9f1e7b9de07..b54b71cabd1e9 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -71,6 +71,12 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// does not use atomics, making it both thread-unsafe as well as significantly /// faster when updating the reference count. /// +/// Note: the inherent methods defined on `Arc` are all associated functions, +/// which means that you have to call them as e.g. `Arc::get_mut(&value)` +/// instead of `value.get_mut()`. This is so that there are no conflicts with +/// methods on the inner type `T`, which are what you want to call in the +/// majority of cases. +/// /// # Examples /// /// In this example, a large vector of data will be shared by several threads. First we diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index c8a78f84f1857..70c429cc3600a 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -271,6 +271,10 @@ impl Box { /// proper way to do so is to convert the raw pointer back into a /// `Box` with the `Box::from_raw` function. /// + /// Note: this is an associated function, which means that you have + /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This + /// is so that there is no conflict with a method on the inner type. + /// /// # Examples /// /// ``` diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 8e43e9eec1608..c24c7ca47ad05 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -182,6 +182,12 @@ struct RcBox { /// A reference-counted pointer type over an immutable value. /// /// See the [module level documentation](./index.html) for more details. +/// +/// Note: the inherent methods defined on `Rc` are all associated functions, +/// which means that you have to call them as e.g. `Rc::get_mut(&value)` instead +/// of `value.get_mut()`. This is so that there are no conflicts with methods +/// on the inner type `T`, which are what you want to call in the majority of +/// cases. #[cfg_attr(stage0, unsafe_no_drop_flag)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Rc { diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index b7cbfb60ec4e9..beb3e6b3d4e31 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -165,9 +165,15 @@ //! provides some helper methods. //! //! Additionally, the return value of this function is `fmt::Result` which is a -//! typedef to `Result<(), std::io::Error>` (also known as `std::io::Result<()>`). -//! Formatting implementations should ensure that they return errors from `write!` -//! correctly (propagating errors upward). +//! type alias of `Result<(), std::fmt::Error>`. Formatting implementations +//! should ensure that they propagate errors from the `Formatter` (e.g., when +//! calling `write!`) however, they should never return errors spuriously. That +//! is, a formatting implementation must and may only return an error if the +//! passed-in `Formatter` returns an error. This is because, contrary to what +//! the function signature might suggest, string formatting is an infallible +//! operation. This function only returns a result because writing to the +//! underlying stream might fail and it must provide a way to propagate the fact +//! that an error has occurred back up the stack. //! //! An example of implementing the formatting traits would look //! like: diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index ec35198b68517..f0710a1d93578 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -119,26 +119,55 @@ //! `Cell`. //! //! ``` +//! #![feature(core_intrinsics)] +//! #![feature(shared)] //! use std::cell::Cell; +//! use std::ptr::Shared; +//! use std::intrinsics::abort; +//! use std::intrinsics::assume; //! -//! struct Rc { -//! ptr: *mut RcBox +//! struct Rc { +//! ptr: Shared> //! } //! -//! struct RcBox { -//! # #[allow(dead_code)] +//! struct RcBox { +//! strong: Cell, +//! refcount: Cell, //! value: T, -//! refcount: Cell //! } //! -//! impl Clone for Rc { +//! impl Clone for Rc { //! fn clone(&self) -> Rc { -//! unsafe { -//! (*self.ptr).refcount.set((*self.ptr).refcount.get() + 1); -//! Rc { ptr: self.ptr } -//! } +//! self.inc_strong(); +//! Rc { ptr: self.ptr } +//! } +//! } +//! +//! trait RcBoxPtr { +//! +//! fn inner(&self) -> &RcBox; +//! +//! fn strong(&self) -> usize { +//! self.inner().strong.get() +//! } +//! +//! fn inc_strong(&self) { +//! self.inner() +//! .strong +//! .set(self.strong() +//! .checked_add(1) +//! .unwrap_or_else(|| unsafe { abort() })); //! } //! } +//! +//! impl RcBoxPtr for Rc { +//! fn inner(&self) -> &RcBox { +//! unsafe { +//! assume(!(*(&self.ptr as *const _ as *const *const ())).is_null()); +//! &(**self.ptr) +//! } +//! } +//! } //! ``` //! diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index b9adaf0206d94..5f9fafbd8ab14 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -21,6 +21,11 @@ //! custom operators are required, you should look toward macros or compiler //! plugins to extend Rust's syntax. //! +//! Note that the `&&` and `||` operators short-circuit, i.e. they only +//! evaluate their second operand if it contributes to the result. Since this +//! behavior is not enforceable by traits, `&&` and `||` are not supported as +//! overloadable operators. +//! //! Many of the operators take their operands by value. In non-generic //! contexts involving built-in types, this is usually not a problem. //! However, using these operators in generic code, requires some @@ -68,6 +73,26 @@ //! ``` //! //! See the documentation for each trait for an example implementation. +//! +//! This example shows the behavior of the various `Range*` structs. +//! +//! ```rust +//! #![feature(inclusive_range_syntax)] +//! fn main() { +//! let arr = [0, 1, 2, 3, 4]; +//! +//! assert_eq!(arr[ .. ], [0,1,2,3,4]); // RangeFull +//! assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo +//! assert_eq!(arr[1.. ], [ 1,2,3,4]); // RangeFrom +//! assert_eq!(arr[1..3], [ 1,2 ]); // Range +//! +//! assert_eq!(arr[ ...3], [0,1,2,3 ]); // RangeToIncusive +//! assert_eq!(arr[1...3], [ 1,2,3 ]); // RangeInclusive +//! } +//! ``` +//! +//! Note: whitespace alignment is not idiomatic Rust. An exception is made in +//! this case to facilitate comparison. #![stable(feature = "rust1", since = "1.0.0")] @@ -793,41 +818,56 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } /// /// # Examples /// -/// In this example, the `BitAnd` trait is implemented for a `BooleanVector` -/// struct. +/// In this example, the `&` operator is lifted to a trivial `Scalar` type. /// /// ``` /// use std::ops::BitAnd; /// -/// #[derive(Debug)] -/// struct BooleanVector { -/// value: Vec, -/// }; +/// #[derive(Debug, PartialEq)] +/// struct Scalar(bool); /// -/// impl BitAnd for BooleanVector { +/// impl BitAnd for Scalar { /// type Output = Self; /// +/// // rhs is the "right-hand side" of the expression `a & b` /// fn bitand(self, rhs: Self) -> Self { -/// BooleanVector { -/// value: self.value -/// .iter() -/// .zip(rhs.value.iter()) -/// .map(|(x, y)| *x && *y) -/// .collect(), -/// } +/// Scalar(self.0 & rhs.0) /// } /// } /// -/// impl PartialEq for BooleanVector { -/// fn eq(&self, other: &Self) -> bool { -/// self.value == other.value +/// fn main() { +/// assert_eq!(Scalar(true) & Scalar(true), Scalar(true)); +/// assert_eq!(Scalar(true) & Scalar(false), Scalar(false)); +/// assert_eq!(Scalar(false) & Scalar(true), Scalar(false)); +/// assert_eq!(Scalar(false) & Scalar(false), Scalar(false)); +/// } +/// ``` +/// +/// In this example, the `BitAnd` trait is implemented for a `BooleanVector` +/// struct. +/// +/// ``` +/// use std::ops::BitAnd; +/// +/// #[derive(Debug, PartialEq)] +/// struct BooleanVector(Vec); +/// +/// impl BitAnd for BooleanVector { +/// type Output = Self; +/// +/// fn bitand(self, BooleanVector(rhs): Self) -> Self { +/// let BooleanVector(lhs) = self; +/// assert_eq!(lhs.len(), rhs.len()); +/// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x && *y).collect()) /// } /// } /// -/// 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); +/// fn main() { +/// let bv1 = BooleanVector(vec![true, true, false, false]); +/// let bv2 = BooleanVector(vec![true, false, true, false]); +/// let expected = BooleanVector(vec![true, false, false, false]); +/// assert_eq!(bv1 & bv2, expected); +/// } /// ``` #[lang = "bitand"] #[stable(feature = "rust1", since = "1.0.0")] @@ -967,25 +1007,54 @@ bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } /// /// # Examples /// -/// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up -/// calling `shl`, and therefore, `main` prints `Shifting left!`. +/// An implementation of `Shl` that lifts the `<<` operation on integers to a +/// `Scalar` struct. /// /// ``` /// use std::ops::Shl; /// -/// struct Foo; +/// #[derive(PartialEq, Debug)] +/// struct Scalar(usize); /// -/// impl Shl for Foo { -/// type Output = Foo; +/// impl Shl for Scalar { +/// type Output = Self; /// -/// fn shl(self, _rhs: Foo) -> Foo { -/// println!("Shifting left!"); -/// self +/// fn shl(self, Scalar(rhs): Self) -> Scalar { +/// let Scalar(lhs) = self; +/// Scalar(lhs << rhs) +/// } +/// } +/// fn main() { +/// assert_eq!(Scalar(4) << Scalar(2), Scalar(16)); +/// } +/// ``` +/// +/// An implementation of `Shl` that spins a vector leftward by a given amount. +/// +/// ``` +/// use std::ops::Shl; +/// +/// #[derive(PartialEq, Debug)] +/// struct SpinVector { +/// vec: Vec, +/// } +/// +/// impl Shl for SpinVector { +/// type Output = Self; +/// +/// fn shl(self, rhs: usize) -> SpinVector { +/// // rotate the vector by `rhs` places +/// let (a, b) = self.vec.split_at(rhs); +/// let mut spun_vector: Vec = vec![]; +/// spun_vector.extend_from_slice(b); +/// spun_vector.extend_from_slice(a); +/// SpinVector { vec: spun_vector } /// } /// } /// /// fn main() { -/// Foo << Foo; +/// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } << 2, +/// SpinVector { vec: vec![2, 3, 4, 0, 1] }); /// } /// ``` #[lang = "shl"] @@ -1039,25 +1108,54 @@ shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } /// /// # Examples /// -/// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up -/// calling `shr`, and therefore, `main` prints `Shifting right!`. +/// An implementation of `Shr` that lifts the `>>` operation on integers to a +/// `Scalar` struct. /// /// ``` /// use std::ops::Shr; /// -/// struct Foo; +/// #[derive(PartialEq, Debug)] +/// struct Scalar(usize); /// -/// impl Shr for Foo { -/// type Output = Foo; +/// impl Shr for Scalar { +/// type Output = Self; /// -/// fn shr(self, _rhs: Foo) -> Foo { -/// println!("Shifting right!"); -/// self +/// fn shr(self, Scalar(rhs): Self) -> Scalar { +/// let Scalar(lhs) = self; +/// Scalar(lhs >> rhs) +/// } +/// } +/// fn main() { +/// assert_eq!(Scalar(16) >> Scalar(2), Scalar(4)); +/// } +/// ``` +/// +/// An implementation of `Shr` that spins a vector rightward by a given amount. +/// +/// ``` +/// use std::ops::Shr; +/// +/// #[derive(PartialEq, Debug)] +/// struct SpinVector { +/// vec: Vec, +/// } +/// +/// impl Shr for SpinVector { +/// type Output = Self; +/// +/// fn shr(self, rhs: usize) -> SpinVector { +/// // rotate the vector by `rhs` places +/// let (a, b) = self.vec.split_at(self.vec.len() - rhs); +/// let mut spun_vector: Vec = vec![]; +/// spun_vector.extend_from_slice(b); +/// spun_vector.extend_from_slice(a); +/// SpinVector { vec: spun_vector } /// } /// } /// /// fn main() { -/// Foo >> Foo; +/// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } >> 2, +/// SpinVector { vec: vec![3, 4, 0, 1, 2] }); /// } /// ``` #[lang = "shr"] @@ -1736,11 +1834,12 @@ pub trait IndexMut: Index { /// /// ``` /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); +/// assert_eq!(arr[ .. ], [0, 1, 2, 3]); /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFull; @@ -1765,12 +1864,13 @@ impl fmt::Debug for RangeFull { /// assert_eq!(3+4+5, (3..6).sum()); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); // Range +/// assert_eq!(arr[1..3], [1, 2]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { @@ -1828,12 +1928,13 @@ impl> Range { /// assert_eq!(2+3+4, (2..).take(3).sum()); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom -/// assert_eq!(arr[1..3], [ 1,2 ]); +/// assert_eq!(arr[1.. ], [1, 2, 3]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { @@ -1878,12 +1979,13 @@ impl> RangeFrom { /// assert_eq!((..5), std::ops::RangeTo{ end: 5 }); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); +/// assert_eq!(arr[ ..3], [0, 1, 2]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeTo { @@ -1930,10 +2032,13 @@ impl> RangeTo { /// assert_eq!(3+4+5, (3...5).sum()); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ ...2], [0,1,2 ]); -/// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive +/// assert_eq!(arr[1...2], [1, 2]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] pub enum RangeInclusive { @@ -2017,10 +2122,13 @@ impl> RangeInclusive { /// assert_eq!((...5), std::ops::RangeToInclusive{ end: 5 }); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive -/// assert_eq!(arr[1...2], [ 1,2 ]); +/// assert_eq!(arr[ ...2], [0, 1, 2]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] pub struct RangeToInclusive { diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 1825a892cf554..5a8a52f7dfc6e 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -726,7 +726,7 @@ pub mod reader { fn read_u8(&mut self) -> DecodeResult { Ok(doc_as_u8(self.next_doc(EsU8)?)) } - fn read_uint(&mut self) -> DecodeResult { + fn read_usize(&mut self) -> DecodeResult { let v = self._next_int(EsU8, EsU64)?; if v > (::std::usize::MAX as u64) { Err(IntTooBig(v as usize)) @@ -747,7 +747,7 @@ pub mod reader { fn read_i8(&mut self) -> DecodeResult { Ok(doc_as_u8(self.next_doc(EsI8)?) as i8) } - fn read_int(&mut self) -> DecodeResult { + fn read_isize(&mut self) -> DecodeResult { let v = self._next_int(EsI8, EsI64)? as i64; if v > (isize::MAX as i64) || v < (isize::MIN as i64) { debug!("FIXME \\#6122: Removing this makes this function miscompile"); @@ -1219,7 +1219,7 @@ pub mod writer { Ok(()) } - fn emit_uint(&mut self, v: usize) -> EncodeResult { + fn emit_usize(&mut self, v: usize) -> EncodeResult { self.emit_u64(v as u64) } fn emit_u64(&mut self, v: u64) -> EncodeResult { @@ -1247,7 +1247,7 @@ pub mod writer { self.wr_tagged_raw_u8(EsU8 as usize, v) } - fn emit_int(&mut self, v: isize) -> EncodeResult { + fn emit_isize(&mut self, v: isize) -> EncodeResult { self.emit_i64(v as i64) } fn emit_i64(&mut self, v: i64) -> EncodeResult { diff --git a/src/librbml/opaque.rs b/src/librbml/opaque.rs index 10f419d169181..6dc7a72b1b1bb 100644 --- a/src/librbml/opaque.rs +++ b/src/librbml/opaque.rs @@ -54,7 +54,7 @@ impl<'a> serialize::Encoder for Encoder<'a> { Ok(()) } - fn emit_uint(&mut self, v: usize) -> EncodeResult { + fn emit_usize(&mut self, v: usize) -> EncodeResult { write_uleb128!(self, v) } @@ -75,7 +75,7 @@ impl<'a> serialize::Encoder for Encoder<'a> { Ok(()) } - fn emit_int(&mut self, v: isize) -> EncodeResult { + fn emit_isize(&mut self, v: isize) -> EncodeResult { write_sleb128!(self, v) } @@ -120,7 +120,7 @@ impl<'a> serialize::Encoder for Encoder<'a> { } fn emit_str(&mut self, v: &str) -> EncodeResult { - self.emit_uint(v.len())?; + self.emit_usize(v.len())?; let _ = self.cursor.write_all(v.as_bytes()); Ok(()) } @@ -139,7 +139,7 @@ impl<'a> serialize::Encoder for Encoder<'a> { -> EncodeResult where F: FnOnce(&mut Self) -> EncodeResult { - self.emit_uint(v_id)?; + self.emit_usize(v_id)?; f(self) } @@ -221,7 +221,7 @@ impl<'a> serialize::Encoder for Encoder<'a> { fn emit_seq(&mut self, len: usize, f: F) -> EncodeResult where F: FnOnce(&mut Encoder<'a>) -> EncodeResult { - self.emit_uint(len)?; + self.emit_usize(len)?; f(self) } @@ -234,7 +234,7 @@ impl<'a> serialize::Encoder for Encoder<'a> { fn emit_map(&mut self, len: usize, f: F) -> EncodeResult where F: FnOnce(&mut Encoder<'a>) -> EncodeResult { - self.emit_uint(len)?; + self.emit_usize(len)?; f(self) } @@ -329,7 +329,7 @@ impl<'a> serialize::Decoder for Decoder<'a> { Ok(value) } - fn read_uint(&mut self) -> Result { + fn read_usize(&mut self) -> Result { read_uleb128!(self, usize) } @@ -351,7 +351,7 @@ impl<'a> serialize::Decoder for Decoder<'a> { unsafe { Ok(::std::mem::transmute(as_u8)) } } - fn read_int(&mut self) -> Result { + fn read_isize(&mut self) -> Result { read_sleb128!(self, isize) } @@ -376,7 +376,7 @@ impl<'a> serialize::Decoder for Decoder<'a> { } fn read_str(&mut self) -> Result { - let len = self.read_uint()?; + let len = self.read_usize()?; let s = ::std::str::from_utf8(&self.data[self.position..self.position + len]).unwrap(); self.position += len; Ok(s.to_string()) @@ -391,7 +391,7 @@ impl<'a> serialize::Decoder for Decoder<'a> { fn read_enum_variant(&mut self, _: &[&str], mut f: F) -> Result where F: FnMut(&mut Decoder<'a>, usize) -> Result { - let disr = self.read_uint()?; + let disr = self.read_usize()?; f(self, disr) } @@ -404,7 +404,7 @@ impl<'a> serialize::Decoder for Decoder<'a> { fn read_enum_struct_variant(&mut self, _: &[&str], mut f: F) -> Result where F: FnMut(&mut Decoder<'a>, usize) -> Result { - let disr = self.read_uint()?; + let disr = self.read_usize()?; f(self, disr) } @@ -483,7 +483,7 @@ impl<'a> serialize::Decoder for Decoder<'a> { fn read_seq(&mut self, f: F) -> Result where F: FnOnce(&mut Decoder<'a>, usize) -> Result { - let len = self.read_uint()?; + let len = self.read_usize()?; f(self, len) } @@ -496,7 +496,7 @@ impl<'a> serialize::Decoder for Decoder<'a> { fn read_map(&mut self, f: F) -> Result where F: FnOnce(&mut Decoder<'a>, usize) -> Result { - let len = self.read_uint()?; + let len = self.read_usize()?; f(self, len) } diff --git a/src/librustc_metadata/loader.rs b/src/librustc_metadata/loader.rs index b2c87db8ef566..44d7861066da3 100644 --- a/src/librustc_metadata/loader.rs +++ b/src/librustc_metadata/loader.rs @@ -342,9 +342,11 @@ impl<'a> Context<'a> { "found crate `{}` compiled by an incompatible version of rustc{}", self.ident, add) } else { - struct_span_err!(self.sess, self.span, E0463, - "can't find crate for `{}`{}", - self.ident, add) + let mut err = struct_span_err!(self.sess, self.span, E0463, + "can't find crate for `{}`{}", + self.ident, add); + err.span_label(self.span, &format!("can't find crate")); + err }; if !self.rejected_via_triple.is_empty() { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6a4a48377c783..9d0c93f3e9dd2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3354,7 +3354,11 @@ impl<'a> Resolver<'a> { e.span_label(span, &"already imported"); e }, - (true, _) | (_, true) => struct_span_err!(self.session, span, E0260, "{}", msg), + (true, _) | (_, true) => { + let mut e = struct_span_err!(self.session, span, E0260, "{}", msg); + e.span_label(span, &format!("`{}` already imported", name)); + e + }, _ => match (old_binding.is_import(), binding.is_import()) { (false, false) => { let mut e = struct_span_err!(self.session, span, E0428, "{}", msg); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fb24971c4251d..a846383309975 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4427,14 +4427,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // use inference variables instead of the provided types. *segment = None; } else if !(can_omit && types.len() == 0) && types.len() < required_len { - let qualifier = - if type_defs.len() != required_len { "at least " } else { "" }; - span_err!(self.tcx.sess, span, E0089, - "too few type parameters provided: \ - expected {}{}, found {}", - qualifier, - count(required_len), - count(types.len())); + let adjust = |len| if len > 1 { "parameters" } else { "parameter" }; + let required_param_str = adjust(required_len); + let actual_param_str = adjust(types.len()); + struct_span_err!(self.tcx.sess, span, E0089, + "too few type parameters provided: \ + expected {} {}, found {} {}", + count(required_len), + required_param_str, + count(types.len()), + actual_param_str) + .span_label(span, &format!("expected {} type {}", required_len, required_param_str)) + .emit(); } if !bindings.is_empty() { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 6b6a688bf1d18..a236c8baa9f9c 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -631,7 +631,9 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N } fn error_194(tcx: TyCtxt, span: Span, name: ast::Name) { - span_err!(tcx.sess, span, E0194, + struct_span_err!(tcx.sess, span, E0194, "type parameter `{}` shadows another type parameter of the same name", - name); + name) + .span_label(span, &format!("`{}` shadows another type parameter", name)) + .emit(); } diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index a3c043fe7cbd3..bcce64cb110c6 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -347,15 +347,19 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { return; } } - hir::ItemDefaultImpl(..) => { + hir::ItemDefaultImpl(_, ref item_trait_ref) => { // "Trait" impl debug!("coherence2::orphan check: default trait impl {}", self.tcx.map.node_to_string(item.id)); let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap(); if trait_ref.def_id.krate != LOCAL_CRATE { - span_err!(self.tcx.sess, item.span, E0318, + struct_span_err!(self.tcx.sess, item_trait_ref.path.span, E0318, "cannot create default implementations for traits outside the \ - crate they're defined in; define a new trait instead"); + crate they're defined in; define a new trait instead") + .span_label(item_trait_ref.path.span, + &format!("`{}` trait not defined in this crate", + item_trait_ref.path)) + .emit(); return; } } diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index 5d652ba2f55bb..7b5092e8848e4 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -136,7 +136,7 @@ impl< for item in self { bits |= item.to_usize(); } - s.emit_uint(bits) + s.emit_usize(bits) } } @@ -144,7 +144,7 @@ impl< T: Decodable + CLike > Decodable for EnumSet { fn decode(d: &mut D) -> Result, D::Error> { - let bits = d.read_uint()?; + let bits = d.read_usize()?; let mut set = EnumSet::new(); for bit in 0..(mem::size_of::()*8) { if bits & (1 << bit) != 0 { diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 6c4b6c4506b81..34df594e84756 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -495,13 +495,13 @@ impl<'a> ::Encoder for Encoder<'a> { Ok(()) } - fn emit_uint(&mut self, v: usize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } + fn emit_usize(&mut self, v: usize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_u64(&mut self, v: u64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_u32(&mut self, v: u32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_u16(&mut self, v: u16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_u8(&mut self, v: u8) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } - fn emit_int(&mut self, v: isize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } + fn emit_isize(&mut self, v: isize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_i64(&mut self, v: i64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_i32(&mut self, v: i32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_i16(&mut self, v: i16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } @@ -743,13 +743,13 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { Ok(()) } - fn emit_uint(&mut self, v: usize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } + fn emit_usize(&mut self, v: usize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_u64(&mut self, v: u64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_u32(&mut self, v: u32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_u16(&mut self, v: u16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_u8(&mut self, v: u8) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } - fn emit_int(&mut self, v: isize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } + fn emit_isize(&mut self, v: isize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_i64(&mut self, v: i64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_i32(&mut self, v: i32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } fn emit_i16(&mut self, v: i16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) } @@ -2137,12 +2137,12 @@ impl ::Decoder for Decoder { expect!(self.pop(), Null) } - read_primitive! { read_uint, usize } + read_primitive! { read_usize, usize } read_primitive! { read_u8, u8 } read_primitive! { read_u16, u16 } read_primitive! { read_u32, u32 } read_primitive! { read_u64, u64 } - read_primitive! { read_int, isize } + read_primitive! { read_isize, isize } read_primitive! { read_i8, i8 } read_primitive! { read_i16, i16 } read_primitive! { read_i32, i32 } diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 0fcab1347d160..b75ec5dad8ddd 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -24,12 +24,12 @@ pub trait Encoder { // Primitive types: fn emit_nil(&mut self) -> Result<(), Self::Error>; - fn emit_uint(&mut self, v: usize) -> Result<(), Self::Error>; + fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error>; fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error>; fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error>; fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error>; fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error>; - fn emit_int(&mut self, v: isize) -> Result<(), Self::Error>; + fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error>; fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error>; fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error>; fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error>; @@ -108,12 +108,12 @@ pub trait Decoder { // Primitive types: fn read_nil(&mut self) -> Result<(), Self::Error>; - fn read_uint(&mut self) -> Result; + fn read_usize(&mut self) -> Result; fn read_u64(&mut self) -> Result; fn read_u32(&mut self) -> Result; fn read_u16(&mut self) -> Result; fn read_u8(&mut self) -> Result; - fn read_int(&mut self) -> Result; + fn read_isize(&mut self) -> Result; fn read_i64(&mut self) -> Result; fn read_i32(&mut self) -> Result; fn read_i16(&mut self) -> Result; @@ -200,13 +200,13 @@ pub trait Decodable: Sized { impl Encodable for usize { fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_uint(*self) + s.emit_usize(*self) } } impl Decodable for usize { fn decode(d: &mut D) -> Result { - d.read_uint() + d.read_usize() } } @@ -260,13 +260,13 @@ impl Decodable for u64 { impl Encodable for isize { fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_int(*self) + s.emit_isize(*self) } } impl Decodable for isize { fn decode(d: &mut D) -> Result { - d.read_int() + d.read_isize() } } diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index f3e1710f50b0d..e3f3f9dd6de1e 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -320,6 +320,24 @@ pub fn spawn(f: F) -> JoinHandle where } /// Gets a handle to the thread that invokes it. +/// +/// #Examples +/// +/// Getting a handle to the current thread with `thread::current()`: +/// +/// ``` +/// use std::thread; +/// +/// let handler = thread::Builder::new() +/// .name("named thread".into()) +/// .spawn(|| { +/// let handle = thread::current(); +/// assert_eq!(handle.name(), Some("named thread")); +/// }) +/// .unwrap(); +/// +/// handler.join().unwrap(); +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn current() -> Thread { thread_info::current_thread().expect("use of std::thread::current() is not \ diff --git a/src/test/compile-fail/E0089.rs b/src/test/compile-fail/E0089.rs index 3b52f76bf09cc..9ce36523709e5 100644 --- a/src/test/compile-fail/E0089.rs +++ b/src/test/compile-fail/E0089.rs @@ -11,5 +11,7 @@ fn foo() {} fn main() { - foo::(); //~ ERROR E0089 + foo::(); +//~^ ERROR E0089 +//~| NOTE expected 2 type parameters } diff --git a/src/test/compile-fail/E0194.rs b/src/test/compile-fail/E0194.rs index 96b3062cacb78..fa94c88328a86 100644 --- a/src/test/compile-fail/E0194.rs +++ b/src/test/compile-fail/E0194.rs @@ -10,7 +10,9 @@ trait Foo { fn do_something(&self) -> T; - fn do_something_else(&self, bar: T); //~ ERROR E0194 + fn do_something_else(&self, bar: T); + //~^ ERROR E0194 + //~| NOTE `T` shadows another type parameter } fn main() { diff --git a/src/test/compile-fail/E0260.rs b/src/test/compile-fail/E0260.rs index d20829bf4d415..63647cb41035a 100644 --- a/src/test/compile-fail/E0260.rs +++ b/src/test/compile-fail/E0260.rs @@ -9,8 +9,11 @@ // except according to those terms. extern crate collections; +//~^ NOTE previous import of `collections` here -mod collections { //~ ERROR E0260 +mod collections { +//~^ ERROR `collections` has already been imported in this module [E0260] +//~| NOTE `collections` already imported pub trait MyTrait { fn do_something(); } diff --git a/src/test/compile-fail/E0463.rs b/src/test/compile-fail/E0463.rs index 3eff107365af1..3ce5b83e89fd4 100644 --- a/src/test/compile-fail/E0463.rs +++ b/src/test/compile-fail/E0463.rs @@ -9,7 +9,9 @@ // except according to those terms. #![feature(plugin)] -#![plugin(cookie_monster)] //~ ERROR E0463 +#![plugin(cookie_monster)] +//~^ ERROR E0463 +//~| NOTE can't find crate extern crate cake_is_a_lie; fn main() { diff --git a/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs b/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs index 09b97dfb30f24..55004fe8557f2 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs @@ -10,7 +10,6 @@ #![feature(optin_builtin_traits)] -impl Copy for .. {} -//~^ ERROR E0318 - +impl Copy for .. {} //~ ERROR E0318 + //~^ ERROR `Copy` trait not defined in this crate fn main() {} diff --git a/src/test/run-pass/issue-35423.rs b/src/test/run-pass/issue-35423.rs new file mode 100644 index 0000000000000..35d0c305ed834 --- /dev/null +++ b/src/test/run-pass/issue-35423.rs @@ -0,0 +1,18 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main () { + let x = 4; + match x { + ref r if *r < 0 => println!("got negative num {} < 0", r), + e @ 1 ... 100 => println!("got number within range [1,100] {}", e), + _ => println!("no"), + } +}