Skip to content

Commit cef94ec

Browse files
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``
2 parents 38fc6be + b4ba7c4 commit cef94ec

File tree

4 files changed

+98
-26
lines changed

4 files changed

+98
-26
lines changed

compiler/rustc_middle/src/ty/mod.rs

+66
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,24 @@ pub enum Clause<'tcx> {
586586
ConstArgHasType(Const<'tcx>, Ty<'tcx>),
587587
}
588588

589+
impl<'tcx> Binder<'tcx, Clause<'tcx>> {
590+
pub fn as_trait_clause(self) -> Option<Binder<'tcx, TraitPredicate<'tcx>>> {
591+
if let ty::Clause::Trait(trait_clause) = self.skip_binder() {
592+
Some(self.rebind(trait_clause))
593+
} else {
594+
None
595+
}
596+
}
597+
598+
pub fn as_projection_clause(self) -> Option<Binder<'tcx, ProjectionPredicate<'tcx>>> {
599+
if let ty::Clause::Projection(projection_clause) = self.skip_binder() {
600+
Some(self.rebind(projection_clause))
601+
} else {
602+
None
603+
}
604+
}
605+
}
606+
589607
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
590608
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
591609
pub enum PredicateKind<'tcx> {
@@ -1203,6 +1221,17 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
12031221
}
12041222
}
12051223

1224+
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for TraitRef<'tcx> {
1225+
#[inline(always)]
1226+
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
1227+
Binder::dummy(Clause::Trait(TraitPredicate {
1228+
trait_ref: self,
1229+
constness: ty::BoundConstness::NotConst,
1230+
polarity: ty::ImplPolarity::Positive,
1231+
}))
1232+
}
1233+
}
1234+
12061235
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
12071236
#[inline(always)]
12081237
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
@@ -1211,6 +1240,14 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
12111240
}
12121241
}
12131242

1243+
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for Binder<'tcx, TraitRef<'tcx>> {
1244+
#[inline(always)]
1245+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
1246+
let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx);
1247+
pred.to_predicate(tcx)
1248+
}
1249+
}
1250+
12141251
impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> {
12151252
#[inline(always)]
12161253
fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> {
@@ -1240,6 +1277,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
12401277
}
12411278
}
12421279

1280+
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyTraitPredicate<'tcx> {
1281+
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
1282+
self.map_bound(|p| Clause::Trait(p))
1283+
}
1284+
}
1285+
12431286
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
12441287
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
12451288
self.map_bound(|p| PredicateKind::Clause(Clause::RegionOutlives(p))).to_predicate(tcx)
@@ -1258,6 +1301,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
12581301
}
12591302
}
12601303

1304+
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyProjectionPredicate<'tcx> {
1305+
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
1306+
self.map_bound(|p| Clause::Projection(p))
1307+
}
1308+
}
1309+
12611310
impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> {
12621311
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
12631312
PredicateKind::Clause(Clause::Trait(self)).to_predicate(tcx)
@@ -1327,6 +1376,23 @@ impl<'tcx> Predicate<'tcx> {
13271376
| PredicateKind::TypeWellFormedFromEnv(..) => None,
13281377
}
13291378
}
1379+
1380+
pub fn as_clause(self) -> Option<Binder<'tcx, Clause<'tcx>>> {
1381+
let predicate = self.kind();
1382+
match predicate.skip_binder() {
1383+
PredicateKind::Clause(clause) => Some(predicate.rebind(clause)),
1384+
PredicateKind::AliasRelate(..)
1385+
| PredicateKind::Subtype(..)
1386+
| PredicateKind::Coerce(..)
1387+
| PredicateKind::WellFormed(..)
1388+
| PredicateKind::ObjectSafe(..)
1389+
| PredicateKind::ClosureKind(..)
1390+
| PredicateKind::ConstEvaluatable(..)
1391+
| PredicateKind::ConstEquate(..)
1392+
| PredicateKind::Ambiguous
1393+
| PredicateKind::TypeWellFormedFromEnv(..) => None,
1394+
}
1395+
}
13301396
}
13311397

13321398
/// Represents the bounds declared on a particular set of type

compiler/rustc_trait_selection/src/solve/assembly/mod.rs

+23-17
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub(super) trait GoalKind<'tcx>:
105105
fn probe_and_match_goal_against_assumption(
106106
ecx: &mut EvalCtxt<'_, 'tcx>,
107107
goal: Goal<'tcx, Self>,
108-
assumption: ty::Predicate<'tcx>,
108+
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
109109
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
110110
) -> QueryResult<'tcx>;
111111

