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 398ec28a42638..75aee0670a258 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 fa5e780ee5e8b..83a0452b088d2 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::(); | ^^^^^^^^^^^^^^ | = 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 |