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