From 50e0fbc9042856527dc35a0dfd9a7716dcf69ccd Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Wed, 17 Aug 2016 14:12:19 -0400 Subject: [PATCH 01/18] 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..`. add `fn main` wrappers to enable Rust Playground "Run" button --- src/libcore/iter/range.rs | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 8408e5d88b4cb..66d05d81d80cd 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -263,14 +263,12 @@ impl ops::RangeFrom { /// # Examples /// /// ``` - /// # #![feature(step_by)] - /// - /// for i in (0u8..).step_by(2).take(10) { - /// println!("{}", i); + /// #![feature(step_by)] + /// fn main() { + /// 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 { @@ -291,8 +289,10 @@ impl ops::Range { /// /// ``` /// #![feature(step_by)] - /// let result: Vec<_> = (0..10).step_by(2).collect(); - /// assert_eq!(result, vec![0, 2, 4, 6, 8]); + /// fn main() { + /// let result: Vec<_> = (0..10).step_by(2).collect(); + /// assert_eq!(result, vec![0, 2, 4, 6, 8]); + /// } /// ``` #[unstable(feature = "step_by", reason = "recent addition", issue = "27741")] @@ -315,20 +315,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 da566aeebf27f5adf2446366a1f2f84ba703f1a8 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Sun, 28 Aug 2016 19:10:12 -0400 Subject: [PATCH 02/18] Add test for #34053 Closes #34053 --- src/test/run-pass/issue-34053.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/run-pass/issue-34053.rs diff --git a/src/test/run-pass/issue-34053.rs b/src/test/run-pass/issue-34053.rs new file mode 100644 index 0000000000000..7f8a4941494a9 --- /dev/null +++ b/src/test/run-pass/issue-34053.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(drop_types_in_const)] + +struct A(i32); + +impl Drop for A { + fn drop(&mut self) {} +} + +static FOO: A = A(123); + +fn main() { + println!("{}", &FOO.0); +} From 91bfa2c829e4a0ca01a75ec5f70e04717f0b4813 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Sun, 28 Aug 2016 19:28:31 -0400 Subject: [PATCH 03/18] Add test for #24204 Closes #24204 --- src/test/compile-fail/issue-24204.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/test/compile-fail/issue-24204.rs diff --git a/src/test/compile-fail/issue-24204.rs b/src/test/compile-fail/issue-24204.rs new file mode 100644 index 0000000000000..2a012da0083bc --- /dev/null +++ b/src/test/compile-fail/issue-24204.rs @@ -0,0 +1,27 @@ +// 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(dead_code)] + +trait MultiDispatch { + type O; +} + +trait Trait: Sized { + type A: MultiDispatch; + type B; + + fn new(u: U) -> >::O where Self::A : MultiDispatch; +} + +fn test>(b: i32) -> T where T::A: MultiDispatch { T::new(b) } +//~^ ERROR type mismatch resolving + +fn main() {} From 10b8e0ed6720e7e7ec7df8fd15671cb293342e20 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 29 Aug 2016 23:35:50 -0400 Subject: [PATCH 04/18] rustbook chapters/sections should be an ordered list. --- src/tools/rustbook/build.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/rustbook/build.rs b/src/tools/rustbook/build.rs index 6014439fafcf9..09c2d2510e317 100644 --- a/src/tools/rustbook/build.rs +++ b/src/tools/rustbook/build.rs @@ -61,9 +61,9 @@ fn write_toc(book: &Book, current_page: &BookItem, out: &mut Write) -> io::Resul section, item.title)?; if !item.children.is_empty() { - writeln!(out, "
    ")?; + writeln!(out, "
      ")?; let _ = walk_items(&item.children[..], section, current_page, out); - writeln!(out, "
")?; + writeln!(out, "")?; } writeln!(out, "")?; @@ -71,9 +71,9 @@ fn write_toc(book: &Book, current_page: &BookItem, out: &mut Write) -> io::Resul } writeln!(out, "
")?; - writeln!(out, "
    ")?; + writeln!(out, "
      ")?; walk_items(&book.chapters[..], "", ¤t_page, out)?; - writeln!(out, "
