1use rustc_hir::def::CtorOf;
2use rustc_index::Idx;
3
4use crate::rmeta::decoder::Metadata;
5use crate::rmeta::*;
6
7pub(super) trait IsDefault: Default {
8 fn is_default(&self) -> bool;
9}
10
11impl<T> IsDefault for Option<T> {
12 fn is_default(&self) -> bool {
13 self.is_none()
14 }
15}
16
17impl IsDefault for AttrFlags {
18 fn is_default(&self) -> bool {
19 self.is_empty()
20 }
21}
22
23impl IsDefault for bool {
24 fn is_default(&self) -> bool {
25 !self
26 }
27}
28
29impl IsDefault for u32 {
30 fn is_default(&self) -> bool {
31 *self == 0
32 }
33}
34
35impl IsDefault for u64 {
36 fn is_default(&self) -> bool {
37 *self == 0
38 }
39}
40
41impl<T> IsDefault for LazyArray<T> {
42 fn is_default(&self) -> bool {
43 self.num_elems == 0
44 }
45}
46
47pub(super) trait FixedSizeEncoding: IsDefault {
54 type ByteArray;
57
58 fn from_bytes(b: &Self::ByteArray) -> Self;
59 fn write_to_bytes(self, b: &mut Self::ByteArray);
60}
61
62impl FixedSizeEncoding for u64 {
63 type ByteArray = [u8; 8];
64
65 #[inline]
66 fn from_bytes(b: &[u8; 8]) -> Self {
67 Self::from_le_bytes(*b)
68 }
69
70 #[inline]
71 fn write_to_bytes(self, b: &mut [u8; 8]) {
72 *b = self.to_le_bytes();
73 }
74}
75
76macro_rules! fixed_size_enum {
77 ($ty:ty { $(($($pat:tt)*))* } $( unreachable { $(($($upat:tt)*))+ } )?) => {
78 impl FixedSizeEncoding for Option<$ty> {
79 type ByteArray = [u8;1];
80
81 #[inline]
82 fn from_bytes(b: &[u8;1]) -> Self {
83 use $ty::*;
84 if b[0] == 0 {
85 return None;
86 }
87 match b[0] - 1 {
88 $(${index()} => Some($($pat)*),)*
89 _ => panic!("Unexpected {} code: {:?}", stringify!($ty), b[0]),
90 }
91 }
92
93 #[inline]
94 fn write_to_bytes(self, b: &mut [u8;1]) {
95 use $ty::*;
96 b[0] = match self {
97 None => unreachable!(),
98 $(Some($($pat)*) => 1 + ${index()},)*
99 $(Some($($($upat)*)|+) => unreachable!(),)?
100 }
101 }
102 }
103 }
104}
105
106macro_rules! defaulted_enum {
107 ($ty:ty { $(($($pat:tt)*))* } $( unreachable { $(($($upat:tt)*))+ } )?) => {
108 impl FixedSizeEncoding for $ty {
109 type ByteArray = [u8; 1];
110
111 #[inline]
112 fn from_bytes(b: &[u8; 1]) -> Self {
113 use $ty::*;
114 let val = match b[0] {
115 $(${index()} => $($pat)*,)*
116 _ => panic!("Unexpected {} code: {:?}", stringify!($ty), b[0]),
117 };
118 debug_assert_ne!((b[0] != 0), IsDefault::is_default(&val));
121 val
122 }
123
124 #[inline]
125 fn write_to_bytes(self, b: &mut [u8; 1]) {
126 debug_assert!(!IsDefault::is_default(&self));
127 use $ty::*;
128 b[0] = match self {
129 $($($pat)* => ${index()},)*
130 $($($($upat)*)|+ => unreachable!(),)?
131 };
132 debug_assert_ne!(b[0], 0);
133 }
134 }
135 impl IsDefault for $ty {
136 fn is_default(&self) -> bool {
137 <$ty as Default>::default() == *self
138 }
139 }
140 }
141}
142
143macro_rules! const_macro_kinds {
145 ($($name:ident),+$(,)?) => (MacroKinds::from_bits_truncate($(MacroKinds::$name.bits())|+))
146}
147const MACRO_KINDS_ATTR_BANG: MacroKinds = MacroKinds::from_bits_truncate(MacroKinds::ATTR.bits() |
MacroKinds::BANG.bits())const_macro_kinds!(ATTR, BANG);
148const MACRO_KINDS_DERIVE_BANG: MacroKinds = MacroKinds::from_bits_truncate(MacroKinds::DERIVE.bits() |
MacroKinds::BANG.bits())const_macro_kinds!(DERIVE, BANG);
149const MACRO_KINDS_DERIVE_ATTR: MacroKinds = MacroKinds::from_bits_truncate(MacroKinds::DERIVE.bits() |
MacroKinds::ATTR.bits())const_macro_kinds!(DERIVE, ATTR);
150const MACRO_KINDS_DERIVE_ATTR_BANG: MacroKinds = MacroKinds::from_bits_truncate(MacroKinds::DERIVE.bits() |
MacroKinds::ATTR.bits() | MacroKinds::BANG.bits())const_macro_kinds!(DERIVE, ATTR, BANG);
151const _: () = if !MACRO_KINDS_DERIVE_ATTR_BANG.is_all() {
::core::panicking::panic("assertion failed: MACRO_KINDS_DERIVE_ATTR_BANG.is_all()")
}assert!(MACRO_KINDS_DERIVE_ATTR_BANG.is_all());
153
154impl FixedSizeEncoding for Option<DefKind> {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
use DefKind::*;
if b[0] == 0 { return None; }
match b[0] - 1 {
0 => Some(Mod),
1 => Some(Struct),
2 => Some(Union),
3 => Some(Enum),
4 => Some(Variant),
5 => Some(Trait),
6 => Some(TyAlias),
7 => Some(ForeignTy),
8 => Some(TraitAlias),
9 => Some(AssocTy),
10 => Some(TyParam),
11 => Some(Fn),
12 => Some(Const { is_type_const: true }),
13 => Some(Const { is_type_const: false }),
14 => Some(ConstParam),
15 => Some(AssocFn),
16 => Some(AssocConst { is_type_const: true }),
17 => Some(AssocConst { is_type_const: false }),
18 => Some(ExternCrate),
19 => Some(Use),
20 => Some(ForeignMod),
21 => Some(AnonConst),
22 => Some(InlineConst),
23 => Some(OpaqueTy),
24 => Some(Field),
25 => Some(LifetimeParam),
26 => Some(GlobalAsm),
27 => Some(Impl { of_trait: false }),
28 => Some(Impl { of_trait: true }),
29 => Some(Closure),
30 =>
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Not,
nested: false,
}),
31 =>
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Not,
nested: false,
}),
32 =>
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Mut,
nested: false,
}),
33 =>
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Mut,
nested: false,
}),
34 =>
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Not,
nested: true,
}),
35 =>
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Not,
nested: true,
}),
36 =>
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Mut,
nested: true,
}),
37 =>
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Mut,
nested: true,
}),
38 => Some(Ctor(CtorOf::Struct, CtorKind::Fn)),
39 => Some(Ctor(CtorOf::Struct, CtorKind::Const)),
40 => Some(Ctor(CtorOf::Variant, CtorKind::Fn)),
41 => Some(Ctor(CtorOf::Variant, CtorKind::Const)),
42 => Some(Macro(MacroKinds::BANG)),
43 => Some(Macro(MacroKinds::ATTR)),
44 => Some(Macro(MacroKinds::DERIVE)),
45 => Some(Macro(MACRO_KINDS_ATTR_BANG)),
46 => Some(Macro(MACRO_KINDS_DERIVE_ATTR)),
47 => Some(Macro(MACRO_KINDS_DERIVE_BANG)),
48 => Some(Macro(MACRO_KINDS_DERIVE_ATTR_BANG)),
49 => Some(SyntheticCoroutineBody),
_ => {
::core::panicking::panic_fmt(format_args!("Unexpected {0} code: {1:?}",
"DefKind", b[0]));
}
}
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
use DefKind::*;
b[0] =
match self {
None =>
::core::panicking::panic("internal error: entered unreachable code"),
Some(Mod) => 1 + 0,
Some(Struct) => 1 + 1,
Some(Union) => 1 + 2,
Some(Enum) => 1 + 3,
Some(Variant) => 1 + 4,
Some(Trait) => 1 + 5,
Some(TyAlias) => 1 + 6,
Some(ForeignTy) => 1 + 7,
Some(TraitAlias) => 1 + 8,
Some(AssocTy) => 1 + 9,
Some(TyParam) => 1 + 10,
Some(Fn) => 1 + 11,
Some(Const { is_type_const: true }) => 1 + 12,
Some(Const { is_type_const: false }) => 1 + 13,
Some(ConstParam) => 1 + 14,
Some(AssocFn) => 1 + 15,
Some(AssocConst { is_type_const: true }) => 1 + 16,
Some(AssocConst { is_type_const: false }) => 1 + 17,
Some(ExternCrate) => 1 + 18,
Some(Use) => 1 + 19,
Some(ForeignMod) => 1 + 20,
Some(AnonConst) => 1 + 21,
Some(InlineConst) => 1 + 22,
Some(OpaqueTy) => 1 + 23,
Some(Field) => 1 + 24,
Some(LifetimeParam) => 1 + 25,
Some(GlobalAsm) => 1 + 26,
Some(Impl { of_trait: false }) => 1 + 27,
Some(Impl { of_trait: true }) => 1 + 28,
Some(Closure) => 1 + 29,
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Not,
nested: false }) => 1 + 30,
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Not,
nested: false }) => 1 + 31,
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Mut,
nested: false }) => 1 + 32,
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Mut,
nested: false }) => 1 + 33,
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Not,
nested: true }) => 1 + 34,
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Not,
nested: true }) => 1 + 35,
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Mut,
nested: true }) => 1 + 36,
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Mut,
nested: true }) => 1 + 37,
Some(Ctor(CtorOf::Struct, CtorKind::Fn)) => 1 + 38,
Some(Ctor(CtorOf::Struct, CtorKind::Const)) => 1 + 39,
Some(Ctor(CtorOf::Variant, CtorKind::Fn)) => 1 + 40,
Some(Ctor(CtorOf::Variant, CtorKind::Const)) => 1 + 41,
Some(Macro(MacroKinds::BANG)) => 1 + 42,
Some(Macro(MacroKinds::ATTR)) => 1 + 43,
Some(Macro(MacroKinds::DERIVE)) => 1 + 44,
Some(Macro(MACRO_KINDS_ATTR_BANG)) => 1 + 45,
Some(Macro(MACRO_KINDS_DERIVE_ATTR)) => 1 + 46,
Some(Macro(MACRO_KINDS_DERIVE_BANG)) => 1 + 47,
Some(Macro(MACRO_KINDS_DERIVE_ATTR_BANG)) => 1 + 48,
Some(SyntheticCoroutineBody) => 1 + 49,
Some(Macro(_)) =>
::core::panicking::panic("internal error: entered unreachable code"),
}
}
}fixed_size_enum! {
155 DefKind {
156 ( Mod )
157 ( Struct )
158 ( Union )
159 ( Enum )
160 ( Variant )
161 ( Trait )
162 ( TyAlias )
163 ( ForeignTy )
164 ( TraitAlias )
165 ( AssocTy )
166 ( TyParam )
167 ( Fn )
168 ( Const { is_type_const: true} )
169 ( Const { is_type_const: false} )
170 ( ConstParam )
171 ( AssocFn )
172 ( AssocConst { is_type_const:true } )
173 ( AssocConst { is_type_const:false } )
174 ( ExternCrate )
175 ( Use )
176 ( ForeignMod )
177 ( AnonConst )
178 ( InlineConst )
179 ( OpaqueTy )
180 ( Field )
181 ( LifetimeParam )
182 ( GlobalAsm )
183 ( Impl { of_trait: false } )
184 ( Impl { of_trait: true } )
185 ( Closure )
186 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: false } )
187 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: false } )
188 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: false } )
189 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: false } )
190 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: true } )
191 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: true } )
192 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: true } )
193 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: true } )
194 ( Ctor(CtorOf::Struct, CtorKind::Fn) )
195 ( Ctor(CtorOf::Struct, CtorKind::Const) )
196 ( Ctor(CtorOf::Variant, CtorKind::Fn) )
197 ( Ctor(CtorOf::Variant, CtorKind::Const) )
198 ( Macro(MacroKinds::BANG) )
199 ( Macro(MacroKinds::ATTR) )
200 ( Macro(MacroKinds::DERIVE) )
201 ( Macro(MACRO_KINDS_ATTR_BANG) )
202 ( Macro(MACRO_KINDS_DERIVE_ATTR) )
203 ( Macro(MACRO_KINDS_DERIVE_BANG) )
204 ( Macro(MACRO_KINDS_DERIVE_ATTR_BANG) )
205 ( SyntheticCoroutineBody )
206 } unreachable {
207 ( Macro(_) )
208 }
209}
210
211impl FixedSizeEncoding for hir::Defaultness {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
use hir::Defaultness::*;
let val =
match b[0] {
0 => Final,
1 => Default { has_value: false },
2 => Default { has_value: true },
_ => {
::core::panicking::panic_fmt(format_args!("Unexpected {0} code: {1:?}",
"hir::Defaultness", b[0]));
}
};
if true {
match (&(b[0] != 0), &IsDefault::is_default(&val)) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};
val
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
if true {
if !!IsDefault::is_default(&self) {
::core::panicking::panic("assertion failed: !IsDefault::is_default(&self)")
};
};
use hir::Defaultness::*;
b[0] =
match self {
Final => 0,
Default { has_value: false } => 1,
Default { has_value: true } => 2,
};
if true {
match (&b[0], &0) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};
}
}
impl IsDefault for hir::Defaultness {
fn is_default(&self) -> bool {
<hir::Defaultness as Default>::default() == *self
}
}defaulted_enum! {
212 hir::Defaultness {
213 ( Final )
214 ( Default { has_value: false } )
215 ( Default { has_value: true } )
216 }
217}
218
219impl FixedSizeEncoding for ty::Asyncness {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
use ty::Asyncness::*;
let val =
match b[0] {
0 => No,
1 => Yes,
_ => {
::core::panicking::panic_fmt(format_args!("Unexpected {0} code: {1:?}",
"ty::Asyncness", b[0]));
}
};
if true {
match (&(b[0] != 0), &IsDefault::is_default(&val)) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};
val
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
if true {
if !!IsDefault::is_default(&self) {
::core::panicking::panic("assertion failed: !IsDefault::is_default(&self)")
};
};
use ty::Asyncness::*;
b[0] = match self { No => 0, Yes => 1, };
if true {
match (&b[0], &0) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};
}
}
impl IsDefault for ty::Asyncness {
fn is_default(&self) -> bool {
<ty::Asyncness as Default>::default() == *self
}
}defaulted_enum! {
220 ty::Asyncness {
221 ( No )
222 ( Yes )
223 }
224}
225
226impl FixedSizeEncoding for hir::Constness {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
use hir::Constness::*;
let val =
match b[0] {
0 => Const,
1 => NotConst,
_ => {
::core::panicking::panic_fmt(format_args!("Unexpected {0} code: {1:?}",
"hir::Constness", b[0]));
}
};
if true {
match (&(b[0] != 0), &IsDefault::is_default(&val)) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};
val
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
if true {
if !!IsDefault::is_default(&self) {
::core::panicking::panic("assertion failed: !IsDefault::is_default(&self)")
};
};
use hir::Constness::*;
b[0] = match self { Const => 0, NotConst => 1, };
if true {
match (&b[0], &0) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};
}
}
impl IsDefault for hir::Constness {
fn is_default(&self) -> bool {
<hir::Constness as Default>::default() == *self
}
}defaulted_enum! {
227 hir::Constness {
228 ( Const )
229 ( NotConst )
230 }
231}
232
233impl FixedSizeEncoding for hir::Safety {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
use hir::Safety::*;
let val =
match b[0] {
0 => Unsafe,
1 => Safe,
_ => {
::core::panicking::panic_fmt(format_args!("Unexpected {0} code: {1:?}",
"hir::Safety", b[0]));
}
};
if true {
match (&(b[0] != 0), &IsDefault::is_default(&val)) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};
val
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
if true {
if !!IsDefault::is_default(&self) {
::core::panicking::panic("assertion failed: !IsDefault::is_default(&self)")
};
};
use hir::Safety::*;
b[0] = match self { Unsafe => 0, Safe => 1, };
if true {
match (&b[0], &0) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};
}
}
impl IsDefault for hir::Safety {
fn is_default(&self) -> bool {
<hir::Safety as Default>::default() == *self
}
}defaulted_enum! {
234 hir::Safety {
235 ( Unsafe )
236 ( Safe )
237 }
238}
239
240impl FixedSizeEncoding for Option<hir::CoroutineKind> {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
use hir::CoroutineKind::*;
if b[0] == 0 { return None; }
match b[0] - 1 {
0 => Some(Coroutine(hir::Movability::Movable)),
1 => Some(Coroutine(hir::Movability::Static)),
2 =>
Some(Desugared(hir::CoroutineDesugaring::Gen,
hir::CoroutineSource::Block)),
3 =>
Some(Desugared(hir::CoroutineDesugaring::Gen,
hir::CoroutineSource::Fn)),
4 =>
Some(Desugared(hir::CoroutineDesugaring::Gen,
hir::CoroutineSource::Closure)),
5 =>
Some(Desugared(hir::CoroutineDesugaring::Async,
hir::CoroutineSource::Block)),
6 =>
Some(Desugared(hir::CoroutineDesugaring::Async,
hir::CoroutineSource::Fn)),
7 =>
Some(Desugared(hir::CoroutineDesugaring::Async,
hir::CoroutineSource::Closure)),
8 =>
Some(Desugared(hir::CoroutineDesugaring::AsyncGen,
hir::CoroutineSource::Block)),
9 =>
Some(Desugared(hir::CoroutineDesugaring::AsyncGen,
hir::CoroutineSource::Fn)),
10 =>
Some(Desugared(hir::CoroutineDesugaring::AsyncGen,
hir::CoroutineSource::Closure)),
_ => {
::core::panicking::panic_fmt(format_args!("Unexpected {0} code: {1:?}",
"hir::CoroutineKind", b[0]));
}
}
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
use hir::CoroutineKind::*;
b[0] =
match self {
None =>
::core::panicking::panic("internal error: entered unreachable code"),
Some(Coroutine(hir::Movability::Movable)) => 1 + 0,
Some(Coroutine(hir::Movability::Static)) => 1 + 1,
Some(Desugared(hir::CoroutineDesugaring::Gen,
hir::CoroutineSource::Block)) => 1 + 2,
Some(Desugared(hir::CoroutineDesugaring::Gen,
hir::CoroutineSource::Fn)) => 1 + 3,
Some(Desugared(hir::CoroutineDesugaring::Gen,
hir::CoroutineSource::Closure)) => 1 + 4,
Some(Desugared(hir::CoroutineDesugaring::Async,
hir::CoroutineSource::Block)) => 1 + 5,
Some(Desugared(hir::CoroutineDesugaring::Async,
hir::CoroutineSource::Fn)) => 1 + 6,
Some(Desugared(hir::CoroutineDesugaring::Async,
hir::CoroutineSource::Closure)) => 1 + 7,
Some(Desugared(hir::CoroutineDesugaring::AsyncGen,
hir::CoroutineSource::Block)) => 1 + 8,
Some(Desugared(hir::CoroutineDesugaring::AsyncGen,
hir::CoroutineSource::Fn)) => 1 + 9,
Some(Desugared(hir::CoroutineDesugaring::AsyncGen,
hir::CoroutineSource::Closure)) => 1 + 10,
}
}
}fixed_size_enum! {
241 hir::CoroutineKind {
242 ( Coroutine(hir::Movability::Movable) )
243 ( Coroutine(hir::Movability::Static) )
244 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Block) )
245 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Fn) )
246 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Closure) )
247 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Block) )
248 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Fn) )
249 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Closure) )
250 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Block) )
251 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Fn) )
252 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Closure) )
253 }
254}
255
256impl FixedSizeEncoding for Option<MacroKind> {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
use MacroKind::*;
if b[0] == 0 { return None; }
match b[0] - 1 {
0 => Some(Attr),
1 => Some(Bang),
2 => Some(Derive),
_ => {
::core::panicking::panic_fmt(format_args!("Unexpected {0} code: {1:?}",
"MacroKind", b[0]));
}
}
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
use MacroKind::*;
b[0] =
match self {
None =>
::core::panicking::panic("internal error: entered unreachable code"),
Some(Attr) => 1 + 0,
Some(Bang) => 1 + 1,
Some(Derive) => 1 + 2,
}
}
}fixed_size_enum! {
257 MacroKind {
258 ( Attr )
259 ( Bang )
260 ( Derive )
261 }
262}
263
264impl FixedSizeEncoding for Option<RawDefId> {
266 type ByteArray = [u8; 8];
267
268 #[inline]
269 fn from_bytes(encoded: &[u8; 8]) -> Self {
270 let (index, krate) = decode_interleaved(encoded);
271 let krate = u32::from_le_bytes(krate);
272 if krate == 0 {
273 return None;
274 }
275 let index = u32::from_le_bytes(index);
276
277 Some(RawDefId { krate: krate - 1, index })
278 }
279
280 #[inline]
281 fn write_to_bytes(self, dest: &mut [u8; 8]) {
282 match self {
283 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
284 Some(RawDefId { krate, index }) => {
285 if true {
if !(krate < u32::MAX) {
::core::panicking::panic("assertion failed: krate < u32::MAX")
};
};debug_assert!(krate < u32::MAX);
286 let krate = (krate + 1).to_le_bytes();
288 let index = index.to_le_bytes();
289
290 encode_interleaved(index, krate, dest);
293 }
294 }
295 }
296}
297
298impl FixedSizeEncoding for AttrFlags {
299 type ByteArray = [u8; 1];
300
301 #[inline]
302 fn from_bytes(b: &[u8; 1]) -> Self {
303 AttrFlags::from_bits_truncate(b[0])
304 }
305
306 #[inline]
307 fn write_to_bytes(self, b: &mut [u8; 1]) {
308 if true {
if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};
};debug_assert!(!self.is_default());
309 b[0] = self.bits();
310 }
311}
312
313impl FixedSizeEncoding for bool {
314 type ByteArray = [u8; 1];
315
316 #[inline]
317 fn from_bytes(b: &[u8; 1]) -> Self {
318 b[0] != 0
319 }
320
321 #[inline]
322 fn write_to_bytes(self, b: &mut [u8; 1]) {
323 if true {
if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};
};debug_assert!(!self.is_default());
324 b[0] = self as u8
325 }
326}
327
328impl<T> FixedSizeEncoding for Option<LazyValue<T>> {
332 type ByteArray = [u8; 8];
333
334 #[inline]
335 fn from_bytes(b: &[u8; 8]) -> Self {
336 let position = NonZero::new(u64::from_bytes(b) as usize)?;
337 Some(LazyValue::from_position(position))
338 }
339
340 #[inline]
341 fn write_to_bytes(self, b: &mut [u8; 8]) {
342 match self {
343 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
344 Some(lazy) => {
345 let position = lazy.position.get();
346 let position: u64 = position.try_into().unwrap();
347 position.write_to_bytes(b)
348 }
349 }
350 }
351}
352
353impl<T> LazyArray<T> {
354 #[inline]
355 fn write_to_bytes_impl(self, dest: &mut [u8; 16]) {
356 let position = (self.position.get() as u64).to_le_bytes();
357 let len = (self.num_elems as u64).to_le_bytes();
358
359 encode_interleaved(position, len, dest)
360 }
361
362 fn from_bytes_impl(position: &[u8; 8], meta: &[u8; 8]) -> Option<LazyArray<T>> {
363 let position = NonZero::new(u64::from_bytes(position) as usize)?;
364 let len = u64::from_bytes(meta) as usize;
365 Some(LazyArray::from_position_and_num_elems(position, len))
366 }
367}
368
369#[inline]
372fn decode_interleaved<const N: usize, const M: usize>(encoded: &[u8; N]) -> ([u8; M], [u8; M]) {
373 match (&(M * 2), &N) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(M * 2, N);
374 let mut first = [0u8; M];
375 let mut second = [0u8; M];
376 for i in 0..M {
377 first[i] = encoded[2 * i];
378 second[i] = encoded[2 * i + 1];
379 }
380 (first, second)
381}
382
383#[inline]
391fn encode_interleaved<const N: usize, const M: usize>(a: [u8; M], b: [u8; M], dest: &mut [u8; N]) {
392 match (&(M * 2), &N) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(M * 2, N);
393 for i in 0..M {
394 dest[2 * i] = a[i];
395 dest[2 * i + 1] = b[i];
396 }
397}
398
399impl<T> FixedSizeEncoding for LazyArray<T> {
400 type ByteArray = [u8; 16];
401
402 #[inline]
403 fn from_bytes(b: &[u8; 16]) -> Self {
404 let (position, meta) = decode_interleaved(b);
405
406 if meta == [0; 8] {
407 return Default::default();
408 }
409 LazyArray::from_bytes_impl(&position, &meta).unwrap()
410 }
411
412 #[inline]
413 fn write_to_bytes(self, b: &mut [u8; 16]) {
414 if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};assert!(!self.is_default());
415 self.write_to_bytes_impl(b)
416 }
417}
418
419impl<T> FixedSizeEncoding for Option<LazyArray<T>> {
420 type ByteArray = [u8; 16];
421
422 #[inline]
423 fn from_bytes(b: &[u8; 16]) -> Self {
424 let (position, meta) = decode_interleaved(b);
425
426 LazyArray::from_bytes_impl(&position, &meta)
427 }
428
429 #[inline]
430 fn write_to_bytes(self, b: &mut [u8; 16]) {
431 match self {
432 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
433 Some(lazy) => lazy.write_to_bytes_impl(b),
434 }
435 }
436}
437
438pub(super) struct TableBuilder<I: Idx, T: FixedSizeEncoding> {
440 width: usize,
441 blocks: IndexVec<I, T::ByteArray>,
442 _marker: PhantomData<T>,
443}
444
445impl<I: Idx, T: FixedSizeEncoding> Default for TableBuilder<I, T> {
446 fn default() -> Self {
447 TableBuilder { width: 0, blocks: Default::default(), _marker: PhantomData }
448 }
449}
450
451impl<I: Idx, const N: usize, T> TableBuilder<I, Option<T>>
452where
453 Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
454{
455 pub(crate) fn set_some(&mut self, i: I, value: T) {
456 self.set(i, Some(value))
457 }
458}
459
460impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBuilder<I, T> {
461 pub(crate) fn set(&mut self, i: I, value: T) {
467 #[cfg(debug_assertions)]
468 {
469 if true {
if !T::from_bytes(&[0; N]).is_default() {
{
::core::panicking::panic_fmt(format_args!("expected all-zeroes to decode to the default value, as per the invariant of FixedSizeEncoding"));
}
};
};debug_assert!(
470 T::from_bytes(&[0; N]).is_default(),
471 "expected all-zeroes to decode to the default value, as per the invariant of FixedSizeEncoding"
472 );
473 }
474 if !value.is_default() {
475 let block = self.blocks.ensure_contains_elem(i, || [0; N]);
481 value.write_to_bytes(block);
482 if self.width != N {
483 let width = N - trailing_zeros(block);
484 self.width = self.width.max(width);
485 }
486 }
487 }
488
489 pub(crate) fn encode(&self, buf: &mut FileEncoder) -> LazyTable<I, T> {
490 let pos = buf.position();
491
492 let width = self.width;
493 for block in &self.blocks {
494 buf.write_with(|dest| {
495 *dest = *block;
496 width
497 });
498 }
499
500 LazyTable::from_position_and_encoded_size(
501 NonZero::new(pos).unwrap(),
502 width,
503 self.blocks.len(),
504 )
505 }
506}
507
508fn trailing_zeros(x: &[u8]) -> usize {
509 x.iter().rev().take_while(|b| **b == 0).count()
510}
511
512impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]> + ParameterizedOverTcx>
513 LazyTable<I, T>
514where
515 for<'tcx> T::Value<'tcx>: FixedSizeEncoding<ByteArray = [u8; N]>,
516{
517 pub(super) fn get<'a, 'tcx, M: Metadata<'a>>(&self, metadata: M, i: I) -> T::Value<'tcx> {
519 if i.index() >= self.len {
521 return Default::default();
522 }
523
524 let width = self.width;
525 let start = self.position.get() + (width * i.index());
526 let end = start + width;
527 let bytes = &metadata.blob()[start..end];
528
529 if let Ok(fixed) = bytes.try_into() {
530 FixedSizeEncoding::from_bytes(fixed)
531 } else {
532 let mut fixed = [0u8; N];
533 fixed[..width].copy_from_slice(bytes);
534 FixedSizeEncoding::from_bytes(&fixed)
535 }
536 }
537
538 pub(super) fn size(&self) -> usize {
540 self.len
541 }
542}