rustc_type_ir/
codec.rs

1use rustc_data_structures::fx::FxHashMap;
2use rustc_span::{SpanDecoder, SpanEncoder};
3
4use crate::{Interner, PredicateKind};
5
6/// The shorthand encoding uses an enum's variant index `usize`
7/// and is offset by this value so it never matches a real variant.
8/// This offset is also chosen so that the first byte is never < 0x80.
9pub const SHORTHAND_OFFSET: usize = 0x80;
10
11/// Trait for decoding to a reference.
12///
13/// This is a separate trait from `Decodable` so that we can implement it for
14/// upstream types, such as `FxHashSet`.
15///
16/// The `TyDecodable` derive macro will use this trait for fields that are
17/// references (and don't use a type alias to hide that).
18///
19/// `Decodable` can still be implemented in cases where `Decodable` is required
20/// by a trait bound.
21pub trait RefDecodable<'tcx, D: TyDecoder> {
22    fn decode(d: &mut D) -> &'tcx Self;
23}
24
25pub trait TyEncoder: SpanEncoder {
26    type I: Interner;
27    const CLEAR_CROSS_CRATE: bool;
28
29    fn position(&self) -> usize;
30
31    fn type_shorthands(&mut self) -> &mut FxHashMap<<Self::I as Interner>::Ty, usize>;
32
33    fn predicate_shorthands(&mut self) -> &mut FxHashMap<PredicateKind<Self::I>, usize>;
34
35    fn encode_alloc_id(&mut self, alloc_id: &<Self::I as Interner>::AllocId);
36}
37
38pub trait TyDecoder: SpanDecoder {
39    type I: Interner;
40    const CLEAR_CROSS_CRATE: bool;
41
42    fn interner(&self) -> Self::I;
43
44    fn cached_ty_for_shorthand<F>(
45        &mut self,
46        shorthand: usize,
47        or_insert_with: F,
48    ) -> <Self::I as Interner>::Ty
49    where
50        F: FnOnce(&mut Self) -> <Self::I as Interner>::Ty;
51
52    fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
53    where
54        F: FnOnce(&mut Self) -> R;
55
56    fn positioned_at_shorthand(&self) -> bool {
57        (self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
58    }
59
60    fn decode_alloc_id(&mut self) -> <Self::I as Interner>::AllocId;
61}