Skip to content

Commit c4309bd

Browse files
Fully fledged Clause type
1 parent d8523b6 commit c4309bd

File tree

6 files changed

+105
-51
lines changed

6 files changed

+105
-51
lines changed

compiler/rustc_infer/src/traits/util.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,26 @@ impl<'tcx> Elaboratable<'tcx> for (ty::Predicate<'tcx>, Span) {
167167
}
168168
}
169169

170+
impl<'tcx> Elaboratable<'tcx> for ty::Clause<'tcx> {
171+
fn predicate(&self) -> ty::Predicate<'tcx> {
172+
self.as_predicate()
173+
}
174+
175+
fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
176+
predicate.as_clause().unwrap()
177+
}
178+
179+
fn child_with_derived_cause(
180+
&self,
181+
predicate: ty::Predicate<'tcx>,
182+
_span: Span,
183+
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
184+
_index: usize,
185+
) -> Self {
186+
predicate.as_clause().unwrap()
187+
}
188+
}
189+
170190
pub fn elaborate<'tcx, O: Elaboratable<'tcx>>(
171191
tcx: TyCtxt<'tcx>,
172192
obligations: impl IntoIterator<Item = O>,

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 54 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,42 @@ impl rustc_errors::IntoDiagnosticArg for Predicate<'_> {
561561
}
562562
}
563563

564+
/// TODO: doc
565+
#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable)]
566+
#[rustc_pass_by_value]
567+
pub struct Clause<'tcx>(Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>);
568+
569+
impl<'tcx> Clause<'tcx> {
570+
pub fn as_predicate(self) -> Predicate<'tcx> {
571+
Predicate(self.0)
572+
}
573+
574+
pub fn kind(self) -> Binder<'tcx, ClauseKind<'tcx>> {
575+
self.0.internee.map_bound(|kind| match kind {
576+
PredicateKind::Clause(clause) => clause,
577+
_ => unreachable!(),
578+
})
579+
}
580+
581+
pub fn as_trait_clause(self) -> Option<Binder<'tcx, TraitPredicate<'tcx>>> {
582+
let clause = self.kind();
583+
if let ty::ClauseKind::Trait(trait_clause) = clause.skip_binder() {
584+
Some(clause.rebind(trait_clause))
585+
} else {
586+
None
587+
}
588+
}
589+
590+
pub fn as_projection_clause(self) -> Option<Binder<'tcx, ProjectionPredicate<'tcx>>> {
591+
let clause = self.kind();
592+
if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() {
593+
Some(clause.rebind(projection_clause))
594+
} else {
595+
None
596+
}
597+
}
598+
}
599+
564600
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
565601
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
566602
/// A clause is something that can appear in where bounds or be inferred
@@ -592,24 +628,6 @@ pub enum ClauseKind<'tcx> {
592628
ConstEvaluatable(ty::Const<'tcx>),
593629
}
594630

595-
impl<'tcx> Binder<'tcx, ClauseKind<'tcx>> {
596-
pub fn as_trait_clause(self) -> Option<Binder<'tcx, TraitPredicate<'tcx>>> {
597-
if let ty::ClauseKind::Trait(trait_clause) = self.skip_binder() {
598-
Some(self.rebind(trait_clause))
599-
} else {
600-
None
601-
}
602-
}
603-
604-
pub fn as_projection_clause(self) -> Option<Binder<'tcx, ProjectionPredicate<'tcx>>> {
605-
if let ty::ClauseKind::Projection(projection_clause) = self.skip_binder() {
606-
Some(self.rebind(projection_clause))
607-
} else {
608-
None
609-
}
610-
}
611-
}
612-
613631
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
614632
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
615633
pub enum PredicateKind<'tcx> {
@@ -1229,14 +1247,11 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
12291247
}
12301248
}
12311249

1232-
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for TraitRef<'tcx> {
1250+
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitRef<'tcx> {
12331251
#[inline(always)]
1234-
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, ClauseKind<'tcx>> {
1235-
Binder::dummy(ClauseKind::Trait(TraitPredicate {
1236-
trait_ref: self,
1237-
constness: ty::BoundConstness::NotConst,
1238-
polarity: ty::ImplPolarity::Positive,
1239-
}))
1252+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
1253+
let p: Predicate<'tcx> = self.to_predicate(tcx);
1254+
Clause(p.0)
12401255
}
12411256
}
12421257

@@ -1248,9 +1263,9 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
12481263
}
12491264
}
12501265

1251-
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for Binder<'tcx, TraitRef<'tcx>> {
1266+
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for Binder<'tcx, TraitRef<'tcx>> {
12521267
#[inline(always)]
1253-
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Binder<'tcx, ClauseKind<'tcx>> {
1268+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
12541269
let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx);
12551270
pred.to_predicate(tcx)
12561271
}
@@ -1285,9 +1300,10 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
12851300
}
12861301
}
12871302

