Skip to content

Commit 5a93f38

Browse files
committed
Revert "Dedup logic and improve output for other types that impl trait"
This reverts commit ef91519.
1 parent 1fdedfc commit 5a93f38

File tree

47 files changed

+357
-363
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+357
-363
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 61 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use rustc_middle::traits::select::OverflowError;
3030
use rustc_middle::ty::error::ExpectedFound;
3131
use rustc_middle::ty::fold::TypeFolder;
3232
use rustc_middle::ty::{
33-
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
33+
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable,
3434
};
3535
use rustc_span::symbol::{kw, sym};
3636
use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP};
@@ -1762,60 +1762,6 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
17621762
trait_ref: ty::PolyTraitRef<'tcx>,
17631763
err: &mut Diagnostic,
17641764
) -> bool {
1765-
let report = |mut candidates: Vec<TraitRef<'_>>, err: &mut Diagnostic| {
1766-
candidates.sort();
1767-
candidates.dedup();
1768-
let len = candidates.len();
1769-
if candidates.len() == 0 {
1770-
return false;
1771-
}
1772-
let trait_ref = candidates[0];
1773-
if candidates.len() == 1 {
1774-
err.highlighted_help(vec![
1775-
(
1776-
format!(
1777-
"the trait `{}` is implemented for `",
1778-
trait_ref.print_only_trait_path()
1779-
),
1780-
Style::NoStyle,
1781-
),
1782-
(candidates[0].self_ty().to_string(), Style::Highlight),
1783-
("`".to_string(), Style::NoStyle),
1784-
]);
1785-
return true;
1786-
}
1787-
// Check if the trait is the same in all cases. If so, we'll only show the type.
1788-
// FIXME: there *has* to be a better way!
1789-
let mut traits: Vec<_> = candidates
1790-
.iter()
1791-
.map(|c| format!("{}", c).split(" as ").last().unwrap().to_string())
1792-
.collect();
1793-
traits.sort();
1794-
traits.dedup();
1795-
1796-
let mut candidates: Vec<String> = candidates
1797-
.into_iter()
1798-
.map(|c| {
1799-
if traits.len() == 1 {
1800-
format!("\n {}", c.self_ty())
1801-
} else {
1802-
format!("\n {}", c)
1803-
}
1804-
})
1805-
.collect();
1806-
1807-
candidates.sort();
1808-
candidates.dedup();
1809-
let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
1810-
err.help(&format!(
1811-
"the following other types implement trait `{}`:{}{}",
1812-
trait_ref.print_only_trait_path(),
1813-
candidates[..end].join(""),
1814-
if len > 9 { format!("\nand {} others", len - 8) } else { String::new() }
1815-
));
1816-
true
1817-
};
1818-
18191765
let def_id = trait_ref.def_id();
18201766
if impl_candidates.is_empty() {
18211767
if self.tcx.trait_is_auto(def_id)
@@ -1825,7 +1771,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
18251771
// Mentioning implementers of `Copy`, `Debug` and friends is not useful.
18261772
return false;
18271773
}
1828-
let normalized_impl_candidates: Vec<_> = self
1774+
let mut normalized_impl_candidates: Vec<_> = self
18291775
.tcx
18301776
.all_impls(def_id)
18311777
// Ignore automatically derived impls and `!Trait` impls.
@@ -1836,19 +1782,54 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
18361782
.filter_map(|def_id| self.tcx.impl_trait_ref(def_id))
18371783
// Avoid mentioning type parameters.
18381784
.filter(|trait_ref| !matches!(trait_ref.self_ty().kind(), ty::Param(_)))
1785+
.map(|trait_ref| format!("\n {}", trait_ref.self_ty()))
18391786
.collect();
1840-
return report(normalized_impl_candidates, err);
1787+
normalized_impl_candidates.sort();
1788+
normalized_impl_candidates.dedup();
1789+
let len = normalized_impl_candidates.len();
1790+
if len == 0 {
1791+
return false;
1792+
}
1793+
if len == 1 {
1794+
err.highlighted_help(vec![
1795+
(
1796+
format!(
1797+
"the trait `{}` is implemented for `",
1798+
trait_ref.print_only_trait_path()
1799+
),
1800+
Style::NoStyle,
1801+
),
1802+
(normalized_impl_candidates[0].trim().to_string(), Style::Highlight),
1803+
("`".to_string(), Style::NoStyle),
1804+
]);
1805+
return true;
1806+
}
1807+
let end = if normalized_impl_candidates.len() <= 9 {
1808+
normalized_impl_candidates.len()
1809+
} else {
1810+
8
1811+
};
1812+
err.help(&format!(
1813+
"the following other types implement trait `{}`:{}{}",
1814+
trait_ref.print_only_trait_path(),
1815+
normalized_impl_candidates[..end].join(""),
1816+
if len > 9 { format!("\nand {} others", len - 8) } else { String::new() }
1817+
));
1818+
return true;
18411819
}
18421820

