66//! The functionality in here is shared between persisting to crate metadata and
77//! persisting to incr. comp. caches.
88
9- use std:: hash:: Hash ;
10- use std:: intrinsics;
11- use std:: marker:: { DiscriminantKind , PointeeSized } ;
12-
139use rustc_abi:: FieldIdx ;
14- use rustc_data_structures:: fx:: FxHashMap ;
1510use rustc_hir:: def_id:: LocalDefId ;
1611use rustc_serialize:: { Decodable , Encodable } ;
12+ use rustc_span:: Span ;
1713use rustc_span:: source_map:: Spanned ;
18- use rustc_span :: { Span , SpanDecoder , SpanEncoder } ;
14+ use rustc_type_ir :: codec as ir_codec ;
1915
2016use crate :: arena:: ArenaAllocatable ;
2117use crate :: infer:: canonical:: { CanonicalVarKind , CanonicalVarKinds } ;
@@ -25,66 +21,13 @@ use crate::mir::{self};
2521use crate :: traits;
2622use crate :: ty:: { self , AdtDef , GenericArgsRef , Ty , TyCtxt } ;
2723
28- /// The shorthand encoding uses an enum's variant index `usize`
29- /// and is offset by this value so it never matches a real variant.
30- /// This offset is also chosen so that the first byte is never < 0x80.
31- pub const SHORTHAND_OFFSET : usize = 0x80 ;
32-
33- pub trait TyEncoder < ' tcx > : SpanEncoder {
34- const CLEAR_CROSS_CRATE : bool ;
35-
36- fn position ( & self ) -> usize ;
37-
38- fn type_shorthands ( & mut self ) -> & mut FxHashMap < Ty < ' tcx > , usize > ;
39-
40- fn predicate_shorthands ( & mut self ) -> & mut FxHashMap < ty:: PredicateKind < ' tcx > , usize > ;
41-
42- fn encode_alloc_id ( & mut self , alloc_id : & AllocId ) ;
43- }
44-
45- pub trait TyDecoder < ' tcx > : SpanDecoder {
46- const CLEAR_CROSS_CRATE : bool ;
47-
48- fn interner ( & self ) -> TyCtxt < ' tcx > ;
49-
50- fn cached_ty_for_shorthand < F > ( & mut self , shorthand : usize , or_insert_with : F ) -> Ty < ' tcx >
51- where
52- F : FnOnce ( & mut Self ) -> Ty < ' tcx > ;
53-
54- fn with_position < F , R > ( & mut self , pos : usize , f : F ) -> R
55- where
56- F : FnOnce ( & mut Self ) -> R ;
24+ pub trait TyEncoder < ' tcx > : ir_codec:: TyEncoder < ' tcx , Interner = TyCtxt < ' tcx > > { }
25+ impl < ' tcx , T > TyEncoder < ' tcx > for T where T : ir_codec:: TyEncoder < ' tcx , Interner = TyCtxt < ' tcx > > { }
5726
58- fn positioned_at_shorthand ( & self ) -> bool {
59- ( self . peek_byte ( ) & ( SHORTHAND_OFFSET as u8 ) ) != 0
60- }
61-
62- fn decode_alloc_id ( & mut self ) -> AllocId ;
63- }
27+ pub trait TyDecoder < ' tcx > : ir_codec:: TyDecoder < ' tcx , Interner = TyCtxt < ' tcx > > { }
28+ impl < ' tcx , T > TyDecoder < ' tcx > for T where T : ir_codec:: TyDecoder < ' tcx , Interner = TyCtxt < ' tcx > > { }
6429
65- pub trait EncodableWithShorthand < ' tcx , E : TyEncoder < ' tcx > > : Copy + Eq + Hash {
66- type Variant : Encodable < E > ;
67- fn variant ( & self ) -> & Self :: Variant ;
68- }
69-
70- #[ allow( rustc:: usage_of_ty_tykind) ]
71- impl < ' tcx , E : TyEncoder < ' tcx > > EncodableWithShorthand < ' tcx , E > for Ty < ' tcx > {
72- type Variant = ty:: TyKind < ' tcx > ;
73-
74- #[ inline]
75- fn variant ( & self ) -> & Self :: Variant {
76- self . kind ( )
77- }
78- }
79-
80- impl < ' tcx , E : TyEncoder < ' tcx > > EncodableWithShorthand < ' tcx , E > for ty:: PredicateKind < ' tcx > {
81- type Variant = ty:: PredicateKind < ' tcx > ;
82-
83- #[ inline]
84- fn variant ( & self ) -> & Self :: Variant {
85- self
86- }
87- }
30+ pub use ir_codec:: { EncodableWithShorthand , SHORTHAND_OFFSET , encode_with_shorthand} ;
8831
8932/// Trait for decoding to a reference.
9033///
@@ -96,55 +39,10 @@ impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::Predicate
9639///
9740/// `Decodable` can still be implemented in cases where `Decodable` is required
9841/// by a trait bound.
99- pub trait RefDecodable < ' tcx , D : TyDecoder < ' tcx > > : PointeeSized {
42+ pub trait RefDecodable < ' tcx , D : TyDecoder < ' tcx > > : std :: marker :: PointeeSized {
10043 fn decode ( d : & mut D ) -> & ' tcx Self ;
10144}
10245
103- /// Encode the given value or a previously cached shorthand.
104- pub fn encode_with_shorthand < ' tcx , E , T , M > ( encoder : & mut E , value : & T , cache : M )
105- where
106- E : TyEncoder < ' tcx > ,
107- M : for < ' b > Fn ( & ' b mut E ) -> & ' b mut FxHashMap < T , usize > ,
108- T : EncodableWithShorthand < ' tcx , E > ,
109- // The discriminant and shorthand must have the same size.
110- T :: Variant : DiscriminantKind < Discriminant = isize > ,
111- {
112- let existing_shorthand = cache ( encoder) . get ( value) . copied ( ) ;
113- if let Some ( shorthand) = existing_shorthand {
114- encoder. emit_usize ( shorthand) ;
115- return ;
116- }
117-
118- let variant = value. variant ( ) ;
119-
120- let start = encoder. position ( ) ;
121- variant. encode ( encoder) ;
122- let len = encoder. position ( ) - start;
123-
124- // The shorthand encoding uses the same usize as the
125- // discriminant, with an offset so they can't conflict.
126- let discriminant = intrinsics:: discriminant_value ( variant) ;
127- assert ! ( SHORTHAND_OFFSET > discriminant as usize ) ;
128-
129- let shorthand = start + SHORTHAND_OFFSET ;
130-
131- // Get the number of bits that leb128 could fit
132- // in the same space as the fully encoded type.
133- let leb128_bits = len * 7 ;
134-
135- // Check that the shorthand is a not longer than the
136- // full encoding itself, i.e., it's an obvious win.
137- if leb128_bits >= 64 || ( shorthand as u64 ) < ( 1 << leb128_bits) {
138- cache ( encoder) . insert ( * value, shorthand) ;
139- }
140- }
141-
142- impl < ' tcx , E : TyEncoder < ' tcx > > Encodable < E > for Ty < ' tcx > {
143- fn encode ( & self , e : & mut E ) {
144- encode_with_shorthand ( e, self , TyEncoder :: type_shorthands) ;
145- }
146- }
147-
14846impl < ' tcx , E : TyEncoder < ' tcx > > Encodable < E > for ty:: Predicate < ' tcx > {
14947 fn encode ( & self , e : & mut E ) {
15048 let kind = self . kind ( ) ;
@@ -231,25 +129,6 @@ fn decode_arena_allocable_slice<
231129 decoder. interner ( ) . arena . alloc_from_iter ( <Vec < T > as Decodable < D > >:: decode ( decoder) )
232130}
233131
234- impl < ' tcx , D : TyDecoder < ' tcx > > Decodable < D > for Ty < ' tcx > {
235- #[ allow( rustc:: usage_of_ty_tykind) ]
236- fn decode ( decoder : & mut D ) -> Ty < ' tcx > {
237- // Handle shorthands first, if we have a usize > 0x80.
238- if decoder. positioned_at_shorthand ( ) {
239- let pos = decoder. read_usize ( ) ;
240- assert ! ( pos >= SHORTHAND_OFFSET ) ;
241- let shorthand = pos - SHORTHAND_OFFSET ;
242-
243- decoder. cached_ty_for_shorthand ( shorthand, |decoder| {
244- decoder. with_position ( shorthand, Ty :: decode)
245- } )
246- } else {
247- let tcx = decoder. interner ( ) ;
248- tcx. mk_ty_from_kind ( ty:: TyKind :: decode ( decoder) )
249- }
250- }
251- }
252-
253132impl < ' tcx , D : TyDecoder < ' tcx > > Decodable < D > for ty:: Predicate < ' tcx > {
254133 fn decode ( decoder : & mut D ) -> ty:: Predicate < ' tcx > {
255134 let bound_vars = Decodable :: decode ( decoder) ;
0 commit comments