1
Fork 0

track the source of nested goals

This commit is contained in:
lcnr 2023-12-18 07:49:46 +01:00
parent 321b6565a5
commit ca718ffd2d
14 changed files with 173 additions and 81 deletions

View file

@ -1,7 +1,7 @@
//! Dealing with trait goals, i.e. `T: Trait<'a, U>`.
use super::assembly::{self, structural_traits, Candidate};
use super::{EvalCtxt, SolverMode};
use super::{EvalCtxt, GoalSource, SolverMode};
use rustc_hir::def_id::DefId;
use rustc_hir::{LangItem, Movability};
use rustc_infer::traits::query::NoSolution;
@ -72,7 +72,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
.predicates
.into_iter()
.map(|pred| goal.with(tcx, pred));
ecx.add_goals(where_clause_bounds);
ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
ecx.evaluate_added_goals_and_make_canonical_response(maximal_certainty)
})
@ -172,7 +172,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
let nested_obligations = tcx
.predicates_of(goal.predicate.def_id())
.instantiate(tcx, goal.predicate.trait_ref.args);
ecx.add_goals(nested_obligations.predicates.into_iter().map(|p| goal.with(tcx, p)));
// FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
ecx.add_goals(
GoalSource::Misc,
nested_obligations.predicates.into_iter().map(|p| goal.with(tcx, p)),
);
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
@ -512,17 +516,23 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
// Check that the type implements all of the predicates of the trait object.
// (i.e. the principal, all of the associated types match, and any auto traits)
ecx.add_goals(b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))));
ecx.add_goals(
GoalSource::ImplWhereBound,
b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
);
// The type must be `Sized` to be unsized.
if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
ecx.add_goal(goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])));
ecx.add_goal(
GoalSource::ImplWhereBound,
goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])),
);
} else {
return Err(NoSolution);
}
// The type must outlive the lifetime of the `dyn` we're unsizing into.
ecx.add_goal(goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
ecx.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
@ -749,11 +759,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
// Also require that a_ty's lifetime outlives b_ty's lifetime.
self.add_goal(Goal::new(
self.tcx(),
param_env,
ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)),
));
self.add_goal(
GoalSource::ImplWhereBound,
Goal::new(
self.tcx(),
param_env,
ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)),
),
);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
@ -826,14 +839,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
// Finally, we require that `TailA: Unsize<TailB>` for the tail field
// types.
self.eq(goal.param_env, unsized_a_ty, b_ty)?;
self.add_goal(goal.with(
tcx,
ty::TraitRef::new(
self.add_goal(
GoalSource::ImplWhereBound,
goal.with(
tcx,
tcx.lang_items().unsize_trait().unwrap(),
[a_tail_ty, b_tail_ty],
ty::TraitRef::new(
tcx,
tcx.lang_items().unsize_trait().unwrap(),
[a_tail_ty, b_tail_ty],
),
),
));
);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
@ -865,14 +881,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
self.eq(goal.param_env, unsized_a_ty, b_ty)?;
// Similar to ADTs, require that we can unsize the tail.
self.add_goal(goal.with(
tcx,
ty::TraitRef::new(
self.add_goal(
GoalSource::ImplWhereBound,
goal.with(
tcx,
tcx.lang_items().unsize_trait().unwrap(),
[a_last_ty, b_last_ty],
ty::TraitRef::new(
tcx,
tcx.lang_items().unsize_trait().unwrap(),
[a_last_ty, b_last_ty],
),
),
));
);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
@ -981,6 +1000,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
) -> QueryResult<'tcx> {
self.probe_misc_candidate("constituent tys").enter(|ecx| {
ecx.add_goals(
GoalSource::ImplWhereBound,
constituent_tys(ecx, goal.predicate.self_ty())?
.into_iter()
.map(|ty| goal.with(ecx.tcx(), goal.predicate.with_self_ty(ecx.tcx(), ty)))