From e805cb6374550190f8b3c4582fe67ae40d5b7a16 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 29 Jul 2016 14:32:35 +0200 Subject: [PATCH 01/39] 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/39] 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/39] 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/39] 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 76026d1dea965113682213a66f5da78f05fd7968 Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Sat, 23 Jul 2016 13:51:54 +0200 Subject: [PATCH 05/39] Fix grammar verification * Use make check-lexer to verify the grammar. * Extend grammar/README * Add make clean-grammar rule * Add target check-build-lexer-verifier to make tidy, so it will build the verifier with every build and catch future errors --- mk/clean.mk | 6 +++++- mk/grammar.mk | 2 +- mk/tests.mk | 3 ++- src/grammar/README.md | 4 ++-- src/grammar/check.sh | 6 +++--- src/grammar/verify.rs | 6 ++++-- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/mk/clean.mk b/mk/clean.mk index ac34ac506bb17..6fc9828745f43 100644 --- a/mk/clean.mk +++ b/mk/clean.mk @@ -35,7 +35,7 @@ clean-all: clean clean-llvm clean-llvm: $(CLEAN_LLVM_RULES) -clean: clean-misc $(CLEAN_STAGE_RULES) +clean: clean-misc clean-grammar $(CLEAN_STAGE_RULES) clean-misc: @$(call E, cleaning) @@ -47,6 +47,10 @@ clean-misc: $(Q)rm -Rf dist/* $(Q)rm -Rf doc +clean-grammar: + @$(call E, cleaning grammar verification) + $(Q)cd src/grammar && rm -Rf verify *.class *.java *.tokens + $(Q)rm -Rf grammar define CLEAN_GENERIC clean-generic-$(2)-$(1): diff --git a/mk/grammar.mk b/mk/grammar.mk index 0d527bd068860..419efa6eff933 100644 --- a/mk/grammar.mk +++ b/mk/grammar.mk @@ -37,7 +37,7 @@ $(BG): $(BG)RustLexer.class: $(BG) $(SG)RustLexer.g4 $(Q)$(CFG_ANTLR4) -o $(BG) $(SG)RustLexer.g4 - $(Q)$(CFG_JAVAC) -d $(BG) $(BG)RustLexer.java + $(Q)$(CFG_JAVAC) -d $(BG) -classpath /usr/share/java/antlr-complete.jar $(BG)RustLexer.java check-build-lexer-verifier: $(BG)verify diff --git a/mk/tests.mk b/mk/tests.mk index 201e4cae51d6d..0b15f4f2d5a20 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -243,7 +243,8 @@ cleantestlibs: .PHONY: tidy tidy: $(HBIN0_H_$(CFG_BUILD))/tidy$(X_$(CFG_BUILD)) \ - $(SNAPSHOT_RUSTC_POST_CLEANUP) + $(SNAPSHOT_RUSTC_POST_CLEANUP) \ + check-build-lexer-verifier $(TARGET_RPATH_VAR0_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $< $(S)src $(HBIN0_H_$(CFG_BUILD))/tidy$(X_$(CFG_BUILD)): \ diff --git a/src/grammar/README.md b/src/grammar/README.md index 6e0cf17a88040..11685df9d4a12 100644 --- a/src/grammar/README.md +++ b/src/grammar/README.md @@ -4,11 +4,11 @@ Uses [antlr4](http://www.antlr.org/) and a custom Rust tool to compare ASTs/token streams generated. You can use the `check-lexer` make target to run all of the available tests. -To use manually: +To use manually, assuming antlr4 ist installed at `/usr/share/java/antlr-complete.jar`: ``` antlr4 RustLexer.g4 -javac *.java +javac -classpath /usr/share/java/antlr-complete.jar *.java rustc -O verify.rs for file in ../*/**.rs; do echo $file; diff --git a/src/grammar/check.sh b/src/grammar/check.sh index 560b6b72471e1..70a8f6fca2e5c 100755 --- a/src/grammar/check.sh +++ b/src/grammar/check.sh @@ -20,11 +20,11 @@ skipped=0 check() { grep --silent "// ignore-lexer-test" "$1"; - # if it's *not* found... + # if it is *not* found... if [ $? -eq 1 ]; then - cd $2 # This `cd` is so java will pick up RustLexer.class. I couldn't + cd $2 # This `cd` is so java will pick up RustLexer.class. I could not # figure out how to wrangle the CLASSPATH, just adding build/grammar - # didn't seem to have any effect. + # did not seem to have any effect. if $3 RustLexer tokens -tokens < $1 | $4 $1 $5; then echo "pass: $1" passed=`expr $passed + 1` diff --git a/src/grammar/verify.rs b/src/grammar/verify.rs index 884db34189240..48be58f731cd7 100644 --- a/src/grammar/verify.rs +++ b/src/grammar/verify.rs @@ -11,6 +11,7 @@ #![feature(plugin, rustc_private)] extern crate syntax; +extern crate syntax_pos; extern crate rustc; #[macro_use] @@ -290,9 +291,10 @@ fn main() { let options = config::basic_options(); let session = session::build_session(options, &DepGraph::new(false), None, - syntax::diagnostics::registry::Registry::new(&[]), + syntax::errors::registry::Registry::new(&[]), Rc::new(DummyCrateStore)); - let filemap = session.parse_sess.codemap().new_filemap(String::from(""), code); + let filemap = session.parse_sess.codemap() + .new_filemap("".to_string(), None, code); let mut lexer = lexer::StringReader::new(session.diagnostic(), filemap); let cm = session.codemap(); From 2bed205d3be05682b84693edeed4d84d850eb801 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 13:30:41 +0200 Subject: [PATCH 06/39] 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 07/39] 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 08/39] 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 09/39] 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 10/39] 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 11/39] 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 cede35eaada00e4993e5ae4400689541837d445d Mon Sep 17 00:00:00 2001 From: Ryan Scheel Date: Sun, 17 Jul 2016 16:47:38 -0700 Subject: [PATCH 12/39] Merge guidelines from RFC 1567 into UX Guidelines. This is a partial fix for issue #34808. Most of the wording was copied verbatim from the RFC. Main difference is that I moved the actual template to the top of the section. It also makes the error explanations the longest section in the guidelines doc for now. --- src/doc/rustc-ux-guidelines.md | 120 +++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/src/doc/rustc-ux-guidelines.md b/src/doc/rustc-ux-guidelines.md index 15b3bfebfac2e..e38ce745ea31f 100644 --- a/src/doc/rustc-ux-guidelines.md +++ b/src/doc/rustc-ux-guidelines.md @@ -56,6 +56,10 @@ Error explanations are long form descriptions of error messages provided with the compiler. They are accessible via the `--explain` flag. Each explanation comes with an example of how to trigger it and advice on how to fix it. +Long error codes explanations are a very important part of Rust. Having an +explanation of what failed helps to understand the error and is appreciated by +Rust developers of all skill levels. + * All of them are accessible [online](http://doc.rust-lang.org/error-index.html), which are auto-generated from rustc source code in different places: [librustc](https://github.com/rust-lang/rust/blob/master/src/librustc/diagnostics.rs), @@ -74,6 +78,122 @@ code with backticks. * When talking about the compiler, call it `the compiler`, not `Rust` or `rustc`. +Note: The following sections are mostly a repaste of [RFC 1567](https://github.com/rust-lang/rfcs/blob/master/text/1567-long-error-codes-explanation-normalization.md). + +### Template + +Long error descriptions should match the following template. The next few +sections of this document describe what each section is about. + + E000: r##" + [Error description] + + Example of erroneous code: + + ```compile_fail + [Minimal example] + ``` + + [Error explanation] + + ``` + [How to fix the problem] + ``` + + [Optional Additional information] + + "##, + +### Error description + +Provide a more detailed error message. For example: + +```ignore +extern crate a; +extern crate b as a; +``` + +We get the `E0259` error code which says "an extern crate named `a` has already been imported in this module" and the error explanation says: "The name chosen for an external crate conflicts with another external crate that has been imported into the current module.". + +### Minimal example + +Provide an erroneous code example which directly follows `Error description`. The erroneous example will be helpful for the `How to fix the problem`. Making it as simple as possible is really important in order to help readers to understand what the error is about. A comment should be added with the error on the same line where the errors occur. Example: + +```ignore +type X = u32; // error: type parameters are not allowed on this type +``` + +If the error comments is too long to fit 80 columns, split it up like this, so the next line start at the same column of the previous line: + +```ignore +type X = u32<'static>; // error: lifetime parameters are not allowed on + // this type +``` + +And if the sample code is too long to write an effective comment, place your comment on the line before the sample code: + +```ignore +// error: lifetime parameters are not allowed on this type +fn super_long_function_name_and_thats_problematic() {} +``` + +Of course, it the comment is too long, the split rules still applies. + +### Error explanation + +Provide a full explanation about "__why__ you get the error" and some leads on __how__ to fix it. If needed, use additional code snippets to improve your explanations. + +### How to fix the problem + +This part will show how to fix the error that we saw previously in the `Minimal example`, with comments explaining how it was fixed. + +### Additional information + +Some details which might be useful for the users, let's take back `E0109` example. At the end, the supplementary explanation is the following: "Note that type parameters for enum-variant constructors go after the variant, not after the enum (`Option::None::`, not `Option::::None`).". It provides more information, not directly linked to the error, but it might help user to avoid doing another error. + +### Full Example + + E0409: r##" + An "or" pattern was used where the variable bindings are not consistently bound + across patterns. + + Example of erroneous code: + + ```compile_fail,E0409 + let x = (0, 2); + match x { + (0, ref y) | (y, 0) ={ /* use y */} // error: variable `y` is bound with + // different mode in pattern #2 + // than in pattern #1 + _ =() + } + ``` + + Here, `y` is bound by-value in one case and by-reference in the other. + + To fix this error, just use the same mode in both cases. + Generally using `ref` or `ref mut` where not already used will fix this: + + ```rust + let x = (0, 2); + match x { + (0, ref y) | (ref y, 0) ={ /* use y */} + _ =() + } + ``` + + Alternatively, split the pattern: + + ```rust + let x = (0, 2); + match x { + (y, 0) ={ /* use y */ } + (0, ref y) ={ /* use y */} + _ =() + } + ``` + "##, + ## Compiler Flags * Flags should be orthogonal to each other. For example, if we'd have a From 157f7c1b30698dcdb2452e687f4940550a6e6467 Mon Sep 17 00:00:00 2001 From: "Ryan Scheel (Havvy)" Date: Tue, 26 Jul 2016 05:14:37 +0000 Subject: [PATCH 13/39] 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 14/39] 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 15/39] 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 16/39] 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 17/39] 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 18/39] 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 19/39] 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 20/39] 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 21/39] 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 22/39] 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 23/39] 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 24/39] 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 25/39] 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 26/39] 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 33a4806248b3a763f6efd173edb3a8cfa863266c Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Wed, 3 Aug 2016 20:22:43 -0400 Subject: [PATCH 27/39] Clean up `std::raw` docs There is no longer a `Repr` trait, so mentioning a missing impl of it was potentially confusing. --- src/libcore/raw.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index 6b2122451db8f..6aa536aefb94a 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -34,12 +34,13 @@ /// only designed to be used by unsafe code that needs to manipulate /// the low-level details. /// -/// There is no `Repr` implementation for `TraitObject` because there -/// is no way to refer to all trait objects generically, so the only +/// There is no way to refer to all trait objects generically, so the only /// way to create values of this type is with functions like -/// `std::mem::transmute`. Similarly, the only way to create a true +/// [`std::mem::transmute`][transmute]. Similarly, the only way to create a true /// trait object from a `TraitObject` value is with `transmute`. /// +/// [transmute]: ../mem/fn.transmute.html +/// /// Synthesizing a trait object with mismatched types—one where the /// vtable does not correspond to the type of the value to which the /// data pointer points—is highly likely to lead to undefined @@ -50,13 +51,13 @@ /// ``` /// #![feature(raw)] /// -/// use std::mem; -/// use std::raw; +/// use std::{mem, raw}; /// /// // an example trait /// trait Foo { /// fn bar(&self) -> i32; /// } +/// /// impl Foo for i32 { /// fn bar(&self) -> i32 { /// *self + 1 @@ -74,7 +75,6 @@ /// // the data pointer is the address of `value` /// assert_eq!(raw_object.data as *const i32, &value as *const _); /// -/// /// let other_value: i32 = 456; /// /// // construct a new object, pointing to a different `i32`, being @@ -82,11 +82,11 @@ /// let synthesized: &Foo = unsafe { /// mem::transmute(raw::TraitObject { /// data: &other_value as *const _ as *mut (), -/// vtable: raw_object.vtable +/// vtable: raw_object.vtable, /// }) /// }; /// -/// // it should work just like we constructed a trait object out of +/// // it should work just as if we had constructed a trait object out of /// // `other_value` directly /// assert_eq!(synthesized.bar(), 457); /// ``` From 61318156f86c828b7d09decf45ea8e40aafbcc25 Mon Sep 17 00:00:00 2001 From: William Lee Date: Thu, 4 Aug 2016 00:32:49 -0400 Subject: [PATCH 28/39] 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 29/39] 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 30/39] 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 31/39] 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 32/39] 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 33/39] 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 34/39] 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 35/39] 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 36/39] 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 37/39] 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 44928388a05673be93c6c4777fd6a4d0c9e0f7b4 Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Thu, 4 Aug 2016 16:10:18 +0100 Subject: [PATCH 38/39] Update error message E0120 --- src/librustc_typeck/coherence/mod.rs | 14 +++++++++++--- src/test/compile-fail/E0120.rs | 4 +++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 198e9afd5e12c..86ab10e3941ed 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -249,8 +249,16 @@ 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 +266,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 a0bdb1761892f77e9ebd2fd3e42e8b49ec1e34fe Mon Sep 17 00:00:00 2001 From: Samuel Cormier-Iijima Date: Thu, 4 Aug 2016 15:09:15 -0400 Subject: [PATCH 39/39] 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() {