1use rustc_hir::def::CtorOf;
2use rustc_index::Idx;
3
4use crate::rmeta::decoder::MetaBlob;
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 { always: false },
1 => NotConst,
2 => Const { always: true },
_ => {
::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 { always: false } => 0,
NotConst => 1,
Const { always: 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::Constness {
fn is_default(&self) -> bool {
<hir::Constness as Default>::default() == *self
}
}defaulted_enum! {
227 hir::Constness {
228 ( Const { always: false } )
229 ( NotConst )
230 ( Const { always: true } )
231 }
232}
233
234impl 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! {
235 hir::Safety {
236 ( Unsafe )
237 ( Safe )
238 }
239}
240
241impl 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! {
242 hir::CoroutineKind {
243 ( Coroutine(hir::Movability::Movable) )
244 ( Coroutine(hir::Movability::Static) )
245 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Block) )
246 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Fn) )
247 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Closure) )
248 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Block) )
249 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Fn) )
250 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Closure) )
251 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Block) )
252 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Fn) )
253 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Closure) )
254 }
255}
256
257impl 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! {
258 MacroKind {
259 ( Attr )
260 ( Bang )
261 ( Derive )
262 }
263}
264
265impl FixedSizeEncoding for Option<RawDefId> {
267 type ByteArray = [u8; 8];
268
269 #[inline]
270 fn from_bytes(encoded: &[u8; 8]) -> Self {
271 let (index, krate) = decode_interleaved(encoded);
272 let krate = u32::from_le_bytes(krate);
273 if krate == 0 {
274 return None;
275 }
276 let index = u32::from_le_bytes(index);
277
278 Some(RawDefId { krate: krate - 1, index })
279 }
280
281 #[inline]
282 fn write_to_bytes(self, dest: &mut [u8; 8]) {
283 match self {
284 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
285 Some(RawDefId { krate, index }) => {
286 if true {
if !(krate < u32::MAX) {
::core::panicking::panic("assertion failed: krate < u32::MAX")
};
};debug_assert!(krate < u32::MAX);
287 let krate = (krate + 1).to_le_bytes();
289 let index = index.to_le_bytes();
290
291 encode_interleaved(index, krate, dest);
294 }
295 }
296 }
297}
298
299impl FixedSizeEncoding for AttrFlags {
300 type ByteArray = [u8; 1];
301
302 #[inline]
303 fn from_bytes(b: &[u8; 1]) -> Self {
304 AttrFlags::from_bits_truncate(b[0])
305 }
306
307 #[inline]
308 fn write_to_bytes(self, b: &mut [u8; 1]) {
309 if true {
if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};
};debug_assert!(!self.is_default());
310 b[0] = self.bits();
311 }
312}
313
314impl FixedSizeEncoding for bool {
315 type ByteArray = [u8; 1];
316
317 #[inline]
318 fn from_bytes(b: &[u8; 1]) -> Self {
319 b[0] != 0
320 }
321
322 #[inline]
323 fn write_to_bytes(self, b: &mut [u8; 1]) {
324 if true {
if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};
};debug_assert!(!self.is_default());
325 b[0] = self as u8
326 }
327}
328
329impl<T> FixedSizeEncoding for Option<LazyValue<T>> {
333 type ByteArray = [u8; 8];
334
335 #[inline]
336 fn from_bytes(b: &[u8; 8]) -> Self {
337 let position = NonZero::new(u64::from_bytes(b) as usize)?;
338 Some(LazyValue::from_position(position))
339 }
340
341 #[inline]
342 fn write_to_bytes(self, b: &mut [u8; 8]) {
343 match self {
344 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
345 Some(lazy) => {
346 let position = lazy.position.get();
347 let position: u64 = position.try_into().unwrap();
348 position.write_to_bytes(b)
349 }
350 }
351 }
352}
353
354impl<T> LazyArray<T> {
355 #[inline]
356 fn write_to_bytes_impl(self, dest: &mut [u8; 16]) {
357 let position = (self.position.get() as u64).to_le_bytes();
358 let len = (self.num_elems as u64).to_le_bytes();
359
360 encode_interleaved(position, len, dest)
361 }
362
363 fn from_bytes_impl(position: &[u8; 8], meta: &[u8; 8]) -> Option<LazyArray<T>> {
364 let position = NonZero::new(u64::from_bytes(position) as usize)?;
365 let len = u64::from_bytes(meta) as usize;
366 Some(LazyArray::from_position_and_num_elems(position, len))
367 }
368}
369
370#[inline]
373fn decode_interleaved<const N: usize, const M: usize>(encoded: &[u8; N]) -> ([u8; M], [u8; M]) {
374 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);
375 let mut first = [0u8; M];
376 let mut second = [0u8; M];
377 for i in 0..M {
378 first[i] = encoded[2 * i];
379 second[i] = encoded[2 * i + 1];
380 }
381 (first, second)
382}
383
384#[inline]
392fn encode_interleaved<const N: usize, const M: usize>(a: [u8; M], b: [u8; M], dest: &mut [u8; N]) {
393 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);
394 for i in 0..M {
395 dest[2 * i] = a[i];
396 dest[2 * i + 1] = b[i];
397 }
398}
399
400impl<T> FixedSizeEncoding for LazyArray<T> {
401 type ByteArray = [u8; 16];
402
403 #[inline]
404 fn from_bytes(b: &[u8; 16]) -> Self {
405 let (position, meta) = decode_interleaved(b);
406
407 if meta == [0; 8] {
408 return Default::default();
409 }
410 LazyArray::from_bytes_impl(&position, &meta).unwrap()
411 }
412
413 #[inline]
414 fn write_to_bytes(self, b: &mut [u8; 16]) {
415 if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};assert!(!self.is_default());
416 self.write_to_bytes_impl(b)
417 }
418}
419
420impl<T> FixedSizeEncoding for Option<LazyArray<T>> {
421 type ByteArray = [u8; 16];
422
423 #[inline]
424 fn from_bytes(b: &[u8; 16]) -> Self {
425 let (position, meta) = decode_interleaved(b);
426
427 LazyArray::from_bytes_impl(&position, &meta)
428 }
429
430 #[inline]
431 fn write_to_bytes(self, b: &mut [u8; 16]) {
432 match self {
433 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
434 Some(lazy) => lazy.write_to_bytes_impl(b),
435 }
436 }
437}
438
439pub(super) struct TableBuilder<I: Idx, T: FixedSizeEncoding> {
441 width: usize,
442 blocks: IndexVec<I, T::ByteArray>,
443 _marker: PhantomData<T>,
444}
445
446impl<I: Idx, T: FixedSizeEncoding> Default for TableBuilder<I, T> {
447 fn default() -> Self {
448 TableBuilder { width: 0, blocks: Default::default(), _marker: PhantomData }
449 }
450}
451
452impl<I: Idx, const N: usize, T> TableBuilder<I, Option<T>>
453where
454 Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
455{
456 pub(crate) fn set_some(&mut self, i: I, value: T) {
457 self.set(i, Some(value))
458 }
459}
460
461impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBuilder<I, T> {
462 pub(crate) fn set(&mut self, i: I, value: T) {
468 #[cfg(debug_assertions)]
469 {
470 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!(
471 T::from_bytes(&[0; N]).is_default(),
472 "expected all-zeroes to decode to the default value, as per the invariant of FixedSizeEncoding"
473 );
474 }
475 if !value.is_default() {
476 let block = self.blocks.ensure_contains_elem(i, || [0; N]);
482 value.write_to_bytes(block);
483 if self.width != N {
484 let width = N - trailing_zeros(block);
485 self.width = self.width.max(width);
486 }
487 }
488 }
489
490 pub(crate) fn encode(&self, buf: &mut FileEncoder<'_>) -> LazyTable<I, T> {
491 let pos = buf.position();
492
493 let width = self.width;
494 for block in &self.blocks {
495 buf.write_with(|dest| {
496 *dest = *block;
497 width
498 });
499 }
500
501 LazyTable::from_position_and_encoded_size(
502 NonZero::new(pos).unwrap(),
503 width,
504 self.blocks.len(),
505 )
506 }
507}
508
509fn trailing_zeros(x: &[u8]) -> usize {
510 x.iter().rev().take_while(|b| **b == 0).count()
511}
512
513impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]> + ParameterizedOverTcx>
514 LazyTable<I, T>
515where
516 for<'tcx> T::Value<'tcx>: FixedSizeEncoding<ByteArray = [u8; N]>,
517{
518 pub(super) fn get<'a, 'tcx, M: MetaBlob<'a>>(&self, metadata: M, i: I) -> T::Value<'tcx> {
520 if i.index() >= self.len {
522 return Default::default();
523 }
524
525 let width = self.width;
526 let start = self.position.get() + (width * i.index());
527 let end = start + width;
528 let bytes = &metadata.blob()[start..end];
529
530 if let Ok(fixed) = bytes.try_into() {
531 FixedSizeEncoding::from_bytes(fixed)
532 } else {
533 let mut fixed = [0u8; N];
534 fixed[..width].copy_from_slice(bytes);
535 FixedSizeEncoding::from_bytes(&fixed)
536 }
537 }
538
539 pub(super) fn size(&self) -> usize {
541 self.len
542 }
543}