]>
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; |
3dfed10e | 19 | use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; |
dfeec247 | 20 | use rustc_span::Span; |
abe05a73 XL |
21 | use std::hash::Hash; |
22 | use std::intrinsics; | |
f9f354fc | 23 | use 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. | |
28 | pub const SHORTHAND_OFFSET: usize = 0x80; | |
29 | ||
3dfed10e XL |
30 | pub 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 | 36 | impl<'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 | 45 | impl<'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 |
54 | pub 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. | |
73 | pub 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 |
78 | pub fn encode_with_shorthand<'tcx, E, T, M>( |
79 | encoder: &mut E, | |
80 | value: &T, | |
81 | cache: M, | |
82 | ) -> Result<(), E::Error> | |
dfeec247 | 83 | where |
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 |
121 | impl<'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 | 127 | impl<'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 |
134 | impl<'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 | ||
140 | impl<'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 | ||
146 | macro_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 | ||
156 | encodable_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 | 166 | pub 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 | 195 | fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>( |
dc9dc135 | 196 | decoder: &mut D, |
48663c56 | 197 | ) -> Result<&'tcx T, D::Error> |
dc9dc135 XL |
198 | where |
199 | D: TyDecoder<'tcx>, | |
48663c56 XL |
200 | { |
201 | Ok(decoder.tcx().arena.alloc(Decodable::decode(decoder)?)) | |
202 | } | |
203 | ||
204 | #[inline] | |
cdc7bbd5 | 205 | fn 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 |
208 | where |
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 |
214 | impl<'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 |
233 | impl<'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 | ||
252 | impl<'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 |
260 | impl<'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 |
268 | impl<'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 |
278 | impl<'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 |
284 | impl<'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 |
293 | impl<'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 |
299 | impl<'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 |
305 | macro_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 |
315 | impl<'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 | 322 | impl<'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 |
331 | impl<'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 |
337 | impl<'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 |
347 | impl<'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 | ||
353 | impl<'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 | 363 | impl<'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 | 373 | impl<'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 |
383 | impl<'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 |
390 | impl_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] |
404 | macro_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 |
415 | macro_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 | 438 | macro_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 |
446 | rustc_hir::arena_types!(impl_arena_allocatable_decoders); |
447 | arena_types!(impl_arena_allocatable_decoders); | |
3dfed10e | 448 | |
abe05a73 XL |
449 | #[macro_export] |
450 | macro_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 | |
498 | macro_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 | ||
517 | impl_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 | } |