Skip to content

Commit 621e61b

Browse files
committed
Add filter to detect local crates for rustc_on_unimplemented
1 parent 4c92a02 commit 621e61b

File tree

16 files changed

+299
-47
lines changed

16 files changed

+299
-47
lines changed

src/libcore/fmt/mod.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -530,9 +530,12 @@ impl<'a> Display for Arguments<'a> {
530530
/// }
531531
/// ```
532532
#[stable(feature = "rust1", since = "1.0.0")]
533-
#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \
534-
defined in your crate, add `#[derive(Debug)]` or \
535-
manually implement it"]
533+
#[rustc_on_unimplemented(
534+
on(crate_local, label="`{Self}` cannot be formatted using `:?`; \
535+
add `#[derive(Debug)]` or manually implement `{Debug}`"),
536+
message="`{Self}` doesn't implement `{Debug}`",
537+
label="`{Self}` cannot be formatted using `:?` because it doesn't implement `{Debug}`",
538+
)]
536539
#[lang = "debug_trait"]
537540
pub trait Debug {
538541
/// Formats the value using the given formatter.
@@ -593,9 +596,11 @@ pub trait Debug {
593596
///
594597
/// println!("The origin is: {}", origin);
595598
/// ```
596-
#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \
597-
formatter; try using `:?` instead if you are using \
598-
a format string"]
599+
#[rustc_on_unimplemented(
600+
message="`{Self}` doesn't implement `{Display}`",
601+
label="`{Self}` cannot be formatted with the default formatter; \
602+
try using `:?` instead if you are using a format string",
603+
)]
599604
#[stable(feature = "rust1", since = "1.0.0")]
600605
pub trait Display {
601606
/// Formats the value using the given formatter.

src/libcore/iter/iterator.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@ fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
2828
/// [module-level documentation]: index.html
2929
/// [impl]: index.html#implementing-iterator
3030
#[stable(feature = "rust1", since = "1.0.0")]
31-
#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \
32-
`.iter()` or a similar method"]
31+
#[rustc_on_unimplemented(
32+
on(
33+
_Self="&str",
34+
label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
35+
),
36+
label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method"
37+
)]
3338
#[doc(spotlight)]
3439
pub trait Iterator {
3540
/// The type of the elements being iterated over.

src/librustc/traits/error_reporting.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
384384
Some(ty_str.clone())));
385385
}
386386

387+
if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) {
388+
flags.push(("crate_local".to_string(), None));
389+
}
390+
387391
if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
388392
self.tcx, trait_ref.def_id, def_id
389393
) {

src/librustc/traits/on_unimplemented.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
185185
let mut message = None;
186186
let mut label = None;
187187
let mut note = None;
188-
info!("evaluate({:?}, trait_ref={:?}, options={:?})",
189-
self, trait_ref, options);
188+
info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options);
190189