@@ -115,7 +115,7 @@ pub(super) trait GoalKind<'tcx>:
115115
fn consider_implied_clause(
116116
ecx: &mut EvalCtxt<'_, 'tcx>,
117117
goal: Goal<'tcx, Self>,
118-
assumption: ty::Predicate<'tcx>,
118+
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
119119
requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
120120
) -> QueryResult<'tcx> {
121121
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
@@ -131,7 +131,7 @@ pub(super) trait GoalKind<'tcx>:
131131
fn consider_alias_bound_candidate(
132132
ecx: &mut EvalCtxt<'_, 'tcx>,
133133
goal: Goal<'tcx, Self>,
134-
assumption: ty::Predicate<'tcx>,
134+
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
135135
) -> QueryResult<'tcx> {
136136
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
137137
ecx.validate_alias_bound_self_from_param_env(goal)
@@ -144,7 +144,7 @@ pub(super) trait GoalKind<'tcx>:
144144
fn consider_object_bound_candidate(
145145
ecx: &mut EvalCtxt<'_, 'tcx>,
146146
goal: Goal<'tcx, Self>,
147-
assumption: ty::Predicate<'tcx>,
147+
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
148148
) -> QueryResult<'tcx> {
149149
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
150150
let tcx = ecx.tcx();
@@ -467,11 +467,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
467467
candidates: &mut Vec<Candidate<'tcx>>,
468468
) {
469469
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
470-
match G::consider_implied_clause(self, goal, assumption, []) {
471-
Ok(result) => {
472-
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
470+
if let Some(clause) = assumption.as_clause() {
471+
match G::consider_implied_clause(self, goal, clause, []) {
472+
Ok(result) => {
473+
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
474+
}
475+
Err(NoSolution) => (),
473476
}
474-
Err(NoSolution) => (),
475477
}
476478
}
477479
}
@@ -517,11 +519,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
517519

518520
for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
519521
{
520-
match G::consider_alias_bound_candidate(self, goal, assumption) {
521-
Ok(result) => {
522-
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
522+
if let Some(clause) = assumption.as_clause() {
523+
match G::consider_alias_bound_candidate(self, goal, clause) {
524+
Ok(result) => {
525+
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
526+
}
527+
Err(NoSolution) => (),
523528
}
524-
Err(NoSolution) => (),
525529
}
526530
}
527531
}
@@ -675,18 +679,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
675679
// projection predicates that we reach by elaborating the principal trait ref,
676680
// since that'll cause ambiguity.
677681
//
678-
// We can remove this when we have implemented intersections in responses.
682+
// We can remove this when we have implemented lifetime intersections in responses.
679683
if assumption.to_opt_poly_projection_pred().is_some()
680684
&& !own_bounds.contains(&assumption)
681685
{
682686
continue;
683687
}
684688

685-
match G::consider_object_bound_candidate(self, goal, assumption) {
686-
Ok(result) => {
687-
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
689+
if let Some(clause) = assumption.as_clause() {
690+
match G::consider_object_bound_candidate(self, goal, clause) {
691+
Ok(result) => {
692+
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
693+
}
694+
Err(NoSolution) => (),
688695
}
689-
Err(NoSolution) => (),
690696
}
691697
}
692698
}

compiler/rustc_trait_selection/src/solve/project_goals.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
105105
fn probe_and_match_goal_against_assumption(
106106
ecx: &mut EvalCtxt<'_, 'tcx>,
107107
goal: Goal<'tcx, Self>,
108-
assumption: ty::Predicate<'tcx>,
108+
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
109109
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
110110
) -> QueryResult<'tcx> {
111-
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
112-
&& poly_projection_pred.projection_def_id() == goal.predicate.def_id()
111+
if let Some(projection_pred) = assumption.as_projection_clause()
112+
&& projection_pred.projection_def_id() == goal.predicate.def_id()
113113
{
114114
ecx.probe(|ecx| {
115115
let assumption_projection_pred =
116-
ecx.instantiate_binder_with_infer(poly_projection_pred);
116+
ecx.instantiate_binder_with_infer(projection_pred);
117117
ecx.eq(
118118
goal.param_env,
119119
goal.predicate.projection_ty,

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
8181
fn probe_and_match_goal_against_assumption(
8282
ecx: &mut EvalCtxt<'_, 'tcx>,
8383
goal: Goal<'tcx, Self>,
84-
assumption: ty::Predicate<'tcx>,
84+
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
8585
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
8686
) -> QueryResult<'tcx> {
87-
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
88-
&& poly_trait_pred.def_id() == goal.predicate.def_id()
89-
&& poly_trait_pred.polarity() == goal.predicate.polarity
87+
if let Some(trait_clause) = assumption.as_trait_clause()
88+
&& trait_clause.def_id() == goal.predicate.def_id()
89+
&& trait_clause.polarity() == goal.predicate.polarity
9090
{
9191
// FIXME: Constness
9292
ecx.probe(|ecx| {
9393
let assumption_trait_pred =
94-
ecx.instantiate_binder_with_infer(poly_trait_pred);
94+
ecx.instantiate_binder_with_infer(trait_clause);
9595
ecx.eq(
9696
goal.param_env,
9797
goal.predicate.trait_ref,

0 commit comments

Comments
 (0)