X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_trait_selection%2Fsrc%2Ftraits%2Ferror_reporting%2Fmod.rs;h=cc61e18743133c94ba0f5951a290937a8516f04d;hb=07fd8089a45cb917ae85eb06e33374db159332e3;hp=56dea916b305f447d03c63cc09016bf058e51f5b;hpb=d1449560e31f7f801d81268a3dad783181656dff;p=rust.git 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 56dea916b30..cc61e187431 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -9,7 +9,7 @@ }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use crate::infer::{self, InferCtxt, TyCtxtInferExt}; +use crate::infer::{self, InferCtxt}; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::query::normalize::QueryNormalizeExt as _; use crate::traits::specialize::to_pretty_impl_header; @@ -1607,7 +1607,7 @@ fn report_projection_error( | ObligationCauseCode::ObjectCastObligation(..) | ObligationCauseCode::OpaqueType ); - let expected_ty = data.term.ty().unwrap(); + let expected_ty = data.term.ty().unwrap_or_else(|| self.tcx.ty_error()); // constrain inference variables a bit more to nested obligations from normalize so // we can have more helpful errors. @@ -1810,7 +1810,8 @@ fn find_similar_impl_candidates( &self, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> Vec> { - self.tcx + let mut candidates: Vec<_> = self + .tcx .all_impls(trait_pred.def_id()) .filter_map(|def_id| { if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative @@ -1826,7 +1827,14 @@ fn find_similar_impl_candidates( self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false) .map(|similarity| ImplCandidate { trait_ref: imp, similarity }) }) - .collect() + .collect(); + if candidates.iter().any(|c| matches!(c.similarity, CandidateSimilarity::Exact { .. })) { + // If any of the candidates is a perfect match, we don't want to show all of them. + // This is particularly relevant for the case of numeric types (as they all have the + // same cathegory). + candidates.retain(|c| matches!(c.similarity, CandidateSimilarity::Exact { .. })); + } + candidates } fn report_similar_impl_candidates( @@ -1934,14 +1942,6 @@ fn report_similar_impl_candidates( return report(normalized_impl_candidates, err); } - let normalize = |candidate| { - let infcx = self.tcx.infer_ctxt().build(); - infcx - .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) - .query_normalize(candidate) - .map_or(candidate, |normalized| normalized.value) - }; - // Sort impl candidates so that ordering is consistent for UI tests. // because the ordering of `impl_candidates` may not be deterministic: // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507 @@ -1951,7 +1951,11 @@ fn report_similar_impl_candidates( let mut normalized_impl_candidates_and_similarities = impl_candidates .into_iter() .map(|ImplCandidate { trait_ref, similarity }| { - let normalized = normalize(trait_ref); + // FIXME(compiler-errors): This should be using `NormalizeExt::normalize` + let normalized = self + .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) + .query_normalize(trait_ref) + .map_or(trait_ref, |normalized| normalized.value); (similarity, normalized) }) .collect::>();