1821+
let len = impl_candidates.len();
1822+
let end = if impl_candidates.len() <= 9 { impl_candidates.len() } else { 8 };
1823+
18431824
let normalize = |candidate| {
18441825
self.tcx.infer_ctxt().enter(|ref infcx| {
18451826
let normalized = infcx
18461827
.at(&ObligationCause::dummy(), ty::ParamEnv::empty())
18471828
.normalize(candidate)
18481829
.ok();
18491830
match normalized {
1850-
Some(normalized) => normalized.value,
1851-
None => candidate,
1831+
Some(normalized) => format!("\n {}", normalized.value),
1832+
None => format!("\n {}", candidate),
18521833
}
18531834
})
18541835
};
@@ -1859,6 +1840,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
18591840
//
18601841
// Prefer more similar candidates first, then sort lexicographically
18611842
// by their normalized string representation.
1843+
let first_candidate = impl_candidates.get(0).map(|candidate| candidate.trait_ref);
18621844
let mut normalized_impl_candidates_and_similarities = impl_candidates
18631845
.into_iter()
18641846
.map(|ImplCandidate { trait_ref, similarity }| {
@@ -1874,7 +1856,26 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
18741856
.map(|(_, normalized)| normalized)
18751857
.collect::<Vec<_>>();
18761858

1877-
report(normalized_impl_candidates, err)
1859+
if normalized_impl_candidates.len() == 1 {
1860+
err.highlighted_help(vec![
1861+
(
1862+
format!(
1863+
"the trait `{}` is implemented for `",
1864+
first_candidate.unwrap().print_only_trait_path()
1865+
),
1866+
Style::NoStyle,
1867+
),
1868+
(first_candidate.unwrap().self_ty().to_string(), Style::Highlight),
1869+
("`".to_string(), Style::NoStyle),
1870+
]);
1871+
} else {
1872+
err.help(&format!(
1873+
"the following implementations were found:{}{}",
1874+
normalized_impl_candidates[..end].join(""),
1875+
if len > 9 { format!("\nand {} others", len - 8) } else { String::new() }
1876+
));
1877+
}
1878+
true
18781879
}
18791880

18801881
/// Gets the parent trait chain start

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -565,11 +565,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
565565
}
566566
} else if real_trait_pred != trait_pred {
567567
// This branch addresses #87437.
568-
let obligation = self.mk_trait_obligation_with_new_self_ty(
569-
param_env,
570-
real_trait_pred,
571-
base_ty,
572-
);
568+
let obligation =
569+
self.mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred, base_ty);
573570
if self.predicate_may_hold(&obligation) {
574571
err.span_suggestion_verbose(
575572
span.shrink_to_lo(),

src/test/ui/binop/binop-mul-i32-f32.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ LL | x * y
55
| ^ no implementation for `i32 * f32`
66
|
77
= help: the trait `Mul<f32>` is not implemented for `i32`
8-
= help: the following other types implement trait `Mul`:
8+
= help: the following implementations were found:
9+
<&'a i32 as Mul<i32>>
10+
<&i32 as Mul<&i32>>
11+
<i32 as Mul<&i32>>
12+
<i32 as Mul>
913
<&'a f32 as Mul<f32>>
1014
<&'a f64 as Mul<f64>>
1115
<&'a i128 as Mul<i128>>
1216
<&'a i16 as Mul<i16>>
13-
<&'a i32 as Mul<i32>>
14-
<&'a i64 as Mul<i64>>
15-
<&'a i8 as Mul<i8>>
16-
<&'a isize as Mul<isize>>
1717
and 49 others
1818

1919
error: aborting due to previous error

src/test/ui/binop/issue-77910-1.stderr

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ LL | assert_eq!(foo, y);
1616
| ^^^^^^^^^^^^^^^^^^ `for<'r> fn(&'r i32) -> &'r i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
1717
|
1818
= help: the trait `Debug` is not implemented for `for<'r> fn(&'r i32) -> &'r i32 {foo}`
19-
= help: the following other types implement trait `Debug`:
20-
extern "C" fn() -> Ret
21-
extern "C" fn(A) -> Ret
22-
extern "C" fn(A, ...) -> Ret
23-
extern "C" fn(A, B) -> Ret
24-
extern "C" fn(A, B, ...) -> Ret
25-
extern "C" fn(A, B, C) -> Ret
26-
extern "C" fn(A, B, C, ...) -> Ret
27-
extern "C" fn(A, B, C, D) -> Ret
19+
= help: the following implementations were found:
20+
<extern "C" fn() -> Ret as Debug>
21+
<extern "C" fn(A) -> Ret as Debug>
22+
<extern "C" fn(A, ...) -> Ret as Debug>
23+
<extern "C" fn(A, B) -> Ret as Debug>
24+
<extern "C" fn(A, B, ...) -> Ret as Debug>
25+
<extern "C" fn(A, B, C) -> Ret as Debug>
26+
<extern "C" fn(A, B, C, ...) -> Ret as Debug>
27+
<extern "C" fn(A, B, C, D) -> Ret as Debug>
2828
and 68 others
2929
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
3030

src/test/ui/binop/shift-various-bad-types.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | 22 >> p.char;
55
| ^^ no implementation for `{integer} >> char`
66
|
77
= help: the trait `Shr<char>` is not implemented for `{integer}`
8-
= help: the following other types implement trait `Shr`:
8+
= help: the following implementations were found:
99
<&'a i128 as Shr<i128>>
1010
<&'a i128 as Shr<i16>>
1111
<&'a i128 as Shr<i32>>
@@ -23,7 +23,7 @@ LL | 22 >> p.str;
2323
| ^^ no implementation for `{integer} >> &str`
2424
|
2525
= help: the trait `Shr<&str>` is not implemented for `{integer}`
26-
= help: the following other types implement trait `Shr`:
26+
= help: the following implementations were found:
2727
<&'a i128 as Shr<i128>>
2828
<&'a i128 as Shr<i16>>
2929
<&'a i128 as Shr<i32>>
@@ -41,7 +41,7 @@ LL | 22 >> p;
4141
| ^^ no implementation for `{integer} >> &Panolpy`
4242
|
4343
= help: the trait `Shr<&Panolpy>` is not implemented for `{integer}`
44-
= help: the following other types implement trait `Shr`:
44+
= help: the following implementations were found:
4545
<&'a i128 as Shr<i128>>
4646
<&'a i128 as Shr<i16>>
4747
<&'a i128 as Shr<i32>>

src/test/ui/chalkify/chalk_initial_program.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ error[E0277]: the trait bound `f32: Foo` is not satisfied
44
LL | gimme::<f32>();
55
| ^^^ the trait `Foo` is not implemented for `f32`
66
|
7-
= help: the following other types implement trait `Foo`:
8-
i32
9-
u32
7+
= help: the following implementations were found:
8+
<i32 as Foo>
9+
<u32 as Foo>
1010
note: required by a bound in `gimme`
1111
--> $DIR/chalk_initial_program.rs:9:13
1212
|

src/test/ui/chalkify/type_inference.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ LL | only_bar(x);
66
| |
77
| required by a bound introduced by this call
88
|
9-
= help: the following other types implement trait `Bar`:
10-
i32
11-
u32
9+
= help: the following implementations were found:
10+
<i32 as Bar>
11+
<u32 as Bar>
1212
note: required by a bound in `only_bar`
1313
--> $DIR/type_inference.rs:12:16
1414
|

src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied
2525
LL | fn uwu<const N: u8>() -> impl Traitor<N> {
2626
| ^^^^^^^^^^^^^^^ the trait `Traitor<N, N>` is not implemented for `u32`
2727
|
28-
= help: the following other types implement trait `Traitor<N, 2_u8>`:
28+
= help: the following implementations were found:
2929
<u32 as Traitor<N, 2_u8>>
3030
<u64 as Traitor<1_u8, 2_u8>>
3131

@@ -50,9 +50,9 @@ error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
5050
LL | fn owo() -> impl Traitor {
5151
| ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64`
5252
|
53-
= help: the following other types implement trait `Traitor<N, 2_u8>`:
54-
<u32 as Traitor<N, 2_u8>>
53+
= help: the following implementations were found:
5554
<u64 as Traitor<1_u8, 2_u8>>
55+
<u32 as Traitor<N, 2_u8>>
5656

5757
error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
5858
--> $DIR/rp_impl_trait_fail.rs:24:26

src/test/ui/const-generics/exhaustive-value.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): Foo<N>` is not satisfied
44
LL | <() as Foo<N>>::test()
55
| ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
66
|
7-
= help: the following other types implement trait `Foo<0_u8>`:
7+
= help: the following implementations were found:
88
<() as Foo<0_u8>>
99
<() as Foo<100_u8>>
1010
<() as Foo<101_u8>>

src/test/ui/const-generics/issues/issue-67185-2.stderr

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
44
LL | <u8 as Baz>::Quaks: Bar,
55
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[u16; 3]`
66
|
7-
= help: the following other types implement trait `Bar`:
8-
[[u16; 3]; 3]
9-
[u16; 4]
7+
= help: the following implementations were found:
8+
<[[u16; 3]; 3] as Bar>
9+
<[u16; 4] as Bar>
1010
= help: see issue #48214
1111
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
1212

@@ -16,9 +16,9 @@ error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
1616
LL | [<u8 as Baz>::Quaks; 2]: Bar,
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
1818
|
19-
= help: the following other types implement trait `Bar`:
20-
[[u16; 3]; 3]
21-
[u16; 4]
19+
= help: the following implementations were found:
20+
<[[u16; 3]; 3] as Bar>
21+
<[u16; 4] as Bar>
2222
= help: see issue #48214
2323
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
2424

@@ -28,9 +28,9 @@ error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
2828
LL | impl Foo for FooImpl {}
2929
| ^^^ the trait `Bar` is not implemented for `[u16; 3]`
3030
|
31-
= help: the following other types implement trait `Bar`:
32-
[[u16; 3]; 3]
33-
[u16; 4]
31+
= help: the following implementations were found:
32+
<[[u16; 3]; 3] as Bar>
33+
<[u16; 4] as Bar>
3434
note: required by a bound in `Foo`
3535
--> $DIR/issue-67185-2.rs:15:25
3636
|
@@ -46,9 +46,9 @@ error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
4646
LL | impl Foo for FooImpl {}
4747
| ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
4848
|
49-
= help: the following other types implement trait `Bar`:
50-
[[u16; 3]; 3]
51-
[u16; 4]
49+
= help: the following implementations were found:
50+
<[[u16; 3]; 3] as Bar>
51+
<[u16; 4] as Bar>
5252
note: required by a bound in `Foo`
5353
--> $DIR/issue-67185-2.rs:14:30
5454
|
@@ -64,9 +64,9 @@ error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
6464
LL | fn f(_: impl Foo) {}
6565
| ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
6666
|
67-
= help: the following other types implement trait `Bar`:
68-
[[u16; 3]; 3]
69-
[u16; 4]
67+
= help: the following implementations were found:
68+
<[[u16; 3]; 3] as Bar>
69+
<[u16; 4] as Bar>
7070
note: required by a bound in `Foo`
7171
--> $DIR/issue-67185-2.rs:14:30
7272
|
@@ -82,9 +82,9 @@ error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
8282
LL | fn f(_: impl Foo) {}
8383
| ^^^ the trait `Bar` is not implemented for `[u16; 3]`
8484
|
85-
= help: the following other types implement trait `Bar`:
86-
[[u16; 3]; 3]
87-
[u16; 4]
85+
= help: the following implementations were found:
86+
<[[u16; 3]; 3] as Bar>
87+
<[u16; 4] as Bar>
8888
note: required by a bound in `Foo`
8989
--> $DIR/issue-67185-2.rs:15:25
9090
|

0 commit comments

Comments
 (0)