use Const::eval instead of QueryNormalize in error reporting

This commit is contained in:
Michael Goulet 2023-06-24 18:03:20 +00:00
parent 1d67eba687
commit 28f39862a8
3 changed files with 52 additions and 25 deletions

View File

@ -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(

View File

@ -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
}

View File

@ -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`.