Skip to content

Commit 21226ee

Browse files
Fully fledged Clause type
1 parent fca56a8 commit 21226ee

File tree

11 files changed

+155
-96
lines changed

11 files changed

+155
-96
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -945,8 +945,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
945945

946946
let mut trait_bounds = vec![];
947947
let mut projection_bounds = vec![];
948-
for (clause, span) in bounds.predicates() {
949-
let pred: ty::Predicate<'tcx> = clause.to_predicate(tcx);
948+
for (clause, span) in bounds.clauses() {
949+
let pred: ty::Predicate<'tcx> = clause.as_predicate();
950950
let bound_pred = pred.kind();
951951
match bound_pred.skip_binder() {
952952
ty::PredicateKind::Clause(clause) => match clause {

compiler/rustc_hir_analysis/src/bounds.rs

+19-24
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//! `ty` form from the HIR.
33
44
use rustc_hir::LangItem;
5-
use rustc_middle::ty::Binder;
65
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
76
use rustc_span::Span;
87

@@ -24,62 +23,58 @@ use rustc_span::Span;
2423
/// include the self type (e.g., `trait_bounds`) but in others we do not
2524
#[derive(Default, PartialEq, Eq, Clone, Debug)]
2625
pub struct Bounds<'tcx> {
27-
pub predicates: Vec<(Binder<'tcx, ty::ClauseKind<'tcx>>, Span)>,
26+
pub clauses: Vec<(ty::Clause<'tcx>, Span)>,
2827
}
2928

3029
impl<'tcx> Bounds<'tcx> {
3130
pub fn push_region_bound(
3231
&mut self,
33-
_tcx: TyCtxt<'tcx>,
32+
tcx: TyCtxt<'tcx>,
3433
region: ty::PolyTypeOutlivesPredicate<'tcx>,
3534
span: Span,
3635
) {
37-
self.predicates.push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)), span));
36+
self.clauses
37+
.push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).to_predicate(tcx), span));
3838
}
3939

4040
pub fn push_trait_bound(
4141
&mut self,
42-
_tcx: TyCtxt<'tcx>,
42+
tcx: TyCtxt<'tcx>,
4343
trait_ref: ty::PolyTraitRef<'tcx>,
4444
span: Span,
4545
constness: ty::BoundConstness,
4646
polarity: ty::ImplPolarity,
4747
) {
48-
self.predicates.push((
49-
trait_ref.map_bound(|trait_ref| {
50-
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness, polarity })
51-
}),
48+
self.clauses.push((
49+
trait_ref
50+
.map_bound(|trait_ref| {
51+
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness, polarity })
52+
})
53+
.to_predicate(tcx),
5254
span,
5355
));
5456
}
5557

5658
pub fn push_projection_bound(
5759
&mut self,
58-
_tcx: TyCtxt<'tcx>,
60+
tcx: TyCtxt<'tcx>,
5961
projection: ty::PolyProjectionPredicate<'tcx>,
6062
span: Span,
6163
) {
62-
self.predicates.push((projection.map_bound(|proj| ty::ClauseKind::Projection(proj)), span));
64+
self.clauses.push((
65+
projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).to_predicate(tcx),
66+
span,
67+
));
6368
}
6469

6570
pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
6671
let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
6772
let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]);
6873
// Preferable to put this obligation first, since we report better errors for sized ambiguity.
69-
self.predicates.insert(
70-
0,
71-
(
72-
ty::Binder::dummy(ty::ClauseKind::Trait(
73-
trait_ref.without_const().to_predicate(tcx),
74-
)),
75-
span,
76-
),
77-
);
74+
self.clauses.insert(0, (trait_ref.to_predicate(tcx), span));
7875
}
7976

80-
pub fn predicates(
81-
&self,
82-
) -> impl Iterator<Item = (Binder<'tcx, ty::ClauseKind<'tcx>>, Span)> + '_ {
83-
self.predicates.iter().cloned()
77+
pub fn clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ {
78+
self.clauses.iter().cloned()
8479
}
8580
}

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::astconv::{AstConv, OnlySelfBounds};
33
use rustc_hir as hir;
44
use rustc_infer::traits::util;
55
use rustc_middle::ty::subst::InternalSubsts;
6-
use rustc_middle::ty::ToPredicate;
76
use rustc_middle::ty::{self, Ty, TyCtxt};
87
use rustc_span::def_id::{DefId, LocalDefId};
98
use rustc_span::Span;
@@ -49,8 +48,8 @@ fn associated_type_bounds<'tcx>(
4948

