From e805cb6374550190f8b3c4582fe67ae40d5b7a16 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 29 Jul 2016 14:32:35 +0200 Subject: [PATCH 01/44] Add io::Error doc examples --- src/libstd/io/error.rs | 145 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 05ae8ed5b0b66..63016a1a79594 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -208,6 +208,14 @@ impl Error { /// This function reads the value of `errno` for the target platform (e.g. /// `GetLastError` on Windows) and will return a corresponding instance of /// `Error` for the error code. + /// + /// # Examples + /// + /// ``` + /// use std::io::Error; + /// + /// println!("last OS error: {:?}", Error::last_os_error()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn last_os_error() -> Error { Error::from_raw_os_error(sys::os::errno() as i32) @@ -248,6 +256,27 @@ impl Error { /// If this `Error` was constructed via `last_os_error` or /// `from_raw_os_error`, then this function will return `Some`, otherwise /// it will return `None`. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// + /// fn print_os_error(err: &Error) { + /// if let Some(raw_os_err) = err.raw_os_error() { + /// println!("raw OS error: {:?}", raw_os_err); + /// } else { + /// println!("Not an OS error"); + /// } + /// } + /// + /// fn main() { + /// // Will print "raw OS error: ...". + /// print_os_error(&Error::last_os_error()); + /// // Will print "Not an OS error". + /// print_os_error(&Error::new(ErrorKind::Other, "oh no!")); + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn raw_os_error(&self) -> Option { match self.repr { @@ -260,6 +289,27 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// + /// fn print_error(err: &Error) { + /// if let Some(inner_err) = err.get_ref() { + /// println!("Inner error: {:?}", inner_err); + /// } else { + /// println!("No inner error"); + /// } + /// } + /// + /// fn main() { + /// // Will print "No inner error". + /// print_error(&Error::last_os_error()); + /// // Will print "Inner error: ...". + /// print_error(&Error::new(ErrorKind::Other, "oh no!")); + /// } + /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> { match self.repr { @@ -273,6 +323,63 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// use std::{error, fmt}; + /// use std::fmt::Display; + /// + /// #[derive(Debug)] + /// struct MyError { + /// v: String, + /// } + /// + /// impl MyError { + /// fn new() -> MyError { + /// MyError { + /// v: "oh no!".to_owned() + /// } + /// } + /// + /// fn change_message(&mut self, new_message: &str) { + /// self.v = new_message.to_owned(); + /// } + /// } + /// + /// impl error::Error for MyError { + /// fn description(&self) -> &str { &self.v } + /// } + /// + /// impl Display for MyError { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f, "MyError: {}", &self.v) + /// } + /// } + /// + /// fn change_error(mut err: Error) -> Error { + /// if let Some(inner_err) = err.get_mut() { + /// inner_err.downcast_mut::().unwrap().change_message("I've been changed!"); + /// } + /// err + /// } + /// + /// fn print_error(err: &Error) { + /// if let Some(inner_err) = err.get_ref() { + /// println!("Inner error: {}", inner_err); + /// } else { + /// println!("No inner error"); + /// } + /// } + /// + /// fn main() { + /// // Will print "No inner error". + /// print_error(&change_error(Error::last_os_error())); + /// // Will print "Inner error: ...". + /// print_error(&change_error(Error::new(ErrorKind::Other, MyError::new()))); + /// } + /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> { match self.repr { @@ -285,6 +392,27 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// + /// fn print_error(err: Error) { + /// if let Some(inner_err) = err.into_inner() { + /// println!("Inner error: {}", inner_err); + /// } else { + /// println!("No inner error"); + /// } + /// } + /// + /// fn main() { + /// // Will print "No inner error". + /// print_error(Error::last_os_error()); + /// // Will print "Inner error: ...". + /// print_error(Error::new(ErrorKind::Other, "oh no!")); + /// } + /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] pub fn into_inner(self) -> Option> { match self.repr { @@ -294,6 +422,23 @@ impl Error { } /// Returns the corresponding `ErrorKind` for this error. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// + /// fn print_error(err: Error) { + /// println!("{:?}", err.kind()); + /// } + /// + /// fn main() { + /// // Will print "No inner error". + /// print_error(Error::last_os_error()); + /// // Will print "Inner error: ...". + /// print_error(Error::new(ErrorKind::AddrInUse, "oh no!")); + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn kind(&self) -> ErrorKind { match self.repr { From aad5f6f912298bd0a4cc1dea698b652f81badd29 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 00:53:18 +0200 Subject: [PATCH 02/44] Add doc example for io::Stderr --- src/libstd/io/stdio.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index c4b573db5f2dd..a25bc038b7ba3 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -505,6 +505,21 @@ impl Stderr { /// /// The lock is released when the returned lock goes out of scope. The /// returned guard also implements the `Write` trait for writing data. + /// + /// # Examples + /// + /// ``` + /// use std::io::{self, Write}; + /// + /// fn foo() -> io::Result<()> { + /// let stderr = io::stderr(); + /// let mut handle = stderr.lock(); + /// + /// try!(handle.write(b"hello world")); + /// + /// Ok(()) + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StderrLock { StderrLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } From 451683f0eec360bf4adbec5c19be764b7fac79e4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 00:56:14 +0200 Subject: [PATCH 03/44] Add doc example for Stdin --- src/libstd/io/stdio.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index a25bc038b7ba3..d7566d5c9a4f1 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -240,6 +240,21 @@ impl Stdin { /// /// [`Read`]: trait.Read.html /// [`BufRead`]: trait.BufRead.html + /// + /// # Examples + /// + /// ``` + /// use std::io::{self, Read}; + /// + /// # fn foo() -> io::Result { + /// let mut buffer = String::new(); + /// let stdin = io::stdin(); + /// let mut handle = stdin.lock(); + /// + /// try!(handle.read_to_string(&mut buffer)); + /// # Ok(buffer) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdinLock { StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } From aeb3af898ae426031376a345f91e04bfc7af32f8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 00:57:20 +0200 Subject: [PATCH 04/44] Add doc example for Stdout --- src/libstd/io/stdio.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index d7566d5c9a4f1..b8b66a58359e7 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -414,6 +414,21 @@ impl Stdout { /// /// The lock is released when the returned lock goes out of scope. The /// returned guard also implements the `Write` trait for writing data. + /// + /// # Examples + /// + /// ``` + /// use std::io::{self, Write}; + /// + /// # fn foo() -> io::Result<()> { + /// let stdout = io::stdout(); + /// let mut handle = stdout.lock(); + /// + /// try!(handle.write(b"hello world")); + /// + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdoutLock { StdoutLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } From 2bed205d3be05682b84693edeed4d84d850eb801 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 13:30:41 +0200 Subject: [PATCH 05/44] Add io::Take doc example --- src/libstd/io/mod.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index d5b255ee57376..3d1ee5b7ae7c9 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1482,6 +1482,24 @@ impl Take { /// /// This instance may reach EOF after reading fewer bytes than indicated by /// this method if the underlying `Read` instance reaches EOF. + /// + /// # Examples + /// + /// ``` + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// + /// # fn foo() -> io::Result<()> { + /// let f = try!(File::open("foo.txt")); + /// + /// // read at most five bytes + /// let handle = f.take(5); + /// + /// println!("limit: {}", handle.limit()); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn limit(&self) -> u64 { self.limit } } From fda473f00fa07b9a8246b104396f9922e54bff16 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 13:37:52 +0200 Subject: [PATCH 06/44] Add urls in std::io types --- src/libstd/io/error.rs | 8 +++++++- src/libstd/io/mod.rs | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 63016a1a79594..5333b0a531eae 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -55,7 +55,9 @@ pub type Result = result::Result; /// /// Errors mostly originate from the underlying OS, but custom instances of /// `Error` can be created with crafted error messages and a particular value of -/// `ErrorKind`. +/// [`ErrorKind`]. +/// +/// [`ErrorKind`]: enum.ErrorKind.html #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Error { @@ -77,6 +79,10 @@ struct Custom { /// /// This list is intended to grow over time and it is not recommended to /// exhaustively match against it. +/// +/// It is used with the [`io::Error`] type. +/// +/// [`io::Error`]: struct.Error.html #[derive(Copy, PartialEq, Eq, Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 3d1ee5b7ae7c9..88fd4186e0a2a 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1082,16 +1082,22 @@ pub trait Seek { /// /// If the seek operation completed successfully, /// this method returns the new position from the start of the stream. - /// That position can be used later with `SeekFrom::Start`. + /// That position can be used later with [`SeekFrom::Start`]. /// /// # Errors /// /// Seeking to a negative offset is considered an error. + /// + /// [`SeekFrom::Start`]: enum.SeekFrom.html#variant.Start #[stable(feature = "rust1", since = "1.0.0")] fn seek(&mut self, pos: SeekFrom) -> Result; } /// Enumeration of possible methods to seek within an I/O object. +/// +/// It is used by the [`Seek`] trait. +/// +/// [`Seek`]: trait.Seek.html #[derive(Copy, PartialEq, Eq, Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub enum SeekFrom { From b77b9b72fe5eb4f7c157816d109b220ab3f2de2c Mon Sep 17 00:00:00 2001 From: Jonathan Giddy Date: Sun, 31 Jul 2016 12:43:39 +0100 Subject: [PATCH 07/44] Provide more explicit example of wildcard version in guessing game doc. Beginners may try to adapt the tutorial to develop their own code. When using different dependencies, they may use the wildcard for versioning. Since they are new to the language, they will not know that the wildcard asterisk is a string, not a token. Make the correct format more explicit, to remove one potential source of frustration. --- src/doc/book/guessing-game.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book/guessing-game.md b/src/doc/book/guessing-game.md index 6ce75efd1031d..22cf6068e4d5a 100644 --- a/src/doc/book/guessing-game.md +++ b/src/doc/book/guessing-game.md @@ -365,7 +365,7 @@ numbers. A bare number like above is actually shorthand for `^0.3.0`, meaning "anything compatible with 0.3.0". If we wanted to use only `0.3.0` exactly, we could say `rand="=0.3.0"` (note the two equal signs). -And if we wanted to use the latest version we could use `*`. +And if we wanted to use the latest version we could use `rand="*"`. We could also use a range of versions. [Cargo’s documentation][cargodoc] contains more details. From 65e3ff4df44effdfa60971cd7b66e4ce8a4c5bb9 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Thu, 16 Jun 2016 23:15:06 -0700 Subject: [PATCH 08/44] add extended information for E0529, slice pattern expects array or slice --- src/librustc_typeck/diagnostics.rs | 32 +++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 500f624ea3f72..3867ed5fa6868 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3980,6 +3980,37 @@ impl SpaceLlama for i32 { ``` "##, +E0529: r##" +An array or slice pattern was matched against some other type. + +Example of erroneous code: + +```compile_fail,E0529 +#![feature(slice_patterns)] + +let r: f32 = 1.0; +match r { + [a, b] => { // error: expected an array or slice, found `f32` + println!("a={}, b={}", a, b); + } +} +``` + +Ensure that the pattern and the expression being matched on are of consistent +types: + +``` +#![feature(slice_patterns)] + +let r = [1.0, 2.0]; +match r { + [a, b] => { // ok! + println!("a={}, b={}", a, b); + } +} +``` +"##, + E0559: r##" An unknown field was specified into an enum's structure variant. @@ -4102,6 +4133,5 @@ register_diagnostics! { E0521, // redundant default implementations of trait E0527, // expected {} elements, found {} E0528, // expected at least {} elements, found {} - E0529, // slice pattern expects array or slice, not `{}` E0533, // `{}` does not name a unit variant, unit struct or a constant } From 7093d1de8455556640578ad3d493bc9bff79b8e5 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Thu, 16 Jun 2016 23:45:44 -0700 Subject: [PATCH 09/44] add extended info for E0527, slice pattern element count expectations --- src/librustc_typeck/diagnostics.rs | 34 +++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 3867ed5fa6868..cf8fd3da1f5ba 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3980,6 +3980,39 @@ impl SpaceLlama for i32 { ``` "##, +E0527: r##" +The number of elements in an array or slice pattern differed from the number of +elements in the array being matched. + +Example of erroneous code: + +```compile_fail,E0527 +#![feature(slice_patterns)] + +let r = &[1, 2, 3, 4]; +match r { + &[a, b] => { // error: pattern requires 2 elements but array + // has 4 + println!("a={}, b={}", a, b); + } +} +``` + +Ensure that the pattern is consistent with the size of the matched +array. Additional elements can be matched with `..`: + +``` +#![feature(slice_patterns)] + +let r = &[1, 2, 3, 4]; +match r { + &[a, b, ..] => { // ok! + println!("a={}, b={}", a, b); + } +} +``` +"##, + E0529: r##" An array or slice pattern was matched against some other type. @@ -4131,7 +4164,6 @@ register_diagnostics! { E0436, // functional record update requires a struct E0513, // no type for local variable .. E0521, // redundant default implementations of trait - E0527, // expected {} elements, found {} E0528, // expected at least {} elements, found {} E0533, // `{}` does not name a unit variant, unit struct or a constant } From e960021d30faff871f98c9c463b43c4359af280d Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Fri, 17 Jun 2016 00:03:36 -0700 Subject: [PATCH 10/44] extended info for E0528, expected at least this-and-such many elements --- src/librustc_typeck/diagnostics.rs | 35 +++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index cf8fd3da1f5ba..4b0b616c5f648 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4013,6 +4013,40 @@ match r { ``` "##, +E0528: r##" +An array or slice pattern required more elements than were present in the +matched array. + +Example of erroneous code: + +```compile_fail,E0528 +#![feature(slice_patterns)] + +let r = &[1, 2]; +match r { + &[a, b, c, rest..] => { // error: pattern requires at least 3 + // elements but array has 2 + println!("a={}, b={}, c={} rest={:?}", a, b, c, rest); + } +} +``` + +Ensure that the matched array has at least as many elements as the pattern +requires. You can match an arbitrary number of remaining elements with `..`: + +``` +#![feature(slice_patterns)] + +let r = &[1, 2, 3, 4, 5]; +match r { + &[a, b, c, rest..] => { // ok! + // prints `a=1, b=2, c=3 rest=[4, 5]` + println!("a={}, b={}, c={} rest={:?}", a, b, c, rest); + } +} +``` +"##, + E0529: r##" An array or slice pattern was matched against some other type. @@ -4164,6 +4198,5 @@ register_diagnostics! { E0436, // functional record update requires a struct E0513, // no type for local variable .. E0521, // redundant default implementations of trait - E0528, // expected at least {} elements, found {} E0533, // `{}` does not name a unit variant, unit struct or a constant } From 157f7c1b30698dcdb2452e687f4940550a6e6467 Mon Sep 17 00:00:00 2001 From: "Ryan Scheel (Havvy)" Date: Tue, 26 Jul 2016 05:14:37 +0000 Subject: [PATCH 11/44] Add Derive not possible question to Copy This adds a question and answer to the Q&A section of the Copy docs. Specifically, it asks the question I asked while reading the docs, and gives its answer. --- src/libcore/marker.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index c18d230be31af..894982abaa939 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -144,6 +144,12 @@ pub trait Unsize { /// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's /// managing some resource besides its own `size_of::()` bytes. /// +/// ## What if I derive `Copy` on a type that can't? +/// +/// If you try to derive `Copy` on a struct or enum, you will get a compile-time error. +/// Specifically, with structs you'll get [E0204](https://doc.rust-lang.org/error-index.html#E0204) +/// and with enums you'll get [E0205](https://doc.rust-lang.org/error-index.html#E0205). +/// /// ## When should my type be `Copy`? /// /// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing From 57e3b9eb713f44a9dce97be5840c536bd7a86069 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 1 Aug 2016 20:16:56 -0400 Subject: [PATCH 12/44] Indicate where the `std::net::Incoming` struct is created. --- src/libstd/net/tcp.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 5ab0d5a0877b7..76617f159707d 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -77,6 +77,11 @@ pub struct TcpListener(net_imp::TcpListener); /// /// This iterator will infinitely yield `Some` of the accepted connections. It /// is equivalent to calling `accept` in a loop. +/// +/// This `struct` is created by the [`incoming`] method on [`TcpListener`]. +/// +/// [`incoming`]: struct.TcpListener.html#method.incoming +/// [`TcpListener`]: struct.TcpListener.html #[stable(feature = "rust1", since = "1.0.0")] pub struct Incoming<'a> { listener: &'a TcpListener } From f2d8db15dfe9b715f0e0a957440d79945270a20f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 1 Aug 2016 20:21:08 -0400 Subject: [PATCH 13/44] Link to relevant method/struct for `std::net::Shutdown` docs. --- src/libstd/net/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index ac13b23ebee50..11a16b271133b 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -35,7 +35,11 @@ mod udp; mod parser; #[cfg(test)] mod test; -/// Possible values which can be passed to the `shutdown` method of `TcpStream`. +/// Possible values which can be passed to the [`shutdown`] method of +/// [`TcpStream`]. +/// +/// [`shutdown`]: struct.TcpStream.html#method.shutdown +/// [`TcpStream`]: struct.TcpStream.html #[derive(Copy, Clone, PartialEq, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub enum Shutdown { From 3081dd863718f941e283ec954f36a23bbe58ffeb Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 2 Aug 2016 08:49:05 -0400 Subject: [PATCH 14/44] Add doc example for `std::ffi::NulError::nul_position`. --- src/libstd/ffi/c_str.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 0d3e18f9b966a..f800a6e228e9b 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -356,6 +356,18 @@ impl Borrow for CString { impl NulError { /// Returns the position of the nul byte in the slice that was provided to /// `CString::new`. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::CString; + /// + /// let nul_error = CString::new("foo\0bar").unwrap_err(); + /// assert_eq!(nul_error.nul_position(), 3); + /// + /// let nul_error = CString::new("foo bar\0").unwrap_err(); + /// assert_eq!(nul_error.nul_position(), 7); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn nul_position(&self) -> usize { self.0 } From 727d9293e47b349c500d34f887e43051d865de4d Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 25 Jul 2016 23:25:12 -0400 Subject: [PATCH 15/44] Add doc examples for `range::RangeArgument::{start,end}`. --- src/libcollections/range.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/libcollections/range.rs b/src/libcollections/range.rs index 4e39191b472ee..1badc72aed07c 100644 --- a/src/libcollections/range.rs +++ b/src/libcollections/range.rs @@ -23,6 +23,22 @@ pub trait RangeArgument { /// Start index (inclusive) /// /// Return start value if present, else `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(collections)] + /// #![feature(collections_range)] + /// + /// extern crate collections; + /// + /// # fn main() { + /// use collections::range::RangeArgument; + /// + /// assert_eq!((..10).start(), None); + /// assert_eq!((3..10).start(), Some(&3)); + /// # } + /// ``` fn start(&self) -> Option<&T> { None } @@ -30,6 +46,22 @@ pub trait RangeArgument { /// End index (exclusive) /// /// Return end value if present, else `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(collections)] + /// #![feature(collections_range)] + /// + /// extern crate collections; + /// + /// # fn main() { + /// use collections::range::RangeArgument; + /// + /// assert_eq!((3..).end(), None); + /// assert_eq!((3..10).end(), Some(&10)); + /// # } + /// ``` fn end(&self) -> Option<&T> { None } From 1fa9b8dc96f95ec5d6c95746d58e96f507ab85fd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 2 Aug 2016 03:28:13 +0200 Subject: [PATCH 16/44] Add doc example for Vec --- src/libcollections/vec.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 275f38b2f787d..8b4fce158de46 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -476,6 +476,25 @@ impl Vec { /// Note that this will drop any excess capacity. Calling this and /// converting back to a vector with `into_vec()` is equivalent to calling /// `shrink_to_fit()`. + /// + /// # Examples + /// + /// ``` + /// let v = vec![1, 2, 3]; + /// + /// let slice = v.into_boxed_slice(); + /// ``` + /// + /// Any excess capacity is removed: + /// + /// ``` + /// let mut vec = Vec::with_capacity(10); + /// vec.extend([1, 2, 3].iter().cloned()); + /// + /// assert_eq!(vec.capacity(), 10); + /// let slice = vec.into_boxed_slice(); + /// assert_eq!(slice.into_vec().capacity(), 3); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn into_boxed_slice(mut self) -> Box<[T]> { unsafe { From d90c16625f932a4e08a56c1f2f131d8c5ce1214c Mon Sep 17 00:00:00 2001 From: mLuby Date: Tue, 2 Aug 2016 14:08:19 -0700 Subject: [PATCH 17/44] Update the-stack-and-the-heap.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was surprised to learn that heaps were used in this way, then realized upon reading [the linked paper](http://www.cs.cmu.edu/afs/cs/academic/class/15213-f98/doc/dsa.pdf) that it's a totally different type of heap—an important distinction. --- src/doc/book/the-stack-and-the-heap.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doc/book/the-stack-and-the-heap.md b/src/doc/book/the-stack-and-the-heap.md index a1f6a065a252b..aee45299cf22d 100644 --- a/src/doc/book/the-stack-and-the-heap.md +++ b/src/doc/book/the-stack-and-the-heap.md @@ -26,6 +26,8 @@ The stack is very fast, and is where memory is allocated in Rust by default. But the allocation is local to a function call, and is limited in size. The heap, on the other hand, is slower, and is explicitly allocated by your program. But it’s effectively unlimited in size, and is globally accessible. +Note this meaning of heap, which allocates arbitrary-sized blocks of memory in arbitrary +order, is quite different from the heap data structure. # The Stack From 3e46c9dfcc60733be20cc8de1361e809669e5096 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 27 Jul 2016 20:55:14 +0200 Subject: [PATCH 18/44] Add doc examples for FileType struct --- src/libstd/fs.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 48753ccf1c353..2b2f21522d4be 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -156,7 +156,10 @@ pub struct OpenOptions(fs_imp::OpenOptions); #[stable(feature = "rust1", since = "1.0.0")] pub struct Permissions(fs_imp::FilePermissions); -/// An structure representing a type of file with accessors for each file type. +/// A structure representing a type of file with accessors for each file type. +/// It is returned by [`Metadata::file_type`] method. +/// +/// [`Metadata::file_type`]: struct.Metadata.html#method.file_type #[stable(feature = "file_type", since = "1.1.0")] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct FileType(fs_imp::FileType); @@ -610,6 +613,19 @@ impl AsInnerMut for OpenOptions { impl Metadata { /// Returns the file type for this metadata. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// + /// println!("{:?}", metadata.file_type()); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn file_type(&self) -> FileType { FileType(self.0.file_type()) @@ -788,14 +804,56 @@ impl Permissions { impl FileType { /// Test whether this file type represents a directory. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// let file_type = metadata.file_type(); + /// + /// assert_eq!(file_type.is_dir(), false); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn is_dir(&self) -> bool { self.0.is_dir() } /// Test whether this file type represents a regular file. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// let file_type = metadata.file_type(); + /// + /// assert_eq!(file_type.is_file(), true); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn is_file(&self) -> bool { self.0.is_file() } /// Test whether this file type represents a symbolic link. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// let file_type = metadata.file_type(); + /// + /// assert_eq!(file_type.is_symlink(), false); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn is_symlink(&self) -> bool { self.0.is_symlink() } } From d603892ea7649f5b1a31f871a2ddc54c18d6a02b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 3 Aug 2016 20:42:05 +0200 Subject: [PATCH 19/44] Add span method for hir::Generics struct --- src/librustc/hir/mod.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 20bf4f7d3edbb..9212fda650253 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -36,7 +36,7 @@ use hir::def::Def; use hir::def_id::DefId; use util::nodemap::{NodeMap, FnvHashSet}; -use syntax_pos::{mk_sp, Span, ExpnId}; +use syntax_pos::{BytePos, mk_sp, Span, ExpnId}; use syntax::codemap::{self, respan, Spanned}; use syntax::abi::Abi; use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect}; @@ -326,6 +326,38 @@ impl Generics { pub fn is_parameterized(&self) -> bool { self.is_lt_parameterized() || self.is_type_parameterized() } + + // Does return a span which includes lifetimes and type parameters, + // not where clause. + pub fn span(&self) -> Option { + if !self.is_parameterized() { + None + } else { + let mut span: Option = None; + for lifetime in self.lifetimes.iter() { + if let Some(ref mut span) = span { + let life_span = lifetime.lifetime.span; + span.hi = if span.hi > life_span.hi { span.hi } else { life_span.hi }; + span.lo = if span.lo < life_span.lo { span.lo } else { life_span.lo }; + } else { + span = Some(lifetime.lifetime.span.clone()); + } + } + for ty_param in self.ty_params.iter() { + if let Some(ref mut span) = span { + span.lo = if span.lo < ty_param.span.lo { span.lo } else { ty_param.span.lo }; + span.hi = if span.hi > ty_param.span.hi { span.hi } else { ty_param.span.hi }; + } else { + span = Some(ty_param.span.clone()); + } + } + if let Some(ref mut span) = span { + span.lo = span.lo - BytePos(1); + span.hi = span.hi + BytePos(1); + } + span + } + } } /// A `where` clause in a definition From 9b690c94f042a49f5f06c417cb9c5ab401dd0be8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 3 Aug 2016 20:42:42 +0200 Subject: [PATCH 20/44] Update E0132 to new format --- src/librustc_typeck/lib.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 3b2d02dc861c4..6f0892cdcdf16 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -261,8 +261,11 @@ fn check_start_fn_ty(ccx: &CrateCtxt, match it.node { hir::ItemFn(_,_,_,_,ref ps,_) if ps.is_parameterized() => { - span_err!(tcx.sess, start_span, E0132, - "start function is not allowed to have type parameters"); + struct_span_err!(tcx.sess, start_span, E0132, + "start function is not allowed to have type parameters") + .span_label(ps.span().unwrap(), + &format!("start function cannot have type parameters")) + .emit(); return; } _ => () From 4fc6f5ac264a58ddaaaf3d2ddfbe011eb675edaf Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Wed, 3 Aug 2016 13:30:28 +0200 Subject: [PATCH 21/44] Add an example to `std::thread::park_timeout` --- src/libstd/thread/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index e9736fea7b37f..40d5c70024683 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -478,6 +478,25 @@ pub fn park_timeout_ms(ms: u32) { /// /// Platforms which do not support nanosecond precision for sleeping will have /// `dur` rounded up to the nearest granularity of time they can sleep for. +/// +/// # Example +/// +/// Waiting for the complete expiration of the timeout: +/// +/// ```rust,no_run +/// use std::thread::park_timeout; +/// use std::time::{Instant, Duration}; +/// +/// let timeout = Duration::from_secs(2); +/// let beginning_park = Instant::now(); +/// park_timeout(timeout); +/// +/// while beginning_park.elapsed() < timeout { +/// println!("restarting park_timeout after {:?}", beginning_park.elapsed()); +/// let timeout = timeout - beginning_park.elapsed(); +/// park_timeout(timeout); +/// } +/// ``` #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { let thread = current(); From 20721a4923db5a8a462d8a8229d1f1a13e56e17c Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Wed, 3 Aug 2016 13:34:49 +0200 Subject: [PATCH 22/44] Add link to replacement function --- src/libstd/thread/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 40d5c70024683..f06c105d30e65 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -447,6 +447,8 @@ pub fn park() { *guard = false; } +/// Use [park_timeout]. +/// /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// @@ -456,7 +458,10 @@ pub fn park() { /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `ms` long. /// -/// See the module doc for more detail. +/// See the [module documentation][thread] for more detail. +/// +/// [thread]: index.html +/// [park_timeout]: fn.park_timeout.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")] pub fn park_timeout_ms(ms: u32) { From 1607d5b437d613908aee08cb9d2bc7330abf5b96 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 3 Aug 2016 23:13:48 +0200 Subject: [PATCH 23/44] Add note test for E0132 --- src/test/compile-fail/E0132.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/compile-fail/E0132.rs b/src/test/compile-fail/E0132.rs index ff19a577f903d..1a33fb24ca1a1 100644 --- a/src/test/compile-fail/E0132.rs +++ b/src/test/compile-fail/E0132.rs @@ -12,6 +12,7 @@ #[start] fn f() {} //~ ERROR E0132 + //~| NOTE start function cannot have type parameters fn main() { } From c89e27824f8f30e0c8dd153a9f6bb6a31ddfc65b Mon Sep 17 00:00:00 2001 From: Chris Stankus Date: Wed, 3 Aug 2016 18:00:52 -0500 Subject: [PATCH 24/44] Update error message for E0109 --- src/librustc/middle/astconv_util.rs | 6 ++++-- src/test/compile-fail/E0109.rs | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index e856eb84ff2c3..f9a05056a7cfd 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -24,8 +24,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn prohibit_type_params(self, segments: &[ast::PathSegment]) { for segment in segments { for typ in segment.parameters.types() { - span_err!(self.sess, typ.span, E0109, - "type parameters are not allowed on this type"); + struct_span_err!(self.sess, typ.span, E0109, + "type parameters are not allowed on this type") + .span_label(typ.span, &format!("type parameter not allowed")) + .emit(); break; } for lifetime in segment.parameters.lifetimes() { diff --git a/src/test/compile-fail/E0109.rs b/src/test/compile-fail/E0109.rs index 9fc478422504b..2e4cbf8692693 100644 --- a/src/test/compile-fail/E0109.rs +++ b/src/test/compile-fail/E0109.rs @@ -9,6 +9,7 @@ // except according to those terms. type X = u32; //~ ERROR E0109 + //~| NOTE type parameter not allowed fn main() { } From 61318156f86c828b7d09decf45ea8e40aafbcc25 Mon Sep 17 00:00:00 2001 From: William Lee Date: Thu, 4 Aug 2016 00:32:49 -0400 Subject: [PATCH 25/44] Fixes for issues #35215 and #35216 --- src/librustc_typeck/check/mod.rs | 6 ++++++ src/test/compile-fail/E0060.rs | 2 ++ src/test/compile-fail/E0061.rs | 4 +++- src/test/compile-fail/issue-18819.rs | 1 + src/test/compile-fail/issue-3044.rs | 2 +- src/test/compile-fail/issue-4935.rs | 1 + src/test/compile-fail/method-call-err-msg.rs | 3 +++ src/test/compile-fail/not-enough-arguments.rs | 1 + src/test/compile-fail/overloaded-calls-bad.rs | 2 ++ src/test/compile-fail/variadic-ffi-3.rs | 2 ++ 10 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 6062bd048b3d2..de81ae26f5dd5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2384,6 +2384,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { arg_count, if arg_count == 1 {" was"} else {"s were"}), error_code); + + err.span_label(sp, &format!("expected {}{} parameter{}", + if variadic {"at least "} else {""}, + expected_count, + if expected_count == 1 {""} else {"s"})); + let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::>(); if input_types.len() > 0 { err.note(&format!("the following parameter type{} expected: {}", diff --git a/src/test/compile-fail/E0060.rs b/src/test/compile-fail/E0060.rs index b4a2898749792..f0aecba8afe5e 100644 --- a/src/test/compile-fail/E0060.rs +++ b/src/test/compile-fail/E0060.rs @@ -14,4 +14,6 @@ extern "C" { fn main() { unsafe { printf(); } //~ ERROR E0060 + //~| NOTE expected at least 1 parameter + //~| NOTE the following parameter type was expected } diff --git a/src/test/compile-fail/E0061.rs b/src/test/compile-fail/E0061.rs index 4a8eac2a9e226..3d8622647ef2f 100644 --- a/src/test/compile-fail/E0061.rs +++ b/src/test/compile-fail/E0061.rs @@ -11,5 +11,7 @@ fn f(a: u16, b: &str) {} fn main() { - f(0); //~ ERROR E0061 + f(0); //~ ERROR E0061 + //~| NOTE expected 2 parameters + //~| NOTE the following parameter types were expected } diff --git a/src/test/compile-fail/issue-18819.rs b/src/test/compile-fail/issue-18819.rs index 3591b9824145b..b6bdd4c2e65dd 100644 --- a/src/test/compile-fail/issue-18819.rs +++ b/src/test/compile-fail/issue-18819.rs @@ -25,4 +25,5 @@ fn print_x(_: &Foo, extra: &str) { fn main() { print_x(X); //~error this function takes 2 parameters but 1 parameter was supplied //~^ NOTE the following parameter types were expected: &Foo, &str + //~| NOTE expected 2 parameters } diff --git a/src/test/compile-fail/issue-3044.rs b/src/test/compile-fail/issue-3044.rs index 68046056fb315..144ceafdbfcd7 100644 --- a/src/test/compile-fail/issue-3044.rs +++ b/src/test/compile-fail/issue-3044.rs @@ -15,6 +15,6 @@ fn main() { }); //~^^ ERROR this function takes 2 parameters but 1 parameter was supplied //~^^^ NOTE the following parameter types were expected - // + //~| NOTE expected 2 parameters // the first error is, um, non-ideal. } diff --git a/src/test/compile-fail/issue-4935.rs b/src/test/compile-fail/issue-4935.rs index 438d238b6fe62..9ca4de7878ce5 100644 --- a/src/test/compile-fail/issue-4935.rs +++ b/src/test/compile-fail/issue-4935.rs @@ -13,3 +13,4 @@ fn foo(a: usize) {} fn main() { foo(5, 6) } //~ ERROR this function takes 1 parameter but 2 parameters were supplied //~^ NOTE the following parameter type was expected +//~| NOTE expected 1 parameter diff --git a/src/test/compile-fail/method-call-err-msg.rs b/src/test/compile-fail/method-call-err-msg.rs index 212c09364cf4c..bcf676dbede6f 100644 --- a/src/test/compile-fail/method-call-err-msg.rs +++ b/src/test/compile-fail/method-call-err-msg.rs @@ -20,10 +20,13 @@ impl Foo { fn main() { let x = Foo; x.zero(0) //~ ERROR this function takes 0 parameters but 1 parameter was supplied + //~^ NOTE expected 0 parameters .one() //~ ERROR this function takes 1 parameter but 0 parameters were supplied //~^ NOTE the following parameter type was expected + //~| NOTE expected 1 parameter .two(0); //~ ERROR this function takes 2 parameters but 1 parameter was supplied //~^ NOTE the following parameter types were expected + //~| NOTE expected 2 parameters let y = Foo; y.zero() diff --git a/src/test/compile-fail/not-enough-arguments.rs b/src/test/compile-fail/not-enough-arguments.rs index 1f5a54477dd6d..8dcde2cf48ce2 100644 --- a/src/test/compile-fail/not-enough-arguments.rs +++ b/src/test/compile-fail/not-enough-arguments.rs @@ -20,4 +20,5 @@ fn main() { foo(1, 2, 3); //~^ ERROR this function takes 4 parameters but 3 //~^^ NOTE the following parameter types were expected + //~| NOTE expected 4 parameters } diff --git a/src/test/compile-fail/overloaded-calls-bad.rs b/src/test/compile-fail/overloaded-calls-bad.rs index 8763fb0913a87..5865d93e1282f 100644 --- a/src/test/compile-fail/overloaded-calls-bad.rs +++ b/src/test/compile-fail/overloaded-calls-bad.rs @@ -42,7 +42,9 @@ fn main() { let ans = s(); //~^ ERROR this function takes 1 parameter but 0 parameters were supplied //~| NOTE the following parameter type was expected + //~| NOTE expected 1 parameter let ans = s("burma", "shave"); //~^ ERROR this function takes 1 parameter but 2 parameters were supplied //~| NOTE the following parameter type was expected + //~| NOTE expected 1 parameter } diff --git a/src/test/compile-fail/variadic-ffi-3.rs b/src/test/compile-fail/variadic-ffi-3.rs index d8620ead83639..cc9a7c84eded4 100644 --- a/src/test/compile-fail/variadic-ffi-3.rs +++ b/src/test/compile-fail/variadic-ffi-3.rs @@ -18,8 +18,10 @@ fn main() { unsafe { foo(); //~ ERROR: this function takes at least 2 parameters but 0 parameters were supplied //~^ NOTE the following parameter types were expected + //~| NOTE expected at least 2 parameters foo(1); //~ ERROR: this function takes at least 2 parameters but 1 parameter was supplied //~^ NOTE the following parameter types were expected + //~| NOTE expected at least 2 parameters let x: unsafe extern "C" fn(f: isize, x: u8) = foo; //~^ ERROR: mismatched types From 0e756840f0625f06a5e150528820e96316f7929f Mon Sep 17 00:00:00 2001 From: William Lee Date: Thu, 4 Aug 2016 08:07:14 -0400 Subject: [PATCH 26/44] Tidying up some of the line spacing / code formatting for NOTE/ERROR annotation to match other files. --- src/test/compile-fail/E0060.rs | 7 ++++--- src/test/compile-fail/E0061.rs | 7 ++++--- src/test/compile-fail/issue-18819.rs | 5 +++-- src/test/compile-fail/issue-3044.rs | 2 +- src/test/compile-fail/issue-4935.rs | 5 +++-- src/test/compile-fail/not-enough-arguments.rs | 2 +- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/test/compile-fail/E0060.rs b/src/test/compile-fail/E0060.rs index f0aecba8afe5e..342ad3f2148ae 100644 --- a/src/test/compile-fail/E0060.rs +++ b/src/test/compile-fail/E0060.rs @@ -13,7 +13,8 @@ extern "C" { } fn main() { - unsafe { printf(); } //~ ERROR E0060 - //~| NOTE expected at least 1 parameter - //~| NOTE the following parameter type was expected + unsafe { printf(); } + //~^ ERROR E0060 + //~| NOTE expected at least 1 parameter + //~| NOTE the following parameter type was expected } diff --git a/src/test/compile-fail/E0061.rs b/src/test/compile-fail/E0061.rs index 3d8622647ef2f..83b32200019f5 100644 --- a/src/test/compile-fail/E0061.rs +++ b/src/test/compile-fail/E0061.rs @@ -11,7 +11,8 @@ fn f(a: u16, b: &str) {} fn main() { - f(0); //~ ERROR E0061 - //~| NOTE expected 2 parameters - //~| NOTE the following parameter types were expected + f(0); + //~^ ERROR E0061 + //~| NOTE expected 2 parameters + //~| NOTE the following parameter types were expected } diff --git a/src/test/compile-fail/issue-18819.rs b/src/test/compile-fail/issue-18819.rs index b6bdd4c2e65dd..0310b4ea75fe1 100644 --- a/src/test/compile-fail/issue-18819.rs +++ b/src/test/compile-fail/issue-18819.rs @@ -23,7 +23,8 @@ fn print_x(_: &Foo, extra: &str) { } fn main() { - print_x(X); //~error this function takes 2 parameters but 1 parameter was supplied - //~^ NOTE the following parameter types were expected: &Foo, &str + print_x(X); + //~^ ERROR this function takes 2 parameters but 1 parameter was supplied + //~| NOTE the following parameter types were expected: &Foo, &str //~| NOTE expected 2 parameters } diff --git a/src/test/compile-fail/issue-3044.rs b/src/test/compile-fail/issue-3044.rs index 144ceafdbfcd7..d19e3b2c7b0a8 100644 --- a/src/test/compile-fail/issue-3044.rs +++ b/src/test/compile-fail/issue-3044.rs @@ -14,7 +14,7 @@ fn main() { needlesArr.iter().fold(|x, y| { }); //~^^ ERROR this function takes 2 parameters but 1 parameter was supplied - //~^^^ NOTE the following parameter types were expected + //~| NOTE the following parameter types were expected //~| NOTE expected 2 parameters // the first error is, um, non-ideal. } diff --git a/src/test/compile-fail/issue-4935.rs b/src/test/compile-fail/issue-4935.rs index 9ca4de7878ce5..58a84f3490b3c 100644 --- a/src/test/compile-fail/issue-4935.rs +++ b/src/test/compile-fail/issue-4935.rs @@ -11,6 +11,7 @@ // Regression test for issue #4935 fn foo(a: usize) {} -fn main() { foo(5, 6) } //~ ERROR this function takes 1 parameter but 2 parameters were supplied -//~^ NOTE the following parameter type was expected +fn main() { foo(5, 6) } +//~^ ERROR this function takes 1 parameter but 2 parameters were supplied +//~| NOTE the following parameter type was expected //~| NOTE expected 1 parameter diff --git a/src/test/compile-fail/not-enough-arguments.rs b/src/test/compile-fail/not-enough-arguments.rs index 8dcde2cf48ce2..f2f61fcaeec16 100644 --- a/src/test/compile-fail/not-enough-arguments.rs +++ b/src/test/compile-fail/not-enough-arguments.rs @@ -19,6 +19,6 @@ fn foo(a: isize, b: isize, c: isize, d:isize) { fn main() { foo(1, 2, 3); //~^ ERROR this function takes 4 parameters but 3 - //~^^ NOTE the following parameter types were expected + //~| NOTE the following parameter types were expected //~| NOTE expected 4 parameters } From ded0d512dc663c774d849cd9836212ff69e56f5c Mon Sep 17 00:00:00 2001 From: William Lee Date: Thu, 4 Aug 2016 08:28:48 -0400 Subject: [PATCH 27/44] Removing trailing whitespace leftover from last re-formatting commit --- src/test/compile-fail/E0060.rs | 2 +- src/test/compile-fail/E0061.rs | 2 +- src/test/compile-fail/issue-18819.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/compile-fail/E0060.rs b/src/test/compile-fail/E0060.rs index 342ad3f2148ae..e1f2618c180f6 100644 --- a/src/test/compile-fail/E0060.rs +++ b/src/test/compile-fail/E0060.rs @@ -13,7 +13,7 @@ extern "C" { } fn main() { - unsafe { printf(); } + unsafe { printf(); } //~^ ERROR E0060 //~| NOTE expected at least 1 parameter //~| NOTE the following parameter type was expected diff --git a/src/test/compile-fail/E0061.rs b/src/test/compile-fail/E0061.rs index 83b32200019f5..ca04b059dc7f6 100644 --- a/src/test/compile-fail/E0061.rs +++ b/src/test/compile-fail/E0061.rs @@ -12,7 +12,7 @@ fn f(a: u16, b: &str) {} fn main() { f(0); - //~^ ERROR E0061 + //~^ ERROR E0061 //~| NOTE expected 2 parameters //~| NOTE the following parameter types were expected } diff --git a/src/test/compile-fail/issue-18819.rs b/src/test/compile-fail/issue-18819.rs index 0310b4ea75fe1..cf650460c3de1 100644 --- a/src/test/compile-fail/issue-18819.rs +++ b/src/test/compile-fail/issue-18819.rs @@ -23,7 +23,7 @@ fn print_x(_: &Foo, extra: &str) { } fn main() { - print_x(X); + print_x(X); //~^ ERROR this function takes 2 parameters but 1 parameter was supplied //~| NOTE the following parameter types were expected: &Foo, &str //~| NOTE expected 2 parameters From 7fc0b2f3e29e9d2d4bcdbd82864864da21ddee8c Mon Sep 17 00:00:00 2001 From: Yossi Konstantinovsky Date: Thu, 4 Aug 2016 16:19:52 +0300 Subject: [PATCH 28/44] Update E0079 to new format --- src/librustc_typeck/collect.rs | 1 + src/test/compile-fail/E0079.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4486748a1f056..d59f07f6c5d69 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1057,6 +1057,7 @@ fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let print_err = |cv: ConstVal| { struct_span_err!(ccx.tcx.sess, e.span, E0079, "mismatched types") .note_expected_found(&"type", &ty_hint, &format!("{}", cv.description())) + .span_label(e.span, &format!("expected '{}' type", ty_hint)) .emit(); }; diff --git a/src/test/compile-fail/E0079.rs b/src/test/compile-fail/E0079.rs index 23957c72ff00e..c9b7f549d5aaa 100644 --- a/src/test/compile-fail/E0079.rs +++ b/src/test/compile-fail/E0079.rs @@ -10,6 +10,7 @@ enum Foo { Q = "32" //~ ERROR E0079 + //~^ expected 'isize' type } fn main() { From ee8d6b07091e762fbef8a3465806b48201ec5a2e Mon Sep 17 00:00:00 2001 From: Roy Brunton Date: Thu, 4 Aug 2016 15:13:46 +0100 Subject: [PATCH 29/44] Update error message for E0172 --- src/librustc_typeck/astconv.rs | 6 ++++-- src/test/compile-fail/E0172.rs | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 3b2bca4ab3912..744b4296ade20 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1075,8 +1075,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Ok((trait_ref, projection_bounds)) } _ => { - span_err!(self.tcx().sess, ty.span, E0172, - "expected a reference to a trait"); + struct_span_err!(self.tcx().sess, ty.span, E0172, + "expected a reference to a trait") + .span_label(ty.span, &format!("expected a trait")) + .emit(); Err(ErrorReported) } } diff --git a/src/test/compile-fail/E0172.rs b/src/test/compile-fail/E0172.rs index 7011bf0e93734..485a31d966637 100644 --- a/src/test/compile-fail/E0172.rs +++ b/src/test/compile-fail/E0172.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn foo(bar: i32+std::fmt::Display) {} //~ ERROR E0172 +fn foo(bar: i32+std::fmt::Display) {} + //~^ ERROR E0172 + //~| NOTE expected a trait fn main() { } From 08ff7a80c06037d5fcdc0a4124c937c02d419d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Medzi=C5=84ski?= Date: Thu, 4 Aug 2016 16:24:39 +0200 Subject: [PATCH 30/44] Update error message E0178 --- src/librustc_typeck/astconv.rs | 1 + src/test/compile-fail/E0178.rs | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 3b2bca4ab3912..01aa0740c0e6b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1086,6 +1086,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { "expected a path on the left-hand side \ of `+`, not `{}`", pprust::ty_to_string(ty)); + err.span_label(ty.span, &format!("expected a path")); let hi = bounds.iter().map(|x| match *x { hir::TraitTyParamBound(ref tr, _) => tr.span.hi, hir::RegionTyParamBound(ref r) => r.span.hi, diff --git a/src/test/compile-fail/E0178.rs b/src/test/compile-fail/E0178.rs index f34f3834e05b1..6527465e0b7f7 100644 --- a/src/test/compile-fail/E0178.rs +++ b/src/test/compile-fail/E0178.rs @@ -11,10 +11,18 @@ trait Foo {} struct Bar<'a> { - w: &'a Foo + Copy, //~ ERROR E0178 - x: &'a Foo + 'a, //~ ERROR E0178 - y: &'a mut Foo + 'a, //~ ERROR E0178 - z: fn() -> Foo + 'a, //~ ERROR E0178 + w: &'a Foo + Copy, + //~^ ERROR E0178 + //~| NOTE expected a path + x: &'a Foo + 'a, + //~^ ERROR E0178 + //~| NOTE expected a path + y: &'a mut Foo + 'a, + //~^ ERROR E0178 + //~| NOTE expected a path + z: fn() -> Foo + 'a, + //~^ ERROR E0178 + //~| NOTE expected a path } fn main() { From eeda69fcca2c554bd60072476292b37fccb01a61 Mon Sep 17 00:00:00 2001 From: saml Date: Thu, 4 Aug 2016 10:42:01 -0400 Subject: [PATCH 31/44] Set label for unreachable pattern Part of #35233 Fixes #35190 r? @jonathandturner --- src/librustc_const_eval/check_match.rs | 1 + src/test/compile-fail/issue-31221.rs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index d3952de2fbe30..6528525a61042 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -335,6 +335,7 @@ fn check_arms(cx: &MatchCheckCtxt, hir::MatchSource::Normal => { let mut err = struct_span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern"); + err.span_label(pat.span, &format!("this is unreachable pattern")); // if we had a catchall pattern, hint at that for row in &seen.0 { if pat_is_catchall(&cx.tcx.def_map.borrow(), row[0].0) { diff --git a/src/test/compile-fail/issue-31221.rs b/src/test/compile-fail/issue-31221.rs index 2b3df9ad1d83b..85eac907105b0 100644 --- a/src/test/compile-fail/issue-31221.rs +++ b/src/test/compile-fail/issue-31221.rs @@ -22,6 +22,7 @@ fn main() { //~^ NOTE this pattern matches any value Var2 => (), //~^ ERROR unreachable pattern + //~^^ NOTE this is unreachable pattern }; match &s { &Var1 => (), @@ -29,6 +30,7 @@ fn main() { //~^ NOTE this pattern matches any value &Var2 => (), //~^ ERROR unreachable pattern + //~^^ NOTE this is unreachable pattern }; let t = (Var1, Var1); match t { @@ -37,6 +39,7 @@ fn main() { //~^ NOTE this pattern matches any value anything => () //~^ ERROR unreachable pattern + //~^^ NOTE this is unreachable pattern }; // `_` need not emit a note, it is pretty obvious already. let t = (Var1, Var1); @@ -45,5 +48,6 @@ fn main() { _ => (), anything => () //~^ ERROR unreachable pattern + //~^^ NOTE this is unreachable pattern }; } From 034e6594112114897b243cb2cc2944c91c28d529 Mon Sep 17 00:00:00 2001 From: saml Date: Thu, 4 Aug 2016 11:22:02 -0400 Subject: [PATCH 32/44] Changing label to "this is an..." --- src/librustc_const_eval/check_match.rs | 2 +- src/test/compile-fail/issue-31221.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 6528525a61042..d148d2a0885ed 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -335,7 +335,7 @@ fn check_arms(cx: &MatchCheckCtxt, hir::MatchSource::Normal => { let mut err = struct_span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern"); - err.span_label(pat.span, &format!("this is unreachable pattern")); + err.span_label(pat.span, &format!("this is an unreachable pattern")); // if we had a catchall pattern, hint at that for row in &seen.0 { if pat_is_catchall(&cx.tcx.def_map.borrow(), row[0].0) { diff --git a/src/test/compile-fail/issue-31221.rs b/src/test/compile-fail/issue-31221.rs index 85eac907105b0..4997a6fee195b 100644 --- a/src/test/compile-fail/issue-31221.rs +++ b/src/test/compile-fail/issue-31221.rs @@ -22,7 +22,7 @@ fn main() { //~^ NOTE this pattern matches any value Var2 => (), //~^ ERROR unreachable pattern - //~^^ NOTE this is unreachable pattern + //~^^ NOTE this is an unreachable pattern }; match &s { &Var1 => (), @@ -30,7 +30,7 @@ fn main() { //~^ NOTE this pattern matches any value &Var2 => (), //~^ ERROR unreachable pattern - //~^^ NOTE this is unreachable pattern + //~^^ NOTE this is an unreachable pattern }; let t = (Var1, Var1); match t { @@ -39,7 +39,7 @@ fn main() { //~^ NOTE this pattern matches any value anything => () //~^ ERROR unreachable pattern - //~^^ NOTE this is unreachable pattern + //~^^ NOTE this is an unreachable pattern }; // `_` need not emit a note, it is pretty obvious already. let t = (Var1, Var1); @@ -48,6 +48,6 @@ fn main() { _ => (), anything => () //~^ ERROR unreachable pattern - //~^^ NOTE this is unreachable pattern + //~^^ NOTE this is an unreachable pattern }; } From 7c58b26f704b60eaac2a872cb4a6268ad4d1a458 Mon Sep 17 00:00:00 2001 From: Federico Ravasio Date: Wed, 3 Aug 2016 22:13:07 +0200 Subject: [PATCH 33/44] Updated E0071 to new format. The span underlines only the name of the thing that's not a struct rather than the whole expression. --- src/librustc_typeck/check/mod.rs | 9 ++++++--- src/test/compile-fail/E0071.rs | 9 +++++++-- src/test/compile-fail/trait-as-struct-constructor.rs | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 6062bd048b3d2..6081ef9964c24 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3147,9 +3147,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; if variant.is_none() || variant.unwrap().kind == ty::VariantKind::Tuple { // Reject tuple structs for now, braced and unit structs are allowed. - span_err!(self.tcx.sess, span, E0071, - "`{}` does not name a struct or a struct variant", - pprust::path_to_string(path)); + struct_span_err!(self.tcx.sess, path.span, E0071, + "`{}` does not name a struct or a struct variant", + pprust::path_to_string(path)) + .span_label(path.span, &format!("not a struct")) + .emit(); + return None; } diff --git a/src/test/compile-fail/E0071.rs b/src/test/compile-fail/E0071.rs index 658c8fb155114..6f0e55efffc92 100644 --- a/src/test/compile-fail/E0071.rs +++ b/src/test/compile-fail/E0071.rs @@ -11,6 +11,11 @@ enum Foo { FirstValue(i32) } fn main() { - let u = Foo::FirstValue { value: 0 }; //~ ERROR E0071 - let t = u32 { value: 4 }; //~ ERROR E0071 + let u = Foo::FirstValue { value: 0 }; + //~^ ERROR `Foo::FirstValue` does not name a struct or a struct variant [E0071] + //~| NOTE not a struct + + let t = u32 { value: 4 }; + //~^ ERROR `u32` does not name a struct or a struct variant [E0071] + //~| NOTE not a struct } diff --git a/src/test/compile-fail/trait-as-struct-constructor.rs b/src/test/compile-fail/trait-as-struct-constructor.rs index 13fdaa302f70a..c78eebddbfdb8 100644 --- a/src/test/compile-fail/trait-as-struct-constructor.rs +++ b/src/test/compile-fail/trait-as-struct-constructor.rs @@ -13,4 +13,5 @@ trait TraitNotAStruct {} fn main() { TraitNotAStruct{ value: 0 }; //~^ ERROR: `TraitNotAStruct` does not name a struct or a struct variant [E0071] + //~| NOTE not a struct } From 5430e555f5eba563a8f99c8ebab641abfb0642c8 Mon Sep 17 00:00:00 2001 From: Chris Stankus Date: Thu, 4 Aug 2016 10:47:39 -0500 Subject: [PATCH 34/44] E0110 update error format --- src/librustc/middle/astconv_util.rs | 7 +++++-- src/test/compile-fail/E0110.rs | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index e856eb84ff2c3..487f2d17cd978 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -29,8 +29,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { break; } for lifetime in segment.parameters.lifetimes() { - span_err!(self.sess, lifetime.span, E0110, - "lifetime parameters are not allowed on this type"); + struct_span_err!(self.sess, lifetime.span, E0110, + "lifetime parameters are not allowed on this type") + .span_label(lifetime.span, + &format!("lifetime parameter not allowed on this type")) + .emit(); break; } for binding in segment.parameters.bindings() { diff --git a/src/test/compile-fail/E0110.rs b/src/test/compile-fail/E0110.rs index fd169f4acc5eb..5a9e7a43de96b 100644 --- a/src/test/compile-fail/E0110.rs +++ b/src/test/compile-fail/E0110.rs @@ -9,6 +9,7 @@ // except according to those terms. type X = u32<'static>; //~ ERROR E0110 + //~| NOTE lifetime parameter not allowed on this type fn main() { } From a0bdb1761892f77e9ebd2fd3e42e8b49ec1e34fe Mon Sep 17 00:00:00 2001 From: Samuel Cormier-Iijima Date: Thu, 4 Aug 2016 15:09:15 -0400 Subject: [PATCH 35/44] Update E0124 to the new error format --- src/librustc_typeck/collect.rs | 11 ++++++----- src/test/compile-fail/E0124.rs | 4 +++- src/test/compile-fail/struct-fields-decl-dupe.rs | 4 +++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4486748a1f056..921df3db63587 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1010,11 +1010,12 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let fid = ccx.tcx.map.local_def_id(f.id); let dup_span = seen_fields.get(&f.name).cloned(); if let Some(prev_span) = dup_span { - let mut err = struct_span_err!(ccx.tcx.sess, f.span, E0124, - "field `{}` is already declared", - f.name); - span_note!(&mut err, prev_span, "previously declared here"); - err.emit(); + struct_span_err!(ccx.tcx.sess, f.span, E0124, + "field `{}` is already declared", + f.name) + .span_label(f.span, &"field already declared") + .span_label(prev_span, &format!("`{}` first declared here", f.name)) + .emit(); } else { seen_fields.insert(f.name, f.span); } diff --git a/src/test/compile-fail/E0124.rs b/src/test/compile-fail/E0124.rs index 414b19ead624d..18c5074610656 100644 --- a/src/test/compile-fail/E0124.rs +++ b/src/test/compile-fail/E0124.rs @@ -9,8 +9,10 @@ // except according to those terms. struct Foo { + field1: i32, //~ NOTE `field1` first declared here field1: i32, - field1: i32, //~ ERROR E0124 + //~^ ERROR field `field1` is already declared [E0124] + //~| NOTE field already declared } fn main() { diff --git a/src/test/compile-fail/struct-fields-decl-dupe.rs b/src/test/compile-fail/struct-fields-decl-dupe.rs index 049569e8a184f..dd9d7d2946882 100644 --- a/src/test/compile-fail/struct-fields-decl-dupe.rs +++ b/src/test/compile-fail/struct-fields-decl-dupe.rs @@ -9,8 +9,10 @@ // except according to those terms. struct BuildData { + foo: isize, //~ NOTE `foo` first declared here foo: isize, - foo: isize, //~ ERROR field `foo` is already declared + //~^ ERROR field `foo` is already declared [E0124] + //~| NOTE field already declared } fn main() { From df726a45e18a9e760931f867b995f642131180ad Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Thu, 4 Aug 2016 20:27:11 +0100 Subject: [PATCH 36/44] Update error format for E0137 --- src/librustc/middle/entry.rs | 7 +++++-- src/test/compile-fail/E0137.rs | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 23a261400ed07..0a363fddd5312 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -121,8 +121,11 @@ fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) { if ctxt.attr_main_fn.is_none() { ctxt.attr_main_fn = Some((item.id, item.span)); } else { - span_err!(ctxt.session, item.span, E0137, - "multiple functions with a #[main] attribute"); + struct_span_err!(ctxt.session, item.span, E0137, + "multiple functions with a #[main] attribute") + .span_label(item.span, &format!("additional #[main] function")) + .span_label(ctxt.attr_main_fn.unwrap().1, &format!("first #[main] function")) + .emit(); } }, EntryPointType::Start => { diff --git a/src/test/compile-fail/E0137.rs b/src/test/compile-fail/E0137.rs index 695ce7995a9a4..f45afc9f37bd5 100644 --- a/src/test/compile-fail/E0137.rs +++ b/src/test/compile-fail/E0137.rs @@ -11,7 +11,9 @@ #![feature(main)] #[main] -fn foo() {} +fn foo() {} //~ NOTE first #[main] function #[main] -fn f() {} //~ ERROR E0137 +fn f() {} +//~^ ERROR E0137 +//~| NOTE additional #[main] function From 76babf9c8ee412b5e4ff492ddd1b5248547c825e Mon Sep 17 00:00:00 2001 From: ubsan Date: Thu, 4 Aug 2016 13:28:24 -0700 Subject: [PATCH 37/44] Fix precedence table in reference --- src/doc/reference.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index a461023642afd..f4ffe5774d27c 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3049,7 +3049,8 @@ as == != < > <= >= && || -= .. +.. ... += ``` Operators at the same precedence level are evaluated left-to-right. [Unary From 0214ec248b2835a17c845c742d0e7697262ca72e Mon Sep 17 00:00:00 2001 From: trixnz Date: Thu, 4 Aug 2016 22:52:16 +0200 Subject: [PATCH 38/44] Update error format for E0062 --- src/librustc_typeck/check/mod.rs | 20 +++++++++++++++++--- src/test/compile-fail/E0062.rs | 4 +++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 6062bd048b3d2..4d3dda8199304 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3063,6 +3063,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { remaining_fields.insert(field.name, field); } + let mut seen_fields = FnvHashMap(); + let mut error_happened = false; // Typecheck each field. @@ -3071,13 +3073,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(v_field) = remaining_fields.remove(&field.name.node) { expected_field_type = self.field_ty(field.span, v_field, substs); + + seen_fields.insert(field.name.node, field.span); } else { error_happened = true; expected_field_type = tcx.types.err; if let Some(_) = variant.find_field_named(field.name.node) { - span_err!(self.tcx.sess, field.name.span, E0062, - "field `{}` specified more than once", - field.name.node); + let mut err = struct_span_err!(self.tcx.sess, + field.name.span, + E0062, + "field `{}` specified more than once", + field.name.node); + + err.span_label(field.name.span, &format!("used more than once")); + + if let Some(prev_span) = seen_fields.get(&field.name.node) { + err.span_label(*prev_span, &format!("first use of `{}`", field.name.node)); + } + + err.emit(); } else { self.report_unknown_field(adt_ty, variant, field, ast_fields); } diff --git a/src/test/compile-fail/E0062.rs b/src/test/compile-fail/E0062.rs index 86ec7db14b5c1..822d93e52d588 100644 --- a/src/test/compile-fail/E0062.rs +++ b/src/test/compile-fail/E0062.rs @@ -14,7 +14,9 @@ struct Foo { fn main() { let x = Foo { + x: 0, //~ NOTE first use of `x` x: 0, - x: 0, //~ ERROR E0062 + //~^ ERROR E0062 + //~| NOTE used more than once }; } From 2f36ecfff0fd6f4d5bd83ba61fc1685c4844dd04 Mon Sep 17 00:00:00 2001 From: Chris Stankus Date: Thu, 4 Aug 2016 15:30:21 -0500 Subject: [PATCH 39/44] E0119 update error format --- src/librustc_typeck/coherence/overlap.rs | 12 +++++++++--- src/test/compile-fail/E0119.rs | 3 ++- src/test/compile-fail/issue-28568.rs | 3 ++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index dcaa5cfb20a46..54bd141304d78 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -141,12 +141,18 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { self.tcx.sess, self.tcx.span_of_impl(impl_def_id).unwrap(), E0119, "conflicting implementations of trait `{}`{}:", overlap.trait_desc, - overlap.self_desc.map_or(String::new(), - |ty| format!(" for type `{}`", ty))); + overlap.self_desc.clone().map_or(String::new(), + |ty| format!(" for type `{}`", ty))); match self.tcx.span_of_impl(overlap.with_impl) { Ok(span) => { - err.span_note(span, "conflicting implementation is here:"); + err.span_label(span, + &format!("first implementation here")); + err.span_label(self.tcx.span_of_impl(impl_def_id).unwrap(), + &format!("conflicting implementation{}", + overlap.self_desc + .map_or(String::new(), + |ty| format!(" for `{}`", ty)))); } Err(cname) => { err.note(&format!("conflicting implementation in crate `{}`", diff --git a/src/test/compile-fail/E0119.rs b/src/test/compile-fail/E0119.rs index 9528631b3047b..56820bcd1840c 100644 --- a/src/test/compile-fail/E0119.rs +++ b/src/test/compile-fail/E0119.rs @@ -12,7 +12,7 @@ trait MyTrait { fn get(&self) -> usize; } -impl MyTrait for T { +impl MyTrait for T { //~ NOTE first implementation here fn get(&self) -> usize { 0 } } @@ -21,6 +21,7 @@ struct Foo { } impl MyTrait for Foo { //~ ERROR E0119 + //~| NOTE conflicting implementation for `Foo` fn get(&self) -> usize { self.value } } diff --git a/src/test/compile-fail/issue-28568.rs b/src/test/compile-fail/issue-28568.rs index 7c051784f61a7..f03daafc63754 100644 --- a/src/test/compile-fail/issue-28568.rs +++ b/src/test/compile-fail/issue-28568.rs @@ -11,12 +11,13 @@ struct MyStruct; impl Drop for MyStruct { -//~^ NOTE conflicting implementation is here +//~^ NOTE first implementation here fn drop(&mut self) { } } impl Drop for MyStruct { //~^ ERROR conflicting implementations of trait +//~| NOTE conflicting implementation for `MyStruct` fn drop(&mut self) { } } From b5b3539186b43d1291bcc5367171d9745f6a427f Mon Sep 17 00:00:00 2001 From: Nick Massey Date: Thu, 4 Aug 2016 15:35:43 -0600 Subject: [PATCH 40/44] Update compiler error E0055 to use new error format --- src/librustc_typeck/check/autoderef.rs | 6 ++++-- src/test/compile-fail/E0055.rs | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index 3c176744fca59..265422468fe2a 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -54,9 +54,11 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> { if self.steps.len() == tcx.sess.recursion_limit.get() { // We've reached the recursion limit, error gracefully. - span_err!(tcx.sess, self.span, E0055, + struct_span_err!(tcx.sess, self.span, E0055, "reached the recursion limit while auto-dereferencing {:?}", - self.cur_ty); + self.cur_ty) + .span_label(self.span, &format!("deref recursion limit reached")) + .emit(); return None; } diff --git a/src/test/compile-fail/E0055.rs b/src/test/compile-fail/E0055.rs index f86d7ec114b93..2b2d278ad4cc6 100644 --- a/src/test/compile-fail/E0055.rs +++ b/src/test/compile-fail/E0055.rs @@ -18,5 +18,7 @@ impl Foo { fn main() { let foo = Foo; let ref_foo = &&Foo; - ref_foo.foo(); //~ ERROR E0055 + ref_foo.foo(); + //~^ ERROR E0055 + //~| NOTE deref recursion limit reached } From 3b2f1845f3a1d8192a14b4184d5ba66ad7a98ac3 Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Thu, 4 Aug 2016 16:10:18 +0100 Subject: [PATCH 41/44] Update error message E0120 --- src/librustc_typeck/coherence/mod.rs | 15 ++++++++++++--- src/test/compile-fail/E0120.rs | 4 +++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 198e9afd5e12c..2d14b0dacf24c 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -249,8 +249,17 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { if let Some(impl_node_id) = tcx.map.as_local_node_id(impl_did) { match tcx.map.find(impl_node_id) { Some(hir_map::NodeItem(item)) => { - span_err!(tcx.sess, item.span, E0120, - "the Drop trait may only be implemented on structures"); + let span = match item.node { + ItemImpl(_, _, _, _, ref ty, _) => { + ty.span + }, + _ => item.span + }; + struct_span_err!(tcx.sess, span, E0120, + "the Drop trait may only be implemented on structures") + .span_label(span, + &format!("implementing Drop requires a struct")) + .emit(); } _ => { bug!("didn't find impl in ast map"); @@ -258,7 +267,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { } } else { bug!("found external impl of Drop trait on \ - :omething other than a struct"); + something other than a struct"); } } } diff --git a/src/test/compile-fail/E0120.rs b/src/test/compile-fail/E0120.rs index de084274f6fb8..3fdeb75317540 100644 --- a/src/test/compile-fail/E0120.rs +++ b/src/test/compile-fail/E0120.rs @@ -10,7 +10,9 @@ trait MyTrait {} -impl Drop for MyTrait { //~ ERROR E0120 +impl Drop for MyTrait { + //~^ ERROR E0120 + //~| NOTE implementing Drop requires a struct fn drop(&mut self) {} } From 1ca95ae5ba9c0b3974b620399297c3d494d73601 Mon Sep 17 00:00:00 2001 From: William Lee Date: Thu, 4 Aug 2016 23:43:56 -0400 Subject: [PATCH 42/44] Fix for issue #35336 - updating error message for for E0368 to include a span_label --- src/librustc_typeck/check/op.rs | 14 +++++++++----- src/test/compile-fail/issue-5239-1.rs | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index d02f87d0b9cd6..63487683ec3b9 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -176,11 +176,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // error types are considered "builtin" if !lhs_ty.references_error() { if let IsAssign::Yes = is_assign { - span_err!(self.tcx.sess, lhs_expr.span, E0368, - "binary assignment operation `{}=` \ - cannot be applied to type `{}`", - op.node.as_str(), - lhs_ty); + struct_span_err!(self.tcx.sess, lhs_expr.span, E0368, + "binary assignment operation `{}=` \ + cannot be applied to type `{}`", + op.node.as_str(), + lhs_ty) + .span_label(lhs_expr.span, + &format!("cannot use `{}=` on type `{}`", + op.node.as_str(), lhs_ty)) + .emit(); } else { let mut err = struct_span_err!(self.tcx.sess, lhs_expr.span, E0369, "binary operation `{}` cannot be applied to type `{}`", diff --git a/src/test/compile-fail/issue-5239-1.rs b/src/test/compile-fail/issue-5239-1.rs index 1ebef06008ffa..06e3c9a207b78 100644 --- a/src/test/compile-fail/issue-5239-1.rs +++ b/src/test/compile-fail/issue-5239-1.rs @@ -13,4 +13,5 @@ fn main() { let x = |ref x: isize| -> isize { x += 1; }; //~^ ERROR E0368 + //~| NOTE cannot use `+=` on type `&isize` } From a6ffa42f7d4352babdcea3a43e85fedb5987a402 Mon Sep 17 00:00:00 2001 From: Ryan Scott Date: Fri, 5 Aug 2016 16:54:37 +0900 Subject: [PATCH 43/44] Update E0391 to new format. --- src/librustc_typeck/collect.rs | 1 + src/test/compile-fail/issue-3907.rs | 1 + src/test/compile-fail/issue-5035.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4486748a1f056..dce4d7f31016b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -184,6 +184,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { let mut err = struct_span_err!(tcx.sess, span, E0391, "unsupported cyclic reference between types/traits detected"); + err.span_label(span, &format!("cyclic reference")); match cycle[0] { AstConvRequest::GetItemTypeScheme(def_id) | diff --git a/src/test/compile-fail/issue-3907.rs b/src/test/compile-fail/issue-3907.rs index cbc09a028c2c6..93556577ad345 100644 --- a/src/test/compile-fail/issue-3907.rs +++ b/src/test/compile-fail/issue-3907.rs @@ -18,6 +18,7 @@ struct S { } impl Foo for S { //~ ERROR: `Foo` is not a trait + //~| NOTE: not a trait //~| NOTE: type aliases cannot be used for traits fn bar() { } } diff --git a/src/test/compile-fail/issue-5035.rs b/src/test/compile-fail/issue-5035.rs index 9648d64d1fb6e..c2154e8a6c0b6 100644 --- a/src/test/compile-fail/issue-5035.rs +++ b/src/test/compile-fail/issue-5035.rs @@ -11,6 +11,7 @@ trait I {} type K = I; impl K for isize {} //~ ERROR: `K` is not a trait + //~| NOTE: not a trait //~| NOTE: aliases cannot be used for traits use ImportError; //~ ERROR unresolved From 19e140b946010a165373ff4d95ba858b28ff192f Mon Sep 17 00:00:00 2001 From: Ryan Scott Date: Fri, 5 Aug 2016 16:59:44 +0900 Subject: [PATCH 44/44] Update E0404 to new format. --- src/librustc_resolve/lib.rs | 8 +++++++- src/test/ui/codemap_tests/two_files.stderr | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c1511b29c9e01..b26e3b3819ce2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -219,7 +219,13 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, name) } ResolutionError::IsNotATrait(name) => { - struct_span_err!(resolver.session, span, E0404, "`{}` is not a trait", name) + let mut err = struct_span_err!(resolver.session, + span, + E0404, + "`{}` is not a trait", + name); + err.span_label(span, &format!("not a trait")); + err } ResolutionError::UndeclaredTraitName(name, candidates) => { let mut err = struct_span_err!(resolver.session, diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index cf3f187af9334..6956017434616 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -2,7 +2,7 @@ error[E0404]: `Bar` is not a trait --> $DIR/two_files.rs:16:6 | 16 | impl Bar for Baz { } - | ^^^ + | ^^^ not a trait | = note: type aliases cannot be used for traits