about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2022-12-10 17:39:00 -0800
committerEsteban Küber <esteban@kuber.com.ar>2022-12-13 10:39:44 -0800
commit3e25bcb02093bad56beb1dff6be7dd0d80115fb1 (patch)
treec421af1a084672cdf78014e384d155aa4c4cfd2a
parentb3fba5e18afe1548f6c6926ee377833d4c53d904 (diff)
Mention implementations that satisfy the trait
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs21
-rw-r--r--src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr6
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr2
-rw-r--r--src/test/ui/lifetimes/issue-34979.stderr1
-rw-r--r--src/test/ui/traits/issue-77982.stderr10
-rw-r--r--src/test/ui/traits/issue-85735.stderr3
6 files changed, 40 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 28351d5ff88..64821b5686a 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -980,6 +980,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 trait_ref,
                                 obligation.cause.body_id,
                                 &mut err,
+                                true,
                             ) {
                                 // This is *almost* equivalent to
                                 // `obligation.cause.code().peel_derives()`, but it gives us the
@@ -1015,6 +1016,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                         trait_ref,
                                         obligation.cause.body_id,
                                         &mut err,
+                                        true,
                                     );
                                 }
                             }
@@ -1432,6 +1434,7 @@ trait InferCtxtPrivExt<'tcx> {
         trait_ref: ty::PolyTraitRef<'tcx>,
         body_id: hir::HirId,
         err: &mut Diagnostic,
+        other: bool,
     ) -> bool;
 
     /// Gets the parent trait chain start
@@ -1887,7 +1890,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         trait_ref: ty::PolyTraitRef<'tcx>,
         body_id: hir::HirId,
         err: &mut Diagnostic,
+        other: bool,
     ) -> bool {
+        let other = if other { "other " } else { "" };
         let report = |mut candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
             candidates.sort();
             candidates.dedup();
@@ -1938,7 +1943,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             candidates.dedup();
             let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
             err.help(&format!(
-                "the following other types implement trait `{}`:{}{}",
+                "the following {other}types implement trait `{}`:{}{}",
                 trait_ref.print_only_trait_path(),
                 candidates[..end].join(""),
                 if len > 9 { format!("\nand {} others", len - 8) } else { String::new() }
@@ -2179,7 +2184,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             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
                         // 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);
                         } else {
                             if self.tainted_by_errors().is_some() {
@@ -2187,6 +2192,18 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 return;
                             }
                             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,
+                                );
+                            }
                         }
                     }
                     _ => {
diff --git a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
index 688db695fa8..2cfc6f61f1a 100644
--- a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
+++ b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
@@ -5,6 +5,12 @@ LL |     let y = Mask::<_, _>::splat(false);
    |         ^   ------------------- type must be known at this point
    |
    = 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`
   --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
    |
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
index 4d0d0253f1b..e0444042614 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
@@ -41,6 +41,7 @@ LL |     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`
   --> $DIR/issue-72787.rs:21:26
@@ -49,6 +50,7 @@ LL |     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
 
diff --git a/src/test/ui/lifetimes/issue-34979.stderr b/src/test/ui/lifetimes/issue-34979.stderr
index 5832c4d173c..a332c6547b8 100644
--- a/src/test/ui/lifetimes/issue-34979.stderr
+++ b/src/test/ui/lifetimes/issue-34979.stderr
@@ -5,6 +5,7 @@ LL |     &'a (): Foo,
    |             ^^^
    |
    = note: cannot satisfy `&'a (): Foo`
+   = help: the trait `Foo` is implemented for `&'a T`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr
index b6a04585583..be7397fdb12 100644
--- a/src/test/ui/traits/issue-77982.stderr
+++ b/src/test/ui/traits/issue-77982.stderr
@@ -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
    |
-   = 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
    |
 LL |     let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into(0u32))).collect();
diff --git a/src/test/ui/traits/issue-85735.stderr b/src/test/ui/traits/issue-85735.stderr
index fa280135beb..930708f9ad8 100644
--- a/src/test/ui/traits/issue-85735.stderr
+++ b/src/test/ui/traits/issue-85735.stderr
@@ -5,6 +5,9 @@ LL |     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