1288-
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for PolyTraitPredicate<'tcx> {
1289-
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, ClauseKind<'tcx>> {
1290-
self.map_bound(|p| ClauseKind::Trait(p))
1303+
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyTraitPredicate<'tcx> {
1304+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
1305+
let p: Predicate<'tcx> = self.to_predicate(tcx);
1306+
Clause(p.0)
12911307
}
12921308
}
12931309

@@ -1309,9 +1325,10 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
13091325
}
13101326
}
13111327

1312-
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for PolyProjectionPredicate<'tcx> {
1313-
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, ClauseKind<'tcx>> {
1314-
self.map_bound(|p| ClauseKind::Projection(p))
1328+
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyProjectionPredicate<'tcx> {
1329+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
1330+
let p: Predicate<'tcx> = self.to_predicate(tcx);
1331+
Clause(p.0)
13151332
}
13161333
}
13171334

@@ -1385,18 +1402,10 @@ impl<'tcx> Predicate<'tcx> {
13851402
}
13861403
}
13871404

1388-
pub fn as_clause(self) -> Option<Binder<'tcx, ClauseKind<'tcx>>> {
1389-
let predicate = self.kind();
1390-
match predicate.skip_binder() {
1391-
PredicateKind::Clause(clause) => Some(predicate.rebind(clause)),
1392-
PredicateKind::AliasRelate(..)
1393-
| PredicateKind::Subtype(..)
1394-
| PredicateKind::Coerce(..)
1395-
| PredicateKind::ObjectSafe(..)
1396-
| PredicateKind::ClosureKind(..)
1397-
| PredicateKind::ConstEquate(..)
1398-
| PredicateKind::Ambiguous
1399-
| PredicateKind::TypeWellFormedFromEnv(..) => None,
1405+
pub fn as_clause(self) -> Option<Clause<'tcx>> {
1406+
match self.kind().skip_binder() {
1407+
PredicateKind::Clause(..) => Some(Clause(self.0)),
1408+
_ => None,
14001409
}
14011410
}
14021411
}

compiler/rustc_middle/src/ty/structural_impls.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
171171
}
172172
}
173173

174+
impl<'tcx> fmt::Debug for ty::Clause<'tcx> {
175+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176+
write!(f, "{:?}", self.kind())
177+
}
178+
}
179+
174180
impl<'tcx> fmt::Debug for ty::ClauseKind<'tcx> {
175181
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176182
match *self {
@@ -654,12 +660,31 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
654660
}
655661
}
656662

663+
// FIXME(clause): This is wonky
664+
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
665+
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
666+
self,
667+
folder: &mut F,
668+
) -> Result<Self, F::Error> {
669+
Ok(folder
670+
.try_fold_predicate(self.as_predicate())?
671+
.as_clause()
672+
.expect("no sensible folder would do this"))
673+
}
674+
}
675+
657676
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
658677
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
659678
visitor.visit_predicate(*self)
660679
}
661680
}
662681

682+
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
683+
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
684+
visitor.visit_predicate(self.as_predicate())
685+
}
686+
}
687+
663688
impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
664689
fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
665690
self,

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

Lines changed: 4 additions & 4 deletions
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::Binder<'tcx, ty::ClauseKind<'tcx>>,
108+
assumption: 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::Binder<'tcx, ty::ClauseKind<'tcx>>,
118+
assumption: 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::Binder<'tcx, ty::ClauseKind<'tcx>>,
134+
assumption: 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::Binder<'tcx, ty::ClauseKind<'tcx>>,
147+
assumption: ty::Clause<'tcx>,
148148
) -> QueryResult<'tcx> {
149149
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
150150
let tcx = ecx.tcx();

compiler/rustc_trait_selection/src/solve/project_goals.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
106106
fn probe_and_match_goal_against_assumption(
107107
ecx: &mut EvalCtxt<'_, 'tcx>,
108108
goal: Goal<'tcx, Self>,
109-
assumption: ty::Binder<'tcx, ty::ClauseKind<'tcx>>,
109+
assumption: ty::Clause<'tcx>,
110110
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
111111
) -> QueryResult<'tcx> {
112112
if let Some(projection_pred) = assumption.as_projection_clause()

compiler/rustc_trait_selection/src/solve/trait_goals.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ 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::Binder<'tcx, ty::ClauseKind<'tcx>>,
84+
assumption: ty::Clause<'tcx>,
8585
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
8686
) -> QueryResult<'tcx> {
8787
if let Some(trait_clause) = assumption.as_trait_clause()

0 commit comments

Comments
 (0)