5049
let all_bounds = tcx.arena.alloc_from_iter(
5150
bounds
52-
.predicates()
53-
.map(|(clause, span)| (clause.to_predicate(tcx), span))
51+
.clauses()
52+
.map(|(clause, span)| (clause.as_predicate(), span))
5453
.chain(bounds_from_parent),
5554
);
5655
debug!(
@@ -80,9 +79,8 @@ fn opaque_type_bounds<'tcx>(
8079
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
8180
debug!(?bounds);
8281

83-
tcx.arena.alloc_from_iter(
84-
bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)),
85-
)
82+
tcx.arena
83+
.alloc_from_iter(bounds.clauses().map(|(clause, span)| (clause.as_predicate(), span)))
8684
})
8785
}
8886

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
126126
predicates.extend(
127127
icx.astconv()
128128
.compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false))
129-
.predicates()
130-
.map(|(clause, span)| (clause.to_predicate(tcx), span)),
129+
.clauses()
130+
.map(|(clause, span)| (clause.as_predicate(), span)),
131131
);
132132
}
133133

@@ -176,9 +176,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
176176
param.span,
177177
);
178178
trace!(?bounds);
179-
predicates.extend(
180-
bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)),
181-
);
179+
predicates
180+
.extend(bounds.clauses().map(|(clause, span)| (clause.as_predicate(), span)));
182181
trace!(?predicates);
183182
}
184183
GenericParamKind::Const { .. } => {
@@ -237,9 +236,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
237236
bound_vars,
238237
OnlySelfBounds(false),
239238
);
240-
predicates.extend(
241-
bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)),
242-
);
239+
predicates
240+
.extend(bounds.clauses().map(|(clause, span)| (clause.as_predicate(), span)));
243241
}
244242

245243
hir::WherePredicate::RegionPredicate(region_pred) => {
@@ -669,8 +667,8 @@ pub(super) fn implied_predicates_with_filter(
669667
// Combine the two lists to form the complete set of superbounds:
670668
let implied_bounds = &*tcx.arena.alloc_from_iter(
671669
superbounds
672-
.predicates()
673-
.map(|(clause, span)| (clause.to_predicate(tcx), span))
670+
.clauses()
671+
.map(|(clause, span)| (clause.as_predicate(), span))
674672
.chain(where_bounds_that_match),
675673
);
676674
debug!(?implied_bounds);
@@ -831,7 +829,7 @@ impl<'tcx> ItemCtxt<'tcx> {
831829
);
832830
}
833831

834-
bounds.predicates().map(|(clause, span)| (clause.to_predicate(self.tcx), span)).collect()
832+
bounds.clauses().map(|(clause, span)| (clause.as_predicate(), span)).collect()
835833
}
836834

837835
#[instrument(level = "trace", skip(self))]

compiler/rustc_infer/src/traits/util.rs

+20
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

+68-45
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> {
@@ -1222,21 +1240,25 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, ClauseKind<'tcx>> {
12221240
}
12231241
}
12241242

1243+
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for Binder<'tcx, ClauseKind<'tcx>> {
1244+
#[inline(always)]
1245+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
1246+
tcx.mk_predicate(self.map_bound(|clause| ty::PredicateKind::Clause(clause))).expect_clause()
1247+
}
1248+
}
1249+
12251250
impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
12261251
#[inline(always)]
12271252
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
12281253
ty::Binder::dummy(self).to_predicate(tcx)
12291254
}
12301255
}
12311256

1232-
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for TraitRef<'tcx> {
1257+
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitRef<'tcx> {
12331258
#[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-
}))
1259+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
1260+
let p: Predicate<'tcx> = self.to_predicate(tcx);
1261+
p.expect_clause()
12401262
}
12411263
}
12421264

@@ -1248,9 +1270,9 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
12481270
}
12491271
}
12501272

1251-
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for Binder<'tcx, TraitRef<'tcx>> {
1273+
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for Binder<'tcx, TraitRef<'tcx>> {
12521274
#[inline(always)]
1253-
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Binder<'tcx, ClauseKind<'tcx>> {
1275+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
12541276
let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx);
12551277
pred.to_predicate(tcx)
12561278
}
@@ -1285,9 +1307,10 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
12851307
}
12861308
}
12871309

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))
1310+
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyTraitPredicate<'tcx> {
1311+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
1312+
let p: Predicate<'tcx> = self.to_predicate(tcx);
1313+
p.expect_clause()
12911314
}
12921315
}
12931316

@@ -1309,9 +1332,10 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
13091332
}
13101333
}
13111334

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))
1335+
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyProjectionPredicate<'tcx> {
1336+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
1337+
let p: Predicate<'tcx> = self.to_predicate(tcx);
1338+
p.expect_clause()
13151339
}
13161340
}
13171341

@@ -1385,18 +1409,17 @@ impl<'tcx> Predicate<'tcx> {
13851409
}
13861410
}
13871411

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,
1412+
pub fn as_clause(self) -> Option<Clause<'tcx>> {
1413+
match self.kind().skip_binder() {
1414+
PredicateKind::Clause(..) => Some(self.expect_clause()),
1415+
_ => None,
1416+
}
1417+
}
1418+
1419+
pub fn expect_clause(self) -> Clause<'tcx> {
1420+
match self.kind().skip_binder() {
1421+
PredicateKind::Clause(..) => Clause(self.0),
1422+
_ => bug!(),
14001423
}
14011424
}
14021425
}

0 commit comments

Comments
 (0)