diff options
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs | 48 | ||||
| -rw-r--r-- | tests/ui/consts/missing-larger-array-impl.rs | 9 | ||||
| -rw-r--r-- | tests/ui/consts/missing-larger-array-impl.stderr | 20 |
3 files changed, 52 insertions, 25 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 67745f04641..5c163630154 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -11,7 +11,6 @@ use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCod use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; 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; use crate::traits::NormalizeExt; use on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _}; @@ -31,7 +30,7 @@ use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::SelectionOutputTypeParameterMismatch; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print}; use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, @@ -60,7 +59,7 @@ pub enum CandidateSimilarity { Fuzzy { ignoring_lifetimes: bool }, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ImplCandidate<'tcx> { pub trait_ref: ty::TraitRef<'tcx>, pub similarity: CandidateSimilarity, @@ -1992,7 +1991,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Mentioning implementers of `Copy`, `Debug` and friends is not useful. return false; } - let normalized_impl_candidates: Vec<_> = self + let impl_candidates: Vec<_> = self .tcx .all_impls(def_id) // Ignore automatically derived impls and `!Trait` impls. @@ -2019,7 +2018,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } }) .collect(); - return report(normalized_impl_candidates, err); + return report(impl_candidates, err); } // Sort impl candidates so that ordering is consistent for UI tests. @@ -2028,27 +2027,26 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // // Prefer more similar candidates first, then sort lexicographically // by their normalized string representation. - let mut normalized_impl_candidates_and_similarities = impl_candidates - .iter() - .copied() - .map(|ImplCandidate { trait_ref, similarity }| { - // 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::<Vec<_>>(); - normalized_impl_candidates_and_similarities.sort(); - normalized_impl_candidates_and_similarities.dedup(); + let mut impl_candidates = impl_candidates.to_vec(); + impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref)); + impl_candidates.dedup(); - let normalized_impl_candidates = normalized_impl_candidates_and_similarities - .into_iter() - .map(|(_, normalized)| normalized) - .collect::<Vec<_>>(); - - report(normalized_impl_candidates, err) + report( + impl_candidates + .into_iter() + .map(|cand| { + // Fold the const so that it shows up as, e.g., `10` + // instead of `core::::array::{impl#30}::{constant#0}`. + cand.trait_ref.fold_with(&mut BottomUpFolder { + tcx: self.tcx, + ty_op: |ty| ty, + lt_op: |lt| lt, + ct_op: |ct| ct.eval(self.tcx, ty::ParamEnv::empty()), + }) + }) + .collect(), + err, + ) } fn report_similar_impl_candidates_for_root_obligation( diff --git a/tests/ui/consts/missing-larger-array-impl.rs b/tests/ui/consts/missing-larger-array-impl.rs new file mode 100644 index 00000000000..e6c879c8ebd --- /dev/null +++ b/tests/ui/consts/missing-larger-array-impl.rs @@ -0,0 +1,9 @@ +struct X; + +// Make sure that we show the impl trait refs in the help message with +// their evaluated constants, rather than `core::::array::{impl#30}::{constant#0}` + +fn main() { + <[X; 35] as Default>::default(); + //~^ ERROR the trait bound `[X; 35]: Default` is not satisfied +} diff --git a/tests/ui/consts/missing-larger-array-impl.stderr b/tests/ui/consts/missing-larger-array-impl.stderr new file mode 100644 index 00000000000..fad5c53f712 --- /dev/null +++ b/tests/ui/consts/missing-larger-array-impl.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `[X; 35]: Default` is not satisfied + --> $DIR/missing-larger-array-impl.rs:7:5 + | +LL | <[X; 35] as Default>::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[X; 35]` + | + = help: the following other types implement trait `Default`: + &[T] + &mut [T] + [T; 0] + [T; 10] + [T; 11] + [T; 12] + [T; 13] + [T; 14] + and 27 others + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. |
