1use std::hash::Hash;
10use std::intrinsics;
11use std::marker::{DiscriminantKind, PointeeSized};
12
13use rustc_abi::FieldIdx;
14use rustc_data_structures::fx::FxHashMap;
15use rustc_hir::def_id::LocalDefId;
16use rustc_middle::ty::Const;
17use rustc_serialize::{Decodable, Encodable};
18use rustc_span::{Span, SpanDecoder, SpanEncoder, Spanned};
19
20use crate::arena::ArenaAllocatable;
21use crate::infer::canonical::{CanonicalVarKind, CanonicalVarKinds};
22use crate::mir::interpret::{AllocId, ConstAllocation, CtfeProvenance};
23use crate::mono::MonoItem;
24use crate::ty::{self, AdtDef, GenericArgsRef, Ty, TyCtxt};
25use crate::{mir, traits};
26
27pub const SHORTHAND_OFFSET: usize = 0x80;
31
32pub trait TyEncoder<'tcx>: SpanEncoder {
33 const CLEAR_CROSS_CRATE: bool;
34
35 fn position(&self) -> usize;
36
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
44pub trait TyDecoder<'tcx>:
45 SpanDecoder + rustc_type_ir::InternerDecoder<Interner = TyCtxt<'tcx>>
46{
47 const CLEAR_CROSS_CRATE: bool;
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}
63
64pub trait EncodableWithShorthand<'tcx, E: TyEncoder<'tcx>>: Copy + Eq + Hash {
65 type Variant: Encodable<E>;
66 fn variant(&self) -> &Self::Variant;
67}
68
69#[allow(rustc::usage_of_ty_tykind)]
70impl<'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
79impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::PredicateKind<'tcx> {
80 type Variant = ty::PredicateKind<'tcx>;
81
82 #[inline]
83 fn variant(&self) -> &Self::Variant {
84 self
85 }
86}
87
88pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>>: PointeeSized {
99 fn decode(d: &mut D) -> &'tcx Self;
100}
101
102pub fn encode_with_shorthand<'tcx, E, T, M>(encoder: &mut E, value: &T, cache: M)
104where
105 E: TyEncoder<'tcx>,
106 M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<T, usize>,
107 T: EncodableWithShorthand<'tcx, E>,
108 T::Variant: DiscriminantKind<Discriminant = isize>,
110{
111 let existing_shorthand = cache(encoder).get(value).copied();
112 if let Some(shorthand) = existing_shorthand {
113 encoder.emit_usize(shorthand);
114 return;
115 }
116
117 let variant = value.variant();
118
119 let start = encoder.position();
120 variant.encode(encoder);
121 let len = encoder.position() - start;
122
123 let discriminant = intrinsics::discriminant_value(variant);
126 if !(SHORTHAND_OFFSET > discriminant as usize) {
::core::panicking::panic("assertion failed: SHORTHAND_OFFSET > discriminant as usize")
};assert!(SHORTHAND_OFFSET > discriminant as usize);
127
128 let shorthand = start + SHORTHAND_OFFSET;
129
130 let leb128_bits = len * 7;
133
134 if leb128_bits >= 64 || (shorthand as u64) < (1 << leb128_bits) {
137 cache(encoder).insert(*value, shorthand);
138 }
139}
140
141impl<'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
147impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
148 fn encode(&self, e: &mut E) {
149 let kind = self.kind();
150 kind.bound_vars().encode(e);
151 encode_with_shorthand(e, &kind.skip_binder(), TyEncoder::predicate_shorthands);
152 }
153}
154
155impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Clause<'tcx> {
156 fn encode(&self, e: &mut E) {
157 self.as_predicate().encode(e);
158 }
159}
160
161impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Const<'tcx> {
162 fn encode(&self, e: &mut E) {
163 self.0.0.encode(e);
164 }
165}
166
167impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Pattern<'tcx> {
168 fn encode(&self, e: &mut E) {
169 self.0.0.encode(e);
170 }
171}
172
173impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::ValTree<'tcx> {
174 fn encode(&self, e: &mut E) {
175 self.0.0.encode(e);
176 }
177}
178
179impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ConstAllocation<'tcx> {
180 fn encode(&self, e: &mut E) {
181 self.inner().encode(e)
182 }
183}
184
185impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AdtDef<'tcx> {
186 fn encode(&self, e: &mut E) {
187 self.0.0.encode(e)
188 }
189}
190
191impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
192 fn encode(&self, e: &mut E) {
193 e.encode_alloc_id(self)
194 }
195}
196
197impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for CtfeProvenance {
198 fn encode(&self, e: &mut E) {
199 self.into_parts().encode(e);
200 }
201}
202
203impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::ParamEnv<'tcx> {
204 fn encode(&self, e: &mut E) {
205 self.caller_bounds().encode(e);
206 }
207}
208
209#[inline]
210fn decode_arena_allocable<'tcx, D: TyDecoder<'tcx>, T: ArenaAllocatable<'tcx> + Decodable<D>>(
211 decoder: &mut D,
212) -> &'tcx T {
213 decoder.interner().arena.alloc(Decodable::decode(decoder))
214}
215
216#[inline]
217fn decode_arena_allocable_slice<
218 'tcx,
219 D: TyDecoder<'tcx>,
220 T: ArenaAllocatable<'tcx> + Decodable<D>,
221>(
222 decoder: &mut D,
223) -> &'tcx [T] {
224 decoder.interner().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder))
225}
226
227impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
228 #[allow(rustc::usage_of_ty_tykind)]
229 fn decode(decoder: &mut D) -> Ty<'tcx> {
230 if decoder.positioned_at_shorthand() {
232 let pos = decoder.read_usize();
233 if !(pos >= SHORTHAND_OFFSET) {
::core::panicking::panic("assertion failed: pos >= SHORTHAND_OFFSET")
};assert!(pos >= SHORTHAND_OFFSET);
234 let shorthand = pos - SHORTHAND_OFFSET;
235
236 decoder.cached_ty_for_shorthand(shorthand, |decoder| {
237 decoder.with_position(shorthand, Ty::decode)
238 })
239 } else {
240 let tcx = decoder.interner();
241 tcx.mk_ty_from_kind(ty::TyKind::decode(decoder))
242 }
243 }
244}
245
246impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
247 fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
248 let bound_vars = Decodable::decode(decoder);
249 let predicate_kind = ty::Binder::bind_with_vars(
251 if decoder.positioned_at_shorthand() {
252 let pos = decoder.read_usize();
253 if !(pos >= SHORTHAND_OFFSET) {
::core::panicking::panic("assertion failed: pos >= SHORTHAND_OFFSET")
};assert!(pos >= SHORTHAND_OFFSET);
254 let shorthand = pos - SHORTHAND_OFFSET;
255
256 decoder.with_position(shorthand, <ty::PredicateKind<'tcx> as Decodable<D>>::decode)
257 } else {
258 <ty::PredicateKind<'tcx> as Decodable<D>>::decode(decoder)
259 },
260 bound_vars,
261 );
262 decoder.interner().mk_predicate(predicate_kind)
263 }
264}
265
266impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Clause<'tcx> {
267 fn decode(decoder: &mut D) -> ty::Clause<'tcx> {
268 let pred: ty::Predicate<'tcx> = Decodable::decode(decoder);
269 pred.expect_clause()
270 }
271}
272
273impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for GenericArgsRef<'tcx> {
274 fn decode(decoder: &mut D) -> Self {
275 let len = decoder.read_usize();
276 let tcx = decoder.interner();
277 tcx.mk_args_from_iter(
278 (0..len).map::<ty::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
279 )
280 }
281}
282
283impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for mir::Place<'tcx> {
284 fn decode(decoder: &mut D) -> Self {
285 let local: mir::Local = Decodable::decode(decoder);
286 let len = decoder.read_usize();
287 let projection = decoder.interner().mk_place_elems_from_iter(
288 (0..len).map::<mir::PlaceElem<'tcx>, _>(|_| Decodable::decode(decoder)),
289 );
290 mir::Place { local, projection }
291 }
292}
293
294impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarKinds<'tcx> {
295 fn decode(decoder: &mut D) -> Self {
296 let len = decoder.read_usize();
297 decoder.interner().mk_canonical_var_infos_from_iter(
298 (0..len).map::<CanonicalVarKind<'tcx>, _>(|_| Decodable::decode(decoder)),
299 )
300 }
301}
302
303impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AllocId {
304 fn decode(decoder: &mut D) -> Self {
305 decoder.decode_alloc_id()
306 }
307}
308
309impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CtfeProvenance {
310 fn decode(decoder: &mut D) -> Self {
311 let parts = Decodable::decode(decoder);
312 CtfeProvenance::from_parts(parts)
313 }
314}
315
316impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::SymbolName<'tcx> {
317 fn decode(decoder: &mut D) -> Self {
318 ty::SymbolName::new(decoder.interner(), decoder.read_str())
319 }
320}
321
322impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::ParamEnv<'tcx> {
323 fn decode(d: &mut D) -> Self {
324 let caller_bounds = Decodable::decode(d);
325 ty::ParamEnv::new(caller_bounds)
326 }
327}
328
329macro_rules! impl_decodable_via_ref {
330 ($($t:ty,)+) => {
331 $(impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for $t {
332 fn decode(decoder: &mut D) -> Self {
333 RefDecodable::decode(decoder)
334 }
335 })*
336 }
337}
338
339impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
340 fn decode(decoder: &mut D) -> &'tcx Self {
341 let len = decoder.read_usize();
342 decoder
343 .interner()
344 .mk_type_list_from_iter((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
345 }
346}
347
348impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
349 for ty::List<ty::PolyExistentialPredicate<'tcx>>
350{
351 fn decode(decoder: &mut D) -> &'tcx Self {
352 let len = decoder.read_usize();
353 decoder.interner().mk_poly_existential_predicates_from_iter(
354 (0..len).map::<ty::Binder<'tcx, _>, _>(|_| Decodable::decode(decoder)),
355 )
356 }
357}
358
359impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Const<'tcx> {
360 fn decode(decoder: &mut D) -> Self {
361 let kind: ty::ConstKind<'tcx> = Decodable::decode(decoder);
362 decoder.interner().mk_ct_from_kind(kind)
363 }
364}
365
366impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Pattern<'tcx> {
367 fn decode(decoder: &mut D) -> Self {
368 decoder.interner().mk_pat(Decodable::decode(decoder))
369 }
370}
371
372impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::ValTree<'tcx> {
373 fn decode(decoder: &mut D) -> Self {
374 decoder.interner().intern_valtree(Decodable::decode(decoder))
375 }
376}
377
378impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ConstAllocation<'tcx> {
379 fn decode(decoder: &mut D) -> Self {
380 decoder.interner().mk_const_alloc(Decodable::decode(decoder))
381 }
382}
383
384impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AdtDef<'tcx> {
385 fn decode(decoder: &mut D) -> Self {
386 decoder.interner().mk_adt_def_from_data(Decodable::decode(decoder))
387 }
388}
389
390impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Clause<'tcx>, Span)] {
391 fn decode(decoder: &mut D) -> &'tcx Self {
392 decoder
393 .interner()
394 .arena
395 .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
396 }
397}
398
399impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::PolyTraitRef<'tcx>, Span)] {
400 fn decode(decoder: &mut D) -> &'tcx Self {
401 decoder
402 .interner()
403 .arena
404 .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
405 }
406}
407
408impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [Spanned<MonoItem<'tcx>>] {
409 fn decode(decoder: &mut D) -> &'tcx Self {
410 decoder
411 .interner()
412 .arena
413 .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
414 }
415}
416
417impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::BoundVariableKind<'tcx>> {
418 fn decode(decoder: &mut D) -> &'tcx Self {
419 let len = decoder.read_usize();
420 decoder.interner().mk_bound_variable_kinds_from_iter(
421 (0..len).map::<ty::BoundVariableKind<'tcx>, _>(|_| Decodable::decode(decoder)),
422 )
423 }
424}
425
426impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::Pattern<'tcx>> {
427 fn decode(decoder: &mut D) -> &'tcx Self {
428 let len = decoder.read_usize();
429 decoder.interner().mk_patterns_from_iter(
430 (0..len).map::<ty::Pattern<'tcx>, _>(|_| Decodable::decode(decoder)),
431 )
432 }
433}
434
435impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::Const<'tcx>> {
436 fn decode(decoder: &mut D) -> &'tcx Self {
437 let len = decoder.read_usize();
438 decoder.interner().mk_const_list_from_iter(
439 (0..len).map::<ty::Const<'tcx>, _>(|_| Decodable::decode(decoder)),
440 )
441 }
442}
443
444impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
445 for ty::ListWithCachedTypeInfo<ty::Clause<'tcx>>
446{
447 fn decode(decoder: &mut D) -> &'tcx Self {
448 let len = decoder.read_usize();
449 decoder.interner().mk_clauses_from_iter(
450 (0..len).map::<ty::Clause<'tcx>, _>(|_| Decodable::decode(decoder)),
451 )
452 }
453}
454
455impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<FieldIdx> {
456 fn decode(decoder: &mut D) -> &'tcx Self {
457 let len = decoder.read_usize();
458 decoder
459 .interner()
460 .mk_fields_from_iter((0..len).map::<FieldIdx, _>(|_| Decodable::decode(decoder)))
461 }
462}
463
464impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<LocalDefId> {
465 fn decode(decoder: &mut D) -> &'tcx Self {
466 let len = decoder.read_usize();
467 decoder.interner().mk_local_def_ids_from_iter(
468 (0..len).map::<LocalDefId, _>(|_| Decodable::decode(decoder)),
469 )
470 }
471}
472
473impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for &'tcx ty::List<LocalDefId> {
474 fn decode(d: &mut D) -> Self {
475 RefDecodable::decode(d)
476 }
477}
478
479impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for &'tcx ty::List<Const<'tcx>> {
fn decode(decoder: &mut D) -> Self { RefDecodable::decode(decoder) }
}impl_decodable_via_ref! {
480 &'tcx ty::TypeckResults<'tcx>,
481 &'tcx ty::List<Ty<'tcx>>,
482 &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
483 &'tcx traits::ImplSource<'tcx, ()>,
484 &'tcx mir::Body<'tcx>,
485 &'tcx ty::List<ty::BoundVariableKind<'tcx>>,
486 &'tcx ty::List<ty::Pattern<'tcx>>,
487 &'tcx ty::ListWithCachedTypeInfo<ty::Clause<'tcx>>,
488 &'tcx ty::List<Const<'tcx>>,
489}
490
491#[macro_export]
492macro_rules! __impl_decoder_methods {
493 ($($name:ident -> $ty:ty;)*) => {
494 $(
495 #[inline]
496 fn $name(&mut self) -> $ty {
497 self.opaque.$name()
498 }
499 )*
500 }
501}
502
503macro_rules! impl_arena_allocatable_decoder {
504 ([] $name:ident: $ty:ty) => {};
505 ([decode] $name:ident: $ty:ty) => {
506 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
507 #[inline]
508 fn decode(decoder: &mut D) -> &'tcx Self {
509 decode_arena_allocable(decoder)
510 }
511 }
512
513 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
514 #[inline]
515 fn decode(decoder: &mut D) -> &'tcx Self {
516 decode_arena_allocable_slice(decoder)
517 }
518 }
519 };
520}
521
522macro_rules! impl_arena_allocatable_decoders {
523 ([$($a:tt $name:ident: $ty:ty,)*]) => {
524 $(
525 impl_arena_allocatable_decoder!($a $name: $ty);
526 )*
527 }
528}
529
530rustc_hir::arena_types!(impl_arena_allocatable_decoders);
531impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for
rustc_ast::tokenstream::TokenStream {
#[inline]
fn decode(decoder: &mut D) -> &'tcx Self {
decode_arena_allocable(decoder)
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for
[rustc_ast::tokenstream::TokenStream] {
#[inline]
fn decode(decoder: &mut D) -> &'tcx Self {
decode_arena_allocable_slice(decoder)
}
}arena_types!(impl_arena_allocatable_decoders);
532
533macro_rules! impl_arena_copy_decoder {
534 (<$tcx:tt> $($ty:ty,)*) => {
535 $(impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
536 #[inline]
537 fn decode(decoder: &mut D) -> &'tcx Self {
538 decoder.interner().arena.alloc(Decodable::decode(decoder))
539 }
540 }
541
542 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
543 #[inline]
544 fn decode(decoder: &mut D) -> &'tcx Self {
545 decoder.interner().arena.alloc_from_iter(<Vec<_> as Decodable<D>>::decode(decoder))
546 }
547 })*
548 };
549}
550
551impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for
rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs {
#[inline]
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.interner().arena.alloc(Decodable::decode(decoder))
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for
[rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs] {
#[inline]
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.interner().arena.alloc_from_iter(<Vec<_> as
Decodable<D>>::decode(decoder))
}
}impl_arena_copy_decoder! {<'tcx>
552 Span,
553 rustc_span::Ident,
554 ty::Variance,
555 rustc_span::def_id::DefId,
556 rustc_span::def_id::LocalDefId,
557 (rustc_middle::middle::exported_symbols::ExportedSymbol<'tcx>, rustc_middle::middle::exported_symbols::SymbolExportInfo),
558 rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs,
559}
560
561#[macro_export]
562macro_rules! implement_ty_decoder {
563 ($DecoderName:ident <$($typaram:tt),*>) => {
564 mod __ty_decoder_impl {
565 use rustc_serialize::Decoder;
566
567 use super::$DecoderName;
568
569 impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
570 $crate::__impl_decoder_methods! {
571 read_usize -> usize;
572 read_u128 -> u128;
573 read_u64 -> u64;
574 read_u32 -> u32;
575 read_u16 -> u16;
576 read_u8 -> u8;
577
578 read_isize -> isize;
579 read_i128 -> i128;
580 read_i64 -> i64;
581 read_i32 -> i32;
582 read_i16 -> i16;
583 }
584
585 #[inline]
586 fn read_raw_bytes(&mut self, len: usize) -> &[u8] {
587 self.opaque.read_raw_bytes(len)
588 }
589
590 #[inline]
591 fn peek_byte(&self) -> u8 {
592 self.opaque.peek_byte()
593 }
594
595 #[inline]
596 fn position(&self) -> usize {
597 self.opaque.position()
598 }
599 }
600 }
601 }
602}