about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs48
-rw-r--r--tests/ui/consts/missing-larger-array-impl.rs9
-rw-r--r--tests/ui/consts/missing-larger-array-impl.stderr20
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`.