Mention implementations that satisfy the trait

This commit is contained in:
Esteban Küber 2022-12-10 17:39:00 -08:00
parent b3fba5e18a
commit 3e25bcb020
6 changed files with 40 additions and 3 deletions

View File

@ -980,6 +980,7 @@ fn report_selection_error(
trait_ref, trait_ref,
obligation.cause.body_id, obligation.cause.body_id,
&mut err, &mut err,
true,
) { ) {
// This is *almost* equivalent to // This is *almost* equivalent to
// `obligation.cause.code().peel_derives()`, but it gives us the // `obligation.cause.code().peel_derives()`, but it gives us the
@ -1015,6 +1016,7 @@ fn report_selection_error(
trait_ref, trait_ref,
obligation.cause.body_id, obligation.cause.body_id,
&mut err, &mut err,
true,
); );
} }
} }
@ -1432,6 +1434,7 @@ fn report_similar_impl_candidates(
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
body_id: hir::HirId, body_id: hir::HirId,
err: &mut Diagnostic, err: &mut Diagnostic,
other: bool,
) -> bool; ) -> bool;
/// Gets the parent trait chain start /// Gets the parent trait chain start
@ -1887,7 +1890,9 @@ fn report_similar_impl_candidates(
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
body_id: hir::HirId, body_id: hir::HirId,
err: &mut Diagnostic, err: &mut Diagnostic,
other: bool,
) -> bool { ) -> bool {
let other = if other { "other " } else { "" };
let report = |mut candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| { let report = |mut candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
candidates.sort(); candidates.sort();
candidates.dedup(); candidates.dedup();
@ -1938,7 +1943,7 @@ fn report_similar_impl_candidates(
candidates.dedup(); candidates.dedup();
let end = if candidates.len() <= 9 { candidates.len() } else { 8 }; let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
err.help(&format!( err.help(&format!(
"the following other types implement trait `{}`:{}{}", "the following {other}types implement trait `{}`:{}{}",
trait_ref.print_only_trait_path(), trait_ref.print_only_trait_path(),
candidates[..end].join(""), candidates[..end].join(""),
if len > 9 { format!("\nand {} others", len - 8) } else { String::new() } if len > 9 { format!("\nand {} others", len - 8) } else { String::new() }
@ -2179,7 +2184,7 @@ fn maybe_report_ambiguity(
trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_infer()); trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_infer());
// It doesn't make sense to talk about applicable impls if there are more // It doesn't make sense to talk about applicable impls if there are more
// than a handful of them. // than a handful of them.
if impls.len() > 1 && impls.len() < 5 && has_non_region_infer { if impls.len() > 1 && impls.len() < 10 && has_non_region_infer {
self.annotate_source_of_ambiguity(&mut err, &impls, predicate); self.annotate_source_of_ambiguity(&mut err, &impls, predicate);
} else { } else {
if self.tainted_by_errors().is_some() { if self.tainted_by_errors().is_some() {
@ -2187,6 +2192,18 @@ fn maybe_report_ambiguity(
return; return;
} }
err.note(&format!("cannot satisfy `{}`", predicate)); err.note(&format!("cannot satisfy `{}`", predicate));
let impl_candidates = self.find_similar_impl_candidates(
predicate.to_opt_poly_trait_pred().unwrap(),
);
if impl_candidates.len() < 10 {
self.report_similar_impl_candidates(
impl_candidates,
trait_ref,
body_id.map(|id| id.hir_id).unwrap_or(obligation.cause.body_id),
&mut err,
false,
);
}
} }
} }
_ => { _ => {

View File

@ -5,6 +5,12 @@ LL | let y = Mask::<_, _>::splat(false);
| ^ ------------------- type must be known at this point | ^ ------------------- type must be known at this point
| |
= note: cannot satisfy `_: MaskElement` = note: cannot satisfy `_: MaskElement`
= help: the following types implement trait `MaskElement`:
i16
i32
i64
i8
isize
note: required by a bound in `Mask::<T, LANES>::splat` note: required by a bound in `Mask::<T, LANES>::splat`
--> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
| |

View File

@ -41,6 +41,7 @@ LL | IsLessOrEqual<I, 8>: True,
| ^^^^ | ^^^^
| |
= note: cannot satisfy `IsLessOrEqual<I, 8>: True` = note: cannot satisfy `IsLessOrEqual<I, 8>: True`
= help: the trait `True` is implemented for `IsLessOrEqual<LHS, RHS>`
error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8>: True` error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8>: True`
--> $DIR/issue-72787.rs:21:26 --> $DIR/issue-72787.rs:21:26
@ -49,6 +50,7 @@ LL | IsLessOrEqual<I, 8>: True,
| ^^^^ | ^^^^
| |
= note: cannot satisfy `IsLessOrEqual<I, 8>: True` = note: cannot satisfy `IsLessOrEqual<I, 8>: True`
= help: the trait `True` is implemented for `IsLessOrEqual<LHS, RHS>`
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View File

@ -5,6 +5,7 @@ LL | &'a (): Foo,
| ^^^ | ^^^
| |
= note: cannot satisfy `&'a (): Foo` = note: cannot satisfy `&'a (): Foo`
= help: the trait `Foo` is implemented for `&'a T`
error: aborting due to previous error error: aborting due to previous error

View File

@ -46,7 +46,15 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= note: cannot satisfy `u32: From<_>` = note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`:
- impl From<Ipv4Addr> for u32;
- impl From<NonZeroU32> for u32;
- impl From<bool> for u32;
- impl From<char> for u32;
- impl From<u16> for u32;
- impl From<u8> for u32;
- impl<T> From<!> for T;
- impl<T> From<T> for T;
help: try using a fully qualified path to specify the expected types help: try using a fully qualified path to specify the expected types
| |
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into(0u32))).collect(); LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into(0u32))).collect();

View File

@ -5,6 +5,9 @@ LL | T: FnMut(&'a ()),
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
| |
= note: cannot satisfy `T: FnMut<(&'a (),)>` = note: cannot satisfy `T: FnMut<(&'a (),)>`
= help: the following types implement trait `FnMut<Args>`:
&F
&mut F
error: aborting due to previous error error: aborting due to previous error