Skip to content

Don't call query_normalize when reporting similar impls #113005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 23 additions & 25 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 _};
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this useful? report sorts everything again.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the sort in report -- that should fix the weird rendering and also actually make this sort meaningful. It does have a lot of fallout, but the changes are either neutral or slightly better suggestions.

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(
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/consts/missing-larger-array-impl.rs
Original file line number Diff line number Diff line change
@@ -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
}
20 changes: 20 additions & 0 deletions tests/ui/consts/missing-larger-array-impl.stderr
Original file line number Diff line number Diff line change
@@ -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`.