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