Skip to content

Commit e5bd0b9

Browse files
committed
move encoder/decoder impls to rustc_type_ir
1 parent 0fc84fa commit e5bd0b9

7 files changed

Lines changed: 130 additions & 82 deletions

File tree

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use rustc_index::Idx;
2424
use rustc_middle::middle::lib_features::LibFeatures;
2525
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
2626
use rustc_middle::ty::Visibility;
27-
use rustc_middle::ty::codec::TyDecoder;
2827
use rustc_middle::{bug, implement_ty_decoder};
2928
use rustc_proc_macro::bridge::client::ProcMacro;
3029
use rustc_serialize::opaque::MemDecoder;
@@ -386,7 +385,7 @@ impl<'a> BlobDecodeContext<'a> {
386385
}
387386
}
388387

389-
impl<'a, 'tcx> TyDecoder<'tcx> for MetadataDecodeContext<'a, 'tcx> {
388+
impl<'a, 'tcx> rustc_type_ir::codec::TyDecoder<'tcx> for MetadataDecodeContext<'a, 'tcx> {
390389
type Interner = TyCtxt<'tcx>;
391390

392391
const CLEAR_CROSS_CRATE: bool = true;

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use rustc_middle::mir::interpret;
2323
use rustc_middle::query::Providers;
2424
use rustc_middle::traits::specialization_graph;
2525
use rustc_middle::ty::AssocContainer;
26-
use rustc_middle::ty::codec::TyEncoder;
2726
use rustc_middle::ty::fast_reject::{self, TreatParams};
2827
use rustc_middle::{bug, span_bug};
2928
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque};
@@ -368,7 +367,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for [u8] {
368367
}
369368
}
370369

371-
impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> {
370+
impl<'a, 'tcx> rustc_type_ir::codec::TyEncoder<'tcx> for EncodeContext<'a, 'tcx> {
372371
type Interner = TyCtxt<'tcx>;
373372

374373
const CLEAR_CROSS_CRATE: bool = true;

compiler/rustc_middle/src/query/on_disk_cache.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::dep_graph::{DepNodeIndex, QuerySideEffect, SerializedDepNodeIndex};
2626
use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState};
2727
use crate::mir::mono::MonoItem;
2828
use crate::mir::{self, interpret};
29-
use crate::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
29+
use crate::ty::codec::RefDecodable;
3030
use crate::ty::{self, Ty, TyCtxt};
3131

3232
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
@@ -513,7 +513,9 @@ where
513513
value
514514
}
515515

516-
impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
516+
impl<'a, 'tcx> rustc_type_ir::codec::TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
517+
type Interner = TyCtxt<'tcx>;
518+
517519
const CLEAR_CROSS_CRATE: bool = false;
518520

519521
#[inline]
@@ -957,7 +959,9 @@ impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> {
957959
}
958960
}
959961

960-
impl<'a, 'tcx> TyEncoder<'tcx> for CacheEncoder<'a, 'tcx> {
962+
impl<'a, 'tcx> rustc_type_ir::codec::TyEncoder<'tcx> for CacheEncoder<'a, 'tcx> {
963+
type Interner = TyCtxt<'tcx>;
964+
961965
const CLEAR_CROSS_CRATE: bool = false;
962966

963967
#[inline]

compiler/rustc_middle/src/ty/codec.rs

Lines changed: 9 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use rustc_data_structures::fx::FxHashMap;
1515
use rustc_hir::def_id::LocalDefId;
1616
use rustc_middle::ty::Const;
1717
use rustc_serialize::{Decodable, Encodable};
18-
use rustc_span::{Span, SpanDecoder, SpanEncoder, Spanned};
18+
use rustc_span::{Span, Spanned};
19+
use rustc_type_ir::codec::{SHORTHAND_OFFSET, TyDecoder as IrTyDecoder, TyEncoder as IrTyEncoder};
1920

2021
use crate::arena::ArenaAllocatable;
2122
use crate::infer::canonical::{CanonicalVarKind, CanonicalVarKinds};
@@ -24,58 +25,19 @@ use crate::mir::mono::MonoItem;
2425
use crate::ty::{self, AdtDef, GenericArgsRef, Ty, TyCtxt};
2526
use crate::{mir, traits};
2627

27-
/// The shorthand encoding uses an enum's variant index `usize`
28-
/// and is offset by this value so it never matches a real variant.
29-
/// This offset is also chosen so that the first byte is never < 0x80.
30-
pub const SHORTHAND_OFFSET: usize = 0x80;
28+
pub trait TyEncoder<'tcx>: IrTyEncoder<'tcx, Interner = TyCtxt<'tcx>> {}
3129

32-
pub trait TyEncoder<'tcx>: SpanEncoder {
33-
const CLEAR_CROSS_CRATE: bool;
30+
impl<'tcx, T> TyEncoder<'tcx> for T where T: IrTyEncoder<'tcx, Interner = TyCtxt<'tcx>> {}
3431

