]>
Commit | Line | Data |
---|---|---|
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 | 9 | use crate::arena::ArenaAllocatable; |
9fa01778 | 10 | use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; |
3dfed10e XL |
11 | use crate::mir::{ |
12 | self, | |
5e7ed085 | 13 | interpret::{AllocId, ConstAllocation}, |
3dfed10e | 14 | }; |
c295e0f8 | 15 | use crate::thir; |
5099ac24 | 16 | use crate::traits; |
dfeec247 | 17 | use crate::ty::subst::SubstsRef; |
5e7ed085 | 18 | use crate::ty::{self, AdtDef, Ty, TyCtxt}; |
abe05a73 | 19 | use rustc_data_structures::fx::FxHashMap; |
3dfed10e | 20 | use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; |
dfeec247 | 21 | use rustc_span::Span; |
abe05a73 XL |
22 | use std::hash::Hash; |
23 | use std::intrinsics; | |
f9f354fc | 24 | use 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. | |
29 | pub const SHORTHAND_OFFSET: usize = 0x80; | |
30 | ||
3dfed10e XL |
31 | pub 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 | 37 | impl<'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 | 46 | impl<'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 |
55 | pub 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. | |
74 | pub 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 |
79 | pub fn encode_with_shorthand<'tcx, E, T, M>( |
80 | encoder: &mut E, | |
81 | value: &T, | |
82 | cache: M, | |
83 | ) -> Result<(), E::Error> | |
dfeec247 | 84 | where |
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 |
122 | impl<'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 | 128 | impl<'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 |
135 | impl<'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 |
141 | impl<'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 | ||
147 | impl<'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 |
153 | impl<'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 | ||
159 | impl<'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 |
165 | impl<'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 | ||
171 | macro_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 | ||
181 | encodable_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 | 190 | pub 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 | 215 | fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>( |
dc9dc135 | 216 | decoder: &mut D, |
5099ac24 | 217 | ) -> &'tcx T |
dc9dc135 XL |
218 | where |
219 | D: TyDecoder<'tcx>, | |
48663c56 | 220 | { |
5099ac24 | 221 | decoder.tcx().arena.alloc(Decodable::decode(decoder)) |
48663c56 XL |
222 | } |
223 | ||
224 | #[inline] | |
cdc7bbd5 | 225 | fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>( |
dc9dc135 | 226 | decoder: &mut D, |
5099ac24 | 227 | ) -> &'tcx [T] |
dc9dc135 XL |
228 | where |
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 |
234 | impl<'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 | 253 | impl<'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 | ||
272 | impl<'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 | 279 | impl<'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 | 289 | impl<'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 | 300 | impl<'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 | 306 | impl<'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 | 315 | impl<'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 | 321 | impl<'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 |
327 | macro_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 | 337 | impl<'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 | 344 | impl<'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 |
355 | impl<'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 | 361 | impl<'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 |
369 | impl<'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 |
375 | impl<'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 | 381 | impl<'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 | 389 | impl<'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 | 397 | impl<'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 | 405 | impl<'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 |
414 | impl_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] |
427 | macro_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 |
438 | macro_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 | 458 | macro_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 |
466 | rustc_hir::arena_types!(impl_arena_allocatable_decoders); |
467 | arena_types!(impl_arena_allocatable_decoders); | |
3dfed10e | 468 | |
abe05a73 XL |
469 | #[macro_export] |
470 | macro_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 | |
510 | macro_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 | ||
529 | impl_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 | } |