about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs83
-rw-r--r--tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr1
2 files changed, 35 insertions, 49 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 398ec28a426..75aee0670a2 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -5,7 +5,7 @@ pub mod suggestions;
 use super::{
     FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause,
     ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow,
-    PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
+    PredicateObligation, SelectionError, TraitNotObjectSafe,
 };
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -2269,55 +2269,40 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     )
                 };
 
-                let obligation = obligation.with(self.tcx, trait_ref);
-                let mut selcx = SelectionContext::new(&self);
-                match selcx.select_from_obligation(&obligation) {
-                    Ok(None) => {
-                        let ambiguities =
-                            ambiguity::recompute_applicable_impls(self.infcx, &obligation);
-                        let has_non_region_infer = trait_ref
-                            .skip_binder()
-                            .substs
-                            .types()
-                            .any(|t| !t.is_ty_or_numeric_infer());
-                        // It doesn't make sense to talk about applicable impls if there are more
-                        // than a handful of them.
-                        if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
-                            if self.tainted_by_errors().is_some() && subst.is_none() {
-                                // If `subst.is_none()`, then this is probably two param-env
-                                // candidates or impl candidates that are equal modulo lifetimes.
-                                // Therefore, if we've already emitted an error, just skip this
-                                // one, since it's not particularly actionable.
-                                err.cancel();
-                                return;
-                            }
-                            self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
-                        } else {
-                            if self.tainted_by_errors().is_some() {
-                                err.cancel();
-                                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.as_slice(),
-                                    trait_ref,
-                                    obligation.cause.body_id,
-                                    &mut err,
-                                    false,
-                                );
-                            }
-                        }
+                let ambiguities = ambiguity::recompute_applicable_impls(
+                    self.infcx,
+                    &obligation.with(self.tcx, trait_ref),
+                );
+                let has_non_region_infer =
+                    trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_or_numeric_infer());
+                // It doesn't make sense to talk about applicable impls if there are more
+                // than a handful of them.
+                if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
+                    if self.tainted_by_errors().is_some() && subst.is_none() {
+                        // If `subst.is_none()`, then this is probably two param-env
+                        // candidates or impl candidates that are equal modulo lifetimes.
+                        // Therefore, if we've already emitted an error, just skip this
+                        // one, since it's not particularly actionable.
+                        err.cancel();
+                        return;
                     }
-                    _ => {
-                        if self.tainted_by_errors().is_some() {
-                            err.cancel();
-                            return;
-                        }
-                        err.note(format!("cannot satisfy `{}`", predicate));
+                    self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
+                } else {
+                    if self.tainted_by_errors().is_some() {
+                        err.cancel();
+                        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.as_slice(),
+                            trait_ref,
+                            obligation.cause.body_id,
+                            &mut err,
+                            false,
+                        );
                     }
                 }
 
diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr
index fa5e780ee5e..83a0452b088 100644
--- a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr
+++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr
@@ -5,6 +5,7 @@ LL |     needs_bar::<T>();
    |     ^^^^^^^^^^^^^^
    |
    = note: cannot satisfy `T: Bar`
+   = help: the trait `Bar` is implemented for `T`
 note: required by a bound in `needs_bar`
   --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17
    |