diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 6c8a1c3062b0..8ad5a9861a02 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -530,9 +530,12 @@ impl<'a> Display for Arguments<'a> { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \ - defined in your crate, add `#[derive(Debug)]` or \ - manually implement it"] +#[rustc_on_unimplemented( + on(crate_local, label="`{Self}` cannot be formatted using `:?`; \ + add `#[derive(Debug)]` or manually implement `{Debug}`"), + message="`{Self}` doesn't implement `{Debug}`", + label="`{Self}` cannot be formatted using `:?` because it doesn't implement `{Debug}`", +)] #[lang = "debug_trait"] pub trait Debug { /// Formats the value using the given formatter. @@ -593,9 +596,11 @@ pub trait Debug { /// /// println!("The origin is: {}", origin); /// ``` -#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \ - formatter; try using `:?` instead if you are using \ - a format string"] +#[rustc_on_unimplemented( + message="`{Self}` doesn't implement `{Display}`", + label="`{Self}` cannot be formatted with the default formatter; \ + try using `:?` instead if you are using a format string", +)] #[stable(feature = "rust1", since = "1.0.0")] pub trait Display { /// Formats the value using the given formatter. diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 35cd7441c66b..296fb8733ba6 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -28,8 +28,13 @@ fn _assert_is_object_safe(_: &Iterator) {} /// [module-level documentation]: index.html /// [impl]: index.html#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \ - `.iter()` or a similar method"] +#[rustc_on_unimplemented( + on( + _Self="&str", + label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" + ), + label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method" +)] #[doc(spotlight)] pub trait Iterator { /// The type of the elements being iterated over. diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index f5ff12266855..be7ecbce8af7 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -384,6 +384,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { Some(ty_str.clone()))); } + if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) { + flags.push(("crate_local".to_string(), None)); + } + if let Ok(Some(command)) = OnUnimplementedDirective::of_item( self.tcx, trait_ref.def_id, def_id ) { diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index a493b7f0bb60..8c2c1cfa4547 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -185,8 +185,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { let mut message = None; let mut label = None; let mut note = None; - info!("evaluate({:?}, trait_ref={:?}, options={:?})", - self, trait_ref, options); + info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options); for command in self.subcommands.iter().chain(Some(self)).rev() { if let Some(ref condition) = command.condition { diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs index 36df4f0eb4d4..9d9d4cef3119 100644 --- a/src/test/ui/impl-trait/equality.rs +++ b/src/test/ui/impl-trait/equality.rs @@ -32,7 +32,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR the trait bound `u32: std::ops::Add` is not satisfied + //~^ ERROR cannot add `impl Foo` to `u32` } } diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr index abbf3da513a6..86c2ad4c0e7a 100644 --- a/src/test/ui/lint/use_suggestion_json.stderr +++ b/src/test/ui/lint/use_suggestion_json.stderr @@ -2,7 +2,72 @@ "message": "cannot find type `Iter` in this scope", "code": { "code": "E0412", - "explanation": null + "explanation": " +The type name used is not in scope. + +Erroneous code examples: + +```compile_fail,E0412 +impl Something {} // error: type name `Something` is not in scope + +// or: + +trait Foo { + fn bar(N); // error: type name `N` is not in scope +} + +// or: + +fn foo(x: T) {} // type name `T` is not in scope +``` + +To fix this error, please verify you didn't misspell the type name, you did +declare it or imported it into the scope. Examples: + +``` +struct Something; + +impl Something {} // ok! + +// or: + +trait Foo { + type N; + + fn bar(_: Self::N); // ok! +} + +// or: + +fn foo(x: T) {} // ok! +``` + +Another case that causes this error is when a type is imported into a parent +module. To fix this, you can follow the suggestion and use File directly or +`use super::File;` which will import the types from the parent namespace. An +example that causes this error is below: + +```compile_fail,E0412 +use std::fs::File; + +mod foo { + fn some_function(f: File) {} +} +``` + +``` +use std::fs::File; + +mod foo { + // either + use super::File; + // or + // use std::fs::File; + fn foo(f: File) {} +} +# fn main() {} // don't insert it for us; that'll break imports +``` +" }, "level": "error", "spans": [ diff --git a/src/test/ui/mismatched_types/binops.rs b/src/test/ui/mismatched_types/binops.rs index e45616cd67a8..5144b59955cc 100644 --- a/src/test/ui/mismatched_types/binops.rs +++ b/src/test/ui/mismatched_types/binops.rs @@ -9,10 +9,10 @@ // except according to those terms. fn main() { - 1 + Some(1); //~ ERROR is not satisfied - 2 as usize - Some(1); //~ ERROR is not satisfied - 3 * (); //~ ERROR is not satisfied - 4 / ""; //~ ERROR is not satisfied + 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}` + 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize` + 3 * (); //~ ERROR cannot multiply `()` to `{integer}` + 4 / ""; //~ ERROR cannot divide `{integer}` by `&str` 5 < String::new(); //~ ERROR is not satisfied 6 == Ok(1); //~ ERROR is not satisfied } diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr index 57e66794a58a..1b7fba050636 100644 --- a/src/test/ui/mismatched_types/binops.stderr +++ b/src/test/ui/mismatched_types/binops.stderr @@ -1,7 +1,7 @@ error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}` --> $DIR/binops.rs:12:7 | -12 | 1 + Some(1); //~ ERROR is not satisfied +12 | 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}` | ^ no implementation for `{integer} + std::option::Option<{integer}>` | = help: the trait `std::ops::Add>` is not implemented for `{integer}` @@ -9,7 +9,7 @@ error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}` error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize` --> $DIR/binops.rs:13:16 | -13 | 2 as usize - Some(1); //~ ERROR is not satisfied +13 | 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize` | ^ no implementation for `usize - std::option::Option<{integer}>` | = help: the trait `std::ops::Sub>` is not implemented for `usize` @@ -17,7 +17,7 @@ error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize` error[E0277]: cannot multiply `()` to `{integer}` --> $DIR/binops.rs:14:7 | -14 | 3 * (); //~ ERROR is not satisfied +14 | 3 * (); //~ ERROR cannot multiply `()` to `{integer}` | ^ no implementation for `{integer} * ()` | = help: the trait `std::ops::Mul<()>` is not implemented for `{integer}` @@ -25,7 +25,7 @@ error[E0277]: cannot multiply `()` to `{integer}` error[E0277]: cannot divide `{integer}` by `&str` --> $DIR/binops.rs:15:7 | -15 | 4 / ""; //~ ERROR is not satisfied +15 | 4 / ""; //~ ERROR cannot divide `{integer}` by `&str` | ^ no implementation for `{integer} / &str` | = help: the trait `std::ops::Div<&str>` is not implemented for `{integer}` diff --git a/src/test/ui/on-unimplemented/auxiliary/no_debug.rs b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs new file mode 100644 index 000000000000..0f833c626372 --- /dev/null +++ b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs @@ -0,0 +1,14 @@ +// Copyright 2018 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. +// ignore-tidy-linelength + +#![crate_type = "lib"] + +pub struct Bar; diff --git a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr index 2ea9b67f2602..c4bac12eebdb 100644 --- a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr @@ -1,44 +1,107 @@ -error[E0277]: trait message `[i32]` - --> $DIR/multiple-impls-complex-filtering.rs:46:5 +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:49:5 | -46 | Index::index(&[] as &[i32], 2usize); - | ^^^^^^^^^^^^ u32 message +49 | Index::index(&[] as &[i32], 2usize); + | ^^^^^^^^^^^^ trait label if i32 | - = help: the trait `Index<_>` is not implemented for `[i32]` + = help: the trait `Index` is not implemented for `[i32]` note: required by `Index::index` - --> $DIR/multiple-impls-complex-filtering.rs:25:5 + --> $DIR/multiple-impls-complex-filtering.rs:26:5 | -25 | fn index(&self, index: Idx) -> &Self::Output; +26 | fn index(&self, index: Idx) -> &Self::Output; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: trait message `[i32]` - --> $DIR/multiple-impls-complex-filtering.rs:46:5 +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:49:5 | -46 | Index::index(&[] as &[i32], 2usize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message +49 | Index::index(&[] as &[i32], 2usize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32 | - = help: the trait `Index<_>` is not implemented for `[i32]` + = help: the trait `Index` is not implemented for `[i32]` -error[E0277]: trait message `[i32]` - --> $DIR/multiple-impls-complex-filtering.rs:47:5 +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:50:5 | -47 | Index::index(&[] as &[i32], 2u32); - | ^^^^^^^^^^^^ u32 message +50 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^ trait label if i32 | - = help: the trait `Index<_>` is not implemented for `[i32]` + = help: the trait `Index` is not implemented for `[i32]` note: required by `Index::index` - --> $DIR/multiple-impls-complex-filtering.rs:25:5 + --> $DIR/multiple-impls-complex-filtering.rs:26:5 | -25 | fn index(&self, index: Idx) -> &Self::Output; +26 | fn index(&self, index: Idx) -> &Self::Output; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: trait message `[i32]` - --> $DIR/multiple-impls-complex-filtering.rs:47:5 +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:50:5 | -47 | Index::index(&[] as &[i32], 2u32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message +50 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32 | - = help: the trait `Index<_>` is not implemented for `[i32]` + = help: the trait `Index` is not implemented for `[i32]` -error: aborting due to 4 previous errors +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:51:5 + | +51 | Index::index(&[] as &[u32], 2u32); + | ^^^^^^^^^^^^ trait label + | + = help: the trait `Index<_>` is not implemented for `[u32]` +note: required by `Index::index` + --> $DIR/multiple-impls-complex-filtering.rs:26:5 + | +26 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:51:5 + | +51 | Index::index(&[] as &[u32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label + | + = help: the trait `Index<_>` is not implemented for `[u32]` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls-complex-filtering.rs:55:5 + | +55 | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^ impl foo [i32] Foo Index + | + = help: the trait `Index>` is not implemented for `[i32]` +note: required by `Index::index` + --> $DIR/multiple-impls-complex-filtering.rs:26:5 + | +26 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls-complex-filtering.rs:55:5 + | +55 | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl foo [i32] Foo Index + | + = help: the trait `Index>` is not implemented for `[i32]` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls-complex-filtering.rs:58:5 + | +58 | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index>` is not implemented for `[i32]` +note: required by `Index::index` + --> $DIR/multiple-impls-complex-filtering.rs:26:5 + | +26 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls-complex-filtering.rs:58:5 + | +58 | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index>` is not implemented for `[i32]` + +error: aborting due to 10 previous errors diff --git a/src/test/ui/on-unimplemented/no-debug.rs b/src/test/ui/on-unimplemented/no-debug.rs new file mode 100644 index 000000000000..fff6122c6b34 --- /dev/null +++ b/src/test/ui/on-unimplemented/no-debug.rs @@ -0,0 +1,27 @@ +// Copyright 2018 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. + +// aux-build:no_debug.rs + +extern crate no_debug; + +use no_debug::Bar; + +struct Foo; + +fn main() { + println!("{:?} {:?}", Foo, Bar); + println!("{} {}", Foo, Bar); +} +//~^^^ ERROR `Foo` doesn't implement `std::fmt::Debug` +//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Debug` +//~^^^^ ERROR `Foo` doesn't implement `std::fmt::Display` +//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Display` + diff --git a/src/test/ui/on-unimplemented/no-debug.stderr b/src/test/ui/on-unimplemented/no-debug.stderr new file mode 100644 index 000000000000..af5b1e91211f --- /dev/null +++ b/src/test/ui/on-unimplemented/no-debug.stderr @@ -0,0 +1,38 @@ +error[E0277]: `Foo` doesn't implement `std::fmt::Debug` + --> $DIR/no-debug.rs:20:27 + | +20 | println!("{:?} {:?}", Foo, Bar); + | ^^^ `Foo` cannot be formatted using `:?`; add `#[derive(Debug)]` or manually implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `Foo` + = note: required by `std::fmt::Debug::fmt` + +error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Debug` + --> $DIR/no-debug.rs:20:32 + | +20 | println!("{:?} {:?}", Foo, Bar); + | ^^^ `no_debug::Bar` cannot be formatted using `:?` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `no_debug::Bar` + = note: required by `std::fmt::Debug::fmt` + +error[E0277]: `Foo` doesn't implement `std::fmt::Display` + --> $DIR/no-debug.rs:21:23 + | +21 | println!("{} {}", Foo, Bar); + | ^^^ `Foo` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string + | + = help: the trait `std::fmt::Display` is not implemented for `Foo` + = note: required by `std::fmt::Display::fmt` + +error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Display` + --> $DIR/no-debug.rs:21:28 + | +21 | println!("{} {}", Foo, Bar); + | ^^^ `no_debug::Bar` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string + | + = help: the trait `std::fmt::Display` is not implemented for `no_debug::Bar` + = note: required by `std::fmt::Display::fmt` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/span/multiline-span-simple.rs b/src/test/ui/span/multiline-span-simple.rs index f8e4cbcbf191..dd09534480e1 100644 --- a/src/test/ui/span/multiline-span-simple.rs +++ b/src/test/ui/span/multiline-span-simple.rs @@ -20,7 +20,7 @@ fn main() { let x = 1; let y = 2; let z = 3; - foo(1 as u32 + //~ ERROR not satisfied + foo(1 as u32 + //~ ERROR cannot add `()` to `u32` bar(x, diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr index b6182825fc27..a18dfeb31d9e 100644 --- a/src/test/ui/span/multiline-span-simple.stderr +++ b/src/test/ui/span/multiline-span-simple.stderr @@ -1,7 +1,7 @@ error[E0277]: cannot add `()` to `u32` --> $DIR/multiline-span-simple.rs:23:18 | -23 | foo(1 as u32 + //~ ERROR not satisfied +23 | foo(1 as u32 + //~ ERROR cannot add `()` to `u32` | ^ no implementation for `u32 + ()` | = help: the trait `std::ops::Add<()>` is not implemented for `u32` diff --git a/src/test/ui/suggestions/iterate-str.rs b/src/test/ui/suggestions/iterate-str.rs new file mode 100644 index 000000000000..1022491b84a3 --- /dev/null +++ b/src/test/ui/suggestions/iterate-str.rs @@ -0,0 +1,19 @@ +// Copyright 2018 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() { + for c in "foobarbaz" { + println!("{}", c); + } + //~^^^ ERROR the trait bound `&str: std::iter::Iterator` is not satisfied + //~| NOTE `&str` is not an iterator; try calling `.chars()` or `.bytes()` + //~| HELP the trait `std::iter::Iterator` is not implemented for `&str` + //~| NOTE required by `std::iter::IntoIterator::into_iter` +} diff --git a/src/test/ui/suggestions/iterate-str.stderr b/src/test/ui/suggestions/iterate-str.stderr new file mode 100644 index 000000000000..59da6d70c023 --- /dev/null +++ b/src/test/ui/suggestions/iterate-str.stderr @@ -0,0 +1,13 @@ +error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied + --> $DIR/iterate-str.rs:12:5 + | +12 | / for c in "foobarbaz" { +13 | | println!("{}", c); +14 | | } + | |_____^ `&str` is not an iterator; try calling `.chars()` or `.bytes()` + | + = help: the trait `std::iter::Iterator` is not implemented for `&str` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to previous error +