]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | //! Support code for encoding and decoding types. |
2 | ||
3 | /* | |
4 | Core encoding and decoding interfaces. | |
5 | */ | |
6 | ||
f2b60f7d | 7 | use std::alloc::Allocator; |
c30ab7b3 | 8 | use std::borrow::Cow; |
dfeec247 | 9 | use std::cell::{Cell, RefCell}; |
0bf4aa26 | 10 | use std::marker::PhantomData; |
c34b1796 | 11 | use std::path; |
1a4d82fc | 12 | use std::rc::Rc; |
1a4d82fc JJ |
13 | use std::sync::Arc; |
14 | ||
923072b8 FG |
15 | /// A note about error handling. |
16 | /// | |
17 | /// Encoders may be fallible, but in practice failure is rare and there are so | |
18 | /// many nested calls that typical Rust error handling (via `Result` and `?`) | |
19 | /// is pervasive and has non-trivial cost. Instead, impls of this trait must | |
20 | /// implement a delayed error handling strategy. If a failure occurs, they | |
21 | /// should record this internally, and all subsequent encoding operations can | |
22 | /// be processed or ignored, whichever is appropriate. Then they should provide | |
23 | /// a `finish` method that finishes up encoding. If the encoder is fallible, | |
24 | /// `finish` should return a `Result` that indicates success or failure. | |
1a4d82fc | 25 | pub trait Encoder { |
1a4d82fc | 26 | // Primitive types: |
923072b8 FG |
27 | fn emit_usize(&mut self, v: usize); |
28 | fn emit_u128(&mut self, v: u128); | |
29 | fn emit_u64(&mut self, v: u64); | |
30 | fn emit_u32(&mut self, v: u32); | |
31 | fn emit_u16(&mut self, v: u16); | |
32 | fn emit_u8(&mut self, v: u8); | |
33 | fn emit_isize(&mut self, v: isize); | |
34 | fn emit_i128(&mut self, v: i128); | |
35 | fn emit_i64(&mut self, v: i64); | |
36 | fn emit_i32(&mut self, v: i32); | |
37 | fn emit_i16(&mut self, v: i16); | |
38 | fn emit_i8(&mut self, v: i8); | |
39 | fn emit_bool(&mut self, v: bool); | |
40 | fn emit_f64(&mut self, v: f64); | |
41 | fn emit_f32(&mut self, v: f32); | |
42 | fn emit_char(&mut self, v: char); | |
43 | fn emit_str(&mut self, v: &str); | |
44 | fn emit_raw_bytes(&mut self, s: &[u8]); | |
45 | ||
923072b8 | 46 | fn emit_enum_variant<F>(&mut self, v_id: usize, f: F) |
dfeec247 | 47 | where |
923072b8 | 48 | F: FnOnce(&mut Self), |
9e0c209e | 49 | { |
923072b8 FG |
50 | self.emit_usize(v_id); |
51 | f(self); | |
9e0c209e | 52 | } |
1a4d82fc JJ |
53 | } |
54 | ||
5099ac24 FG |
55 | // Note: all the methods in this trait are infallible, which may be surprising. |
56 | // They used to be fallible (i.e. return a `Result`) but many of the impls just | |
57 | // panicked when something went wrong, and for the cases that didn't the | |
58 | // top-level invocation would also just panic on failure. Switching to | |
59 | // infallibility made things faster and lots of code a little simpler and more | |
60 | // concise. | |
1a4d82fc | 61 | pub trait Decoder { |
1a4d82fc | 62 | // Primitive types: |
5099ac24 FG |
63 | fn read_usize(&mut self) -> usize; |
64 | fn read_u128(&mut self) -> u128; | |
65 | fn read_u64(&mut self) -> u64; | |
66 | fn read_u32(&mut self) -> u32; | |
67 | fn read_u16(&mut self) -> u16; | |
68 | fn read_u8(&mut self) -> u8; | |
69 | fn read_isize(&mut self) -> isize; | |
70 | fn read_i128(&mut self) -> i128; | |
71 | fn read_i64(&mut self) -> i64; | |
72 | fn read_i32(&mut self) -> i32; | |
73 | fn read_i16(&mut self) -> i16; | |
74 | fn read_i8(&mut self) -> i8; | |
75 | fn read_bool(&mut self) -> bool; | |
76 | fn read_f64(&mut self) -> f64; | |
77 | fn read_f32(&mut self) -> f32; | |
78 | fn read_char(&mut self) -> char; | |
5e7ed085 FG |
79 | fn read_str(&mut self) -> &str; |
80 | fn read_raw_bytes(&mut self, len: usize) -> &[u8]; | |
1a4d82fc JJ |
81 | } |
82 | ||
3dfed10e XL |
83 | /// Trait for types that can be serialized |
84 | /// | |
85 | /// This can be implemented using the `Encodable`, `TyEncodable` and | |
86 | /// `MetadataEncodable` macros. | |
87 | /// | |
88 | /// * `Encodable` should be used in crates that don't depend on | |
89 | /// `rustc_middle`. | |
90 | /// * `MetadataEncodable` is used in `rustc_metadata` for types that contain | |
91 | /// `rustc_metadata::rmeta::Lazy`. | |
92 | /// * `TyEncodable` should be used for types that are only serialized in crate | |
93 | /// metadata or the incremental cache. This is most types in `rustc_middle`. | |
94 | pub trait Encodable<S: Encoder> { | |
923072b8 | 95 | fn encode(&self, s: &mut S); |
1a4d82fc JJ |
96 | } |
97 | ||
3dfed10e XL |
98 | /// Trait for types that can be deserialized |
99 | /// | |
100 | /// This can be implemented using the `Decodable`, `TyDecodable` and | |
101 | /// `MetadataDecodable` macros. | |
102 | /// | |
103 | /// * `Decodable` should be used in crates that don't depend on | |
104 | /// `rustc_middle`. | |
105 | /// * `MetadataDecodable` is used in `rustc_metadata` for types that contain | |
106 | /// `rustc_metadata::rmeta::Lazy`. | |
107 | /// * `TyDecodable` should be used for types that are only serialized in crate | |
108 | /// metadata or the incremental cache. This is most types in `rustc_middle`. | |
109 | pub trait Decodable<D: Decoder>: Sized { | |
5099ac24 | 110 | fn decode(d: &mut D) -> Self; |
3dfed10e XL |
111 | } |
112 | ||
113 | macro_rules! direct_serialize_impls { | |
114 | ($($ty:ident $emit_method:ident $read_method:ident),*) => { | |
115 | $( | |
116 | impl<S: Encoder> Encodable<S> for $ty { | |
923072b8 FG |
117 | fn encode(&self, s: &mut S) { |
118 | s.$emit_method(*self); | |
3dfed10e XL |
119 | } |
120 | } | |
1a4d82fc | 121 | |
3dfed10e | 122 | impl<D: Decoder> Decodable<D> for $ty { |
5099ac24 | 123 | fn decode(d: &mut D) -> $ty { |
3dfed10e XL |
124 | d.$read_method() |
125 | } | |
126 | } | |
127 | )* | |
128 | } | |
129 | } | |
130 | ||
131 | direct_serialize_impls! { | |
132 | usize emit_usize read_usize, | |
133 | u8 emit_u8 read_u8, | |
134 | u16 emit_u16 read_u16, | |
135 | u32 emit_u32 read_u32, | |
136 | u64 emit_u64 read_u64, | |
137 | u128 emit_u128 read_u128, | |
923072b8 | 138 | |
3dfed10e XL |
139 | isize emit_isize read_isize, |
140 | i8 emit_i8 read_i8, | |
141 | i16 emit_i16 read_i16, | |
142 | i32 emit_i32 read_i32, | |
143 | i64 emit_i64 read_i64, | |
144 | i128 emit_i128 read_i128, | |
923072b8 | 145 | |
3dfed10e XL |
146 | f32 emit_f32 read_f32, |
147 | f64 emit_f64 read_f64, | |
148 | bool emit_bool read_bool, | |
149 | char emit_char read_char | |
150 | } | |
151 | ||
923072b8 FG |
152 | impl<S: Encoder, T: ?Sized> Encodable<S> for &T |
153 | where | |
154 | T: Encodable<S>, | |
155 | { | |
156 | fn encode(&self, s: &mut S) { | |
157 | (**self).encode(s) | |
158 | } | |
159 | } | |
160 | ||
c295e0f8 | 161 | impl<S: Encoder> Encodable<S> for ! { |
923072b8 FG |
162 | fn encode(&self, _s: &mut S) { |
163 | unreachable!(); | |
c295e0f8 XL |
164 | } |
165 | } | |
166 | ||
167 | impl<D: Decoder> Decodable<D> for ! { | |
5099ac24 | 168 | fn decode(_d: &mut D) -> ! { |
c295e0f8 XL |
169 | unreachable!() |
170 | } | |
171 | } | |
172 | ||
3dfed10e | 173 | impl<S: Encoder> Encodable<S> for ::std::num::NonZeroU32 { |
923072b8 FG |
174 | fn encode(&self, s: &mut S) { |
175 | s.emit_u32(self.get()); | |
b7449926 XL |
176 | } |
177 | } | |
178 | ||
3dfed10e | 179 | impl<D: Decoder> Decodable<D> for ::std::num::NonZeroU32 { |
5099ac24 FG |
180 | fn decode(d: &mut D) -> Self { |
181 | ::std::num::NonZeroU32::new(d.read_u32()).unwrap() | |
b7449926 XL |
182 | } |
183 | } | |
184 | ||
3dfed10e | 185 | impl<S: Encoder> Encodable<S> for str { |
923072b8 FG |
186 | fn encode(&self, s: &mut S) { |
187 | s.emit_str(self); | |
1a4d82fc JJ |
188 | } |
189 | } | |
190 | ||
3dfed10e | 191 | impl<S: Encoder> Encodable<S> for String { |
923072b8 FG |
192 | fn encode(&self, s: &mut S) { |
193 | s.emit_str(&self[..]); | |
1a4d82fc JJ |
194 | } |
195 | } | |
196 | ||
3dfed10e | 197 | impl<D: Decoder> Decodable<D> for String { |
5099ac24 | 198 | fn decode(d: &mut D) -> String { |
5e7ed085 | 199 | d.read_str().to_owned() |
1a4d82fc JJ |
200 | } |
201 | } | |
202 | ||
3dfed10e | 203 | impl<S: Encoder> Encodable<S> for () { |
923072b8 | 204 | fn encode(&self, _s: &mut S) {} |
1a4d82fc JJ |
205 | } |
206 | ||
3dfed10e | 207 | impl<D: Decoder> Decodable<D> for () { |
5e7ed085 | 208 | fn decode(_: &mut D) -> () {} |
1a4d82fc JJ |
209 | } |
210 | ||
3dfed10e | 211 | impl<S: Encoder, T> Encodable<S> for PhantomData<T> { |
923072b8 | 212 | fn encode(&self, _s: &mut S) {} |
0bf4aa26 XL |
213 | } |
214 | ||
3dfed10e | 215 | impl<D: Decoder, T> Decodable<D> for PhantomData<T> { |
5e7ed085 | 216 | fn decode(_: &mut D) -> PhantomData<T> { |
5099ac24 | 217 | PhantomData |
0bf4aa26 XL |
218 | } |
219 | } | |
220 | ||
f2b60f7d FG |
221 | impl<D: Decoder, A: Allocator + Default, T: Decodable<D>> Decodable<D> for Box<[T], A> { |
222 | fn decode(d: &mut D) -> Box<[T], A> { | |
223 | let v: Vec<T, A> = Decodable::decode(d); | |
5099ac24 | 224 | v.into_boxed_slice() |
1a4d82fc JJ |
225 | } |
226 | } | |
227 | ||
3dfed10e | 228 | impl<S: Encoder, T: Encodable<S>> Encodable<S> for Rc<T> { |
923072b8 FG |
229 | fn encode(&self, s: &mut S) { |
230 | (**self).encode(s); | |
1a4d82fc JJ |
231 | } |
232 | } | |
233 | ||
3dfed10e | 234 | impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<T> { |
5099ac24 FG |
235 | fn decode(d: &mut D) -> Rc<T> { |
236 | Rc::new(Decodable::decode(d)) | |
1a4d82fc JJ |
237 | } |
238 | } | |
239 | ||
3dfed10e | 240 | impl<S: Encoder, T: Encodable<S>> Encodable<S> for [T] { |
923072b8 FG |
241 | default fn encode(&self, s: &mut S) { |
242 | s.emit_usize(self.len()); | |
243 | for e in self.iter() { | |
244 | e.encode(s); | |
245 | } | |
1a4d82fc JJ |
246 | } |
247 | } | |
248 | ||
3dfed10e | 249 | impl<S: Encoder, T: Encodable<S>> Encodable<S> for Vec<T> { |
923072b8 | 250 | fn encode(&self, s: &mut S) { |
1b1a35ee | 251 | let slice: &[T] = self; |
923072b8 | 252 | slice.encode(s); |
1a4d82fc JJ |
253 | } |
254 | } | |
255 | ||
f2b60f7d FG |
256 | impl<D: Decoder, T: Decodable<D>, A: Allocator + Default> Decodable<D> for Vec<T, A> { |
257 | default fn decode(d: &mut D) -> Vec<T, A> { | |
5e7ed085 | 258 | let len = d.read_usize(); |
f2b60f7d | 259 | let allocator = A::default(); |
5e7ed085 FG |
260 | // SAFETY: we set the capacity in advance, only write elements, and |
261 | // only set the length at the end once the writing has succeeded. | |
f2b60f7d | 262 | let mut vec = Vec::with_capacity_in(len, allocator); |
5e7ed085 FG |
263 | unsafe { |
264 | let ptr: *mut T = vec.as_mut_ptr(); | |
265 | for i in 0..len { | |
f2b60f7d | 266 | std::ptr::write(ptr.add(i), Decodable::decode(d)); |
1a4d82fc | 267 | } |
5e7ed085 FG |
268 | vec.set_len(len); |
269 | } | |
270 | vec | |
1a4d82fc JJ |
271 | } |
272 | } | |
273 | ||
1b1a35ee | 274 | impl<S: Encoder, T: Encodable<S>, const N: usize> Encodable<S> for [T; N] { |
923072b8 | 275 | fn encode(&self, s: &mut S) { |
1b1a35ee | 276 | let slice: &[T] = self; |
923072b8 | 277 | slice.encode(s); |
ba9703b0 XL |
278 | } |
279 | } | |
280 | ||
1b1a35ee | 281 | impl<D: Decoder, const N: usize> Decodable<D> for [u8; N] { |
5099ac24 | 282 | fn decode(d: &mut D) -> [u8; N] { |
5e7ed085 FG |
283 | let len = d.read_usize(); |
284 | assert!(len == N); | |
285 | let mut v = [0u8; N]; | |
286 | for i in 0..len { | |
287 | v[i] = Decodable::decode(d); | |
288 | } | |
289 | v | |
ba9703b0 XL |
290 | } |
291 | } | |
292 | ||
3dfed10e | 293 | impl<'a, S: Encoder, T: Encodable<S>> Encodable<S> for Cow<'a, [T]> |
dfeec247 XL |
294 | where |
295 | [T]: ToOwned<Owned = Vec<T>>, | |
296 | { | |
923072b8 | 297 | fn encode(&self, s: &mut S) { |
1b1a35ee | 298 | let slice: &[T] = self; |
923072b8 | 299 | slice.encode(s); |
8bb4bdeb XL |
300 | } |
301 | } | |
302 | ||
3dfed10e | 303 | impl<D: Decoder, T: Decodable<D> + ToOwned> Decodable<D> for Cow<'static, [T]> |
dfeec247 XL |
304 | where |
305 | [T]: ToOwned<Owned = Vec<T>>, | |
8bb4bdeb | 306 | { |
5099ac24 FG |
307 | fn decode(d: &mut D) -> Cow<'static, [T]> { |
308 | let v: Vec<T> = Decodable::decode(d); | |
309 | Cow::Owned(v) | |
8bb4bdeb XL |
310 | } |
311 | } | |
312 | ||
04454e1e | 313 | impl<'a, S: Encoder> Encodable<S> for Cow<'a, str> { |
923072b8 | 314 | fn encode(&self, s: &mut S) { |
04454e1e FG |
315 | let val: &str = self; |
316 | val.encode(s) | |
317 | } | |
318 | } | |
319 | ||
320 | impl<'a, D: Decoder> Decodable<D> for Cow<'a, str> { | |
321 | fn decode(d: &mut D) -> Cow<'static, str> { | |
322 | let v: String = Decodable::decode(d); | |
323 | Cow::Owned(v) | |
324 | } | |
325 | } | |
326 | ||
3dfed10e | 327 | impl<S: Encoder, T: Encodable<S>> Encodable<S> for Option<T> { |
923072b8 FG |
328 | fn encode(&self, s: &mut S) { |
329 | match *self { | |
330 | None => s.emit_enum_variant(0, |_| {}), | |
331 | Some(ref v) => s.emit_enum_variant(1, |s| v.encode(s)), | |
332 | } | |
1a4d82fc JJ |
333 | } |
334 | } | |
335 | ||
3dfed10e | 336 | impl<D: Decoder, T: Decodable<D>> Decodable<D> for Option<T> { |
5099ac24 | 337 | fn decode(d: &mut D) -> Option<T> { |
5e7ed085 FG |
338 | match d.read_usize() { |
339 | 0 => None, | |
340 | 1 => Some(Decodable::decode(d)), | |
341 | _ => panic!("Encountered invalid discriminant while decoding `Option`."), | |
342 | } | |
ff7c6d11 XL |
343 | } |
344 | } | |
345 | ||
3dfed10e | 346 | impl<S: Encoder, T1: Encodable<S>, T2: Encodable<S>> Encodable<S> for Result<T1, T2> { |
923072b8 FG |
347 | fn encode(&self, s: &mut S) { |
348 | match *self { | |
349 | Ok(ref v) => s.emit_enum_variant(0, |s| v.encode(s)), | |
350 | Err(ref v) => s.emit_enum_variant(1, |s| v.encode(s)), | |
351 | } | |
ff7c6d11 XL |
352 | } |
353 | } | |
354 | ||
3dfed10e | 355 | impl<D: Decoder, T1: Decodable<D>, T2: Decodable<D>> Decodable<D> for Result<T1, T2> { |
5099ac24 | 356 | fn decode(d: &mut D) -> Result<T1, T2> { |
5e7ed085 FG |
357 | match d.read_usize() { |
358 | 0 => Ok(T1::decode(d)), | |
359 | 1 => Err(T2::decode(d)), | |
360 | _ => panic!("Encountered invalid discriminant while decoding `Result`."), | |
361 | } | |
1a4d82fc JJ |
362 | } |
363 | } | |
364 | ||
365 | macro_rules! peel { | |
366 | ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* }) | |
367 | } | |
368 | ||
1a4d82fc JJ |
369 | macro_rules! tuple { |
370 | () => (); | |
371 | ( $($name:ident,)+ ) => ( | |
3dfed10e | 372 | impl<D: Decoder, $($name: Decodable<D>),+> Decodable<D> for ($($name,)+) { |
5099ac24 | 373 | fn decode(d: &mut D) -> ($($name,)+) { |
5e7ed085 | 374 | ($({ let element: $name = Decodable::decode(d); element },)+) |
1a4d82fc JJ |
375 | } |
376 | } | |
3dfed10e | 377 | impl<S: Encoder, $($name: Encodable<S>),+> Encodable<S> for ($($name,)+) { |
1a4d82fc | 378 | #[allow(non_snake_case)] |
923072b8 | 379 | fn encode(&self, s: &mut S) { |
dc9dc135 | 380 | let ($(ref $name,)+) = *self; |
923072b8 | 381 | $($name.encode(s);)+ |
1a4d82fc JJ |
382 | } |
383 | } | |
dc9dc135 | 384 | peel! { $($name,)+ } |
1a4d82fc JJ |
385 | ) |
386 | } | |
387 | ||
388 | tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } | |
389 | ||
3dfed10e | 390 | impl<S: Encoder> Encodable<S> for path::Path { |
923072b8 FG |
391 | fn encode(&self, e: &mut S) { |
392 | self.to_str().unwrap().encode(e); | |
c34b1796 AL |
393 | } |
394 | } | |
395 | ||
3dfed10e | 396 | impl<S: Encoder> Encodable<S> for path::PathBuf { |
923072b8 FG |
397 | fn encode(&self, e: &mut S) { |
398 | path::Path::encode(self, e); | |
48663c56 XL |
399 | } |
400 | } | |
401 | ||
3dfed10e | 402 | impl<D: Decoder> Decodable<D> for path::PathBuf { |
5099ac24 FG |
403 | fn decode(d: &mut D) -> path::PathBuf { |
404 | let bytes: String = Decodable::decode(d); | |
405 | path::PathBuf::from(bytes) | |
c34b1796 AL |
406 | } |
407 | } | |
408 | ||
3dfed10e | 409 | impl<S: Encoder, T: Encodable<S> + Copy> Encodable<S> for Cell<T> { |
923072b8 FG |
410 | fn encode(&self, s: &mut S) { |
411 | self.get().encode(s); | |
1a4d82fc JJ |
412 | } |
413 | } | |
414 | ||
3dfed10e | 415 | impl<D: Decoder, T: Decodable<D> + Copy> Decodable<D> for Cell<T> { |
5099ac24 FG |
416 | fn decode(d: &mut D) -> Cell<T> { |
417 | Cell::new(Decodable::decode(d)) | |
1a4d82fc JJ |
418 | } |
419 | } | |
420 | ||
3dfed10e | 421 | impl<S: Encoder, T: Encodable<S>> Encodable<S> for RefCell<T> { |
923072b8 FG |
422 | fn encode(&self, s: &mut S) { |
423 | self.borrow().encode(s); | |
1a4d82fc JJ |
424 | } |
425 | } | |
426 | ||
3dfed10e | 427 | impl<D: Decoder, T: Decodable<D>> Decodable<D> for RefCell<T> { |
5099ac24 FG |
428 | fn decode(d: &mut D) -> RefCell<T> { |
429 | RefCell::new(Decodable::decode(d)) | |
1a4d82fc JJ |
430 | } |
431 | } | |
432 | ||
3dfed10e | 433 | impl<S: Encoder, T: Encodable<S>> Encodable<S> for Arc<T> { |
923072b8 FG |
434 | fn encode(&self, s: &mut S) { |
435 | (**self).encode(s); | |
1a4d82fc JJ |
436 | } |
437 | } | |
438 | ||
3dfed10e | 439 | impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<T> { |
5099ac24 FG |
440 | fn decode(d: &mut D) -> Arc<T> { |
441 | Arc::new(Decodable::decode(d)) | |
1a4d82fc JJ |
442 | } |
443 | } | |
444 | ||
f2b60f7d | 445 | impl<S: Encoder, T: ?Sized + Encodable<S>, A: Allocator + Default> Encodable<S> for Box<T, A> { |
923072b8 | 446 | fn encode(&self, s: &mut S) { |
f2b60f7d | 447 | (**self).encode(s) |
f035d41b XL |
448 | } |
449 | } | |
f2b60f7d FG |
450 | |
451 | impl<D: Decoder, A: Allocator + Default, T: Decodable<D>> Decodable<D> for Box<T, A> { | |
452 | fn decode(d: &mut D) -> Box<T, A> { | |
453 | let allocator = A::default(); | |
454 | Box::new_in(Decodable::decode(d), allocator) | |
f035d41b XL |
455 | } |
456 | } |