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