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