mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Rollup merge of #112665 - compiler-errors:assumption-takes-clause, r=lcnr
Make assumption functions in new solver take `Binder<'tcx, Clause<'tcx>>` We just use an if-let to match on an optional clause at all the places where we transition from `Predicate` -> `Clause`, but I assume that when things like item-bounds and param-env start to only store `Clause`s then those can just be trivially dropped. r? ``@lcnr``
This commit is contained in:
commit
cef94ecedf
@ -586,6 +586,24 @@ pub enum Clause<'tcx> {
|
||||
ConstArgHasType(Const<'tcx>, Ty<'tcx>),
|
||||
}
|
||||
|
||||
impl<'tcx> Binder<'tcx, Clause<'tcx>> {
|
||||
pub fn as_trait_clause(self) -> Option<Binder<'tcx, TraitPredicate<'tcx>>> {
|
||||
if let ty::Clause::Trait(trait_clause) = self.skip_binder() {
|
||||
Some(self.rebind(trait_clause))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_projection_clause(self) -> Option<Binder<'tcx, ProjectionPredicate<'tcx>>> {
|
||||
if let ty::Clause::Projection(projection_clause) = self.skip_binder() {
|
||||
Some(self.rebind(projection_clause))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub enum PredicateKind<'tcx> {
|
||||
@ -1203,6 +1221,17 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for TraitRef<'tcx> {
|
||||
#[inline(always)]
|
||||
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
|
||||
Binder::dummy(Clause::Trait(TraitPredicate {
|
||||
trait_ref: self,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
|
||||
#[inline(always)]
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
@ -1211,6 +1240,14 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for Binder<'tcx, TraitRef<'tcx>> {
|
||||
#[inline(always)]
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
|
||||
let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx);
|
||||
pred.to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> {
|
||||
#[inline(always)]
|
||||
fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> {
|
||||
@ -1240,6 +1277,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyTraitPredicate<'tcx> {
|
||||
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
|
||||
self.map_bound(|p| Clause::Trait(p))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
self.map_bound(|p| PredicateKind::Clause(Clause::RegionOutlives(p))).to_predicate(tcx)
|
||||
@ -1258,6 +1301,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyProjectionPredicate<'tcx> {
|
||||
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
|
||||
self.map_bound(|p| Clause::Projection(p))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
PredicateKind::Clause(Clause::Trait(self)).to_predicate(tcx)
|
||||
@ -1327,6 +1376,23 @@ impl<'tcx> Predicate<'tcx> {
|
||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_clause(self) -> Option<Binder<'tcx, Clause<'tcx>>> {
|
||||
let predicate = self.kind();
|
||||
match predicate.skip_binder() {
|
||||
PredicateKind::Clause(clause) => Some(predicate.rebind(clause)),
|
||||
PredicateKind::AliasRelate(..)
|
||||
| PredicateKind::Subtype(..)
|
||||
| PredicateKind::Coerce(..)
|
||||
| PredicateKind::WellFormed(..)
|
||||
| PredicateKind::ObjectSafe(..)
|
||||
| PredicateKind::ClosureKind(..)
|
||||
| PredicateKind::ConstEvaluatable(..)
|
||||
| PredicateKind::ConstEquate(..)
|
||||
| PredicateKind::Ambiguous
|
||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the bounds declared on a particular set of type
|
||||
|
@ -105,7 +105,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn probe_and_match_goal_against_assumption(
|
||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Predicate<'tcx>,
|
||||
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
|
||||
) -> QueryResult<'tcx>;
|
||||
|
||||
@ -115,7 +115,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_implied_clause(
|
||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Predicate<'tcx>,
|
||||
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||
requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
|
||||
@ -131,7 +131,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_alias_bound_candidate(
|
||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Predicate<'tcx>,
|
||||
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
|
||||
ecx.validate_alias_bound_self_from_param_env(goal)
|
||||
@ -144,7 +144,7 @@ pub(super) trait GoalKind<'tcx>:
|
||||
fn consider_object_bound_candidate(
|
||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Predicate<'tcx>,
|
||||
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
|
||||
let tcx = ecx.tcx();
|
||||
@ -467,11 +467,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
) {
|
||||
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
|
||||
match G::consider_implied_clause(self, goal, assumption, []) {
|
||||
Ok(result) => {
|
||||
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
|
||||
if let Some(clause) = assumption.as_clause() {
|
||||
match G::consider_implied_clause(self, goal, clause, []) {
|
||||
Ok(result) => {
|
||||
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
|
||||
}
|
||||
Err(NoSolution) => (),
|
||||
}
|
||||
Err(NoSolution) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -517,11 +519,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
|
||||
for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
|
||||
{
|
||||
match G::consider_alias_bound_candidate(self, goal, assumption) {
|
||||
Ok(result) => {
|
||||
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
|
||||
if let Some(clause) = assumption.as_clause() {
|
||||
match G::consider_alias_bound_candidate(self, goal, clause) {
|
||||
Ok(result) => {
|
||||
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
|
||||
}
|
||||
Err(NoSolution) => (),
|
||||
}
|
||||
Err(NoSolution) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -675,18 +679,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
// projection predicates that we reach by elaborating the principal trait ref,
|
||||
// since that'll cause ambiguity.
|
||||
//
|
||||
// We can remove this when we have implemented intersections in responses.
|
||||
// We can remove this when we have implemented lifetime intersections in responses.
|
||||
if assumption.to_opt_poly_projection_pred().is_some()
|
||||
&& !own_bounds.contains(&assumption)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
match G::consider_object_bound_candidate(self, goal, assumption) {
|
||||
Ok(result) => {
|
||||
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
||||
if let Some(clause) = assumption.as_clause() {
|
||||
match G::consider_object_bound_candidate(self, goal, clause) {
|
||||
Ok(result) => {
|
||||
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
||||
}
|
||||
Err(NoSolution) => (),
|
||||
}
|
||||
Err(NoSolution) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,15 +105,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||
fn probe_and_match_goal_against_assumption(
|
||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Predicate<'tcx>,
|
||||
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
|
||||
) -> QueryResult<'tcx> {
|
||||
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
|
||||
&& poly_projection_pred.projection_def_id() == goal.predicate.def_id()
|
||||
if let Some(projection_pred) = assumption.as_projection_clause()
|
||||
&& projection_pred.projection_def_id() == goal.predicate.def_id()
|
||||
{
|
||||
ecx.probe(|ecx| {
|
||||
let assumption_projection_pred =
|
||||
ecx.instantiate_binder_with_infer(poly_projection_pred);
|
||||
ecx.instantiate_binder_with_infer(projection_pred);
|
||||
ecx.eq(
|
||||
goal.param_env,
|
||||
goal.predicate.projection_ty,
|
||||
|
@ -81,17 +81,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn probe_and_match_goal_against_assumption(
|
||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
assumption: ty::Predicate<'tcx>,
|
||||
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
|
||||
) -> QueryResult<'tcx> {
|
||||
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
|
||||
&& poly_trait_pred.def_id() == goal.predicate.def_id()
|
||||
&& poly_trait_pred.polarity() == goal.predicate.polarity
|
||||
if let Some(trait_clause) = assumption.as_trait_clause()
|
||||
&& trait_clause.def_id() == goal.predicate.def_id()
|
||||
&& trait_clause.polarity() == goal.predicate.polarity
|
||||
{
|
||||
// FIXME: Constness
|
||||
ecx.probe(|ecx| {
|
||||
let assumption_trait_pred =
|
||||
ecx.instantiate_binder_with_infer(poly_trait_pred);
|
||||
ecx.instantiate_binder_with_infer(trait_clause);
|
||||
ecx.eq(
|
||||
goal.param_env,
|
||||
goal.predicate.trait_ref,
|
||||
|
Loading…
Reference in New Issue
Block a user