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