From eb6d44d697e00f561411a07f306702ddb2078b2d Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Sun, 21 Aug 2016 16:01:27 -0400 Subject: [PATCH 1/6] more evocative examples for `Sub` and `SubAssign` These examples are exactly analogous to those in PRs #35709 and #35806. I'll probably remove the `fn main` wrappers for `Add` and `Sub` once this is merged in. Part of #29365. r? @steveklabnik --- src/libcore/ops.rs | 62 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 3a2d6c8bcf7d6..dffd9ca214ecb 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -245,25 +245,38 @@ add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } /// /// # Examples /// -/// A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up -/// calling `sub`, and therefore, `main` prints `Subtracting!`. +/// This example creates a `Point` struct that implements the `Sub` trait, and +/// then demonstrates subtracting two `Point`s. /// /// ``` /// use std::ops::Sub; /// -/// struct Foo; +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } /// -/// impl Sub for Foo { -/// type Output = Foo; +/// impl Sub for Point { +/// type Output = Point; /// -/// fn sub(self, _rhs: Foo) -> Foo { -/// println!("Subtracting!"); -/// self +/// fn sub(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: 3, y: 3 } - Point { x: 2, y: 3 }, +/// Point { x: 1, y: 0 }); /// } /// ``` #[lang = "sub"] @@ -1053,25 +1066,36 @@ add_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } /// /// # Examples /// -/// A trivial implementation of `SubAssign`. When `Foo -= Foo` happens, it ends up -/// calling `sub_assign`, and therefore, `main` prints `Subtracting!`. +/// This example creates a `Point` struct that implements the `SubAssign` +/// trait, and then demonstrates sub-assigning to a mutable `Point`. /// /// ``` /// use std::ops::SubAssign; /// -/// struct Foo; +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } /// -/// impl SubAssign for Foo { -/// fn sub_assign(&mut self, _rhs: Foo) { -/// println!("Subtracting!"); +/// impl SubAssign for Point { +/// fn sub_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: 3, y: 3 }; +/// point -= Point { x: 2, y: 3 }; +/// assert_eq!(point, Point {x: 1, y: 0}); /// ``` #[lang = "sub_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] From ab4c492d68be1d32f52f47bd263b62063ae9b8ae Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 23 Aug 2016 22:25:40 +0200 Subject: [PATCH 2/6] reference: add trailing commas --- src/doc/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index f0ab1488d4015..be3559a588089 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2283,7 +2283,7 @@ the `PartialEq` or `Clone` constraints for the appropriate `impl`: #[derive(PartialEq, Clone)] struct Foo { a: i32, - b: T + b: T, } ``` @@ -3896,7 +3896,7 @@ Coercion is allowed between the following types: use std::ops::Deref; struct CharContainer { - value: char + value: char, } impl Deref for CharContainer { From 3ddb46852242ab75d7610bceafc737378d636734 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 23 Aug 2016 15:35:10 +0200 Subject: [PATCH 3/6] Add E0478 error explanation --- src/librustc/diagnostics.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 07e54dc9e8796..ba68686c55117 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1527,6 +1527,37 @@ fn main() { ``` "##, +E0478: r##" +A lifetime bound was not satisfied. + +Erroneous code example: + +```compile_fail,E0478 +// Check that the explicit lifetime bound (`'SnowWhite`, in this example) must +// outlive all the superbounds from the trait (`'kiss`, in this example). + +trait Wedding<'t>: 't { } + +struct Prince<'kiss, 'SnowWhite> { + child: Box + 'SnowWhite>, + // error: lifetime bound not satisfied +} +``` + +In this example, the `'SnowWhite` lifetime is supposed to outlive the `'kiss` +lifetime but the declaration of the `Prince` struct doesn't enforce it. To fix +this issue, you need to specify it: + +``` +trait Wedding<'t>: 't { } + +struct Prince<'kiss, 'SnowWhite: 'kiss> { // You say here that 'kiss must live + // longer than 'SnowWhite. + child: Box + 'SnowWhite>, // And now it's all good! +} +``` +"##, + E0496: r##" A lifetime name is shadowing another lifetime name. Erroneous code example: @@ -1715,7 +1746,6 @@ register_diagnostics! { E0475, // index of slice outside its lifetime E0476, // lifetime of the source pointer does not outlive lifetime bound... E0477, // the type `..` does not fulfill the required lifetime... - E0478, // lifetime bound not satisfied E0479, // the type `..` (provided as the value of a type parameter) is... E0480, // lifetime of method receiver does not outlive the method call E0481, // lifetime of function argument does not outlive the function call From f200061bd698aa7f5befa508e5bbb8bc4a2bdba1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 23 Aug 2016 15:35:26 +0200 Subject: [PATCH 4/6] Add error code test checkup --- src/librustc_mir/diagnostics.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 4a731d898a937..eb16812af9b02 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -18,7 +18,7 @@ for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time. Erroneous code example: -```compile_fail +```compile_fail,E0010 #![feature(box_syntax)] const CON : Box = box 0; @@ -30,7 +30,7 @@ Static and const variables can refer to other const variables. But a const variable cannot refer to a static variable. For example, `Y` cannot refer to `X` here: -```compile_fail +```compile_fail,E0013 static X: i32 = 42; const Y: i32 = X; ``` @@ -66,7 +66,7 @@ E0016: r##" Blocks in constants may only contain items (such as constant, function definition, etc...) and a tail expression. Erroneous code example: -```compile_fail +```compile_fail,E0016 const FOO: i32 = { let x = 0; x }; // 'x' isn't an item! ``` @@ -81,7 +81,7 @@ E0017: r##" References in statics and constants may only refer to immutable values. Erroneous code example: -```compile_fail +```compile_fail,E0017 static X: i32 = 1; const C: i32 = 2; @@ -107,7 +107,7 @@ vary. For example, if you write: -```compile_fail +```compile_fail,E0018 static MY_STATIC: u32 = 42; static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize; static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR; @@ -152,7 +152,7 @@ impl Test { fn main() { const FOO: Test = Test::V1; - const A: i32 = FOO.test(); // You can't call Test::func() here ! + const A: i32 = FOO.test(); // You can't call Test::func() here! } ``` @@ -214,14 +214,13 @@ static B: &'static u32 = &A; // ok! ``` "##, - E0395: r##" The value assigned to a constant scalar must be known at compile time, which is not the case when comparing raw pointers. Erroneous code example: -```compile_fail +```compile_fail,E0395 static FOO: i32 = 42; static BAR: i32 = 42; @@ -250,7 +249,7 @@ The value behind a raw pointer can't be determined at compile-time (or even link-time), which means it can't be used in a constant expression. Erroneous code example: -```compile_fail +```compile_fail,E0396 const REG_ADDR: *const u8 = 0x5f3759df as *const u8; const VALUE: u8 = unsafe { *REG_ADDR }; @@ -272,7 +271,7 @@ E0492: r##" A borrow of a constant containing interior mutability was attempted. Erroneous code example: -```compile_fail +```compile_fail,E0492 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT}; const A: AtomicUsize = ATOMIC_USIZE_INIT; @@ -299,7 +298,7 @@ static B: &'static AtomicUsize = &A; // ok! You can also have this error while using a cell type: -```compile_fail +```compile_fail,E0492 #![feature(const_fn)] use std::cell::Cell; @@ -351,7 +350,7 @@ E0493: r##" A type with a destructor was assigned to an invalid type of variable. Erroneous code example: -```compile_fail +```compile_fail,E0493 struct Foo { a: u32 } @@ -374,7 +373,7 @@ E0494: r##" A reference of an interior static was assigned to another const/static. Erroneous code example: -```compile_fail +```compile_fail,E0494 struct Foo { a: u32 } From 5c5f483b40d6b7d125e110a82d928b07220230f3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 23 Aug 2016 15:35:59 +0200 Subject: [PATCH 5/6] Add new error code tests --- src/test/compile-fail/E0478.rs | 18 ++++++++++++++++++ src/test/compile-fail/E0492.rs | 17 +++++++++++++++++ src/test/compile-fail/E0493.rs | 22 ++++++++++++++++++++++ src/test/compile-fail/E0494.rs | 19 +++++++++++++++++++ src/test/compile-fail/E0496.rs | 21 +++++++++++++++++++++ src/test/compile-fail/E0499.rs | 15 +++++++++++++++ src/test/compile-fail/E0501.rs | 25 +++++++++++++++++++++++++ 7 files changed, 137 insertions(+) create mode 100644 src/test/compile-fail/E0478.rs create mode 100644 src/test/compile-fail/E0492.rs create mode 100644 src/test/compile-fail/E0493.rs create mode 100644 src/test/compile-fail/E0494.rs create mode 100644 src/test/compile-fail/E0496.rs create mode 100644 src/test/compile-fail/E0499.rs create mode 100644 src/test/compile-fail/E0501.rs diff --git a/src/test/compile-fail/E0478.rs b/src/test/compile-fail/E0478.rs new file mode 100644 index 0000000000000..8eb4003fc9734 --- /dev/null +++ b/src/test/compile-fail/E0478.rs @@ -0,0 +1,18 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Wedding<'t>: 't { } + +struct Prince<'kiss, 'SnowWhite> { + child: Box + 'SnowWhite>, //~ ERROR E0478 +} + +fn main() { +} diff --git a/src/test/compile-fail/E0492.rs b/src/test/compile-fail/E0492.rs new file mode 100644 index 0000000000000..8e4964c97c593 --- /dev/null +++ b/src/test/compile-fail/E0492.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. + +use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT}; + +const A: AtomicUsize = ATOMIC_USIZE_INIT; +static B: &'static AtomicUsize = &A; //~ ERROR E0492 + +fn main() { +} diff --git a/src/test/compile-fail/E0493.rs b/src/test/compile-fail/E0493.rs new file mode 100644 index 0000000000000..689f469533d96 --- /dev/null +++ b/src/test/compile-fail/E0493.rs @@ -0,0 +1,22 @@ +// 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 Foo { + a: u32 +} + +impl Drop for Foo { + fn drop(&mut self) {} +} + +const F : Foo = Foo { a : 0 }; //~ ERROR E0493 + +fn main() { +} diff --git a/src/test/compile-fail/E0494.rs b/src/test/compile-fail/E0494.rs new file mode 100644 index 0000000000000..5f8632ac1c23d --- /dev/null +++ b/src/test/compile-fail/E0494.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. + +struct Foo { + a: u32 +} + +static S : Foo = Foo { a : 0 }; +static A : &'static u32 = &S.a; //~ ERROR E0494 + +fn main() { +} diff --git a/src/test/compile-fail/E0496.rs b/src/test/compile-fail/E0496.rs new file mode 100644 index 0000000000000..4ca3cd9c13da6 --- /dev/null +++ b/src/test/compile-fail/E0496.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. + +struct Foo<'a> { + a: &'a i32, +} + +impl<'a> Foo<'a> { + fn f<'a>(x: &'a i32) { //~ ERROR E0496 + } +} + +fn main() { +} diff --git a/src/test/compile-fail/E0499.rs b/src/test/compile-fail/E0499.rs new file mode 100644 index 0000000000000..9a64bfe2ea9e7 --- /dev/null +++ b/src/test/compile-fail/E0499.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. + +fn main() { + let mut i = 0; + let mut x = &mut i; + let mut a = &mut i; //~ ERROR E0499 +} diff --git a/src/test/compile-fail/E0501.rs b/src/test/compile-fail/E0501.rs new file mode 100644 index 0000000000000..04678b96c8d08 --- /dev/null +++ b/src/test/compile-fail/E0501.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn inside_closure(x: &mut i32) { +} + +fn outside_closure(x: &mut i32) { +} + +fn foo(a: &mut i32) { + let bar = || { + inside_closure(a) + }; + outside_closure(a); //~ ERROR E0501 +} + +fn main() { +} From 11e9b8de7db8d5500cbee2252f6afd870f186104 Mon Sep 17 00:00:00 2001 From: Mohit Agarwal Date: Wed, 24 Aug 2016 17:43:51 +0530 Subject: [PATCH 6/6] Update E0445 and E0454 to new error format Fixes #35922. Fixes #35930. Part of #35233. r? @GuillaumeGomez --- src/librustc_metadata/creader.rs | 6 ++++-- src/librustc_privacy/lib.rs | 7 +++++-- src/test/compile-fail/E0445.rs | 12 +++++++++--- src/test/compile-fail/E0454.rs | 4 +++- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 4a656b180f259..46469efea6bc8 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -101,8 +101,10 @@ fn register_native_lib(sess: &Session, if name.is_empty() { match span { Some(span) => { - span_err!(sess, span, E0454, - "#[link(name = \"\")] given with empty name"); + struct_span_err!(sess, span, E0454, + "#[link(name = \"\")] given with empty name") + .span_label(span, &format!("empty name given")) + .emit(); } None => { sess.err("empty library name given via `-l`"); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index de9ddcd934216..028632ad7c006 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -964,8 +964,11 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, if !vis.is_at_least(self.required_visibility, &self.tcx.map) { if self.tcx.sess.features.borrow().pub_restricted || self.old_error_set.contains(&trait_ref.ref_id) { - span_err!(self.tcx.sess, trait_ref.path.span, E0445, - "private trait in public interface"); + struct_span_err!(self.tcx.sess, trait_ref.path.span, E0445, + "private trait in public interface") + .span_label(trait_ref.path.span, &format!( + "private trait can't be public")) + .emit(); } else { self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC, node_id, diff --git a/src/test/compile-fail/E0445.rs b/src/test/compile-fail/E0445.rs index 6b360c60a0f90..7c5c862a6f812 100644 --- a/src/test/compile-fail/E0445.rs +++ b/src/test/compile-fail/E0445.rs @@ -12,8 +12,14 @@ 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 +pub trait Bar : Foo {} +//~^ ERROR private trait in public interface [E0445] +//~| NOTE private trait can't be public +pub struct Bar2(pub T); +//~^ ERROR private trait in public interface [E0445] +//~| NOTE private trait can't be public +pub fn foo (t: T) {} +//~^ ERROR private trait in public interface [E0445] +//~| NOTE private trait can't be public fn main() {} diff --git a/src/test/compile-fail/E0454.rs b/src/test/compile-fail/E0454.rs index 1439c3133d9ca..39887927c885f 100644 --- a/src/test/compile-fail/E0454.rs +++ b/src/test/compile-fail/E0454.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[link(name = "")] extern {} //~ ERROR E0454 +#[link(name = "")] extern {} +//~^ ERROR E0454 +//~| NOTE empty name given fn main() { }