rustc_middle/ty/
codec.rs

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
9use std::hash::Hash;
10use std::intrinsics;
11use std::marker::{DiscriminantKind, PointeeSized};
12
13use rustc_abi::{FieldIdx, VariantIdx};
14use rustc_data_structures::fx::FxHashMap;
15use rustc_hir::def_id::LocalDefId;
16use rustc_serialize::{Decodable, Encodable};
17use rustc_span::source_map::Spanned;
18use rustc_span::{Span, SpanDecoder, SpanEncoder};
19
20use crate::arena::ArenaAllocatable;
21use crate::infer::canonical::{CanonicalVarKind, CanonicalVarKinds};
22use crate::mir::interpret::{AllocId, ConstAllocation, CtfeProvenance};
23use crate::mir::mono::MonoItem;
24use crate::mir::{self};
25use crate::traits;
26use crate::ty::{self, AdtDef, GenericArgsRef, Ty, TyCtxt};
27
28/// The shorthand encoding uses an enum's variant index `usize`
29/// and is offset by this value so it never matches a real variant.
30/// This offset is also chosen so that the first byte is never < 0x80.
31pub const SHORTHAND_OFFSET: usize = 0x80;
32
33pub trait TyEncoder<'tcx>: SpanEncoder {
34    const CLEAR_CROSS_CRATE: bool;
35
36    fn position(&self) -> usize;
37
38    fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize>;
39
40    fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::PredicateKind<'tcx>, usize>;
41
42    fn encode_alloc_id(&mut self, alloc_id: &AllocId);
43}
44
45pub trait TyDecoder<'tcx>: SpanDecoder {
46    const CLEAR_CROSS_CRATE: bool;
47
48    fn interner(&self) -> TyCtxt<'tcx>;
49
50    fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
51    where
52        F: FnOnce(&mut Self) -> Ty<'tcx>;
53
54    fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
55    where
56        F: FnOnce(&mut Self) -> R;
57
58    fn positioned_at_shorthand(&self) -> bool {
59        (self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
60    }
61
62    fn decode_alloc_id(&mut self) -> AllocId;
63}
64
65pub trait EncodableWithShorthand<'tcx, E: TyEncoder<'tcx>>: Copy + Eq + Hash {
66    type Variant: Encodable<E>;
67    fn variant(&self) -> &Self::Variant;
68}
69
70#[allow(rustc::usage_of_ty_tykind)]
71impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for Ty<'tcx> {
72    type Variant = ty::TyKind<'tcx>;
73
74    #[inline]
75    fn variant(&self) -> &Self::Variant {
76        self.kind()
77    }
78}
79
80impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::PredicateKind<'tcx> {
81    type Variant = ty::PredicateKind<'tcx>;
82
83    #[inline]
84    fn variant(&self) -> &Self::Variant {
85        self
86    }
87}
88
89/// Trait for decoding to a reference.
90///
91/// This is a separate trait from `Decodable` so that we can implement it for
92/// upstream types, such as `FxHashSet`.
93///
94/// The `TyDecodable` derive macro will use this trait for fields that are
95/// references (and don't use a type alias to hide that).
96///
97/// `Decodable` can still be implemented in cases where `Decodable` is required
98/// by a trait bound.
99pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>>: PointeeSized {
100    fn decode(d: &mut D) -> &'tcx Self;
101}
102
103/// Encode the given value or a previously cached shorthand.
104pub fn encode_with_shorthand<'tcx, E, T, M>(encoder: &mut E, value: &T, cache: M)
105where
106    E: TyEncoder<'tcx>,
107    M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<T, usize>,
108    T: EncodableWithShorthand<'tcx, E>,
109    // The discriminant and shorthand must have the same size.
110    T::Variant: DiscriminantKind<Discriminant = isize>,
111{
112    let existing_shorthand = cache(encoder).get(value).copied();
113    if let Some(shorthand) = existing_shorthand {
114        encoder.emit_usize(shorthand);
115        return;
116    }
117
118    let variant = value.variant();
119
120    let start = encoder.position();
121    variant.encode(encoder);
122    let len = encoder.position() - start;
123
124    // The shorthand encoding uses the same usize as the
125    // discriminant, with an offset so they can't conflict.
126    let discriminant = intrinsics::discriminant_value(variant);
127    assert!(SHORTHAND_OFFSET > discriminant as usize);
128
129    let shorthand = start + SHORTHAND_OFFSET;
130
131    // Get the number of bits that leb128 could fit
132    // in the same space as the fully encoded type.
133    let leb128_bits = len * 7;
134
135    // Check that the shorthand is a not longer than the
136    // full encoding itself, i.e., it's an obvious win.
137    if leb128_bits >= 64 || (shorthand as u64) < (1 << leb128_bits) {
138        cache(encoder).insert(*value, shorthand);
139    }
140}
141
142impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Ty<'tcx> {
143    fn encode(&self, e: &mut E) {
144        encode_with_shorthand(e, self, TyEncoder::type_shorthands);
145    }
146}
147
148impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
149    fn encode(&self, e: &mut E) {
150        let kind = self.kind();
151        kind.bound_vars().encode(e);
152        encode_with_shorthand(e, &kind.skip_binder(), TyEncoder::predicate_shorthands);
153    }
154}
155
156impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Clause<'tcx> {
157    fn encode(&self, e: &mut E) {
158        self.as_predicate().encode(e);
159    }
160}
161
162impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Region<'tcx> {
163    fn encode(&self, e: &mut E) {
164        self.kind().encode(e);
165    }
166}
167
168impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Const<'tcx> {
169    fn encode(&self, e: &mut E) {
170        self.0.0.encode(e);
171    }
172}
173
174impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Pattern<'tcx> {
175    fn encode(&self, e: &mut E) {
176        self.0.0.encode(e);
177    }
178}
179
180impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::ValTree<'tcx> {
181    fn encode(&self, e: &mut E) {
182        self.0.0.encode(e);
183    }
184}
185
186impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ConstAllocation<'tcx> {
187    fn encode(&self, e: &mut E) {
188        self.inner().encode(e)
189    }
190}
191
192impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AdtDef<'tcx> {
193    fn encode(&self, e: &mut E) {
194        self.0.0.encode(e)
195    }
196}
197
198impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
199    fn encode(&self, e: &mut E) {
200        e.encode_alloc_id(self)
201    }
202}
203
204impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for CtfeProvenance {
205    fn encode(&self, e: &mut E) {
206        self.into_parts().encode(e);
207    }
208}
209
210impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::ParamEnv<'tcx> {
211    fn encode(&self, e: &mut E) {
212        self.caller_bounds().encode(e);
213    }
214}
215
216#[inline]
217fn decode_arena_allocable<'tcx, D: TyDecoder<'tcx>, T: ArenaAllocatable<'tcx> + Decodable<D>>(
218    decoder: &mut D,
219) -> &'tcx T {
220    decoder.interner().arena.alloc(Decodable::decode(decoder))
221}
222
223#[inline]
224fn decode_arena_allocable_slice<
225    'tcx,
226    D: TyDecoder<'tcx>,
227    T: ArenaAllocatable<'tcx> + Decodable<D>,
228>(
229    decoder: &mut D,
230) -> &'tcx [T] {
231    decoder.interner().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder))
232}
233
234impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
235    #[allow(rustc::usage_of_ty_tykind)]
236    fn decode(decoder: &mut D) -> Ty<'tcx> {
237        // Handle shorthands first, if we have a usize > 0x80.
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.cached_ty_for_shorthand(shorthand, |decoder| {
244                decoder.with_position(shorthand, Ty::decode)
245            })
246        } else {
247            let tcx = decoder.interner();
248            tcx.mk_ty_from_kind(ty::TyKind::decode(decoder))
249        }
250    }
251}
252
253impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
254    fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
255        let bound_vars = Decodable::decode(decoder);
256        // Handle shorthands first, if we have a usize > 0x80.
257        let predicate_kind = ty::Binder::bind_with_vars(
258            if decoder.positioned_at_shorthand() {
259                let pos = decoder.read_usize();
260                assert!(pos >= SHORTHAND_OFFSET);
261                let shorthand = pos - SHORTHAND_OFFSET;
262
263                decoder.with_position(shorthand, <ty::PredicateKind<'tcx> as Decodable<D>>::decode)
264            } else {
265                <ty::PredicateKind<'tcx> as Decodable<D>>::decode(decoder)
266            },
267            bound_vars,
268        );
269        decoder.interner().mk_predicate(predicate_kind)
270    }
271}
272
273impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Clause<'tcx> {
274    fn decode(decoder: &mut D) -> ty::Clause<'tcx> {
275        let pred: ty::Predicate<'tcx> = Decodable::decode(decoder);
276        pred.expect_clause()
277    }
278}
279
280impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for GenericArgsRef<'tcx> {
281    fn decode(decoder: &mut D) -> Self {
282        let len = decoder.read_usize();
283        let tcx = decoder.interner();
284        tcx.mk_args_from_iter(
285            (0..len).map::<ty::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
286        )
287    }
288}
289
290impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for mir::Place<'tcx> {
291    fn decode(decoder: &mut D) -> Self {
292        let local: mir::Local = Decodable::decode(decoder);
293        let len = decoder.read_usize();
294        let projection = decoder.interner().mk_place_elems_from_iter(
295            (0..len).map::<mir::PlaceElem<'tcx>, _>(|_| Decodable::decode(decoder)),
296        );
297        mir::Place { local, projection }
298    }
299}
300
301impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Region<'tcx> {
302    fn decode(decoder: &mut D) -> Self {
303        ty::Region::new_from_kind(decoder.interner(), Decodable::decode(decoder))
304    }
305}
306
307impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarKinds<'tcx> {
308    fn decode(decoder: &mut D) -> Self {
309        let len = decoder.read_usize();
310        decoder.interner().mk_canonical_var_infos_from_iter(
311            (0..len).map::<CanonicalVarKind<'tcx>, _>(|_| Decodable::decode(decoder)),
312        )
313    }
314}
315
316impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AllocId {
317    fn decode(decoder: &mut D) -> Self {
318        decoder.decode_alloc_id()
319    }
320}
321
322impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CtfeProvenance {
323    fn decode(decoder: &mut D) -> Self {
324        let parts = Decodable::decode(decoder);
325        CtfeProvenance::from_parts(parts)
326    }
327}
328
329impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::SymbolName<'tcx> {
330    fn decode(decoder: &mut D) -> Self {
331        ty::SymbolName::new(decoder.interner(), decoder.read_str())
332    }
333}
334
335impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::ParamEnv<'tcx> {
336    fn decode(d: &mut D) -> Self {
337        let caller_bounds = Decodable::decode(d);
338        ty::ParamEnv::new(caller_bounds)
339    }
340}
341
342macro_rules! impl_decodable_via_ref {
343    ($($t:ty,)+) => {
344        $(impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for $t {
345            fn decode(decoder: &mut D) -> Self {
346                RefDecodable::decode(decoder)
347            }
348        })*
349    }
350}
351
352impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
353    fn decode(decoder: &mut D) -> &'tcx Self {
354        let len = decoder.read_usize();
355        decoder
356            .interner()
357            .mk_type_list_from_iter((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
358    }
359}
360
361impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
362    for ty::List<ty::PolyExistentialPredicate<'tcx>>
363{
364    fn decode(decoder: &mut D) -> &'tcx Self {
365        let len = decoder.read_usize();
366        decoder.interner().mk_poly_existential_predicates_from_iter(
367            (0..len).map::<ty::Binder<'tcx, _>, _>(|_| Decodable::decode(decoder)),
368        )
369    }
370}
371
372impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Const<'tcx> {
373    fn decode(decoder: &mut D) -> Self {
374        let kind: ty::ConstKind<'tcx> = Decodable::decode(decoder);
375        decoder.interner().mk_ct_from_kind(kind)
376    }
377}
378
379impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Pattern<'tcx> {
380    fn decode(decoder: &mut D) -> Self {
381        decoder.interner().mk_pat(Decodable::decode(decoder))
382    }
383}
384
385impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::ValTree<'tcx> {
386    fn decode(decoder: &mut D) -> Self {
387        decoder.interner().intern_valtree(Decodable::decode(decoder))
388    }
389}
390
391impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ConstAllocation<'tcx> {
392    fn decode(decoder: &mut D) -> Self {
393        decoder.interner().mk_const_alloc(Decodable::decode(decoder))
394    }
395}
396
397impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AdtDef<'tcx> {
398    fn decode(decoder: &mut D) -> Self {
399        decoder.interner().mk_adt_def_from_data(Decodable::decode(decoder))
400    }
401}
402
403impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Clause<'tcx>, Span)] {
404    fn decode(decoder: &mut D) -> &'tcx Self {
405        decoder
406            .interner()
407            .arena
408            .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
409    }
410}
411
412impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::PolyTraitRef<'tcx>, Span)] {
413    fn decode(decoder: &mut D) -> &'tcx Self {
414        decoder
415            .interner()
416            .arena
417            .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
418    }
419}
420
421impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [Spanned<MonoItem<'tcx>>] {
422    fn decode(decoder: &mut D) -> &'tcx Self {
423        decoder
424            .interner()
425            .arena
426            .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
427    }
428}
429
430impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::BoundVariableKind> {
431    fn decode(decoder: &mut D) -> &'tcx Self {
432        let len = decoder.read_usize();
433        decoder.interner().mk_bound_variable_kinds_from_iter(
434            (0..len).map::<ty::BoundVariableKind, _>(|_| Decodable::decode(decoder)),
435        )
436    }
437}
438
439impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::Pattern<'tcx>> {
440    fn decode(decoder: &mut D) -> &'tcx Self {
441        let len = decoder.read_usize();
442        decoder.interner().mk_patterns_from_iter(
443            (0..len).map::<ty::Pattern<'tcx>, _>(|_| Decodable::decode(decoder)),
444        )
445    }
446}
447
448impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::Const<'tcx>> {
449    fn decode(decoder: &mut D) -> &'tcx Self {
450        let len = decoder.read_usize();
451        decoder.interner().mk_const_list_from_iter(
452            (0..len).map::<ty::Const<'tcx>, _>(|_| Decodable::decode(decoder)),
453        )
454    }
455}
456
457impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
458    for ty::ListWithCachedTypeInfo<ty::Clause<'tcx>>
459{
460    fn decode(decoder: &mut D) -> &'tcx Self {
461        let len = decoder.read_usize();
462        decoder.interner().mk_clauses_from_iter(
463            (0..len).map::<ty::Clause<'tcx>, _>(|_| Decodable::decode(decoder)),
464        )
465    }
466}
467
468impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<FieldIdx> {
469    fn decode(decoder: &mut D) -> &'tcx Self {
470        let len = decoder.read_usize();
471        decoder
472            .interner()
473            .mk_fields_from_iter((0..len).map::<FieldIdx, _>(|_| Decodable::decode(decoder)))
474    }
475}
476
477impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<LocalDefId> {
478    fn decode(decoder: &mut D) -> &'tcx Self {
479        let len = decoder.read_usize();
480        decoder.interner().mk_local_def_ids_from_iter(
481            (0..len).map::<LocalDefId, _>(|_| Decodable::decode(decoder)),
482        )
483    }
484}
485
486impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for &'tcx ty::List<LocalDefId> {
487    fn decode(d: &mut D) -> Self {
488        RefDecodable::decode(d)
489    }
490}
491
492impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<(VariantIdx, FieldIdx)> {
493    fn decode(decoder: &mut D) -> &'tcx Self {
494        let len = decoder.read_usize();
495        decoder.interner().mk_offset_of_from_iter(
496            (0..len).map::<(VariantIdx, FieldIdx), _>(|_| Decodable::decode(decoder)),
497        )
498    }
499}
500
501impl_decodable_via_ref! {
502    &'tcx ty::TypeckResults<'tcx>,
503    &'tcx ty::List<Ty<'tcx>>,
504    &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
505    &'tcx traits::ImplSource<'tcx, ()>,
506    &'tcx mir::Body<'tcx>,
507    &'tcx ty::List<ty::BoundVariableKind>,
508    &'tcx ty::List<ty::Pattern<'tcx>>,
509    &'tcx ty::ListWithCachedTypeInfo<ty::Clause<'tcx>>,
510}
511
512#[macro_export]
513macro_rules! __impl_decoder_methods {
514    ($($name:ident -> $ty:ty;)*) => {
515        $(
516            #[inline]
517            fn $name(&mut self) -> $ty {
518                self.opaque.$name()
519            }
520        )*
521    }
522}
523
524macro_rules! impl_arena_allocatable_decoder {
525    ([]$args:tt) => {};
526    ([decode $(, $attrs:ident)*]
527     [$name:ident: $ty:ty]) => {
528        impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
529            #[inline]
530            fn decode(decoder: &mut D) -> &'tcx Self {
531                decode_arena_allocable(decoder)
532            }
533        }
534
535        impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
536            #[inline]
537            fn decode(decoder: &mut D) -> &'tcx Self {
538                decode_arena_allocable_slice(decoder)
539            }
540        }
541    };
542}
543
544macro_rules! impl_arena_allocatable_decoders {
545    ([$($a:tt $name:ident: $ty:ty,)*]) => {
546        $(
547            impl_arena_allocatable_decoder!($a [$name: $ty]);
548        )*
549    }
550}
551
552rustc_hir::arena_types!(impl_arena_allocatable_decoders);
553arena_types!(impl_arena_allocatable_decoders);
554
555macro_rules! impl_arena_copy_decoder {
556    (<$tcx:tt> $($ty:ty,)*) => {
557        $(impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
558            #[inline]
559            fn decode(decoder: &mut D) -> &'tcx Self {
560                decoder.interner().arena.alloc(Decodable::decode(decoder))
561            }
562        }
563
564        impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
565            #[inline]
566            fn decode(decoder: &mut D) -> &'tcx Self {
567                decoder.interner().arena.alloc_from_iter(<Vec<_> as Decodable<D>>::decode(decoder))
568            }
569        })*
570    };
571}
572
573impl_arena_copy_decoder! {<'tcx>
574    Span,
575    rustc_span::Ident,
576    ty::Variance,
577    rustc_span::def_id::DefId,
578    rustc_span::def_id::LocalDefId,
579    (rustc_middle::middle::exported_symbols::ExportedSymbol<'tcx>, rustc_middle::middle::exported_symbols::SymbolExportInfo),
580    ty::DeducedParamAttrs,
581}
582
583#[macro_export]
584macro_rules! implement_ty_decoder {
585    ($DecoderName:ident <$($typaram:tt),*>) => {
586        mod __ty_decoder_impl {
587            use rustc_serialize::Decoder;
588
589            use super::$DecoderName;
590
591            impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
592                $crate::__impl_decoder_methods! {
593                    read_usize -> usize;
594                    read_u128 -> u128;
595                    read_u64 -> u64;
596                    read_u32 -> u32;
597                    read_u16 -> u16;
598                    read_u8 -> u8;
599
600                    read_isize -> isize;
601                    read_i128 -> i128;
602                    read_i64 -> i64;
603                    read_i32 -> i32;
604                    read_i16 -> i16;
605                }
606
607                #[inline]
608                fn read_raw_bytes(&mut self, len: usize) -> &[u8] {
609                    self.opaque.read_raw_bytes(len)
610                }
611
612                #[inline]
613                fn peek_byte(&self) -> u8 {
614                    self.opaque.peek_byte()
615                }
616
617                #[inline]
618                fn position(&self) -> usize {
619                    self.opaque.position()
620                }
621            }
622        }
623    }
624}