Skip to content

Commit 925ec0d

Browse files
committed
Overhaul PredicateInner and Predicate.
Specifically, change `Ty` from this: ``` pub struct Predicate<'tcx> { inner: &'tcx PredicateInner<'tcx> } ``` to this: ``` pub struct Predicate<'tcx>(&'tcx Interned<PredicateS<'tcx>>) ``` where `PredicateInner` is renamed as `PredicateS`. This (plus a few other minor changes) makes the parallels with `Ty` and `TyS` much clearer, and makes the uniqueness more explicit.
1 parent e9a0c42 commit 925ec0d

File tree

8 files changed

+69
-70
lines changed

8 files changed

+69
-70
lines changed

compiler/rustc_middle/src/arena.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ macro_rules! arena_types {
8888

8989
// Interned types
9090
[] tys: rustc_middle::ty::TyS<'tcx>,
91-
[] predicates: rustc_middle::ty::PredicateInner<'tcx>,
91+
[] predicates: rustc_middle::ty::PredicateS<'tcx>,
9292

9393
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
9494
// since we need to allocate this type on both the `rustc_hir` arena

compiler/rustc_middle/src/ty/context.rs

+24-26
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::ty::{
2020
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
2121
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
2222
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
23-
ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind,
23+
ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, RegionKind,
2424
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
2525
};
2626
use rustc_ast as ast;
@@ -107,7 +107,7 @@ pub struct CtxtInterners<'tcx> {
107107
region: InternedSet<'tcx, RegionKind>,
108108
poly_existential_predicates:
109109
InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
110-
predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
110+
predicate: InternedSet<'tcx, PredicateS<'tcx>>,
111111
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
112112
projs: InternedSet<'tcx, List<ProjectionKind>>,
113113
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
@@ -170,23 +170,22 @@ impl<'tcx> CtxtInterners<'tcx> {
170170
}
171171

172172
#[inline(never)]
173-
fn intern_predicate(
174-
&self,
175-
kind: Binder<'tcx, PredicateKind<'tcx>>,
176-
) -> &'tcx PredicateInner<'tcx> {
177-
self.predicate
178-
.intern(kind, |kind| {
179-
let flags = super::flags::FlagComputation::for_predicate(kind);
180-
181-
let predicate_struct = PredicateInner {
182-
kind,
183-
flags: flags.flags,
184-
outer_exclusive_binder: flags.outer_exclusive_binder,
185-
};
173+
fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
174+
Predicate(Interned::new_unchecked(
175+
self.predicate
176+
.intern(kind, |kind| {
177+
let flags = super::flags::FlagComputation::for_predicate(kind);
186178

187-
InternedInSet(self.arena.alloc(predicate_struct))
188-
})
189-
.0
179+
let predicate_struct = PredicateS {
180+
kind,
181+
flags: flags.flags,
182+
outer_exclusive_binder: flags.outer_exclusive_binder,
183+
};
184+
185+
InternedInSet(self.arena.alloc(predicate_struct))
186+
})
187+
.0,
188+
))
190189
}
191190
}
192191

@@ -1684,7 +1683,7 @@ nop_lift! {type_; Ty<'a> => Ty<'tcx>}
16841683
nop_lift_old! {region; Region<'a> => Region<'tcx>}
16851684
nop_lift_old! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
16861685
nop_lift_old! {const_allocation; &'a Allocation => &'tcx Allocation}
1687-
nop_lift_old! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
1686+
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
16881687

16891688
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
16901689
nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
@@ -2040,23 +2039,23 @@ impl<'tcx> Hash for InternedInSet<'tcx, TyS<'tcx>> {
20402039
}
20412040
}
20422041

2043-
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for InternedInSet<'tcx, PredicateInner<'tcx>> {
2042+
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for InternedInSet<'tcx, PredicateS<'tcx>> {
20442043
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
20452044
&self.0.kind
20462045
}
20472046
}
20482047

2049-
impl<'tcx> PartialEq for InternedInSet<'tcx, PredicateInner<'tcx>> {
2050-
fn eq(&self, other: &InternedInSet<'tcx, PredicateInner<'tcx>>) -> bool {
2048+
impl<'tcx> PartialEq for InternedInSet<'tcx, PredicateS<'tcx>> {
2049+
fn eq(&self, other: &InternedInSet<'tcx, PredicateS<'tcx>>) -> bool {
20512050
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
20522051
// `x == y`.
20532052
self.0.kind == other.0.kind
20542053
}
20552054
}
20562055

2057-
impl<'tcx> Eq for InternedInSet<'tcx, PredicateInner<'tcx>> {}
2056+
impl<'tcx> Eq for InternedInSet<'tcx, PredicateS<'tcx>> {}
20582057