35-
fn position(&self) -> usize;
32+
pub trait TyDecoder<'tcx>: IrTyDecoder<'tcx, Interner = TyCtxt<'tcx>> {}
3633

37-
fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize>;
38-
39-
fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::PredicateKind<'tcx>, usize>;
40-
41-
fn encode_alloc_id(&mut self, alloc_id: &AllocId);
42-
}
43-
44-
pub trait TyDecoder<'tcx>: SpanDecoder {
45-
const CLEAR_CROSS_CRATE: bool;
46-
47-
fn interner(&self) -> TyCtxt<'tcx>;
48-
49-
fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
50-
where
51-
F: FnOnce(&mut Self) -> Ty<'tcx>;
52-
53-
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
54-
where
55-
F: FnOnce(&mut Self) -> R;
56-
57-
fn positioned_at_shorthand(&self) -> bool {
58-
(self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
59-
}
60-
61-
fn decode_alloc_id(&mut self) -> AllocId;
62-
}
34+
impl<'tcx, T> TyDecoder<'tcx> for T where T: IrTyDecoder<'tcx, Interner = TyCtxt<'tcx>> {}
6335

6436
pub trait EncodableWithShorthand<'tcx, E: TyEncoder<'tcx>>: Copy + Eq + Hash {
65-
type Variant: Encodable<E>;
37+
type Variant;
6638
fn variant(&self) -> &Self::Variant;
6739
}
6840

69-
#[allow(rustc::usage_of_ty_tykind)]
70-
impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for Ty<'tcx> {
71-
type Variant = ty::TyKind<'tcx>;
72-
73-
#[inline]
74-
fn variant(&self) -> &Self::Variant {
75-
self.kind()
76-
}
77-
}
78-
7941
impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::PredicateKind<'tcx> {
8042
type Variant = ty::PredicateKind<'tcx>;
8143

@@ -106,7 +68,7 @@ where
10668
M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<T, usize>,
10769
T: EncodableWithShorthand<'tcx, E>,
10870
// The discriminant and shorthand must have the same size.
109-
T::Variant: DiscriminantKind<Discriminant = isize>,
71+
T::Variant: DiscriminantKind<Discriminant = isize> + Encodable<E>,
11072
{
11173
let existing_shorthand = cache(encoder).get(value).copied();
11274
if let Some(shorthand) = existing_shorthand {
@@ -138,17 +100,11 @@ where
138100
}
139101
}
140102

141-
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Ty<'tcx> {
142-
fn encode(&self, e: &mut E) {
143-
encode_with_shorthand(e, self, TyEncoder::type_shorthands);
144-
}
145-
}
146-
147103
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
148104
fn encode(&self, e: &mut E) {
149105
let kind = self.kind();
150106
kind.bound_vars().encode(e);
151-
encode_with_shorthand(e, &kind.skip_binder(), TyEncoder::predicate_shorthands);
107+
encode_with_shorthand(e, &kind.skip_binder(), |e| e.predicate_shorthands());
152108
}
153109
}
154110

@@ -230,25 +186,6 @@ fn decode_arena_allocable_slice<
230186
decoder.interner().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder))
231187
}
232188

233-
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
234-
#[allow(rustc::usage_of_ty_tykind)]
235-
fn decode(decoder: &mut D) -> Ty<'tcx> {
236-
// Handle shorthands first, if we have a usize > 0x80.
237-
if decoder.positioned_at_shorthand() {
238-
let pos = decoder.read_usize();
239-
assert!(pos >= SHORTHAND_OFFSET);
240-
let shorthand = pos - SHORTHAND_OFFSET;
241-
242-
decoder.cached_ty_for_shorthand(shorthand, |decoder| {
243-
decoder.with_position(shorthand, Ty::decode)
244-
})
245-
} else {
246-
let tcx = decoder.interner();
247-
tcx.mk_ty_from_kind(ty::TyKind::decode(decoder))
248-
}
249-
}
250-
}
251-
252189
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
253190
fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
254191
let bound_vars = Decodable::decode(decoder);

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ use crate::middle::privacy::EffectiveVisibilities;
122122
use crate::mir::{Body, CoroutineLayout, CoroutineSavedLocal, SourceInfo};
123123
use crate::query::{IntoQueryParam, Providers};
124124
use crate::ty;
125-
use crate::ty::codec::{TyDecoder, TyEncoder};
125+
use crate::ty::codec::{TyDecoder as CodecTyDecoder, TyEncoder as CodecTyEncoder};
126126
pub use crate::ty::diagnostics::*;
127127
use crate::ty::fast_reject::SimplifiedType;
128128
use crate::ty::layout::{FnAbiError, LayoutError};
@@ -558,13 +558,13 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
558558
}
559559
}
560560

561-
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Term<'tcx> {
561+
impl<'tcx, E: CodecTyEncoder<'tcx>> Encodable<E> for Term<'tcx> {
562562
fn encode(&self, e: &mut E) {
563563
self.kind().encode(e)
564564
}
565565
}
566566

