From 377ae44cf276599a5b7a21e545d83372067db754 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Mon, 15 Aug 2016 18:46:19 -0400 Subject: [PATCH 01/22] explicitly show how iterating over `..` fails I've also removed the `main()` wrapper, which I believe is extraneous. LMK if that's incorrect. --- src/libcore/ops.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 9347ac2a8c82f..558b78a2fbfaa 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -1463,15 +1463,17 @@ pub trait IndexMut: Index { /// # Examples /// /// ``` -/// fn main() { -/// assert_eq!((..), std::ops::RangeFull); +/// assert_eq!((..), std::ops::RangeFull); /// -/// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); -/// } +/// // for i in .. { +/// // println!("This errors because .. has no Iterator impl"); +/// // } +/// +/// let arr = [0, 1, 2, 3]; +/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull +/// assert_eq!(arr[ ..3], [0,1,2 ]); +/// assert_eq!(arr[1.. ], [ 1,2,3]); +/// assert_eq!(arr[1..3], [ 1,2 ]); /// ``` #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] From c186da706dda6ddaa4df20691702249c4ef0d2dc Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Tue, 16 Aug 2016 06:54:45 -0400 Subject: [PATCH 02/22] RangeFull for-loop iteration fails because of IntoIterator Saying that "[for-loop iteration] fails because .. has no IntoIterator impl" is more direct than saying "...no Iterator impl" because for loops sugar into IntoIterator invocations. It just happens that the other Range* operators implement Iterator and rely on the fact that `IntoIterator` is implemented for `T: Iterator`. --- src/libcore/ops.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 558b78a2fbfaa..cee374ccc7bc5 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -1466,7 +1466,7 @@ pub trait IndexMut: Index { /// assert_eq!((..), std::ops::RangeFull); /// /// // for i in .. { -/// // println!("This errors because .. has no Iterator impl"); +/// // println!("This errors because .. has no IntoIterator impl"); /// // } /// /// let arr = [0, 1, 2, 3]; From 95c53b1e32ac4121af33209c371476526882febe Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Wed, 17 Aug 2016 14:12:19 -0400 Subject: [PATCH 03/22] accumulate vector and assert for RangeFrom and RangeInclusive examples PR #35695 for `Range` was approved, so it seems that this side-effect-free style is preferred for Range* examples. This PR performs the same translation for `RangeFrom` and `RangeInclusive`. It also removes what looks to be an erroneously commented line for `#![feature(step_by)]`, and an unnecessary primitive-type annotation in `0u8..`. --- src/libcore/iter/range.rs | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 079dfe2a81f80..f8b3c84be5aa7 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -267,14 +267,11 @@ impl ops::RangeFrom { /// # Examples /// /// ``` - /// # #![feature(step_by)] + /// #![feature(step_by)] /// - /// for i in (0u8..).step_by(2).take(10) { - /// println!("{}", i); - /// } + /// let result: Vec<_> = (0..).step_by(2).take(5).collect(); + /// assert_eq!(result, vec![0, 2, 4, 6, 8]); /// ``` - /// - /// This prints the first ten even natural integers (0 to 18). #[unstable(feature = "step_by", reason = "recent addition", issue = "27741")] pub fn step_by(self, by: A) -> StepBy { @@ -319,20 +316,8 @@ impl ops::RangeInclusive { /// ``` /// #![feature(step_by, inclusive_range_syntax)] /// - /// for i in (0...10).step_by(2) { - /// println!("{}", i); - /// } - /// ``` - /// - /// This prints: - /// - /// ```text - /// 0 - /// 2 - /// 4 - /// 6 - /// 8 - /// 10 + /// let result: Vec<_> = (0...10).step_by(2).collect(); + /// assert_eq!(result, vec![0, 2, 4, 6, 8, 10]); /// ``` #[unstable(feature = "step_by", reason = "recent addition", issue = "27741")] From dcee93a8030c3a62c5a05b45b050f90251d93af8 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Tue, 16 Aug 2016 04:11:48 -0400 Subject: [PATCH 04/22] replace Add example with something more evocative of addition Currently most of the operator traits use trivial implementation examples that only perform side effects. Honestly, that might not be too bad for the sake of documentation; but anyway, here's a proposal to move a slightly modified version of the module-level point-addition example into the `Add` documentation, since it's more evocative of addition semantics. Part of #29365 wrap identifiers in backticks minor rephrasing fix module-level documentation to be more truthful This branch changes the example for `Add` to no longer be a "minimum implementation that prints something to the screen". --- src/libcore/ops.rs | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 9347ac2a8c82f..9e6310ed460d2 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -62,8 +62,7 @@ //! } //! ``` //! -//! See the documentation for each trait for a minimum implementation that -//! prints something to the screen. +//! See the documentation for each trait for an example implementation. #![stable(feature = "rust1", since = "1.0.0")] @@ -166,25 +165,38 @@ macro_rules! forward_ref_binop { /// /// # Examples /// -/// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up -/// calling `add`, and therefore, `main` prints `Adding!`. +/// This example creates a `Point` struct that implements the `Add` trait, and +/// then demonstrates adding two `Point`s. /// /// ``` /// use std::ops::Add; /// -/// struct Foo; +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } /// -/// impl Add for Foo { -/// type Output = Foo; +/// impl Add for Point { +/// type Output = Point; /// -/// fn add(self, _rhs: Foo) -> Foo { -/// println!("Adding!"); -/// self +/// fn add(self, other: Point) -> Point { +/// Point { +/// x: self.x + other.x, +/// y: self.y + other.y, +/// } +/// } +/// } +/// +/// impl PartialEq for Point { +/// fn eq(&self, other: &Self) -> bool { +/// self.x == other.x && self.y == other.y /// } /// } /// /// fn main() { -/// Foo + Foo; +/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 }, +/// Point { x: 3, y: 3 }); /// } /// ``` #[lang = "add"] From 0dc13ee7f23f878e626771c1a3925b37b19fd6e4 Mon Sep 17 00:00:00 2001 From: clementmiao Date: Wed, 17 Aug 2016 22:03:52 -0700 Subject: [PATCH 05/22] updated E0395 to new error format --- src/librustc_mir/transform/qualify_consts.rs | 11 ++++++++--- src/test/compile-fail/E0395.rs | 2 +- src/test/compile-fail/issue-25826.rs | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 103a15dadb61c..a9ef702ee0548 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -678,9 +678,14 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { self.add(Qualif::NOT_CONST); if self.mode != Mode::Fn { - span_err!(self.tcx.sess, self.span, E0395, - "raw pointers cannot be compared in {}s", - self.mode); + struct_span_err!( + self.tcx.sess, self.span, E0395, + "raw pointers cannot be compared in {}s", + self.mode) + .span_label( + self.span, + &format!("comparing raw pointers in static")) + .emit(); } } } diff --git a/src/test/compile-fail/E0395.rs b/src/test/compile-fail/E0395.rs index 6ab66313a0472..98f08cd68c22d 100644 --- a/src/test/compile-fail/E0395.rs +++ b/src/test/compile-fail/E0395.rs @@ -12,6 +12,6 @@ static FOO: i32 = 42; static BAR: i32 = 42; static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR E0395 - + //~| NOTE comparing raw pointers in static fn main() { } diff --git a/src/test/compile-fail/issue-25826.rs b/src/test/compile-fail/issue-25826.rs index 00e1279d58a0e..468282fa7cca9 100644 --- a/src/test/compile-fail/issue-25826.rs +++ b/src/test/compile-fail/issue-25826.rs @@ -12,5 +12,6 @@ fn id(t: T) -> T { t } fn main() { const A: bool = id:: as *const () < id:: as *const (); //~^ ERROR raw pointers cannot be compared in constants [E0395] + //~^^ NOTE comparing raw pointers in static println!("{}", A); } From dae1406b822c1357f701047951e747dbca2b1446 Mon Sep 17 00:00:00 2001 From: clementmiao Date: Wed, 17 Aug 2016 22:45:21 -0700 Subject: [PATCH 06/22] updated E0396 to new error format --- src/librustc_mir/transform/qualify_consts.rs | 10 +++++++--- src/test/compile-fail/E0396.rs | 1 + src/test/compile-fail/const-deref-ptr.rs | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 103a15dadb61c..e5473d288d4f3 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -490,9 +490,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if let ty::TyRawPtr(_) = base_ty.sty { this.add(Qualif::NOT_CONST); if this.mode != Mode::Fn { - span_err!(this.tcx.sess, this.span, E0396, - "raw pointers cannot be dereferenced in {}s", - this.mode); + struct_span_err!(this.tcx.sess, + this.span, E0396, + "raw pointers cannot be dereferenced in {}s", + this.mode) + .span_label(this.span, + &format!("dereference of raw pointer in constant")) + .emit(); } } } diff --git a/src/test/compile-fail/E0396.rs b/src/test/compile-fail/E0396.rs index 7f34acdfb9007..47080fb6e9ef7 100644 --- a/src/test/compile-fail/E0396.rs +++ b/src/test/compile-fail/E0396.rs @@ -11,6 +11,7 @@ const REG_ADDR: *const u8 = 0x5f3759df as *const u8; const VALUE: u8 = unsafe { *REG_ADDR }; //~ ERROR E0396 + //~| NOTE dereference of raw pointer in constant fn main() { } diff --git a/src/test/compile-fail/const-deref-ptr.rs b/src/test/compile-fail/const-deref-ptr.rs index fa15f3e87c694..c626801d48c03 100644 --- a/src/test/compile-fail/const-deref-ptr.rs +++ b/src/test/compile-fail/const-deref-ptr.rs @@ -12,5 +12,6 @@ fn main() { static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0396 + //~| NOTE dereference of raw pointer in constant println!("{}", C); } From 6976991569977e8097da5f7660a31a42d11e48d2 Mon Sep 17 00:00:00 2001 From: Erik Uggeldahl Date: Thu, 18 Aug 2016 02:03:42 -0400 Subject: [PATCH 07/22] Fix tiny spelling mistake in book Changed datastructure to data structure --- src/doc/book/borrow-and-asref.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/book/borrow-and-asref.md b/src/doc/book/borrow-and-asref.md index 1cfeb2620bd08..c30b2e68665f1 100644 --- a/src/doc/book/borrow-and-asref.md +++ b/src/doc/book/borrow-and-asref.md @@ -8,7 +8,7 @@ different. Here’s a quick refresher on what these two traits mean. # Borrow -The `Borrow` trait is used when you’re writing a datastructure, and you want to +The `Borrow` trait is used when you’re writing a data structure, and you want to use either an owned or borrowed type as synonymous for some purpose. For example, [`HashMap`][hashmap] has a [`get` method][get] which uses `Borrow`: @@ -86,7 +86,7 @@ We can see how they’re kind of the same: they both deal with owned and borrowe versions of some type. However, they’re a bit different. Choose `Borrow` when you want to abstract over different kinds of borrowing, or -when you’re building a datastructure that treats owned and borrowed values in +when you’re building a data structure that treats owned and borrowed values in equivalent ways, such as hashing and comparison. Choose `AsRef` when you want to convert something to a reference directly, and From c2b6f7211472d5e1321e9836f5b339aec1d916d8 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 17 Aug 2016 22:56:43 -0400 Subject: [PATCH 08/22] Add a few doc examples for `std::ffi::OsStr`. * `std::ffi::OsStr::new`. * `std::ffi::OsStr::is_empty`. * `std::ffi::OsStr::len`. --- src/libstd/ffi/os_str.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 0d29e62485abb..3d23a9a2383ff 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -251,6 +251,14 @@ impl Hash for OsString { impl OsStr { /// Coerces into an `OsStr` slice. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new("foo"); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new + ?Sized>(s: &S) -> &OsStr { s.as_ref() @@ -283,6 +291,18 @@ impl OsStr { } /// Checks whether the `OsStr` is empty. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new(""); + /// assert!(os_str.is_empty()); + /// + /// let os_str = OsStr::new("foo"); + /// assert!(!os_str.is_empty()); + /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn is_empty(&self) -> bool { self.inner.inner.is_empty() @@ -296,6 +316,18 @@ impl OsStr { /// other methods like `OsString::with_capacity` to avoid reallocations. /// /// See `OsStr` introduction for more information about encoding. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new(""); + /// assert_eq!(os_str.len(), 0); + /// + /// let os_str = OsStr::new("foo"); + /// assert_eq!(os_str.len(), 3); + /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn len(&self) -> usize { self.inner.inner.len() From 06302cb983198bdf6b984510d24673f4d0f49a98 Mon Sep 17 00:00:00 2001 From: Andrew Cantino Date: Thu, 18 Aug 2016 15:06:05 -0400 Subject: [PATCH 09/22] Fix minor typo --- src/doc/book/closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md index d332cac7d8d16..3ed85c1a90b69 100644 --- a/src/doc/book/closures.md +++ b/src/doc/book/closures.md @@ -340,7 +340,7 @@ fn call_with_ref<'a, F>(some_closure:F) -> i32 where F: Fn(&'a i32) -> i32 { ``` -However this presents a problem with in our case. When you specify the explicit +However this presents a problem in our case. When you specify the explicit lifetime on a function it binds that lifetime to the *entire* scope of the function instead of just the invocation scope of our closure. This means that the borrow checker will see a mutable reference in the same lifetime as our immutable reference and fail From 9563f14eb5d77d992f7cde5db227f8c83351427b Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Thu, 18 Aug 2016 16:04:53 -0400 Subject: [PATCH 10/22] demonstrate `RHS != Self` use cases for `Mul` and `Div` Vector-scalar multipication is a good usecase for this. Thanks #rust! --- src/libcore/ops.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 9347ac2a8c82f..aefafa1b739cb 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -295,6 +295,37 @@ sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } /// Foo * Foo; /// } /// ``` +/// +/// Note that `RHS = Self` by default, but this is not mandatory. Here is an +/// implementation which enables multiplication of vectors by scalars, as is +/// done in linear algebra. +/// +/// ``` +/// use std::ops::Mul; +/// +/// struct Scalar {value: usize}; +/// +/// #[derive(Debug)] +/// struct Vector {value: Vec}; +/// +/// impl Mul for Scalar { +/// type Output = Vector; +/// +/// fn mul(self, rhs: Vector) -> Vector { +/// Vector {value: rhs.value.iter().map(|v| self.value * v).collect()} +/// } +/// } +/// +/// impl PartialEq for Vector { +/// fn eq(&self, other: &Self) -> bool { +/// self.value == other.value +/// } +/// } +/// +/// let scalar = Scalar{value: 3}; +/// let vector = Vector{value: vec![2, 4, 6]}; +/// assert_eq!(scalar * vector, Vector{value: vec![6, 12, 18]}); +/// ``` #[lang = "mul"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Mul { @@ -349,6 +380,37 @@ mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } /// Foo / Foo; /// } /// ``` +/// +/// Note that `RHS = Self` by default, but this is not mandatory. Here is an +/// implementation which enables division of vectors by scalars, as is done in +/// linear algebra. +/// +/// ``` +/// use std::ops::Div; +/// +/// struct Scalar {value: f32}; +/// +/// #[derive(Debug)] +/// struct Vector {value: Vec}; +/// +/// impl Div for Vector { +/// type Output = Vector; +/// +/// fn div(self, rhs: Scalar) -> Vector { +/// Vector {value: self.value.iter().map(|v| v / rhs.value).collect()} +/// } +/// } +/// +/// impl PartialEq for Vector { +/// fn eq(&self, other: &Self) -> bool { +/// self.value == other.value +/// } +/// } +/// +/// let scalar = Scalar{value: 2f32}; +/// let vector = Vector{value: vec![2f32, 4f32, 6f32]}; +/// assert_eq!(vector / scalar, Vector{value: vec![1f32, 2f32, 3f32]}); +/// ``` #[lang = "div"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Div { From 469b7fd1c09e5759f8cbce0f4e42be91c6f1b81a Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Thu, 18 Aug 2016 16:12:40 -0400 Subject: [PATCH 11/22] split example into three sections with explanation --- src/libcore/ops.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index cee374ccc7bc5..932e5f086cbbe 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -1462,13 +1462,24 @@ pub trait IndexMut: Index { /// /// # Examples /// +/// The `..` syntax is a `RangeFull`: +/// /// ``` /// assert_eq!((..), std::ops::RangeFull); +/// ``` /// -/// // for i in .. { -/// // println!("This errors because .. has no IntoIterator impl"); -/// // } +/// It does not have an `IntoIterator` implementation, so you can't use it in a +/// `for` loop directly. This won't compile: /// +/// ```ignore +/// for i in .. { +/// // ... +/// } +/// ``` +/// +/// Used as a slicing index, `RangeFull` produces the full array as a slice. +/// +/// ``` /// let arr = [0, 1, 2, 3]; /// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull /// assert_eq!(arr[ ..3], [0,1,2 ]); From 161cb36159337edfeba546c9ead24262bc5a5dfc Mon Sep 17 00:00:00 2001 From: pliniker Date: Thu, 18 Aug 2016 16:27:33 -0400 Subject: [PATCH 12/22] Update error message for E0084 --- src/librustc_typeck/check/mod.rs | 7 +++++-- src/test/compile-fail/E0084.rs | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ff0b86aa59540..78d311865aa87 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1245,8 +1245,11 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny); if hint != attr::ReprAny && vs.is_empty() { - span_err!(ccx.tcx.sess, sp, E0084, - "unsupported representation for zero-variant enum"); + struct_span_err!( + ccx.tcx.sess, sp, E0084, + "unsupported representation for zero-variant enum") + .span_label(sp, &format!("unsupported enum representation")) + .emit(); } let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(ccx.tcx); diff --git a/src/test/compile-fail/E0084.rs b/src/test/compile-fail/E0084.rs index c579101325f5d..c7c5662f1feda 100644 --- a/src/test/compile-fail/E0084.rs +++ b/src/test/compile-fail/E0084.rs @@ -9,7 +9,9 @@ // except according to those terms. #[repr(i32)] -enum Foo {} //~ ERROR E0084 +enum Foo {} +//~^ ERROR E0084 +//~| unsupported enum representation fn main() { } From a516dbb7d946fc26ed036ae4bd23f4c7abdff3a2 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Tue, 16 Aug 2016 04:33:59 -0400 Subject: [PATCH 13/22] note that calling drop() explicitly is a compiler error Part of #29365 explain that std::mem::drop in prelude will invoke Drop change "prelude" -> "the prelude"; change links to reference-style move link references to links' section --- src/libcore/ops.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 9347ac2a8c82f..daa5ebb61f96d 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -102,6 +102,13 @@ pub trait Drop { /// /// After this function is over, the memory of `self` will be deallocated. /// + /// This function cannot be called explicitly. This is compiler error + /// [0040]. However, the [`std::mem::drop`] function in the prelude can be + /// used to call the argument's `Drop` implementation. + /// + /// [0040]: https://doc.rust-lang.org/error-index.html#E0040 + /// [`std::mem::drop`]: https://doc.rust-lang.org/std/mem/fn.drop.html + /// /// # Panics /// /// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in From 6c66eaa035e5fc47ebbff44b81d2cb3cf1d7d568 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Thu, 18 Aug 2016 16:54:33 -0400 Subject: [PATCH 14/22] replace `AddAssign` example with something more evocative of addition This is analogous to PR #35709 for the `Add` trait. --- src/libcore/ops.rs | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 9347ac2a8c82f..1a203a898f73e 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -894,25 +894,36 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } /// /// # Examples /// -/// A trivial implementation of `AddAssign`. When `Foo += Foo` happens, it ends up -/// calling `add_assign`, and therefore, `main` prints `Adding!`. +/// This example creates a `Point` struct that implements the `AddAssign` +/// trait, and then demonstrates add-assigning to a mutable `Point`. /// /// ``` /// use std::ops::AddAssign; /// -/// struct Foo; +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } /// -/// impl AddAssign for Foo { -/// fn add_assign(&mut self, _rhs: Foo) { -/// println!("Adding!"); +/// impl AddAssign for Point { +/// fn add_assign(&mut self, other: Point) { +/// *self = Point { +/// x: self.x + other.x, +/// y: self.y + other.y, +/// }; /// } /// } /// -/// # #[allow(unused_assignments)] -/// fn main() { -/// let mut foo = Foo; -/// foo += Foo; +/// impl PartialEq for Point { +/// fn eq(&self, other: &Self) -> bool { +/// self.x == other.x && self.y == other.y +/// } /// } +/// +/// let mut point = Point { x: 1, y: 0 }; +/// point += Point { x: 2, y: 3 }; +/// assert_eq!(point, Point { x: 3, y: 3 }); /// ``` #[lang = "add_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] From ffbb8600fbba009598cbebf7149d0bd7a736b928 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 18 Aug 2016 15:22:23 -0700 Subject: [PATCH 15/22] Add workaround to detect correct compiler version --- src/bootstrap/bin/rustc.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index c64cbb9a74e09..175e32125f272 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -38,13 +38,19 @@ fn main() { // is passed (a bit janky...) let target = args.windows(2).find(|w| &*w[0] == "--target") .and_then(|w| w[1].to_str()); + let version = args.iter().find(|w| &**w == "-vV"); // Build scripts always use the snapshot compiler which is guaranteed to be // able to produce an executable, whereas intermediate compilers may not // have the standard library built yet and may not be able to produce an // executable. Otherwise we just use the standard compiler we're // bootstrapping with. - let (rustc, libdir) = if target.is_none() { + // + // Also note that cargo will detect the version of the compiler to trigger + // a rebuild when the compiler changes. If this happens, we want to make + // sure to use the actual compiler instead of the snapshot compiler becase + // that's the one that's actually changing. + let (rustc, libdir) = if target.is_none() && version.is_none() { ("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR") } else { ("RUSTC_REAL", "RUSTC_LIBDIR") From 39f318bb4d7144a8deb10f520a01164133c1b6ec Mon Sep 17 00:00:00 2001 From: Michael Layne Date: Thu, 18 Aug 2016 14:40:59 -0700 Subject: [PATCH 16/22] Update error format for E0232 --- src/librustc_typeck/check/mod.rs | 9 ++++++--- src/test/compile-fail/E0232.rs | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ff0b86aa59540..3a21ffb5e7d93 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -903,9 +903,12 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } } else { - span_err!(ccx.tcx.sess, attr.span, E0232, - "this attribute must have a value, \ - eg `#[rustc_on_unimplemented = \"foo\"]`") + struct_span_err!( + ccx.tcx.sess, attr.span, E0232, + "this attribute must have a value") + .span_label(attr.span, &format!("attribute requires a value")) + .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`")) + .emit(); } } } diff --git a/src/test/compile-fail/E0232.rs b/src/test/compile-fail/E0232.rs index efeb869d71fa5..ce4f4638dac59 100644 --- a/src/test/compile-fail/E0232.rs +++ b/src/test/compile-fail/E0232.rs @@ -10,7 +10,10 @@ #![feature(on_unimplemented)] -#[rustc_on_unimplemented] //~ ERROR E0232 +#[rustc_on_unimplemented] +//~^ ERROR E0232 +//~| NOTE attribute requires a value +//~| NOTE eg `#[rustc_on_unimplemented = "foo"]` trait Bar {} fn main() { From 2128d31a41346c726d2271845d92533ccae882e7 Mon Sep 17 00:00:00 2001 From: Chiu-Hsiang Hsu Date: Fri, 19 Aug 2016 11:58:26 +0800 Subject: [PATCH 17/22] Fix label messages for E0133 Issue #35789 --- src/librustc/middle/effect.rs | 2 +- src/test/compile-fail/E0133.rs | 2 +- src/test/compile-fail/issue-28776.rs | 2 +- src/test/compile-fail/trait-safety-fn-body.rs | 2 +- src/test/compile-fail/unsafe-const-fn.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 3ca6cf0399797..250ad80f5af6c 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -66,7 +66,7 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> { struct_span_err!( self.tcx.sess, span, E0133, "{} requires unsafe function or block", description) - .span_label(span, &format!("unsafe call requires unsafe function or block")) + .span_label(span, &description) .emit(); } UnsafeBlock(block_id) => { diff --git a/src/test/compile-fail/E0133.rs b/src/test/compile-fail/E0133.rs index b8a4476fc5967..f60d9a5083f6f 100644 --- a/src/test/compile-fail/E0133.rs +++ b/src/test/compile-fail/E0133.rs @@ -13,5 +13,5 @@ unsafe fn f() { return; } fn main() { f(); //~^ ERROR E0133 - //~| NOTE unsafe call requires unsafe function or block + //~| NOTE call to unsafe function } diff --git a/src/test/compile-fail/issue-28776.rs b/src/test/compile-fail/issue-28776.rs index 52b0eba96cbdf..4a36bc88fa7d9 100644 --- a/src/test/compile-fail/issue-28776.rs +++ b/src/test/compile-fail/issue-28776.rs @@ -13,5 +13,5 @@ use std::ptr; fn main() { (&ptr::write)(1 as *mut _, 42); //~^ ERROR E0133 - //~| NOTE unsafe call requires unsafe function or block + //~| NOTE call to unsafe function } diff --git a/src/test/compile-fail/trait-safety-fn-body.rs b/src/test/compile-fail/trait-safety-fn-body.rs index 0df7ee8cabed2..65732a8ff69e5 100644 --- a/src/test/compile-fail/trait-safety-fn-body.rs +++ b/src/test/compile-fail/trait-safety-fn-body.rs @@ -20,7 +20,7 @@ unsafe impl UnsafeTrait for *mut isize { // Unsafe actions are not made legal by taking place in an unsafe trait: *self += 1; //~^ ERROR E0133 - //~| NOTE unsafe call requires unsafe function or block + //~| NOTE dereference of raw pointer } } diff --git a/src/test/compile-fail/unsafe-const-fn.rs b/src/test/compile-fail/unsafe-const-fn.rs index 174939b09009c..91e16592be472 100644 --- a/src/test/compile-fail/unsafe-const-fn.rs +++ b/src/test/compile-fail/unsafe-const-fn.rs @@ -18,7 +18,7 @@ const unsafe fn dummy(v: u32) -> u32 { const VAL: u32 = dummy(0xFFFF); //~^ ERROR E0133 -//~| NOTE unsafe call requires unsafe function or block +//~| NOTE call to unsafe function fn main() { assert_eq!(VAL, 0xFFFF0000); From 2c190ad0d2a20719e45fd34e4fc50f9b3184ea4d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 19 Aug 2016 16:44:29 +0200 Subject: [PATCH 18/22] Update block codes' flags --- src/librustc_metadata/diagnostics.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_metadata/diagnostics.rs b/src/librustc_metadata/diagnostics.rs index ae9f500c5de59..099ec62b38de7 100644 --- a/src/librustc_metadata/diagnostics.rs +++ b/src/librustc_metadata/diagnostics.rs @@ -14,7 +14,7 @@ register_long_diagnostics! { E0454: r##" A link name was given with an empty name. Erroneous code example: -``` +```compile_fail,E0454 #[link(name = "")] extern {} // error: #[link(name = "")] given with empty name ``` @@ -32,7 +32,7 @@ as frameworks are specific to that operating system. Erroneous code example: -```compile_fail" +```compile_fail,E0455 #[link(name = "FooCoreServices", kind = "framework")] extern {} // OS used to compile is Linux for example ``` @@ -50,7 +50,7 @@ See more: https://doc.rust-lang.org/book/conditional-compilation.html E0458: r##" An unknown "kind" was specified for a link attribute. Erroneous code example: -``` +```compile_fail,E0458 #[link(kind = "wonderful_unicorn")] extern {} // error: unknown kind: `wonderful_unicorn` ``` @@ -64,7 +64,7 @@ Please specify a valid "kind" value, from one of the following: E0459: r##" A link was used without a name parameter. Erroneous code example: -``` +```compile_fail,E0459 #[link(kind = "dylib")] extern {} // error: #[link(...)] specified without `name = "foo"` ``` @@ -80,7 +80,7 @@ you want. Example: E0463: r##" A plugin/crate was declared but cannot be found. Erroneous code example: -``` +```compile_fail,E0463 #![feature(plugin)] #![plugin(cookie_monster)] // error: can't find crate for `cookie_monster` extern crate cake_is_a_lie; // error: can't find crate for `cake_is_a_lie` From f551674c6d3340822c8f5cf7159263df44718937 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 19 Aug 2016 16:44:47 +0200 Subject: [PATCH 19/22] Add new error code tests --- src/test/compile-fail/E0441.rs | 21 +++++++++++++++++++++ src/test/compile-fail/E0442.rs | 29 +++++++++++++++++++++++++++++ src/test/compile-fail/E0443.rs | 23 +++++++++++++++++++++++ src/test/compile-fail/E0444.rs | 21 +++++++++++++++++++++ src/test/compile-fail/E0445.rs | 19 +++++++++++++++++++ src/test/compile-fail/E0446.rs | 19 +++++++++++++++++++ src/test/compile-fail/E0449.rs | 24 ++++++++++++++++++++++++ src/test/compile-fail/E0450.rs | 17 +++++++++++++++++ src/test/compile-fail/E0451.rs | 20 ++++++++++++++++++++ src/test/compile-fail/E0452.rs | 14 ++++++++++++++ src/test/compile-fail/E0453.rs | 15 +++++++++++++++ src/test/compile-fail/E0454.rs | 14 ++++++++++++++ src/test/compile-fail/E0455.rs | 14 ++++++++++++++ src/test/compile-fail/E0458.rs | 15 +++++++++++++++ src/test/compile-fail/E0459.rs | 14 ++++++++++++++ src/test/compile-fail/E0463.rs | 16 ++++++++++++++++ 16 files changed, 295 insertions(+) create mode 100644 src/test/compile-fail/E0441.rs create mode 100644 src/test/compile-fail/E0442.rs create mode 100644 src/test/compile-fail/E0443.rs create mode 100644 src/test/compile-fail/E0444.rs create mode 100644 src/test/compile-fail/E0445.rs create mode 100644 src/test/compile-fail/E0446.rs create mode 100644 src/test/compile-fail/E0449.rs create mode 100644 src/test/compile-fail/E0450.rs create mode 100644 src/test/compile-fail/E0451.rs create mode 100644 src/test/compile-fail/E0452.rs create mode 100644 src/test/compile-fail/E0453.rs create mode 100644 src/test/compile-fail/E0454.rs create mode 100644 src/test/compile-fail/E0455.rs create mode 100644 src/test/compile-fail/E0458.rs create mode 100644 src/test/compile-fail/E0459.rs create mode 100644 src/test/compile-fail/E0463.rs diff --git a/src/test/compile-fail/E0441.rs b/src/test/compile-fail/E0441.rs new file mode 100644 index 0000000000000..967ff64327235 --- /dev/null +++ b/src/test/compile-fail/E0441.rs @@ -0,0 +1,21 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + +#[repr(simd)] +struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); + +extern "platform-intrinsic" { + fn x86_mm_adds_ep16(x: i16x8, y: i16x8) -> i16x8; //~ ERROR E0441 +} + +fn main() {} diff --git a/src/test/compile-fail/E0442.rs b/src/test/compile-fail/E0442.rs new file mode 100644 index 0000000000000..ddd927054be1d --- /dev/null +++ b/src/test/compile-fail/E0442.rs @@ -0,0 +1,29 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + +#[repr(simd)] +struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, + i8, i8, i8, i8, i8, i8, i8, i8); +#[repr(simd)] +struct i32x4(i32, i32, i32, i32); +#[repr(simd)] +struct i64x2(i64, i64); + +extern "platform-intrinsic" { + fn x86_mm_adds_epi16(x: i8x16, y: i32x4) -> i64x2; + //~^ ERROR E0442 + //~| ERROR E0442 + //~| ERROR E0442 +} + +fn main() {} diff --git a/src/test/compile-fail/E0443.rs b/src/test/compile-fail/E0443.rs new file mode 100644 index 0000000000000..24d1ee01dd46e --- /dev/null +++ b/src/test/compile-fail/E0443.rs @@ -0,0 +1,23 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + +#[repr(simd)] +struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); +#[repr(simd)] +struct i64x8(i64, i64, i64, i64, i64, i64, i64, i64); + +extern "platform-intrinsic" { + fn x86_mm_adds_epi16(x: i16x8, y: i16x8) -> i64x8; //~ ERROR E0443 +} + +fn main() {} diff --git a/src/test/compile-fail/E0444.rs b/src/test/compile-fail/E0444.rs new file mode 100644 index 0000000000000..a424a3ca20ec0 --- /dev/null +++ b/src/test/compile-fail/E0444.rs @@ -0,0 +1,21 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + +#[repr(simd)] +struct f64x2(f64, f64); + +extern "platform-intrinsic" { + fn x86_mm_movemask_pd(x: f64x2, y: f64x2, z: f64x2) -> i32; //~ ERROR E0444 +} + +fn main() {} diff --git a/src/test/compile-fail/E0445.rs b/src/test/compile-fail/E0445.rs new file mode 100644 index 0000000000000..6b360c60a0f90 --- /dev/null +++ b/src/test/compile-fail/E0445.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo { + fn dummy(&self) { } +} + +pub trait Bar : Foo {} //~ ERROR E0445 +pub struct Bar2(pub T); //~ ERROR E0445 +pub fn foo (t: T) {} //~ ERROR E0445 + +fn main() {} diff --git a/src/test/compile-fail/E0446.rs b/src/test/compile-fail/E0446.rs new file mode 100644 index 0000000000000..c576661828471 --- /dev/null +++ b/src/test/compile-fail/E0446.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod Foo { + struct Bar(u32); + + pub fn bar() -> Bar { //~ ERROR E0446 + Bar(0) + } +} + +fn main() {} diff --git a/src/test/compile-fail/E0449.rs b/src/test/compile-fail/E0449.rs new file mode 100644 index 0000000000000..ac365db33e5cd --- /dev/null +++ b/src/test/compile-fail/E0449.rs @@ -0,0 +1,24 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Bar; + +trait Foo { + fn foo(); +} + +pub impl Bar {} //~ ERROR E0449 + +pub impl Foo for Bar { //~ ERROR E0449 + pub fn foo() {} //~ ERROR E0449 +} + +fn main() { +} diff --git a/src/test/compile-fail/E0450.rs b/src/test/compile-fail/E0450.rs new file mode 100644 index 0000000000000..3d76cb9377316 --- /dev/null +++ b/src/test/compile-fail/E0450.rs @@ -0,0 +1,17 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod Bar { + pub struct Foo(isize); +} + +fn main() { + let f = Bar::Foo(0); //~ ERROR E0450 +} diff --git a/src/test/compile-fail/E0451.rs b/src/test/compile-fail/E0451.rs new file mode 100644 index 0000000000000..9e4a8713a33e0 --- /dev/null +++ b/src/test/compile-fail/E0451.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod Bar { + pub struct Foo { + pub a: isize, + b: isize, + } +} + +fn main() { + let f = Bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451 +} diff --git a/src/test/compile-fail/E0452.rs b/src/test/compile-fail/E0452.rs new file mode 100644 index 0000000000000..1665bbdd4c2c1 --- /dev/null +++ b/src/test/compile-fail/E0452.rs @@ -0,0 +1,14 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(foo = "")] //~ ERROR E0452 + +fn main() { +} diff --git a/src/test/compile-fail/E0453.rs b/src/test/compile-fail/E0453.rs new file mode 100644 index 0000000000000..629b373cd7f12 --- /dev/null +++ b/src/test/compile-fail/E0453.rs @@ -0,0 +1,15 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![forbid(non_snake_case)] + +#[allow(non_snake_case)] //~ ERROR E0453 +fn main() { +} diff --git a/src/test/compile-fail/E0454.rs b/src/test/compile-fail/E0454.rs new file mode 100644 index 0000000000000..1439c3133d9ca --- /dev/null +++ b/src/test/compile-fail/E0454.rs @@ -0,0 +1,14 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[link(name = "")] extern {} //~ ERROR E0454 + +fn main() { +} diff --git a/src/test/compile-fail/E0455.rs b/src/test/compile-fail/E0455.rs new file mode 100644 index 0000000000000..a90f97f89f490 --- /dev/null +++ b/src/test/compile-fail/E0455.rs @@ -0,0 +1,14 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[link(name = "FooCoreServices", kind = "framework")] extern {} //~ ERROR E0455 + +fn main() { +} diff --git a/src/test/compile-fail/E0458.rs b/src/test/compile-fail/E0458.rs new file mode 100644 index 0000000000000..21bedc6b84c2b --- /dev/null +++ b/src/test/compile-fail/E0458.rs @@ -0,0 +1,15 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[link(kind = "wonderful_unicorn")] extern {} //~ ERROR E0458 + //~^ ERROR E0459 + +fn main() { +} diff --git a/src/test/compile-fail/E0459.rs b/src/test/compile-fail/E0459.rs new file mode 100644 index 0000000000000..dc7ac714f2239 --- /dev/null +++ b/src/test/compile-fail/E0459.rs @@ -0,0 +1,14 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[link(kind = "dylib")] extern {} //~ ERROR E0459 + +fn main() { +} diff --git a/src/test/compile-fail/E0463.rs b/src/test/compile-fail/E0463.rs new file mode 100644 index 0000000000000..3eff107365af1 --- /dev/null +++ b/src/test/compile-fail/E0463.rs @@ -0,0 +1,16 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(plugin)] +#![plugin(cookie_monster)] //~ ERROR E0463 +extern crate cake_is_a_lie; + +fn main() { +} From 06147ac29152877830454330c16fd82f23d050df Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Fri, 19 Aug 2016 12:35:54 -0400 Subject: [PATCH 20/22] replace `Not` example with something more evocative --- src/libcore/ops.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 9347ac2a8c82f..67c25d42f1f4d 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -538,26 +538,31 @@ neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 } /// /// # Examples /// -/// A trivial implementation of `Not`. When `!Foo` happens, it ends up calling -/// `not`, and therefore, `main` prints `Not-ing!`. +/// An implementation of `Not` for `Answer`, which enables the use of `!` to +/// invert its value. /// /// ``` /// use std::ops::Not; /// -/// struct Foo; +/// #[derive(Debug, PartialEq)] +/// enum Answer { +/// Yes, +/// No, +/// } /// -/// impl Not for Foo { -/// type Output = Foo; +/// impl Not for Answer { +/// type Output = Answer; /// -/// fn not(self) -> Foo { -/// println!("Not-ing!"); -/// self +/// fn not(self) -> Answer { +/// match self { +/// Answer::Yes => Answer::No, +/// Answer::No => Answer::Yes +/// } /// } /// } /// -/// fn main() { -/// !Foo; -/// } +/// assert_eq!(!Answer::Yes, Answer::No); +/// assert_eq!(!Answer::No, Answer::Yes); /// ``` #[lang = "not"] #[stable(feature = "rust1", since = "1.0.0")] From c0eccb120326bc559a4cbe30ace4935d83420073 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Fri, 19 Aug 2016 12:46:11 -0400 Subject: [PATCH 21/22] replace `Neg` example with something more evocative of negation --- src/libcore/ops.rs | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 9347ac2a8c82f..73979d84ad314 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -470,26 +470,37 @@ rem_impl_float! { f32 f64 } /// /// # Examples /// -/// A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling -/// `neg`, and therefore, `main` prints `Negating!`. +/// An implementation of `Neg` for `Sign`, which allows the use of `-` to +/// negate its value. /// /// ``` /// use std::ops::Neg; /// -/// struct Foo; +/// #[derive(Debug, PartialEq)] +/// enum Sign { +/// Negative, +/// Zero, +/// Positive, +/// } /// -/// impl Neg for Foo { -/// type Output = Foo; +/// impl Neg for Sign { +/// type Output = Sign; /// -/// fn neg(self) -> Foo { -/// println!("Negating!"); -/// self +/// fn neg(self) -> Sign { +/// match self { +/// Sign::Negative => Sign::Positive, +/// Sign::Zero => Sign::Zero, +/// Sign::Positive => Sign::Negative, +/// } /// } /// } /// -/// fn main() { -/// -Foo; -/// } +/// // a negative positive is a negative +/// assert_eq!(-Sign::Positive, Sign::Negative); +/// // a double negative is a positive +/// assert_eq!(-Sign::Negative, Sign::Positive); +/// // zero is its own negation +/// assert_eq!(-Sign::Zero, Sign::Zero); /// ``` #[lang = "neg"] #[stable(feature = "rust1", since = "1.0.0")] From 3b64cf669cef3aec090b2c6fa6ba7b8b23d4ba97 Mon Sep 17 00:00:00 2001 From: trixnz Date: Fri, 19 Aug 2016 19:19:34 +0200 Subject: [PATCH 22/22] Update E0428 to new format --- src/librustc_resolve/lib.rs | 6 +++++- src/test/compile-fail/E0428.rs | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b91ede5b2fa8a..af39f8a415c67 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3382,7 +3382,11 @@ impl<'a> Resolver<'a> { }, (true, _) | (_, true) => struct_span_err!(self.session, span, E0260, "{}", msg), _ => match (old_binding.is_import(), binding.is_import()) { - (false, false) => struct_span_err!(self.session, span, E0428, "{}", msg), + (false, false) => { + let mut e = struct_span_err!(self.session, span, E0428, "{}", msg); + e.span_label(span, &format!("already defined")); + e + }, (true, true) => { let mut e = struct_span_err!(self.session, span, E0252, "{}", msg); e.span_label(span, &format!("already imported")); diff --git a/src/test/compile-fail/E0428.rs b/src/test/compile-fail/E0428.rs index 42e237d31cbee..63b4efb73f0c5 100644 --- a/src/test/compile-fail/E0428.rs +++ b/src/test/compile-fail/E0428.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Bar; +struct Bar; //~ previous definition of `Bar` here + //~| previous definition of `Bar` here struct Bar; //~ ERROR E0428 - //~^ ERROR E0428 + //~| NOTE already defined + //~| ERROR E0428 + //~| NOTE already defined fn main () { }