Add filter to detect local crates for rustc_on_unimplemented

This commit is contained in:
Esteban Küber 2018-01-20 01:33:39 -08:00
parent 4c92a02b64
commit 621e61bff9
16 changed files with 299 additions and 47 deletions

View File

@ -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.

View File

@ -28,8 +28,13 @@ fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
/// [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.

View File

@ -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
) {

View File

@ -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 {

View File

@ -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<impl Foo>` is not satisfied
//~^ ERROR cannot add `impl Foo` to `u32`
}
}

View File

@ -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<T>(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": [

View File

@ -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
}

View File

@ -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<std::option::Option<{integer}>>` 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<std::option::Option<{integer}>>` 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}`

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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;

View File

@ -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<usize>` 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<usize>` 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<u32>` 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<u32>` 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<Foo<u32>>` is not satisfied
--> $DIR/multiple-impls-complex-filtering.rs:55:5
|
55 | Index::index(&[] as &[i32], Foo(2u32));
| ^^^^^^^^^^^^ impl foo [i32] Foo<u32> Index
|
= help: the trait `Index<Foo<u32>>` 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<Foo<u32>>` is not satisfied
--> $DIR/multiple-impls-complex-filtering.rs:55:5
|
55 | Index::index(&[] as &[i32], Foo(2u32));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl foo [i32] Foo<u32> Index
|
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` 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<Bar<u32>>` 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<Bar<u32>>` 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<Bar<u32>>` is not implemented for `[i32]`
error: aborting due to 10 previous errors

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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`

View File

@ -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

View File

@ -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,

View File

@ -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`

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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`
}

View File

@ -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