]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/ty/codec.rs
New upstream version 1.62.1+dfsg1
[rustc.git] / compiler / rustc_middle / src / ty / codec.rs
CommitLineData
c295e0f8
XL
1//! This module contains some shared code for encoding and decoding various
2//! things from the `ty` module, and in particular implements support for
3//! "shorthands" which allow to have pointers back into the already encoded
4//! stream instead of re-encoding the same thing twice.
5//!
6//! The functionality in here is shared between persisting to crate metadata and
7//! persisting to incr. comp. caches.
abe05a73 8
48663c56 9use crate::arena::ArenaAllocatable;
9fa01778 10use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
3dfed10e
XL
11use crate::mir::{
12 self,
5e7ed085 13 interpret::{AllocId, ConstAllocation},
3dfed10e 14};
c295e0f8 15use crate::thir;
5099ac24 16use crate::traits;
dfeec247 17use crate::ty::subst::SubstsRef;
5e7ed085 18use crate::ty::{self, AdtDef, Ty, TyCtxt};
abe05a73 19use rustc_data_structures::fx::FxHashMap;
3dfed10e 20use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
dfeec247 21use rustc_span::Span;
abe05a73
XL
22use std::hash::Hash;
23use std::intrinsics;
f9f354fc 24use std::marker::DiscriminantKind;
abe05a73
XL
25
26/// The shorthand encoding uses an enum's variant index `usize`
27/// and is offset by this value so it never matches a real variant.
28/// This offset is also chosen so that the first byte is never < 0x80.
29pub const SHORTHAND_OFFSET: usize = 0x80;
30
3dfed10e
XL
31pub trait EncodableWithShorthand<'tcx, E: TyEncoder<'tcx>>: Copy + Eq + Hash {
32 type Variant: Encodable<E>;
abe05a73
XL
33 fn variant(&self) -> &Self::Variant;
34}
35
e1599b0c 36#[allow(rustc::usage_of_ty_tykind)]
3dfed10e 37impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for Ty<'tcx> {
b7449926 38 type Variant = ty::TyKind<'tcx>;
1b1a35ee
XL
39
40 #[inline]
abe05a73 41 fn variant(&self) -> &Self::Variant {
1b1a35ee 42 self.kind()
abe05a73
XL
43 }
44}
45
5869c6ff 46impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::PredicateKind<'tcx> {
f9f354fc 47 type Variant = ty::PredicateKind<'tcx>;
abe05a73 48
3dfed10e 49 #[inline]
5869c6ff 50 fn variant(&self) -> &Self::Variant {
3dfed10e
XL
51 self
52 }
abe05a73
XL
53}
54
3dfed10e
XL
55pub trait TyEncoder<'tcx>: Encoder {
56 const CLEAR_CROSS_CRATE: bool;
57
3dfed10e
XL
58 fn position(&self) -> usize;
59 fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize>;
5869c6ff 60 fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::PredicateKind<'tcx>, usize>;
3dfed10e
XL
61 fn encode_alloc_id(&mut self, alloc_id: &AllocId) -> Result<(), Self::Error>;
62}
63
64/// Trait for decoding to a reference.
65///
66/// This is a separate trait from `Decodable` so that we can implement it for
67/// upstream types, such as `FxHashSet`.
68///
69/// The `TyDecodable` derive macro will use this trait for fields that are
70/// references (and don't use a type alias to hide that).
71///
72/// `Decodable` can still be implemented in cases where `Decodable` is required
73/// by a trait bound.
74pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>> {
5099ac24 75 fn decode(d: &mut D) -> &'tcx Self;
3dfed10e
XL
76}
77
abe05a73 78/// Encode the given value or a previously cached shorthand.
a2a8927a
XL
79pub fn encode_with_shorthand<'tcx, E, T, M>(
80 encoder: &mut E,
81 value: &T,
82 cache: M,
83) -> Result<(), E::Error>
dfeec247 84where
3dfed10e 85 E: TyEncoder<'tcx>,
dfeec247 86 M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<T, usize>,
3dfed10e 87 T: EncodableWithShorthand<'tcx, E>,
5869c6ff
XL
88 // The discriminant and shorthand must have the same size.
89 T::Variant: DiscriminantKind<Discriminant = isize>,
abe05a73 90{
3dfed10e 91 let existing_shorthand = cache(encoder).get(value).copied();
abe05a73
XL
92 if let Some(shorthand) = existing_shorthand {
93 return encoder.emit_usize(shorthand);
94 }
95
96 let variant = value.variant();
97
98 let start = encoder.position();
99 variant.encode(encoder)?;
100 let len = encoder.position() - start;
101
102 // The shorthand encoding uses the same usize as the
103 // discriminant, with an offset so they can't conflict.
60c5eb7d 104 let discriminant = intrinsics::discriminant_value(variant);
5869c6ff 105 assert!(SHORTHAND_OFFSET > discriminant as usize);
f9f354fc 106
abe05a73
XL
107 let shorthand = start + SHORTHAND_OFFSET;
108
109 // Get the number of bits that leb128 could fit
110 // in the same space as the fully encoded type.
111 let leb128_bits = len * 7;
112
113 // Check that the shorthand is a not longer than the
0731742a 114 // full encoding itself, i.e., it's an obvious win.
abe05a73 115 if leb128_bits >= 64 || (shorthand as u64) < (1 << leb128_bits) {
3dfed10e 116 cache(encoder).insert(*value, shorthand);
abe05a73
XL
117 }
118
119 Ok(())
120}
121
3dfed10e
XL
122impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Ty<'tcx> {
123 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
124 encode_with_shorthand(e, self, TyEncoder::type_shorthands)
125 }
126}
127
cdc7bbd5 128impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
5869c6ff 129 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
cdc7bbd5 130 self.bound_vars().encode(e)?;
5869c6ff
XL
131 encode_with_shorthand(e, &self.skip_binder(), TyEncoder::predicate_shorthands)
132 }
133}
134
3dfed10e
XL
135impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
136 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
5869c6ff 137 self.kind().encode(e)
3dfed10e
XL
138 }
139}
140
5099ac24
FG
141impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Region<'tcx> {
142 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
143 self.kind().encode(e)
144 }
145}
146
147impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Const<'tcx> {
148 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
149 self.0.0.encode(e)
150 }
151}
152
5e7ed085
FG
153impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ConstAllocation<'tcx> {
154 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
155 self.inner().encode(e)
156 }
157}
158
159impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AdtDef<'tcx> {
160 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
161 self.0.0.encode(e)
162 }
163}
164
3dfed10e
XL
165impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
166 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
167 e.encode_alloc_id(self)
168 }
169}
170
171macro_rules! encodable_via_deref {
172 ($($t:ty),+) => {
173 $(impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for $t {
174 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
175 (**self).encode(e)
176 }
177 })*
178 }
179}
180
181encodable_via_deref! {
182 &'tcx ty::TypeckResults<'tcx>,
5099ac24 183 &'tcx traits::ImplSource<'tcx, ()>,
3dfed10e
XL
184 &'tcx mir::Body<'tcx>,
185 &'tcx mir::UnsafetyCheckResult,
fc512014 186 &'tcx mir::BorrowCheckResult<'tcx>,
5e7ed085 187 &'tcx mir::coverage::CodeRegion
3dfed10e
XL
188}
189
dc9dc135 190pub trait TyDecoder<'tcx>: Decoder {
3dfed10e
XL
191 const CLEAR_CROSS_CRATE: bool;
192
dc9dc135 193 fn tcx(&self) -> TyCtxt<'tcx>;
abe05a73
XL
194
195 fn peek_byte(&self) -> u8;
196
197 fn position(&self) -> usize;
198
5099ac24 199 fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
dfeec247 200 where
5099ac24 201 F: FnOnce(&mut Self) -> Ty<'tcx>;
abe05a73
XL
202
203 fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
dfeec247
XL
204 where
205 F: FnOnce(&mut Self) -> R;
abe05a73 206
abe05a73
XL
207 fn positioned_at_shorthand(&self) -> bool {
208 (self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
209 }
3dfed10e 210
5099ac24 211 fn decode_alloc_id(&mut self) -> AllocId;
abe05a73
XL
212}
213
48663c56 214#[inline]
cdc7bbd5 215fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
dc9dc135 216 decoder: &mut D,
5099ac24 217) -> &'tcx T
dc9dc135
XL
218where
219 D: TyDecoder<'tcx>,
48663c56 220{
5099ac24 221 decoder.tcx().arena.alloc(Decodable::decode(decoder))
48663c56
XL
222}
223
224#[inline]
cdc7bbd5 225fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
dc9dc135 226 decoder: &mut D,
5099ac24 227) -> &'tcx [T]
dc9dc135
XL
228where
229 D: TyDecoder<'tcx>,
48663c56 230{
5099ac24 231 decoder.tcx().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder))
48663c56
XL
232}
233
3dfed10e
XL
234impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
235 #[allow(rustc::usage_of_ty_tykind)]
5099ac24 236 fn decode(decoder: &mut D) -> Ty<'tcx> {
94222f64 237 // Handle shorthands first, if we have a usize > 0x80.
3dfed10e 238 if decoder.positioned_at_shorthand() {
5099ac24 239 let pos = decoder.read_usize();
3dfed10e
XL
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.tcx();
5099ac24 248 tcx.mk_ty(ty::TyKind::decode(decoder))
3dfed10e
XL
249 }
250 }
abe05a73
XL
251}
252
cdc7bbd5 253impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
5099ac24
FG
254 fn decode(decoder: &mut D) -> ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
255 let bound_vars = Decodable::decode(decoder);
94222f64 256 // Handle shorthands first, if we have a usize > 0x80.
5099ac24 257 ty::Binder::bind_with_vars(
cdc7bbd5 258 if decoder.positioned_at_shorthand() {
5099ac24 259 let pos = decoder.read_usize();
cdc7bbd5
XL
260 assert!(pos >= SHORTHAND_OFFSET);
261 let shorthand = pos - SHORTHAND_OFFSET;
262
5099ac24 263 decoder.with_position(shorthand, ty::PredicateKind::decode)
cdc7bbd5 264 } else {
5099ac24 265 ty::PredicateKind::decode(decoder)
cdc7bbd5
XL
266 },
267 bound_vars,
5099ac24 268 )
5869c6ff
XL
269 }
270}
271
272impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
5099ac24
FG
273 fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
274 let predicate_kind = Decodable::decode(decoder);
275 decoder.tcx().mk_predicate(predicate_kind)
abe05a73
XL
276 }
277}
278
3dfed10e 279impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for SubstsRef<'tcx> {
5099ac24
FG
280 fn decode(decoder: &mut D) -> Self {
281 let len = decoder.read_usize();
f035d41b 282 let tcx = decoder.tcx();
5099ac24
FG
283 tcx.mk_substs(
284 (0..len).map::<ty::subst::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
285 )
f035d41b
XL
286 }
287}
288
3dfed10e 289impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for mir::Place<'tcx> {
5099ac24
FG
290 fn decode(decoder: &mut D) -> Self {
291 let local: mir::Local = Decodable::decode(decoder);
292 let len = decoder.read_usize();
293 let projection = decoder.tcx().mk_place_elems(
294 (0..len).map::<mir::PlaceElem<'tcx>, _>(|_| Decodable::decode(decoder)),
295 );
296 mir::Place { local, projection }
3dfed10e 297 }
abe05a73
XL
298}
299
3dfed10e 300impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Region<'tcx> {
5099ac24
FG
301 fn decode(decoder: &mut D) -> Self {
302 decoder.tcx().mk_region(Decodable::decode(decoder))
3dfed10e 303 }
abe05a73
XL
304}
305
3dfed10e 306impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarInfos<'tcx> {
5099ac24
FG
307 fn decode(decoder: &mut D) -> Self {
308 let len = decoder.read_usize();
309 let interned: Vec<CanonicalVarInfo<'tcx>> =
3dfed10e 310 (0..len).map(|_| Decodable::decode(decoder)).collect();
5099ac24 311 decoder.tcx().intern_canonical_var_infos(interned.as_slice())
3dfed10e 312 }
e74abb32
XL
313}
314
3dfed10e 315impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AllocId {
5099ac24 316 fn decode(decoder: &mut D) -> Self {
3dfed10e
XL
317 decoder.decode_alloc_id()
318 }
abe05a73
XL
319}
320
3dfed10e 321impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::SymbolName<'tcx> {
5099ac24
FG
322 fn decode(decoder: &mut D) -> Self {
323 ty::SymbolName::new(decoder.tcx(), &decoder.read_str())
3dfed10e 324 }
abe05a73
XL
325}
326
3dfed10e
XL
327macro_rules! impl_decodable_via_ref {
328 ($($t:ty),+) => {
329 $(impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for $t {
5099ac24 330 fn decode(decoder: &mut D) -> Self {
3dfed10e
XL
331 RefDecodable::decode(decoder)
332 }
333 })*
334 }
abe05a73
XL
335}
336
3dfed10e 337impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
5099ac24
FG
338 fn decode(decoder: &mut D) -> &'tcx Self {
339 let len = decoder.read_usize();
340 decoder.tcx().mk_type_list((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
3dfed10e 341 }
abe05a73
XL
342}
343
fc512014 344impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
cdc7bbd5 345 for ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>
fc512014 346{
5099ac24
FG
347 fn decode(decoder: &mut D) -> &'tcx Self {
348 let len = decoder.read_usize();
349 decoder.tcx().mk_poly_existential_predicates(
350 (0..len).map::<ty::Binder<'tcx, _>, _>(|_| Decodable::decode(decoder)),
351 )
3dfed10e 352 }
abe05a73
XL
353}
354
5099ac24
FG
355impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Const<'tcx> {
356 fn decode(decoder: &mut D) -> Self {
357 decoder.tcx().mk_const(Decodable::decode(decoder))
3dfed10e
XL
358 }
359}
360
6a06907d 361impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] {
5099ac24
FG
362 fn decode(decoder: &mut D) -> &'tcx Self {
363 decoder.tcx().arena.alloc_from_iter(
364 (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
365 )
6a06907d
XL
366 }
367}
368
5e7ed085
FG
369impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ConstAllocation<'tcx> {
370 fn decode(decoder: &mut D) -> Self {
5099ac24 371 decoder.tcx().intern_const_alloc(Decodable::decode(decoder))
3dfed10e
XL
372 }
373}
374
5e7ed085
FG
375impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AdtDef<'tcx> {
376 fn decode(decoder: &mut D) -> Self {
377 decoder.tcx().intern_adt_def(Decodable::decode(decoder))
378 }
379}
380
3dfed10e 381impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, Span)] {
5099ac24
FG
382 fn decode(decoder: &mut D) -> &'tcx Self {
383 decoder.tcx().arena.alloc_from_iter(
384 (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
385 )
1b1a35ee
XL
386 }
387}
388
c295e0f8 389impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::Node<'tcx>] {
5099ac24
FG
390 fn decode(decoder: &mut D) -> &'tcx Self {
391 decoder.tcx().arena.alloc_from_iter(
392 (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
393 )
1b1a35ee
XL
394 }
395}
396
c295e0f8 397impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::NodeId] {
5099ac24
FG
398 fn decode(decoder: &mut D) -> &'tcx Self {
399 decoder.tcx().arena.alloc_from_iter(
400 (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
401 )
3dfed10e
XL
402 }
403}
404
cdc7bbd5 405impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::BoundVariableKind> {
5099ac24
FG
406 fn decode(decoder: &mut D) -> &'tcx Self {
407 let len = decoder.read_usize();
408 decoder.tcx().mk_bound_variable_kinds(
409 (0..len).map::<ty::BoundVariableKind, _>(|_| Decodable::decode(decoder)),
410 )
cdc7bbd5
XL
411 }
412}
413
3dfed10e
XL
414impl_decodable_via_ref! {
415 &'tcx ty::TypeckResults<'tcx>,
416 &'tcx ty::List<Ty<'tcx>>,
cdc7bbd5 417 &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
5099ac24 418 &'tcx traits::ImplSource<'tcx, ()>,
3dfed10e
XL
419 &'tcx mir::Body<'tcx>,
420 &'tcx mir::UnsafetyCheckResult,
fc512014 421 &'tcx mir::BorrowCheckResult<'tcx>,
cdc7bbd5 422 &'tcx mir::coverage::CodeRegion,
5e7ed085 423 &'tcx ty::List<ty::BoundVariableKind>
94b46f34
XL
424}
425
abe05a73
XL
426#[macro_export]
427macro_rules! __impl_decoder_methods {
428 ($($name:ident -> $ty:ty;)*) => {
e1599b0c 429 $(
74b04a01 430 #[inline]
5099ac24 431 fn $name(&mut self) -> $ty {
e1599b0c
XL
432 self.opaque.$name()
433 }
434 )*
abe05a73
XL
435 }
436}
437
48663c56
XL
438macro_rules! impl_arena_allocatable_decoder {
439 ([]$args:tt) => {};
440 ([decode $(, $attrs:ident)*]
3c0e092e
XL
441 [$name:ident: $ty:ty]) => {
442 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
48663c56 443 #[inline]
5099ac24 444 fn decode(decoder: &mut D) -> &'tcx Self {
3dfed10e 445 decode_arena_allocable(decoder)
48663c56
XL
446 }
447 }
448
3c0e092e 449 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
48663c56 450 #[inline]
5099ac24 451 fn decode(decoder: &mut D) -> &'tcx Self {
3dfed10e 452 decode_arena_allocable_slice(decoder)
48663c56
XL
453 }
454 }
455 };
48663c56
XL
456}
457
48663c56 458macro_rules! impl_arena_allocatable_decoders {
3c0e092e 459 ([$($a:tt $name:ident: $ty:ty,)*]) => {
48663c56 460 $(
3c0e092e 461 impl_arena_allocatable_decoder!($a [$name: $ty]);
48663c56
XL
462 )*
463 }
464}
465
3c0e092e
XL
466rustc_hir::arena_types!(impl_arena_allocatable_decoders);
467arena_types!(impl_arena_allocatable_decoders);
3dfed10e 468
abe05a73
XL
469#[macro_export]
470macro_rules! implement_ty_decoder {
471 ($DecoderName:ident <$($typaram:tt),*>) => {
472 mod __ty_decoder_impl {
e1599b0c 473 use std::borrow::Cow;
3dfed10e 474 use rustc_serialize::Decoder;
e74abb32 475
e1599b0c 476 use super::$DecoderName;
abe05a73
XL
477
478 impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
3dfed10e 479 $crate::__impl_decoder_methods! {
abe05a73
XL
480 read_u128 -> u128;
481 read_u64 -> u64;
482 read_u32 -> u32;
483 read_u16 -> u16;
484 read_u8 -> u8;
485 read_usize -> usize;
486
487 read_i128 -> i128;
488 read_i64 -> i64;
489 read_i32 -> i32;
490 read_i16 -> i16;
491 read_i8 -> i8;
492 read_isize -> isize;
493
494 read_bool -> bool;
495 read_f64 -> f64;
496 read_f32 -> f32;
497 read_char -> char;
5e7ed085 498 read_str -> &str;
abe05a73
XL
499 }
500
cdc7bbd5 501 #[inline]
5e7ed085
FG
502 fn read_raw_bytes(&mut self, len: usize) -> &[u8] {
503 self.opaque.read_raw_bytes(len)
cdc7bbd5 504 }
abe05a73 505 }
abe05a73 506 }
3dfed10e 507 }
abe05a73 508}
5869c6ff
XL
509
510macro_rules! impl_binder_encode_decode {
511 ($($t:ty),+ $(,)?) => {
512 $(
cdc7bbd5 513 impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<'tcx, $t> {
5869c6ff 514 fn encode(&self, e: &mut E) -> Result<(), E::Error> {
cdc7bbd5 515 self.bound_vars().encode(e)?;
5869c6ff
XL
516 self.as_ref().skip_binder().encode(e)
517 }
518 }
cdc7bbd5 519 impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, $t> {
5099ac24
FG
520 fn decode(decoder: &mut D) -> Self {
521 let bound_vars = Decodable::decode(decoder);
522 ty::Binder::bind_with_vars(Decodable::decode(decoder), bound_vars)
5869c6ff
XL
523 }
524 }
525 )*
526 }
527}
528
529impl_binder_encode_decode! {
530 &'tcx ty::List<Ty<'tcx>>,
531 ty::FnSig<'tcx>,
532 ty::ExistentialPredicate<'tcx>,
533 ty::TraitRef<'tcx>,
534 Vec<ty::GeneratorInteriorTypeCause<'tcx>>,
535}