1
Fork 0

Be better at reporting alias errors

This commit is contained in:
Michael Goulet 2024-10-14 13:04:10 -04:00
parent fd2038d344
commit 8528387743
39 changed files with 237 additions and 420 deletions

View file

@ -13,7 +13,7 @@ use rustc_middle::bug;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, TyCtxt};
use rustc_next_trait_solver::solve::{GenerateProofTree, HasChanged, SolverDelegateEvalExt as _};
use tracing::instrument;
use tracing::{instrument, trace};
use super::Certainty;
use super::delegate::SolverDelegate;
@ -402,6 +402,7 @@ impl<'tcx> BestObligation<'tcx> {
nested_goal.source(),
GoalSource::ImplWhereBound
| GoalSource::InstantiateHigherRanked
| GoalSource::AliasWellFormed
) && match self.consider_ambiguities {
true => {
matches!(
@ -416,6 +417,13 @@ impl<'tcx> BestObligation<'tcx> {
})
});
}
// Prefer a non-rigid candidate if there is one.
if candidates.len() > 1 {
candidates.retain(|candidate| {
!matches!(candidate.kind(), inspect::ProbeKind::RigidAlias { .. })
});
}
}
}
@ -430,8 +438,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
self.obligation.cause.span
}
#[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))]
fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
let candidates = self.non_trivial_candidates(goal);
trace!(candidates = ?candidates.iter().map(|c| c.kind()).collect::<Vec<_>>());
let [candidate] = candidates.as_slice() else {
return ControlFlow::Break(self.obligation.clone());
};
@ -470,6 +481,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
let mut impl_where_bound_count = 0;
for nested_goal in candidate.instantiate_nested_goals(self.span()) {
trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
let make_obligation = |cause| Obligation {
cause,
param_env: nested_goal.goal().param_env,
@ -496,7 +509,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
(_, GoalSource::InstantiateHigherRanked) => {
obligation = self.obligation.clone();
}
(ChildMode::PassThrough, _) => {
(ChildMode::PassThrough, _) | (_, GoalSource::AliasWellFormed) => {
obligation = make_obligation(self.obligation.cause.clone());
}
}

View file

@ -292,7 +292,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
| inspect::ProbeKind::Root { .. }
| inspect::ProbeKind::TryNormalizeNonRigid { .. }
| inspect::ProbeKind::TraitCandidate { .. }
| inspect::ProbeKind::OpaqueTypeStorageLookup { .. } => {
| inspect::ProbeKind::OpaqueTypeStorageLookup { .. }
| inspect::ProbeKind::RigidAlias { .. } => {
// Nested probes have to prove goals added in their parent
// but do not leak them, so we truncate the added goals
// afterwards.
@ -316,7 +317,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
inspect::ProbeKind::Root { result }
| inspect::ProbeKind::TryNormalizeNonRigid { result }
| inspect::ProbeKind::TraitCandidate { source: _, result }
| inspect::ProbeKind::OpaqueTypeStorageLookup { result } => {
| inspect::ProbeKind::OpaqueTypeStorageLookup { result }
| inspect::ProbeKind::RigidAlias { result } => {
// We only add a candidate if `shallow_certainty` was set, which means
// that we ended up calling `evaluate_added_goals_and_make_canonical_response`.
if let Some(shallow_certainty) = shallow_certainty {

View file

@ -177,7 +177,8 @@ fn to_selection<'tcx>(
| ProbeKind::UpcastProjectionCompatibility
| ProbeKind::OpaqueTypeStorageLookup { result: _ }
| ProbeKind::Root { result: _ }
| ProbeKind::ShadowedEnvProbing => {
| ProbeKind::ShadowedEnvProbing
| ProbeKind::RigidAlias { result: _ } => {
span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
}
})