2059-
impl<'tcx> Hash for InternedInSet<'tcx, PredicateInner<'tcx>> {
2058+
impl<'tcx> Hash for InternedInSet<'tcx, PredicateS<'tcx>> {
20602059
fn hash<H: Hasher>(&self, s: &mut H) {
20612060
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
20622061
self.0.kind.hash(s)
@@ -2237,8 +2236,7 @@ impl<'tcx> TyCtxt<'tcx> {
22372236

22382237
#[inline]
22392238
pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2240-
let inner = self.interners.intern_predicate(binder);
2241-
Predicate { inner }
2239+
self.interners.intern_predicate(binder)
22422240
}
22432241

22442242
#[inline]

compiler/rustc_middle/src/ty/fold.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
11811181

11821182
#[inline]
11831183
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
1184-
if predicate.inner.outer_exclusive_binder > self.outer_index {
1184+
if predicate.outer_exclusive_binder() > self.outer_index {
11851185
ControlFlow::Break(FoundEscapingVars)
11861186
} else {
11871187
ControlFlow::CONTINUE
@@ -1263,9 +1263,11 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
12631263
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
12641264
debug!(
12651265
"HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}",
1266-
predicate, predicate.inner.flags, self.flags
1266+
predicate,
1267+
predicate.flags(),
1268+
self.flags
12671269
);
1268-
if predicate.inner.flags.intersects(self.flags) {
1270+
if predicate.flags().intersects(self.flags) {
12691271
ControlFlow::Break(FoundFlags)
12701272
} else {
12711273
ControlFlow::CONTINUE

compiler/rustc_middle/src/ty/mod.rs

+28-29
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ use rustc_span::symbol::{kw, Ident, Symbol};
4343
use rustc_span::{sym, Span};
4444
use rustc_target::abi::Align;
4545

46-
use std::hash::{Hash, Hasher};
46+
use std::hash::Hash;
4747
use std::ops::ControlFlow;
48-
use std::{fmt, ptr, str};
48+
use std::{fmt, str};
4949

5050
pub use crate::ty::diagnostics::*;
5151
pub use rustc_type_ir::InferTy::*;
@@ -466,51 +466,50 @@ impl ty::EarlyBoundRegion {
466466
}
467467
}
468468

469+
/// Represents a predicate.
470+
///
471+
/// See comments on `TyS`, which apply here too (albeit for
472+
/// `PredicateS`/`Predicate` rather than `TyS`/`Ty`).
469473
#[derive(Debug)]
470-
crate struct PredicateInner<'tcx> {
474+
crate struct PredicateS<'tcx> {
471475
kind: Binder<'tcx, PredicateKind<'tcx>>,
472476
flags: TypeFlags,
473477
/// See the comment for the corresponding field of [TyS].
474478
outer_exclusive_binder: ty::DebruijnIndex,
475479
}
476480

481+
// This type is used a lot. Make sure it doesn't unintentionally get bigger.
477482
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
478-
static_assert_size!(PredicateInner<'_>, 56);
479-
480-
#[derive(Clone, Copy, Lift)]
481-
pub struct Predicate<'tcx> {
482-
inner: &'tcx PredicateInner<'tcx>,
483-
}
484-
485-
impl<'tcx> PartialEq for Predicate<'tcx> {
486-
fn eq(&self, other: &Self) -> bool {
487-
// `self.kind` is always interned.
488-
ptr::eq(self.inner, other.inner)
489-
}
490-
}
491-
492-
impl Hash for Predicate<'_> {
493-
fn hash<H: Hasher>(&self, s: &mut H) {
494-
(self.inner as *const PredicateInner<'_>).hash(s)
495-
}
496-
}
483+
static_assert_size!(PredicateS<'_>, 56);
497484

498-
impl<'tcx> Eq for Predicate<'tcx> {}
485+
/// Use this rather than `PredicateS`, whenever possible.
486+
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
487+
#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
488+
pub struct Predicate<'tcx>(Interned<'tcx, PredicateS<'tcx>>);
499489

500490
impl<'tcx> Predicate<'tcx> {
501491
/// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`.
502492
#[inline]
503493
pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> {
504-
self.inner.kind
494+
self.0.kind
495+
}
496+
497+
#[inline(always)]
498+
pub fn flags(self) -> TypeFlags {
499+
self.0.flags
500+
}
501+
502+
#[inline(always)]
503+
pub fn outer_exclusive_binder(self) -> DebruijnIndex {
504+
self.0.outer_exclusive_binder
505505
}
506506

507507
/// Flips the polarity of a Predicate.
508508
///
509509
/// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`.
510-
pub fn flip_polarity(&self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
510+
pub fn flip_polarity(self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
511511
let kind = self
512-
.inner
513-
.kind
512+
.kind()
514513
.map_bound(|kind| match kind {
515514
PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) => {
516515
Some(PredicateKind::Trait(TraitPredicate {
@@ -530,14 +529,14 @@ impl<'tcx> Predicate<'tcx> {
530529

531530
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
532531
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
533-
let PredicateInner {
532+
let PredicateS {
534533
ref kind,
535534

536535
// The other fields just provide fast access to information that is
537536
// also contained in `kind`, so no need to hash them.
538537
flags: _,
539538
outer_exclusive_binder: _,
540-
} = self.inner;
539+
} = self.0.0;
541540

542541
kind.hash_stable(hcx, hasher);
543542
}

compiler/rustc_middle/src/ty/structural_impls.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1112,24 +1112,24 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
11121112
self,
11131113
folder: &mut F,
11141114
) -> Result<Self, F::Error> {
1115-
let new = self.inner.kind.try_fold_with(folder)?;
1115+
let new = self.kind().try_fold_with(folder)?;
11161116
Ok(folder.tcx().reuse_or_mk_predicate(self, new))
11171117
}
11181118

11191119
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1120-
self.inner.kind.visit_with(visitor)
1120+
self.kind().visit_with(visitor)
11211121
}
11221122

11231123
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
11241124
visitor.visit_predicate(*self)
11251125
}
11261126

11271127
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
1128-
self.inner.outer_exclusive_binder > binder
1128+
self.outer_exclusive_binder() > binder
11291129
}
11301130

11311131
fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
1132-
self.inner.flags.intersects(flags)
1132+
self.flags().intersects(flags)
11331133
}
11341134
}
11351135

compiler/rustc_trait_selection/src/traits/wf.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
198198
trait_ref: &ty::TraitRef<'tcx>,
199199
item: Option<&hir::Item<'tcx>>,
200200
cause: &mut traits::ObligationCause<'tcx>,
201-
pred: &ty::Predicate<'tcx>,
201+
pred: ty::Predicate<'tcx>,
202202
) {
203203
debug!(
204204
"extended_cause_with_original_assoc_item_obligation {:?} {:?} {:?} {:?}",
@@ -319,7 +319,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
319319
trait_ref,
320320
item,
321321
&mut cause,
322-
&obligation.predicate,
322+
obligation.predicate,
323323
);
324324
traits::Obligation::with_depth(cause, depth, param_env, obligation.predicate)
325325
};

compiler/rustc_traits/src/normalize_erasing_regions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq +
3939
// always only region relations, and we are about to
4040
// erase those anyway:
4141
debug_assert_eq!(
42-
normalized_obligations.iter().find(|p| not_outlives_predicate(&p.predicate)),
42+
normalized_obligations.iter().find(|p| not_outlives_predicate(p.predicate)),
4343
None,
4444
);
4545

@@ -57,7 +57,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq +
5757
})
5858
}
5959

60-
fn not_outlives_predicate<'tcx>(p: &ty::Predicate<'tcx>) -> bool {
60+
fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool {
6161
match p.kind().skip_binder() {
6262
ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::TypeOutlives(..) => false,
6363
ty::PredicateKind::Trait(..)

compiler/rustc_typeck/src/check/method/suggest.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
703703
let mut bound_spans = vec![];
704704

705705
let mut collect_type_param_suggestions =
706-
|self_ty: Ty<'tcx>, parent_pred: &ty::Predicate<'tcx>, obligation: &str| {
706+
|self_ty: Ty<'tcx>, parent_pred: ty::Predicate<'tcx>, obligation: &str| {
707707
// We don't care about regions here, so it's fine to skip the binder here.
708708
if let (ty::Param(_), ty::PredicateKind::Trait(p)) =
709709
(self_ty.kind(), parent_pred.kind().skip_binder())
@@ -892,15 +892,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
892892
.filter(|(pred, _, _parent_pred)| !skip_list.contains(&pred))
893893
.filter_map(|(pred, parent_pred, _cause)| {
894894
format_pred(*pred).map(|(p, self_ty)| {
895-
collect_type_param_suggestions(self_ty, pred, &p);
895+
collect_type_param_suggestions(self_ty, *pred, &p);
896896
match parent_pred {
897897
None => format!("`{}`", &p),
898898
Some(parent_pred) => match format_pred(*parent_pred) {
899899
None => format!("`{}`", &p),
900900
Some((parent_p, _)) => {
901901
collect_type_param_suggestions(
902902
self_ty,
903-
parent_pred,
903+
*parent_pred,
904904
&p,
905905
);
906906
format!("`{}`\nwhich is required by `{}`", p, parent_p)

0 commit comments

Comments
 (0)