")?; + writeln!(out, "")?; writeln!(out, "
")?; Ok(()) From c36ccf7912a1dd229cda0c2443cad31c0e5f8fd6 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 30 Aug 2016 06:42:56 +0200 Subject: [PATCH 05/18] doc: make TcpListener example more simple --- src/libstd/net/tcp.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index dcd3652af876b..3c5f07c3e33a6 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -45,7 +45,6 @@ pub struct TcpStream(net_imp::TcpStream); /// /// ```no_run /// use std::net::{TcpListener, TcpStream}; -/// use std::thread; /// /// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); /// @@ -57,17 +56,11 @@ pub struct TcpStream(net_imp::TcpStream); /// for stream in listener.incoming() { /// match stream { /// Ok(stream) => { -/// thread::spawn(move|| { -/// // connection succeeded -/// handle_client(stream) -/// }); +/// handle_client(stream); /// } /// Err(e) => { /* connection failed */ } /// } /// } -/// -/// // close the socket server -/// drop(listener); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct TcpListener(net_imp::TcpListener); From fb65fe95ebb51ae2fc153d96127cfd6b5860dd02 Mon Sep 17 00:00:00 2001 From: athulappadan Date: Tue, 30 Aug 2016 10:29:24 +0530 Subject: [PATCH 06/18] Update compiler error 0034 to use new format. --- src/librustc_typeck/check/method/suggest.rs | 1 + src/test/compile-fail/E0034.rs | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index f9699a55f5068..46b3f503b6e76 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -242,6 +242,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { MethodError::Ambiguity(sources) => { let mut err = struct_span_err!(self.sess(), span, E0034, "multiple applicable items in scope"); + err.span_label(span, &format!("multiple `{}` found", item_name)); report_candidates(&mut err, sources); err.emit(); diff --git a/src/test/compile-fail/E0034.rs b/src/test/compile-fail/E0034.rs index 669bece0f7d17..136a74f7a8b74 100644 --- a/src/test/compile-fail/E0034.rs +++ b/src/test/compile-fail/E0034.rs @@ -18,9 +18,17 @@ trait Trait2 { fn foo(); } -impl Trait1 for Test { fn foo() {} } -impl Trait2 for Test { fn foo() {} } +impl Trait1 for Test { + fn foo() {} + //~^ NOTE candidate #1 is defined in an impl of the trait `Trait1` for the type `Test` +} + +impl Trait2 for Test { + fn foo() {} + //~^ NOTE candidate #2 is defined in an impl of the trait `Trait2` for the type `Test` +} fn main() { - Test::foo() //~ ERROR E0034 + Test::foo() //~ ERROR multiple applicable items in scope + //~| NOTE multiple `foo` found } From 34e18175768bc9147f86ed44cd5f6c055468854e Mon Sep 17 00:00:00 2001 From: Cristi Cobzarenco Date: Tue, 30 Aug 2016 11:01:08 +0100 Subject: [PATCH 07/18] add test for #14875 --- src/test/run-pass/issue-14875.rs | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/run-pass/issue-14875.rs diff --git a/src/test/run-pass/issue-14875.rs b/src/test/run-pass/issue-14875.rs new file mode 100644 index 0000000000000..ad19a9be76f88 --- /dev/null +++ b/src/test/run-pass/issue-14875.rs @@ -0,0 +1,43 @@ +// 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. + +// Check that values are not leaked when a dtor panics (#14875) + +use std::panic::{self, UnwindSafe}; + +struct SetInnerOnDrop<'a>(&'a mut bool); + +impl<'a> UnwindSafe for SetInnerOnDrop<'a> {} + +impl<'a> Drop for SetInnerOnDrop<'a> { + fn drop(&mut self) { + *self.0 = true; + } +} + +struct PanicOnDrop; +impl Drop for PanicOnDrop { + fn drop(&mut self) { + panic!("test panic"); + } +} + + +fn main() { + let mut set_on_drop = false; + { + let set_inner_on_drop = SetInnerOnDrop(&mut set_on_drop); + let _ = panic::catch_unwind(|| { + let _set_inner_on_drop = set_inner_on_drop; + let _panic_on_drop = PanicOnDrop; + }); + } + assert!(set_on_drop); +} From 77cd09a88cd21f22865287025dafc1252856c5d9 Mon Sep 17 00:00:00 2001 From: Mohit Agarwal Date: Tue, 30 Aug 2016 10:21:27 +0530 Subject: [PATCH 08/18] Update E0520 to new error format Fixes #36112. Part of #35233. r? @jonathandturner --- src/librustc_typeck/check/mod.rs | 12 ++++++++---- src/test/compile-fail/E0520.rs | 6 +++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8f2dc42726696..e73c3e2de5320 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -903,14 +903,18 @@ fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, { let mut err = struct_span_err!( tcx.sess, impl_item.span, E0520, - "item `{}` is provided by an `impl` that specializes \ - another, but the item in the parent `impl` is not \ - marked `default` and so it cannot be specialized.", + "`{}` specializes an item from a parent `impl`, but \ + neither that item nor the `impl` are marked `default`", impl_item.name); + err.span_label(impl_item.span, &format!("cannot specialize default item `{}`", + impl_item.name)); match tcx.span_of_impl(parent_impl) { Ok(span) => { - err.span_note(span, "parent implementation is here:"); + err.span_label(span, &"parent `impl` is here"); + err.note(&format!("to specialize, either the parent `impl` or `{}` \ + in the parent `impl` must be marked `default`", + impl_item.name)); } Err(cname) => { err.note(&format!("parent implementation is in crate `{}`", cname)); diff --git a/src/test/compile-fail/E0520.rs b/src/test/compile-fail/E0520.rs index bb52843ee7835..0bb8faea62e1e 100644 --- a/src/test/compile-fail/E0520.rs +++ b/src/test/compile-fail/E0520.rs @@ -19,11 +19,15 @@ impl SpaceLlama for T { } impl SpaceLlama for T { +//~^ NOTE parent `impl` is here fn fly(&self) {} } impl SpaceLlama for i32 { - default fn fly(&self) {} //~ ERROR E0520 + default fn fly(&self) {} + //~^ ERROR E0520 + //~| NOTE cannot specialize default item `fly` + //~| NOTE either the parent `impl` or `fly` in the parent `impl` must be marked `default` } fn main() { From 150599d01d2d8f8ec410ac6509478084ee920eb4 Mon Sep 17 00:00:00 2001 From: ggomez Date: Tue, 30 Aug 2016 12:54:51 +0200 Subject: [PATCH 09/18] Add E0530 error explanation --- src/librustc_resolve/diagnostics.rs | 38 +++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 5183d68065c7d..f8f90bdb4e7f5 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1270,7 +1270,42 @@ trait Foo {} impl Foo for i32 {} ``` -"## +"##, + +E0530: r##" +A binding shadowed something it shouldn't. + +Erroneous code example: + +```compile_fail,E0530 +static TEST: i32 = 0; + +let r: (i32, i32) = (0, 0); +match r { + TEST => {} // error: match bindings cannot shadow statics +} +``` + +To fix this error, just change the binding's name in order to avoid shadowing +one of the following: + +* struct name +* struct/enum variant +* static +* const +* associated const + +Fixed example: + +``` +static TEST: i32 = 0; + +let r: (i32, i32) = (0, 0); +match r { + something => {} // ok! +} +``` +"##, } @@ -1289,7 +1324,6 @@ register_diagnostics! { // E0419, merged into 531 // E0420, merged into 532 // E0421, merged into 531 - E0530, // X bindings cannot shadow Ys E0531, // unresolved pattern path kind `name` E0532, // expected pattern path kind, found another pattern path kind // E0427, merged into 530 From 37bf449de4ff1d6519b577d014fbe17ccdce29b9 Mon Sep 17 00:00:00 2001 From: ggomez Date: Tue, 30 Aug 2016 13:13:37 +0200 Subject: [PATCH 10/18] Add new error code tests --- src/test/compile-fail/E0528.rs | 19 +++++++++++++++++++ src/test/compile-fail/E0529.rs | 19 +++++++++++++++++++ src/test/compile-fail/E0530.rs | 18 ++++++++++++++++++ src/test/compile-fail/E0534.rs | 14 ++++++++++++++ src/test/compile-fail/E0535.rs | 14 ++++++++++++++ src/test/compile-fail/E0536.rs | 14 ++++++++++++++ src/test/compile-fail/E0537.rs | 14 ++++++++++++++ src/test/compile-fail/E0558.rs | 14 ++++++++++++++ src/test/compile-fail/E0559.rs | 17 +++++++++++++++++ src/test/compile-fail/E560.rs | 17 +++++++++++++++++ 10 files changed, 160 insertions(+) create mode 100644 src/test/compile-fail/E0528.rs create mode 100644 src/test/compile-fail/E0529.rs create mode 100644 src/test/compile-fail/E0530.rs create mode 100644 src/test/compile-fail/E0534.rs create mode 100644 src/test/compile-fail/E0535.rs create mode 100644 src/test/compile-fail/E0536.rs create mode 100644 src/test/compile-fail/E0537.rs create mode 100644 src/test/compile-fail/E0558.rs create mode 100644 src/test/compile-fail/E0559.rs create mode 100644 src/test/compile-fail/E560.rs diff --git a/src/test/compile-fail/E0528.rs b/src/test/compile-fail/E0528.rs new file mode 100644 index 0000000000000..27187bb5aba08 --- /dev/null +++ b/src/test/compile-fail/E0528.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. + +#![feature(slice_patterns)] + +fn main() { + let r = &[1, 2]; + match r { + &[a, b, c, rest..] => { //~ ERROR E0528 + } + } +} diff --git a/src/test/compile-fail/E0529.rs b/src/test/compile-fail/E0529.rs new file mode 100644 index 0000000000000..488fe7c7763ae --- /dev/null +++ b/src/test/compile-fail/E0529.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. + +#![feature(slice_patterns)] + +fn main() { + let r: f32 = 1.0; + match r { + [a, b] => { //~ ERROR E0529 + } + } +} diff --git a/src/test/compile-fail/E0530.rs b/src/test/compile-fail/E0530.rs new file mode 100644 index 0000000000000..4f674d0e67106 --- /dev/null +++ b/src/test/compile-fail/E0530.rs @@ -0,0 +1,18 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + static TEST: i32 = 0; + + let r: (i32, i32) = (0, 0); + match r { + TEST => {} //~ ERROR E0530 + } +} diff --git a/src/test/compile-fail/E0534.rs b/src/test/compile-fail/E0534.rs new file mode 100644 index 0000000000000..8c036e6076d1d --- /dev/null +++ b/src/test/compile-fail/E0534.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. + +#[inline()] //~ ERROR E0534 +pub fn something() {} + +fn main() {} diff --git a/src/test/compile-fail/E0535.rs b/src/test/compile-fail/E0535.rs new file mode 100644 index 0000000000000..17558cc05c612 --- /dev/null +++ b/src/test/compile-fail/E0535.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. + +#[inline(unknown)] //~ ERROR E0535 +pub fn something() {} + +fn main() {} diff --git a/src/test/compile-fail/E0536.rs b/src/test/compile-fail/E0536.rs new file mode 100644 index 0000000000000..127bdc258d947 --- /dev/null +++ b/src/test/compile-fail/E0536.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. + +#[cfg(not())] //~ ERROR E0536 +pub fn something() {} + +pub fn main() {} diff --git a/src/test/compile-fail/E0537.rs b/src/test/compile-fail/E0537.rs new file mode 100644 index 0000000000000..497936fbcd28e --- /dev/null +++ b/src/test/compile-fail/E0537.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. + +#[cfg(unknown())] //~ ERROR E0537 +pub fn something() {} + +pub fn main() {} diff --git a/src/test/compile-fail/E0558.rs b/src/test/compile-fail/E0558.rs new file mode 100644 index 0000000000000..4ab0506a9c0cd --- /dev/null +++ b/src/test/compile-fail/E0558.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. + +#[export_name] //~ ERROR E0558 +pub fn something() {} + +fn main() {} diff --git a/src/test/compile-fail/E0559.rs b/src/test/compile-fail/E0559.rs new file mode 100644 index 0000000000000..80eeb203a850e --- /dev/null +++ b/src/test/compile-fail/E0559.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. + +enum Field { + Fool { x: u32 }, +} + +fn main() { + let s = Field::Fool { joke: 0 }; //~ ERROR E0559 +} diff --git a/src/test/compile-fail/E560.rs b/src/test/compile-fail/E560.rs new file mode 100644 index 0000000000000..ec9b86ee1f00f --- /dev/null +++ b/src/test/compile-fail/E560.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. + +struct Simba { + mother: u32, +} + +fn main() { + let s = Simba { mother: 1, father: 0 }; //~ ERROR E0560 +} From f48d3859bc90e6e8a2e5455845b13d55bb8720ab Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 29 Aug 2016 07:17:27 -0400 Subject: [PATCH 11/18] Implement `Debug` for `std::path::Components`. --- src/libstd/path.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 67219b6fd1b9c..791b7b2288d5d 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -639,6 +639,25 @@ pub struct Iter<'a> { inner: Components<'a>, } +#[stable(feature = "path_components_debug", since = "1.13.0")] +impl<'a> fmt::Debug for Components<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + struct DebugHelper<'a>(&'a Path); + + impl<'a> fmt::Debug for DebugHelper<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list() + .entries(self.0.components()) + .finish() + } + } + + f.debug_tuple("Components") + .field(&DebugHelper(self.as_path())) + .finish() + } +} + impl<'a> Components<'a> { // how long is the prefix, if any? #[inline] @@ -3483,4 +3502,25 @@ mod tests { ); } } + + #[test] + fn test_components_debug() { + let path = Path::new("/tmp"); + + let mut components = path.components(); + + let expected = "Components([RootDir, Normal(\"tmp\")])"; + let actual = format!("{:?}", components); + assert_eq!(expected, actual); + + let _ = components.next().unwrap(); + let expected = "Components([Normal(\"tmp\")])"; + let actual = format!("{:?}", components); + assert_eq!(expected, actual); + + let _ = components.next().unwrap(); + let expected = "Components([])"; + let actual = format!("{:?}", components); + assert_eq!(expected, actual); + } } From bdfcd782bc3fe3d59bd584684c13aca3daa7f562 Mon Sep 17 00:00:00 2001 From: Andrea Corradi Date: Sun, 28 Aug 2016 17:55:07 +0200 Subject: [PATCH 12/18] Update E0318 to new format --- src/librustc_typeck/coherence/orphan.rs | 10 +++++++--- .../typeck-default-trait-impl-outside-crate.rs | 5 ++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index a3c043fe7cbd3..bcce64cb110c6 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -347,15 +347,19 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { return; } } - hir::ItemDefaultImpl(..) => { + hir::ItemDefaultImpl(_, ref item_trait_ref) => { // "Trait" impl debug!("coherence2::orphan check: default trait impl {}", self.tcx.map.node_to_string(item.id)); let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap(); if trait_ref.def_id.krate != LOCAL_CRATE { - span_err!(self.tcx.sess, item.span, E0318, + struct_span_err!(self.tcx.sess, item_trait_ref.path.span, E0318, "cannot create default implementations for traits outside the \ - crate they're defined in; define a new trait instead"); + crate they're defined in; define a new trait instead") + .span_label(item_trait_ref.path.span, + &format!("`{}` trait not defined in this crate", + item_trait_ref.path)) + .emit(); return; } } diff --git a/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs b/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs index 09b97dfb30f24..4d71517e06058 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs @@ -10,7 +10,6 @@ #![feature(optin_builtin_traits)] -impl Copy for .. {} -//~^ ERROR E0318 - +impl Copy for .. {} //~ ERROR E0318 + //~^ NOTE `Copy` trait not defined in this crate fn main() {} From 8ca9fa11f9a04a7ffa4cded6775336d55268e7ac Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Tue, 23 Aug 2016 11:23:42 -0400 Subject: [PATCH 13/18] add evocative examples for `BitOr` and `BitXor` These are exactly equivalent to PR #35809, with one caveat: I do not believe there is a non-bitwise binary "xor" operator in Rust, so here it's expressed as (a || b) && !(a && b). r? @GuillaumeGomez improved documentation a la PR #35993 --- src/libcore/ops.rs | 99 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 18 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 282f281047e47..f551357341d3e 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -807,25 +807,55 @@ bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } /// /// # Examples /// -/// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up -/// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`. +/// In this example, the `|` operator is lifted to a trivial `Scalar` type. /// /// ``` /// use std::ops::BitOr; /// -/// struct Foo; +/// #[derive(Debug, PartialEq)] +/// struct Scalar(bool); /// -/// impl BitOr for Foo { -/// type Output = Foo; +/// impl BitOr for Scalar { +/// type Output = Self; /// -/// fn bitor(self, _rhs: Foo) -> Foo { -/// println!("Bitwise Or-ing!"); -/// self +/// // rhs is the "right-hand side" of the expression `a | b` +/// fn bitor(self, rhs: Self) -> Self { +/// Scalar(self.0 | rhs.0) +/// } +/// } +/// +/// fn main() { +/// assert_eq!(Scalar(true) | Scalar(true), Scalar(true)); +/// assert_eq!(Scalar(true) | Scalar(false), Scalar(true)); +/// assert_eq!(Scalar(false) | Scalar(true), Scalar(true)); +/// assert_eq!(Scalar(false) | Scalar(false), Scalar(false)); +/// } +/// ``` +/// +/// In this example, the `BitOr` trait is implemented for a `BooleanVector` +/// struct. +/// +/// ``` +/// use std::ops::BitOr; +/// +/// #[derive(Debug, PartialEq)] +/// struct BooleanVector(Vec); +/// +/// impl BitOr for BooleanVector { +/// type Output = Self; +/// +/// fn bitor(self, BooleanVector(rhs): Self) -> Self { +/// let BooleanVector(lhs) = self; +/// assert_eq!(lhs.len(), rhs.len()); +/// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect()) /// } /// } /// /// fn main() { -/// Foo | Foo; +/// let bv1 = BooleanVector(vec![true, true, false, false]); +/// let bv2 = BooleanVector(vec![true, false, true, false]); +/// let expected = BooleanVector(vec![true, true, true, false]); +/// assert_eq!(bv1 | bv2, expected); /// } /// ``` #[lang = "bitor"] @@ -860,25 +890,58 @@ bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } /// /// # Examples /// -/// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up -/// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`. +/// In this example, the `^` operator is lifted to a trivial `Scalar` type. /// /// ``` /// use std::ops::BitXor; /// -/// struct Foo; +/// #[derive(Debug, PartialEq)] +/// struct Scalar(bool); /// -/// impl BitXor for Foo { -/// type Output = Foo; +/// impl BitXor for Scalar { +/// type Output = Self; /// -/// fn bitxor(self, _rhs: Foo) -> Foo { -/// println!("Bitwise Xor-ing!"); -/// self +/// // rhs is the "right-hand side" of the expression `a ^ b` +/// fn bitxor(self, rhs: Self) -> Self { +/// Scalar(self.0 ^ rhs.0) +/// } +/// } +/// +/// fn main() { +/// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false)); +/// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true)); +/// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true)); +/// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false)); +/// } +/// ``` +/// +/// In this example, the `BitXor` trait is implemented for a `BooleanVector` +/// struct. +/// +/// ``` +/// use std::ops::BitXor; +/// +/// #[derive(Debug, PartialEq)] +/// struct BooleanVector(Vec); +/// +/// impl BitXor for BooleanVector { +/// type Output = Self; +/// +/// fn bitxor(self, BooleanVector(rhs): Self) -> Self { +/// let BooleanVector(lhs) = self; +/// assert_eq!(lhs.len(), rhs.len()); +/// BooleanVector(lhs.iter() +/// .zip(rhs.iter()) +/// .map(|(x, y)| (*x || *y) && !(*x && *y)) +/// .collect()) /// } /// } /// /// fn main() { -/// Foo ^ Foo; +/// let bv1 = BooleanVector(vec![true, true, false, false]); +/// let bv2 = BooleanVector(vec![true, false, true, false]); +/// let expected = BooleanVector(vec![false, true, true, false]); +/// assert_eq!(bv1 ^ bv2, expected); /// } /// ``` #[lang = "bitxor"] From 507fe146377171013e445783ba00ad8ff2c35e69 Mon Sep 17 00:00:00 2001 From: Mikhail Modin Date: Tue, 30 Aug 2016 22:46:52 +0300 Subject: [PATCH 14/18] update E0265 to new format --- src/librustc_passes/static_recursion.rs | 14 ++++++++------ src/test/compile-fail/issue-23302.rs | 8 ++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index 8b2943a33c006..d23f77af32155 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -126,7 +126,7 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> { idstack: Vec::new(), } } - fn with_item_id_pushed(&mut self, id: ast::NodeId, f: F) + fn with_item_id_pushed(&mut self, id: ast::NodeId, f: F, span: Span) where F: Fn(&mut Self) { if self.idstack.iter().any(|&x| x == id) { @@ -150,7 +150,9 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> { "recursive static"); } } else { - span_err!(self.sess, *self.root_span, E0265, "recursive constant"); + struct_span_err!(self.sess, span, E0265, "recursive constant") + .span_label(span, &format!("recursion not allowed in constant")) + .emit(); } return; } @@ -203,7 +205,7 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> { impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { fn visit_item(&mut self, it: &'ast hir::Item) { - self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it)); + self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it), it.span); } fn visit_enum_def(&mut self, @@ -233,16 +235,16 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { // If `maybe_expr` is `None`, that's because no discriminant is // specified that affects this variant. Thus, no risk of recursion. if let Some(expr) = maybe_expr { - self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr)); + self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr), expr.span); } } fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) { - self.with_item_id_pushed(ti.id, |v| intravisit::walk_trait_item(v, ti)); + self.with_item_id_pushed(ti.id, |v| intravisit::walk_trait_item(v, ti), ti.span); } fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) { - self.with_item_id_pushed(ii.id, |v| intravisit::walk_impl_item(v, ii)); + self.with_item_id_pushed(ii.id, |v| intravisit::walk_impl_item(v, ii), ii.span); } fn visit_expr(&mut self, e: &'ast hir::Expr) { diff --git a/src/test/compile-fail/issue-23302.rs b/src/test/compile-fail/issue-23302.rs index 7ac8cf45edbef..35f32d16a9a2a 100644 --- a/src/test/compile-fail/issue-23302.rs +++ b/src/test/compile-fail/issue-23302.rs @@ -12,13 +12,21 @@ // the appropriate error (rather than, say, blowing the stack). enum X { A = X::A as isize, //~ ERROR E0265 + //~^ NOTE recursion not allowed in constant } // Since `Y::B` here defaults to `Y::A+1`, this is also a // recursive definition. enum Y { A = Y::B as isize, //~ ERROR E0265 + //~^ NOTE recursion not allowed in constant B, } +const A: i32 = B; //~ ERROR E0265 + //~^ NOTE recursion not allowed in constant + +const B: i32 = A; //~ ERROR E0265 + //~^ NOTE recursion not allowed in constant + fn main() { } From d3a6ea52d750499abfaed307cee519879ecbb4c9 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Sun, 28 Aug 2016 01:12:54 +0530 Subject: [PATCH 15/18] Update compiler error E0076 to use new error format Fixes #35221 part of #35233 --- src/librustc_typeck/check/mod.rs | 4 +++- src/test/compile-fail/E0076.rs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 16300d869abf5..bd52967e72a43 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1228,7 +1228,9 @@ pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, id: ast::Node } let e = fields[0].ty(tcx, substs); if !fields.iter().all(|f| f.ty(tcx, substs) == e) { - span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous"); + struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous") + .span_label(sp, &format!("SIMD elements must have the same type")) + .emit(); return; } match e.sty { diff --git a/src/test/compile-fail/E0076.rs b/src/test/compile-fail/E0076.rs index b0f02a03e0051..c31dc62eb666b 100644 --- a/src/test/compile-fail/E0076.rs +++ b/src/test/compile-fail/E0076.rs @@ -11,7 +11,9 @@ #![feature(repr_simd)] #[repr(simd)] -struct Bad(u16, u32, u32); //~ ERROR E0076 +struct Bad(u16, u32, u32); +//~^ ERROR E0076 +//~| NOTE SIMD elements must have the same type fn main() { } From 268b3f58184cc7efa8196a28cccffcc01a5d61ac Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 30 Aug 2016 09:29:22 -0400 Subject: [PATCH 16/18] Implement `Debug` for `std::path::Iter`. --- src/libstd/path.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 791b7b2288d5d..dbf17b3c813f6 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -837,6 +837,25 @@ impl<'a> AsRef for Components<'a> { } } +#[stable(feature = "path_iter_debug", since = "1.13.0")] +impl<'a> fmt::Debug for Iter<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + struct DebugHelper<'a>(&'a Path); + + impl<'a> fmt::Debug for DebugHelper<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list() + .entries(self.0.iter()) + .finish() + } + } + + f.debug_tuple("Iter") + .field(&DebugHelper(self.as_path())) + .finish() + } +} + impl<'a> Iter<'a> { /// Extracts a slice corresponding to the portion of the path remaining for iteration. #[stable(feature = "rust1", since = "1.0.0")] @@ -3523,4 +3542,26 @@ mod tests { let actual = format!("{:?}", components); assert_eq!(expected, actual); } + + #[cfg(unix)] + #[test] + fn test_iter_debug() { + let path = Path::new("/tmp"); + + let mut iter = path.iter(); + + let expected = "Iter([\"/\", \"tmp\"])"; + let actual = format!("{:?}", iter); + assert_eq!(expected, actual); + + let _ = iter.next().unwrap(); + let expected = "Iter([\"tmp\"])"; + let actual = format!("{:?}", iter); + assert_eq!(expected, actual); + + let _ = iter.next().unwrap(); + let expected = "Iter([])"; + let actual = format!("{:?}", iter); + assert_eq!(expected, actual); + } } From 56edae2f424ab0e8325c826a1d0b83783b47adaa Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Wed, 31 Aug 2016 13:50:58 +0200 Subject: [PATCH 17/18] Fix typo in PartialOrd docs --- src/libcore/cmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 907dd1508d8be..670978a2d49af 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -383,7 +383,7 @@ impl PartialOrd for Ordering { /// } /// ``` /// -/// You may also find it useful to use `partial_cmp()` on your type`s fields. Here +/// You may also find it useful to use `partial_cmp()` on your type's fields. Here /// is an example of `Person` types who have a floating-point `height` field that /// is the only field to be used for sorting: /// From 69f0cee85dab86b8a27321cfce45adcb1f549d0c Mon Sep 17 00:00:00 2001 From: William Lee Date: Tue, 30 Aug 2016 17:30:08 -0400 Subject: [PATCH 18/18] Bonus fix for #35280. Part of #35233. Fixes #36057. Adding expanded notes/context for what trait a parameter shadows as part of E0194 error messages. --- src/librustc_typeck/check/wfcheck.rs | 28 ++++++++++++++++++++++------ src/test/compile-fail/E0194.rs | 4 ++-- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index a236c8baa9f9c..435442bd30a65 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -16,7 +16,7 @@ use middle::region::{CodeExtent}; use rustc::infer::TypeOrigin; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::util::nodemap::FnvHashSet; +use rustc::util::nodemap::{FnvHashSet, FnvHashMap}; use syntax::ast; use syntax_pos::Span; @@ -519,11 +519,26 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) { let parent = tcx.lookup_generics(generics.parent.unwrap()); - let impl_params: FnvHashSet<_> = parent.types.iter().map(|tp| tp.name).collect(); + let impl_params: FnvHashMap<_, _> = parent.types + .iter() + .map(|tp| (tp.name, tp.def_id)) + .collect(); for method_param in &generics.types { - if impl_params.contains(&method_param.name) { - error_194(tcx, span, method_param.name); + if impl_params.contains_key(&method_param.name) { + // Tighten up the span to focus on only the shadowing type + let shadow_node_id = tcx.map.as_local_node_id(method_param.def_id).unwrap(); + let type_span = match tcx.map.opt_span(shadow_node_id) { + Some(osp) => osp, + None => span + }; + + // The expectation here is that the original trait declaration is + // local so it should be okay to just unwrap everything. + let trait_def_id = impl_params.get(&method_param.name).unwrap(); + let trait_node_id = tcx.map.as_local_node_id(*trait_def_id).unwrap(); + let trait_decl_span = tcx.map.opt_span(trait_node_id).unwrap(); + error_194(tcx, type_span, trait_decl_span, method_param.name); } } } @@ -630,10 +645,11 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N err } -fn error_194(tcx: TyCtxt, span: Span, name: ast::Name) { +fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: ast::Name) { struct_span_err!(tcx.sess, span, E0194, "type parameter `{}` shadows another type parameter of the same name", name) - .span_label(span, &format!("`{}` shadows another type parameter", name)) + .span_label(span, &format!("shadows another type parameter")) + .span_label(trait_decl_span, &format!("first `{}` declared here", name)) .emit(); } diff --git a/src/test/compile-fail/E0194.rs b/src/test/compile-fail/E0194.rs index fa94c88328a86..6b1f718dd76c5 100644 --- a/src/test/compile-fail/E0194.rs +++ b/src/test/compile-fail/E0194.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { +trait Foo { //~ NOTE first `T` declared here fn do_something(&self) -> T; fn do_something_else(&self, bar: T); //~^ ERROR E0194 - //~| NOTE `T` shadows another type parameter + //~| NOTE shadows another type parameter } fn main() {