567-
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Term<'tcx> {
567+
impl<'tcx, D: CodecTyDecoder<'tcx>> Decodable<D> for Term<'tcx> {
568568
fn decode(d: &mut D) -> Self {
569569
let res: TermKind<'tcx> = Decodable::decode(d);
570570
res.pack()
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
use rustc_hash::FxHashMap;
2+
use rustc_serialize::{Decodable, Encodable};
3+
use rustc_span::{SpanDecoder, SpanEncoder};
4+
5+
use crate::{Interner, PredicateKind, Ty, TyKind};
6+
7+
/// The shorthand encoding uses an enum's variant index `usize`
8+
/// and is offset by this value so it never matches a real variant.
9+
/// This offset is also chosen so that the first byte is never < 0x80.
10+
pub const SHORTHAND_OFFSET: usize = 0x80;
11+
12+
pub trait TyEncoder<'tcx>: SpanEncoder {
13+
type Interner: Interner;
14+
15+
const CLEAR_CROSS_CRATE: bool;
16+
17+
fn position(&self) -> usize;
18+
19+
fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<Self::Interner>, usize>;
20+
21+
fn predicate_shorthands(&mut self) -> &mut FxHashMap<PredicateKind<Self::Interner>, usize>;
22+
23+
fn encode_alloc_id(&mut self, alloc_id: &<Self::Interner as Interner>::AllocId);
24+
}
25+
26+
pub trait TyDecoder<'tcx>: SpanDecoder {
27+
type Interner: Interner;
28+
29+
const CLEAR_CROSS_CRATE: bool;
30+
31+
fn interner(&self) -> Self::Interner;
32+
33+
fn cached_ty_for_shorthand<F>(
34+
&mut self,
35+
shorthand: usize,
36+
or_insert_with: F,
37+
) -> Ty<Self::Interner>
38+
where
39+
F: FnOnce(&mut Self) -> Ty<Self::Interner>;
40+
41+
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
42+
where
43+
F: FnOnce(&mut Self) -> R;
44+
45+
fn positioned_at_shorthand(&self) -> bool {
46+
(self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
47+
}
48+
49+
fn decode_alloc_id(&mut self) -> <Self::Interner as Interner>::AllocId;
50+
}
51+
52+
impl<'tcx, I, E> Encodable<E> for Ty<I>
53+
where
54+
I: Interner,
55+
E: TyEncoder<'tcx, Interner = I>,
56+
TyKind<I>: Encodable<E>,
57+
{
58+
fn encode(&self, e: &mut E) {
59+
let existing_shorthand = e.type_shorthands().get(self).copied();
60+
if let Some(shorthand) = existing_shorthand {
61+
e.emit_usize(shorthand);
62+
return;
63+
}
64+
65+
let kind = crate::inherent::IntoKind::kind(*self);
66+
let start = e.position();
67+
kind.encode(e);
68+
let len = e.position() - start;
69+
70+
let shorthand = start + SHORTHAND_OFFSET;
71+
72+
// Get the number of bits that leb128 could fit
73+
// in the same space as the fully encoded type.
74+
let leb128_bits = len * 7;
75+
76+
// Check that the shorthand is a not longer than the
77+
// full encoding itself, i.e., it's an obvious win.
78+
if leb128_bits >= 64 || (shorthand as u64) < (1 << leb128_bits) {
79+
e.type_shorthands().insert(*self, shorthand);
80+
}
81+
}
82+
}
83+
84+
impl<'tcx, I, D> Decodable<D> for Ty<I>
85+
where
86+
I: Interner,
87+
D: TyDecoder<'tcx, Interner = I>,
88+
TyKind<I>: Decodable<D>,
89+
{
90+
fn decode(decoder: &mut D) -> Ty<I> {
91+
// Handle shorthands first, if we have a usize > 0x80.
92+
if decoder.positioned_at_shorthand() {
93+
let pos = decoder.read_usize();
94+
assert!(pos >= SHORTHAND_OFFSET);
95+
let shorthand = pos - SHORTHAND_OFFSET;
96+
97+
decoder.cached_ty_for_shorthand(shorthand, |decoder| {
98+
decoder.with_position(shorthand, Ty::decode)
99+
})
100+
} else {
101+
let interner = decoder.interner();
102+
interner.mk_ty_from_kind(TyKind::decode(decoder))
103+
}
104+
}
105+
}

compiler/rustc_type_ir/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ use rustc_macros::{Decodable, Encodable, HashStable_NoContext};
1919

2020
// These modules are `pub` since they are not glob-imported.
2121
#[cfg(feature = "nightly")]
22+
pub mod codec;
23+
#[cfg(feature = "nightly")]
2224
pub mod data_structures;
2325
pub mod elaborate;
2426
pub mod error;
@@ -65,6 +67,8 @@ pub use TyKind::*;
6567
pub use Variance::*;
6668
pub use binder::{Placeholder, *};
6769
pub use canonical::*;
70+
#[cfg(feature = "nightly")]
71+
pub use codec::*;
6872
pub use const_kind::*;
6973
pub use flags::*;
7074
pub use fold::*;

0 commit comments

Comments
 (0)