191190
for command in self.subcommands.iter().chain(Some(self)).rev() {
192191
if let Some(ref condition) = command.condition {

src/test/ui/impl-trait/equality.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn sum_to(n: u32) -> impl Foo {
3232
0
3333
} else {
3434
n + sum_to(n - 1)
35-
//~^ ERROR the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
35+
//~^ ERROR cannot add `impl Foo` to `u32`
3636
}
3737
}
3838

src/test/ui/lint/use_suggestion_json.stderr

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,72 @@
22
"message": "cannot find type `Iter` in this scope",
33
"code": {
44
"code": "E0412",
5-
"explanation": null
5+
"explanation": "
6+
The type name used is not in scope.
7+
8+
Erroneous code examples:
9+
10+
```compile_fail,E0412
11+
impl Something {} // error: type name `Something` is not in scope
12+
13+
// or:
14+
15+
trait Foo {
16+
fn bar(N); // error: type name `N` is not in scope
17+
}
18+
19+
// or:
20+
21+
fn foo(x: T) {} // type name `T` is not in scope
22+
```
23+
24+
To fix this error, please verify you didn't misspell the type name, you did
25+
declare it or imported it into the scope. Examples:
26+
27+
```
28+
struct Something;
29+
30+
impl Something {} // ok!
31+
32+
// or:
33+
34+
trait Foo {
35+
type N;
36+
37+
fn bar(_: Self::N); // ok!
38+
}
39+
40+
// or:
41+
42+
fn foo<T>(x: T) {} // ok!
43+
```
44+
45+
Another case that causes this error is when a type is imported into a parent
46+
module. To fix this, you can follow the suggestion and use File directly or
47+
`use super::File;` which will import the types from the parent namespace. An
48+
example that causes this error is below:
49+
50+
```compile_fail,E0412
51+
use std::fs::File;
52+
53+
mod foo {
54+
fn some_function(f: File) {}
55+
}
56+
```
57+
58+
```
59+
use std::fs::File;
60+
61+
mod foo {
62+
// either
63+
use super::File;
64+
// or
65+
// use std::fs::File;
66+
fn foo(f: File) {}
67+
}
68+
# fn main() {} // don't insert it for us; that'll break imports
69+
```
70+
"
671
},
772
"level": "error",
873
"spans": [

src/test/ui/mismatched_types/binops.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
// except according to those terms.
1010

1111
fn main() {
12-
1 + Some(1); //~ ERROR is not satisfied
13-
2 as usize - Some(1); //~ ERROR is not satisfied
14-
3 * (); //~ ERROR is not satisfied
15-
4 / ""; //~ ERROR is not satisfied
12+
1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
13+
2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
14+
3 * (); //~ ERROR cannot multiply `()` to `{integer}`
15+
4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
1616
5 < String::new(); //~ ERROR is not satisfied
1717
6 == Ok(1); //~ ERROR is not satisfied
1818
}

src/test/ui/mismatched_types/binops.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}`
22
--> $DIR/binops.rs:12:7
33
|
4-
12 | 1 + Some(1); //~ ERROR is not satisfied
4+
12 | 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
55
| ^ no implementation for `{integer} + std::option::Option<{integer}>`
66
|
77
= help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
88

99
error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize`
1010
--> $DIR/binops.rs:13:16
1111
|
12-
13 | 2 as usize - Some(1); //~ ERROR is not satisfied
12+
13 | 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
1313
| ^ no implementation for `usize - std::option::Option<{integer}>`
1414
|
1515
= help: the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize`
1616

1717
error[E0277]: cannot multiply `()` to `{integer}`
1818
--> $DIR/binops.rs:14:7
1919
|
20-
14 | 3 * (); //~ ERROR is not satisfied
20+
14 | 3 * (); //~ ERROR cannot multiply `()` to `{integer}`
2121
| ^ no implementation for `{integer} * ()`
2222
|
2323
= help: the trait `std::ops::Mul<()>` is not implemented for `{integer}`
2424

2525
error[E0277]: cannot divide `{integer}` by `&str`
2626
--> $DIR/binops.rs:15:7
2727
|
28-
15 | 4 / ""; //~ ERROR is not satisfied
28+
15 | 4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
2929
| ^ no implementation for `{integer} / &str`
3030
|
3131
= help: the trait `std::ops::Div<&str>` is not implemented for `{integer}`
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
// ignore-tidy-linelength
11+
12+
#![crate_type = "lib"]
13+
14+
pub struct Bar;
Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,107 @@
1-
error[E0277]: trait message `[i32]`
2-
--> $DIR/multiple-impls-complex-filtering.rs:46:5
1+
error[E0277]: trait message
2+
--> $DIR/multiple-impls-complex-filtering.rs:49:5
33
|
4-
46 | Index::index(&[] as &[i32], 2usize);
5-
| ^^^^^^^^^^^^ u32 message
4+
49 | Index::index(&[] as &[i32], 2usize);
5+
| ^^^^^^^^^^^^ trait label if i32
66
|
7-
= help: the trait `Index<_>` is not implemented for `[i32]`
7+
= help: the trait `Index<usize>` is not implemented for `[i32]`
88
note: required by `Index::index`
9-
--> $DIR/multiple-impls-complex-filtering.rs:25:5
9+
--> $DIR/multiple-impls-complex-filtering.rs:26:5
1010
|
11-
25 | fn index(&self, index: Idx) -> &Self::Output;
11+
26 | fn index(&self, index: Idx) -> &Self::Output;
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1313

14-
error[E0277]: trait message `[i32]`
15-
--> $DIR/multiple-impls-complex-filtering.rs:46:5
14+
error[E0277]: trait message
15+
--> $DIR/multiple-impls-complex-filtering.rs:49:5
1616
|
17-
46 | Index::index(&[] as &[i32], 2usize);
18-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message
17+
49 | Index::index(&[] as &[i32], 2usize);
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32
1919
|
20-
= help: the trait `Index<_>` is not implemented for `[i32]`
20+
= help: the trait `Index<usize>` is not implemented for `[i32]`
2121

22-
error[E0277]: trait message `[i32]`
23-
--> $DIR/multiple-impls-complex-filtering.rs:47:5
22+
error[E0277]: trait message
23+
--> $DIR/multiple-impls-complex-filtering.rs:50:5
2424
|
25-
47 | Index::index(&[] as &[i32], 2u32);
26-
| ^^^^^^^^^^^^ u32 message
25+
50 | Index::index(&[] as &[i32], 2u32);
26+
| ^^^^^^^^^^^^ trait label if i32
2727
|
28-
= help: the trait `Index<_>` is not implemented for `[i32]`
28+
= help: the trait `Index<u32>` is not implemented for `[i32]`
2929
note: required by `Index::index`
30-
--> $DIR/multiple-impls-complex-filtering.rs:25:5
30+
--> $DIR/multiple-impls-complex-filtering.rs:26:5
3131
|
32-
25 | fn index(&self, index: Idx) -> &Self::Output;
32+
26 | fn index(&self, index: Idx) -> &Self::Output;
3333
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3434

35-
error[E0277]: trait message `[i32]`
36-
--> $DIR/multiple-impls-complex-filtering.rs:47:5
35+
error[E0277]: trait message
36+
--> $DIR/multiple-impls-complex-filtering.rs:50:5
3737
|
38-
47 | Index::index(&[] as &[i32], 2u32);
39-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message
38+
50 | Index::index(&[] as &[i32], 2u32);
39+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32
4040
|
41-
= help: the trait `Index<_>` is not implemented for `[i32]`
41+
= help: the trait `Index<u32>` is not implemented for `[i32]`
4242

43-
error: aborting due to 4 previous errors
43+
error[E0277]: trait message
44+
--> $DIR/multiple-impls-complex-filtering.rs:51:5
45+
|
46+
51 | Index::index(&[] as &[u32], 2u32);
47+
| ^^^^^^^^^^^^ trait label
48+
|
49+
= help: the trait `Index<_>` is not implemented for `[u32]`
50+
note: required by `Index::index`
51+
--> $DIR/multiple-impls-complex-filtering.rs:26:5
52+
|
53+
26 | fn index(&self, index: Idx) -> &Self::Output;
54+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
55+
56+
error[E0277]: trait message
57+
--> $DIR/multiple-impls-complex-filtering.rs:51:5
58+
|
59+
51 | Index::index(&[] as &[u32], 2u32);
60+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label
61+
|
62+
= help: the trait `Index<_>` is not implemented for `[u32]`
63+
64+
error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
65+
--> $DIR/multiple-impls-complex-filtering.rs:55:5
66+
|
67+
55 | Index::index(&[] as &[i32], Foo(2u32));
68+
| ^^^^^^^^^^^^ impl foo [i32] Foo<u32> Index
69+
|
70+
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
71+
note: required by `Index::index`
72+
--> $DIR/multiple-impls-complex-filtering.rs:26:5
73+
|
74+
26 | fn index(&self, index: Idx) -> &Self::Output;
75+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76+
77+
error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
78+
--> $DIR/multiple-impls-complex-filtering.rs:55:5
79+
|
80+
55 | Index::index(&[] as &[i32], Foo(2u32));
81+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl foo [i32] Foo<u32> Index
82+
|
83+
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
84+
85+
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
86+
--> $DIR/multiple-impls-complex-filtering.rs:58:5
87+
|
88+
58 | Index::index(&[] as &[i32], Bar(2u32));
89+
| ^^^^^^^^^^^^ on impl for Bar
90+
|
91+
= help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
92+
note: required by `Index::index`
93+
--> $DIR/multiple-impls-complex-filtering.rs:26:5
94+
|
95+
26 | fn index(&self, index: Idx) -> &Self::Output;
96+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
97+
98+
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
99+
--> $DIR/multiple-impls-complex-filtering.rs:58:5
100+
|
101+
58 | Index::index(&[] as &[i32], Bar(2u32));
102+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
103+
|
104+
= help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
105+
106+
error: aborting due to 10 previous errors
44107

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:no_debug.rs
12+
13+
extern crate no_debug;
14+
15+
use no_debug::Bar;
16+
17+
struct Foo;
18+
19+
fn main() {
20+
println!("{:?} {:?}", Foo, Bar);
21+
println!("{} {}", Foo, Bar);
22+
}
23+
//~^^^ ERROR `Foo` doesn't implement `std::fmt::Debug`
24+
//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Debug`
25+
//~^^^^ ERROR `Foo` doesn't implement `std::fmt::Display`
26+
//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Display`
27+

0 commit comments

Comments
 (0)