Skip to content
4 changes: 4 additions & 0 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ impl<'a, 'tcx> rustc_middle::ty::InternerDecoder for MetadataDecodeContext<'a, '
fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}

fn decode_predicate(&mut self) -> rustc_middle::ty::predicates::Predicate<Self::Interner> {
rustc_middle::ty::codec::decode_predicate(self)
}
}

impl<'a, 'tcx> Decodable<MetadataDecodeContext<'a, 'tcx>> for ExpnIndex {
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for [u8] {
}
}

impl<'a, 'tcx> rustc_middle::ty::PredicateEncoder<TyCtxt<'tcx>> for EncodeContext<'a, 'tcx> {
fn encode_predicate(
&mut self,
predicate: rustc_middle::ty::predicates::Predicate<TyCtxt<'tcx>>,
) {
rustc_middle::ty::codec::encode_predicate(self, predicate);
}
}

impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> {
const CLEAR_CROSS_CRATE: bool = true;

Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_middle/src/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,10 @@ impl<'a, 'tcx> rustc_type_ir::InternerDecoder for CacheDecoder<'a, 'tcx> {
fn interner(&self) -> Self::Interner {
self.tcx
}

fn decode_predicate(&mut self) -> rustc_type_ir::predicates::Predicate<Self::Interner> {
ty::codec::decode_predicate(self)
}
}

impl<'a, 'tcx> Decoder for CacheDecoder<'a, 'tcx> {
Expand Down Expand Up @@ -916,6 +920,12 @@ impl<'tcx> SpanEncoder for CacheEncoder<'tcx> {
}
}

impl<'tcx> rustc_type_ir::PredicateEncoder<TyCtxt<'tcx>> for CacheEncoder<'tcx> {
fn encode_predicate(&mut self, predicate: rustc_type_ir::predicates::Predicate<TyCtxt<'tcx>>) {
ty::codec::encode_predicate(self, predicate);
}
}

impl<'tcx> TyEncoder<'tcx> for CacheEncoder<'tcx> {
const CLEAR_CROSS_CRATE: bool = false;

Expand Down
59 changes: 22 additions & 37 deletions compiler/rustc_middle/src/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ mod ref_decodable;
/// This offset is also chosen so that the first byte is never < 0x80.
pub const SHORTHAND_OFFSET: usize = 0x80;

pub trait TyEncoder<'tcx>: SpanEncoder {
pub trait TyEncoder<'tcx>: SpanEncoder + rustc_type_ir::PredicateEncoder<TyCtxt<'tcx>> {
const CLEAR_CROSS_CRATE: bool;

fn position(&self) -> usize;
Expand Down Expand Up @@ -128,18 +128,11 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Ty<'tcx> {
}
}

impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
fn encode(&self, e: &mut E) {
let kind = self.kind();
kind.bound_vars().encode(e);
encode_with_shorthand(e, &kind.skip_binder(), TyEncoder::predicate_shorthands);
}
}

impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Clause<'tcx> {
fn encode(&self, e: &mut E) {
self.as_predicate().encode(e);
}
/// Encode a predicate using rustc's existing shorthand representation.
pub fn encode_predicate<'tcx, E: TyEncoder<'tcx>>(e: &mut E, predicate: ty::Predicate<'tcx>) {
let kind = predicate.kind();
kind.bound_vars().encode(e);
encode_with_shorthand(e, &kind.skip_binder(), TyEncoder::predicate_shorthands);
}

impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Pattern<'tcx> {
Expand Down Expand Up @@ -203,31 +196,23 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
}
}

impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
let bound_vars = Decodable::decode(decoder);
// Handle shorthands first, if we have a usize > 0x80.
let predicate_kind = ty::Binder::bind_with_vars(
if decoder.positioned_at_shorthand() {
let pos = decoder.read_usize();
assert!(pos >= SHORTHAND_OFFSET);
let shorthand = pos - SHORTHAND_OFFSET;

decoder.with_position(shorthand, <ty::PredicateKind<'tcx> as Decodable<D>>::decode)
} else {
<ty::PredicateKind<'tcx> as Decodable<D>>::decode(decoder)
},
bound_vars,
);
decoder.interner().mk_predicate(predicate_kind)
}
}
/// Decode a predicate, resolving shorthand references before interning it.
pub fn decode_predicate<'tcx, D: TyDecoder<'tcx>>(decoder: &mut D) -> ty::Predicate<'tcx> {
let bound_vars = Decodable::decode(decoder);
// Handle shorthands first, if we have a usize > 0x80.
let predicate_kind = ty::Binder::bind_with_vars(
if decoder.positioned_at_shorthand() {
let pos = decoder.read_usize();
assert!(pos >= SHORTHAND_OFFSET);
let shorthand = pos - SHORTHAND_OFFSET;

impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Clause<'tcx> {
fn decode(decoder: &mut D) -> ty::Clause<'tcx> {
let pred: ty::Predicate<'tcx> = Decodable::decode(decoder);
pred.expect_clause()
}
decoder.with_position(shorthand, <ty::PredicateKind<'tcx> as Decodable<D>>::decode)
} else {
<ty::PredicateKind<'tcx> as Decodable<D>>::decode(decoder)
},
bound_vars,
);
decoder.interner().mk_predicate(predicate_kind)
}

impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for GenericArgsRef<'tcx> {
Expand Down
20 changes: 17 additions & 3 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ impl<'tcx> CtxtInterners<'tcx> {
/// Interns a predicate. (Use `mk_predicate` instead, where possible.)
#[inline(never)]
fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
Predicate(Interned::new_unchecked(
rustc_type_ir::predicates::Predicate(Interned::new_unchecked(
self.predicate
.intern(kind, |kind| {
let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
Expand Down Expand Up @@ -1747,8 +1747,6 @@ macro_rules! nop_list_lift {
nop_lift! { type_; Ty<'a> => Ty<'tcx> }
nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
nop_lift! { layout; Layout<'a> => Layout<'tcx> }
nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }

Expand Down Expand Up @@ -1777,6 +1775,22 @@ impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, WithCachedTypeInfo<ConstKind<
}
}

// Lift the interned representation used by the shared Predicate and Clause.
impl<'a, 'tcx> Lift<TyCtxt<'tcx>>
for Interned<'a, WithCachedTypeInfo<ty::Binder<'a, ty::PredicateKind<'a>>>>
{
type Lifted = Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, ty::PredicateKind<'tcx>>>>;

#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
assert!(tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0)));

// SAFETY: The predicate is interned in this TyCtxt, so its storage
// remains valid for the lifetime of the target context.
unsafe { mem::transmute(self) }
}
}

nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
nop_list_lift! { clauses: ListWithCachedTypeInfo; Clause<'a> => Clause<'tcx> }
nop_list_lift! {
Expand Down
15 changes: 12 additions & 3 deletions compiler/rustc_middle/src/ty/context/impl_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_span::{DUMMY_SP, Span, Symbol, bug};
use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem};
use rustc_type_ir::predicates::Predicate;
use rustc_type_ir::solve::CanonicalInputData;
use rustc_type_ir::{
BoundVar, CollectAndApply, DebruijnIndex, Interner, RegionVid, TypeFoldable, Unnormalized,
Expand All @@ -24,8 +25,8 @@ use crate::traits::solve::{
self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect,
};
use crate::ty::{
self, BoundRegion, Clause, Const, List, ParamTy, Pattern, PolyExistentialPredicate, Predicate,
Region, RegionKind, RequiredDepth, Ty, TyCtxt,
self, BoundRegion, Clause, Const, List, ParamTy, Pattern, PolyExistentialPredicate, Region,
RegionKind, RequiredDepth, Ty, TyCtxt,
};

#[allow(rustc::usage_of_ty_tykind)]
Expand Down Expand Up @@ -121,17 +122,25 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type Scalar = Scalar;
type InternedRegionKind = Interned<'tcx, ty::RegionKind<'tcx>>;
type InternedConstKind = Interned<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>;
type InternedPredicateKind =
Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, ty::PredicateKind<'tcx>>>>;
type EarlyParamRegion = ty::EarlyParamRegion;
type LateParamRegionKind = ty::LateParamRegionKind;

type RegionAssumptions = &'tcx ty::List<ty::ArgOutlivesClause<'tcx>>;

type ParamEnv = ty::ParamEnv<'tcx>;
type Predicate = Predicate<'tcx>;

type Clause = Clause<'tcx>;
type Clauses = ty::Clauses<'tcx>;

fn intern_predicate(
self,
predicate: ty::Binder<'tcx, ty::PredicateKind<'tcx>>,
) -> Predicate<Self> {
self.interners.intern_predicate(predicate)
}

type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
fn mk_tracked<T: fmt::Debug + Clone>(
self,
Expand Down
20 changes: 0 additions & 20 deletions compiler/rustc_middle/src/ty/elaborate_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,6 @@ impl<'tcx> Elaboratable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
}
}

impl<'tcx> Elaboratable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
fn predicate(&self) -> ty::Predicate<'tcx> {
*self
}

fn child(&self, clause: ty::Clause<'tcx>) -> Self {
clause.as_predicate()
}

fn child_with_derived_cause(
&self,
clause: ty::Clause<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitClause<'tcx>,
_index: usize,
) -> Self {
clause.as_predicate()
}
}

impl<'tcx> Elaboratable<TyCtxt<'tcx>> for (ty::Predicate<'tcx>, Span) {
fn predicate(&self) -> ty::Predicate<'tcx> {
self.0
Expand Down
Loading
Loading