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