Skip to content

Commit fe30357

Browse files
committed
Make diagnostics clearer for binop-related errors in foreign crates
Fixes redundant language and bad grammar.
1 parent 5c7ae0c commit fe30357

File tree

10 files changed

+38
-58
lines changed

10 files changed

+38
-58
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::path::PathBuf;
99

1010
use hir::Expr;
1111
use rustc_ast::ast::Mutability;
12-
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
12+
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
1313
use rustc_data_structures::sorted_map::SortedMap;
1414
use rustc_data_structures::unord::UnordSet;
1515
use rustc_errors::codes::*;
@@ -2988,40 +2988,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29882988
let foreign_def_ids = foreign_preds
29892989
.iter()
29902990
.filter_map(|pred| match pred.self_ty().kind() {
2991-
ty::Adt(def, _) => Some(def.did()),
2991+
ty::Adt(def, _) => Some((pred, def.did())),
29922992
_ => None,
29932993
})
2994-
.collect::<FxIndexSet<_>>();
2994+
.collect::<Vec<_>>();
29952995
let mut foreign_spans: MultiSpan = foreign_def_ids
29962996
.iter()
2997-
.filter_map(|def_id| {
2997+
.filter_map(|(_, def_id)| {
29982998
let span = self.tcx.def_span(*def_id);
2999-
if span.is_dummy() { None } else { Some(span) }
2999+
(!span.is_dummy()).then_some(span)
30003000
})
30013001
.collect::<Vec<_>>()
30023002
.into();
3003-
for pred in &foreign_preds {
3004-
if let ty::Adt(def, _) = pred.self_ty().kind() {
3003+
3004+
let unique_traits =
3005+
foreign_preds.iter().map(|pred| pred.def_id()).collect::<FxHashSet<_>>().len();
3006+
3007+
if foreign_def_ids.len() > 1 {
3008+
for (pred, def_id) in foreign_def_ids {
30053009
foreign_spans.push_span_label(
3006-
self.tcx.def_span(def.did()),
3007-
format!("not implement `{}`", pred.trait_ref.print_trait_sugared()),
3010+
self.tcx.def_span(def_id),
3011+
format!(
3012+
"`{}` does not implement `{}`",
3013+
pred.self_ty(),
3014+
pred.trait_ref.print_trait_sugared()
3015+
),
30083016
);
30093017
}
30103018
}
3019+
30113020
if foreign_spans.primary_span().is_some() {
30123021
let msg = if let [foreign_pred] = foreign_preds.as_slice() {
30133022
format!(
3014-
"the foreign item type `{}` doesn't implement `{}`",
3023+
"`{}`, which is defined in another crate, doesn't implement `{}`",
30153024
foreign_pred.self_ty(),
30163025
foreign_pred.trait_ref.print_trait_sugared()
30173026
)
30183027
} else {
30193028
format!(
3020-
"the foreign item type{} {} implement required trait{} for this \
3021-
operation to be valid",
3022-
pluralize!(foreign_def_ids.len()),
3023-
if foreign_def_ids.len() > 1 { "don't" } else { "doesn't" },
3024-
pluralize!(foreign_preds.len()),
3029+
"these types, defined in other crates, do not implement the required trait{}",
3030+
pluralize!(unique_traits),
30253031
)
30263032
};
30273033
err.span_note(foreign_spans, msg);

tests/ui/array-slice-vec/vec-res-add.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ LL | let k = i + j;
66
| |
77
| Vec<R>
88
|
9-
note: the foreign item type `Vec<R>` doesn't implement `Add`
9+
note: `Vec<R>`, which is defined in another crate, doesn't implement `Add`
1010
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
11-
|
12-
= note: not implement `Add`
1311

1412
error: aborting due to 1 previous error
1513

tests/ui/autoref-autoderef/autoderef-box-no-add.stderr

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ LL | let z: isize = a.x + b.y;
66
| |
77
| Box<isize>
88
|
9-
note: the foreign item type `Box<isize>` doesn't implement `Add`
9+
note: `Box<isize>`, which is defined in another crate, doesn't implement `Add`
1010
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
11-
::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
12-
|
13-
= note: not implement `Add`
1411

1512
error[E0369]: cannot add `Box<isize>` to `Box<isize>`
1613
--> $DIR/autoderef-box-no-add.rs:31:33
@@ -20,11 +17,8 @@ LL | let answer: isize = forty.a + two.a;
2017
| |
2118
| Box<isize>
2219
|
23-
note: the foreign item type `Box<isize>` doesn't implement `Add`
20+
note: `Box<isize>`, which is defined in another crate, doesn't implement `Add`
2421
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
25-
::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
26-
|
27-
= note: not implement `Add`
2822

2923
error: aborting due to 2 previous errors
3024

tests/ui/binop/binary-op-not-allowed-issue-125631.stderr

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ note: an implementation of `PartialEq` might be missing for `T1`
1111
|
1212
LL | struct T1;
1313
| ^^^^^^^^^ must implement `PartialEq`
14-
note: the foreign item type `std::io::Error` doesn't implement `PartialEq`
14+
note: `std::io::Error`, which is defined in another crate, doesn't implement `PartialEq`
1515
--> $SRC_DIR/std/src/io/error.rs:LL:COL
16-
|
17-
= note: not implement `PartialEq`
1816
help: consider annotating `T1` with `#[derive(PartialEq)]`
1917
|
2018
LL + #[derive(PartialEq)]
@@ -29,13 +27,13 @@ LL | (Error::new(ErrorKind::Other, "2"), thread::current())
2927
LL | == (Error::new(ErrorKind::Other, "2"), thread::current());
3028
| ^^ ------------------------------------------------------ (std::io::Error, Thread)
3129
|
32-
note: the foreign item types don't implement required traits for this operation to be valid
30+
note: these types, defined in other crates, do not implement the required trait
3331
--> $SRC_DIR/std/src/io/error.rs:LL:COL
3432
|
35-
= note: not implement `PartialEq`
33+
= note: `std::io::Error` does not implement `PartialEq`
3634
--> $SRC_DIR/std/src/thread/mod.rs:LL:COL
3735
|
38-
= note: not implement `PartialEq`
36+
= note: `Thread` does not implement `PartialEq`
3937

4038
error[E0369]: binary operation `==` cannot be applied to type `(std::io::Error, Thread, T1, T2)`
4139
--> $DIR/binary-op-not-allowed-issue-125631.rs:14:9
@@ -52,13 +50,13 @@ LL | struct T1;
5250
| ^^^^^^^^^ must implement `PartialEq`
5351
LL | struct T2;
5452
| ^^^^^^^^^ must implement `PartialEq`
55-
note: the foreign item types don't implement required traits for this operation to be valid
53+
note: these types, defined in other crates, do not implement the required trait
5654
--> $SRC_DIR/std/src/io/error.rs:LL:COL
5755
|
58-
= note: not implement `PartialEq`
56+
= note: `std::io::Error` does not implement `PartialEq`
5957
--> $SRC_DIR/std/src/thread/mod.rs:LL:COL
6058
|
61-
= note: not implement `PartialEq`
59+
= note: `Thread` does not implement `PartialEq`
6260
help: consider annotating `T1` with `#[derive(PartialEq)]`
6361
|
6462
LL + #[derive(PartialEq)]

tests/ui/binop/binop-bitxor-str.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ LL | fn main() { let x = "a".to_string() ^ "b".to_string(); }
66
| |
77
| String
88
|
9-
note: the foreign item type `String` doesn't implement `BitXor`
9+
note: `String`, which is defined in another crate, doesn't implement `BitXor`
1010
--> $SRC_DIR/alloc/src/string.rs:LL:COL
11-
|
12-
= note: not implement `BitXor`
1311

1412
error: aborting due to 1 previous error
1513

tests/ui/error-codes/E0067.stderr

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ LL | LinkedList::new() += 1;
66
| |
77
| cannot use `+=` on type `LinkedList<_>`
88
|
9-
note: the foreign item type `LinkedList<_>` doesn't implement `AddAssign<{integer}>`
9+
note: `LinkedList<_>`, which is defined in another crate, doesn't implement `AddAssign<{integer}>`
1010
--> $SRC_DIR/alloc/src/collections/linked_list.rs:LL:COL
11-
::: $SRC_DIR/alloc/src/collections/linked_list.rs:LL:COL
12-
|
13-
= note: not implement `AddAssign<{integer}>`
1411

1512
error[E0067]: invalid left-hand side of assignment
1613
--> $DIR/E0067.rs:4:23

tests/ui/operator-recovery/box-arithmetic-14915.stderr

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ LL | println!("{}", x + 1);
66
| |
77
| Box<isize>
88
|
9-
note: the foreign item type `Box<isize>` doesn't implement `Add<{integer}>`
9+
note: `Box<isize>`, which is defined in another crate, doesn't implement `Add<{integer}>`
1010
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
11-
::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
12-
|
13-
= note: not implement `Add<{integer}>`
1411

1512
error: aborting due to 1 previous error
1613

tests/ui/pattern/pattern-tyvar-2.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ LL | fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3;
66
| |
77
| Vec<isize>
88
|
9-
note: the foreign item type `Vec<isize>` doesn't implement `Mul<{integer}>`
9+
note: `Vec<isize>`, which is defined in another crate, doesn't implement `Mul<{integer}>`
1010
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
11-
|
12-
= note: not implement `Mul<{integer}>`
1311

1412
error: aborting due to 1 previous error
1513

tests/ui/typeck/assign-non-lval-derefmut.stderr

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ LL | x.lock().unwrap() += 1;
1919
| |
2020
| cannot use `+=` on type `std::sync::MutexGuard<'_, usize>`
2121
|
22-
note: the foreign item type `std::sync::MutexGuard<'_, usize>` doesn't implement `AddAssign<{integer}>`
22+
note: `std::sync::MutexGuard<'_, usize>`, which is defined in another crate, doesn't implement `AddAssign<{integer}>`
2323
--> $SRC_DIR/std/src/sync/poison/mutex.rs:LL:COL
24-
|
25-
= note: not implement `AddAssign<{integer}>`
2624
help: `+=` can be used on `usize` if you dereference the left-hand side
2725
|
2826
LL | *x.lock().unwrap() += 1;
@@ -51,10 +49,8 @@ LL | y += 1;
5149
| |
5250
| cannot use `+=` on type `std::sync::MutexGuard<'_, usize>`
5351
|
54-
note: the foreign item type `std::sync::MutexGuard<'_, usize>` doesn't implement `AddAssign<{integer}>`
52+
note: `std::sync::MutexGuard<'_, usize>`, which is defined in another crate, doesn't implement `AddAssign<{integer}>`
5553
--> $SRC_DIR/std/src/sync/poison/mutex.rs:LL:COL
56-
|
57-
= note: not implement `AddAssign<{integer}>`
5854
help: `+=` can be used on `usize` if you dereference the left-hand side
5955
|
6056
LL | *y += 1;

tests/ui/typeck/minus-string.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ error[E0600]: cannot apply unary operator `-` to type `String`
44
LL | -"foo".to_string();
55
| ^^^^^^^^^^^^^^^^^^ cannot apply unary operator `-`
66
|
7-
note: the foreign item type `String` doesn't implement `Neg`
7+
note: `String`, which is defined in another crate, doesn't implement `Neg`
88
--> $SRC_DIR/alloc/src/string.rs:LL:COL
9-
|
10-
= note: not implement `Neg`
119

1210
error: aborting due to 1 previous error
1311

0 commit comments

Comments
 (0)