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),
13 => Some(ConstParam),
14 => Some(AssocFn),
15 => Some(AssocConst),
16 => Some(ExternCrate),
17 => Some(Use),
18 => Some(ForeignMod),
19 => Some(AnonConst),
20 => Some(OpaqueTy),
21 => Some(Field),
22 => Some(LifetimeParam),
23 => Some(GlobalAsm),
24 => Some(Impl { of_trait: false }),
25 => Some(Impl { of_trait: true }),
26 => Some(Closure),
27 =>
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Not,
nested: false,
}),
28 =>
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Not,
nested: false,
}),
29 =>
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Mut,
nested: false,
}),
30 =>
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Mut,
nested: false,
}),
31 =>
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Not,
nested: true,
}),
32 =>
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Not,
nested: true,
}),
33 =>
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Mut,
nested: true,
}),
34 =>
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Mut,
nested: true,
}),
35 => Some(Ctor(CtorOf::Struct, CtorKind::Fn)),
36 => Some(Ctor(CtorOf::Struct, CtorKind::Const)),
37 => Some(Ctor(CtorOf::Variant, CtorKind::Fn)),
38 => Some(Ctor(CtorOf::Variant, CtorKind::Const)),
39 => Some(Macro(MacroKinds::BANG)),
40 => Some(Macro(MacroKinds::ATTR)),
41 => Some(Macro(MacroKinds::DERIVE)),
42 => Some(Macro(MACRO_KINDS_ATTR_BANG)),
43 => Some(Macro(MACRO_KINDS_DERIVE_ATTR)),
44 => Some(Macro(MACRO_KINDS_DERIVE_BANG)),
45 => Some(Macro(MACRO_KINDS_DERIVE_ATTR_BANG)),
46 => Some(SyntheticCoroutineBody),
47 => Some(TestBinderConstraints),
_ => {
::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) => 1 + 12,
Some(ConstParam) => 1 + 13,
Some(AssocFn) => 1 + 14,
Some(AssocConst) => 1 + 15,
Some(ExternCrate) => 1 + 16,
Some(Use) => 1 + 17,
Some(ForeignMod) => 1 + 18,
Some(AnonConst) => 1 + 19,
Some(OpaqueTy) => 1 + 20,
Some(Field) => 1 + 21,
Some(LifetimeParam) => 1 + 22,
Some(GlobalAsm) => 1 + 23,
Some(Impl { of_trait: false }) => 1 + 24,
Some(Impl { of_trait: true }) => 1 + 25,
Some(Closure) => 1 + 26,
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Not,
nested: false }) => 1 + 27,
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Not,
nested: false }) => 1 + 28,
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Mut,
nested: false }) => 1 + 29,
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Mut,
nested: false }) => 1 + 30,
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Not,
nested: true }) => 1 + 31,
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Not,
nested: true }) => 1 + 32,
Some(Static {
safety: hir::Safety::Unsafe,
mutability: ast::Mutability::Mut,
nested: true }) => 1 + 33,
Some(Static {
safety: hir::Safety::Safe,
mutability: ast::Mutability::Mut,
nested: true }) => 1 + 34,
Some(Ctor(CtorOf::Struct, CtorKind::Fn)) => 1 + 35,
Some(Ctor(CtorOf::Struct, CtorKind::Const)) => 1 + 36,
Some(Ctor(CtorOf::Variant, CtorKind::Fn)) => 1 + 37,
Some(Ctor(CtorOf::Variant, CtorKind::Const)) => 1 + 38,
Some(Macro(MacroKinds::BANG)) => 1 + 39,
Some(Macro(MacroKinds::ATTR)) => 1 + 40,
Some(Macro(MacroKinds::DERIVE)) => 1 + 41,
Some(Macro(MACRO_KINDS_ATTR_BANG)) => 1 + 42,
Some(Macro(MACRO_KINDS_DERIVE_ATTR)) => 1 + 43,
Some(Macro(MACRO_KINDS_DERIVE_BANG)) => 1 + 44,
Some(Macro(MACRO_KINDS_DERIVE_ATTR_BANG)) => 1 + 45,
Some(SyntheticCoroutineBody) => 1 + 46,
Some(TestBinderConstraints) => 1 + 47,
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 )
169 ( ConstParam )
170 ( AssocFn )
171 ( AssocConst )
172 ( ExternCrate )
173 ( Use )
174 ( ForeignMod )
175 ( AnonConst )
176 ( OpaqueTy )
177 ( Field )
178 ( LifetimeParam )
179 ( GlobalAsm )
180 ( Impl { of_trait: false } )
181 ( Impl { of_trait: true } )
182 ( Closure )
183 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: false } )
184 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: false } )
185 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: false } )
186 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: false } )
187 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: true } )
188 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: true } )
189 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: true } )
190 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: true } )
191 ( Ctor(CtorOf::Struct, CtorKind::Fn) )
192 ( Ctor(CtorOf::Struct, CtorKind::Const) )
193 ( Ctor(CtorOf::Variant, CtorKind::Fn) )
194 ( Ctor(CtorOf::Variant, CtorKind::Const) )
195 ( Macro(MacroKinds::BANG) )
196 ( Macro(MacroKinds::ATTR) )
197 ( Macro(MacroKinds::DERIVE) )
198 ( Macro(MACRO_KINDS_ATTR_BANG) )
199 ( Macro(MACRO_KINDS_DERIVE_ATTR) )
200 ( Macro(MACRO_KINDS_DERIVE_BANG) )
201 ( Macro(MACRO_KINDS_DERIVE_ATTR_BANG) )
202 ( SyntheticCoroutineBody )
203 ( TestBinderConstraints )
204 } unreachable {
205 ( Macro(_) )
206 }
207}
208
209impl 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! {
210 hir::Defaultness {
211 ( Final )
212 ( Default { has_value: false } )
213 ( Default { has_value: true } )
214 }
215}
216
217impl 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! {
218 ty::Asyncness {
219 ( No )
220 ( Yes )
221 }
222}
223
224impl 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! {
225 hir::Constness {
226 ( Const { always: false } )
227 ( NotConst )
228 ( Const { always: true } )
229 }
230}
231
232impl 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! {
233 hir::Safety {
234 ( Unsafe )
235 ( Safe )
236 }
237}
238
239impl 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! {
240 hir::CoroutineKind {
241 ( Coroutine(hir::Movability::Movable) )
242 ( Coroutine(hir::Movability::Static) )
243 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Block) )
244 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Fn) )
245 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Closure) )
246 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Block) )
247 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Fn) )
248 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Closure) )
249 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Block) )
250 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Fn) )
251 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Closure) )
252 }
253}
254
255impl 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! {
256 MacroKind {
257 ( Attr )
258 ( Bang )
259 ( Derive )
260 }
261}
262
263impl FixedSizeEncoding for Option<RawDefId> {
265 type ByteArray = [u8; 8];
266
267 #[inline]
268 fn from_bytes(encoded: &[u8; 8]) -> Self {
269 let (index, krate) = decode_interleaved(encoded);
270 let krate = u32::from_le_bytes(krate);
271 if krate == 0 {
272 return None;
273 }
274 let index = u32::from_le_bytes(index);
275
276 Some(RawDefId { krate: krate - 1, index })
277 }
278
279 #[inline]
280 fn write_to_bytes(self, dest: &mut [u8; 8]) {
281 match self {
282 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
283 Some(RawDefId { krate, index }) => {
284 if true {
if !(krate < u32::MAX) {
::core::panicking::panic("assertion failed: krate < u32::MAX")
};
};debug_assert!(krate < u32::MAX);
285 let krate = (krate + 1).to_le_bytes();
287 let index = index.to_le_bytes();
288
289 encode_interleaved(index, krate, dest);
292 }
293 }
294 }
295}
296
297impl FixedSizeEncoding for AttrFlags {
298 type ByteArray = [u8; 1];
299
300 #[inline]
301 fn from_bytes(b: &[u8; 1]) -> Self {
302 AttrFlags::from_bits_truncate(b[0])
303 }
304
305 #[inline]
306 fn write_to_bytes(self, b: &mut [u8; 1]) {
307 if true {
if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};
};debug_assert!(!self.is_default());
308 b[0] = self.bits();
309 }
310}
311
312impl FixedSizeEncoding for bool {
313 type ByteArray = [u8; 1];
314
315 #[inline]
316 fn from_bytes(b: &[u8; 1]) -> Self {
317 b[0] != 0
318 }
319
320 #[inline]
321 fn write_to_bytes(self, b: &mut [u8; 1]) {
322 if true {
if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};
};debug_assert!(!self.is_default());
323 b[0] = self as u8
324 }
325}
326
327impl<T> FixedSizeEncoding for Option<LazyValue<T>> {
331 type ByteArray = [u8; 8];
332
333 #[inline]
334 fn from_bytes(b: &[u8; 8]) -> Self {
335 let position = NonZero::new(u64::from_bytes(b) as usize)?;
336 Some(LazyValue::from_position(position))
337 }
338
339 #[inline]
340 fn write_to_bytes(self, b: &mut [u8; 8]) {
341 match self {
342 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
343 Some(lazy) => {
344 let position = lazy.position.get();
345 let position: u64 = position.try_into().unwrap();
346 position.write_to_bytes(b)
347 }
348 }
349 }
350}
351
352impl<T> LazyArray<T> {
353 #[inline]
354 fn write_to_bytes_impl(self, dest: &mut [u8; 16]) {
355 let position = (self.position.get() as u64).to_le_bytes();
356 let len = (self.num_elems as u64).to_le_bytes();
357
358 encode_interleaved(position, len, dest)
359 }
360
361 fn from_bytes_impl(position: &[u8; 8], meta: &[u8; 8]) -> Option<LazyArray<T>> {
362 let position = NonZero::new(u64::from_bytes(position) as usize)?;
363 let len = u64::from_bytes(meta) as usize;
364 Some(LazyArray::from_position_and_num_elems(position, len))
365 }
366}
367
368#[inline]
371fn decode_interleaved<const N: usize, const M: usize>(encoded: &[u8; N]) -> ([u8; M], [u8; M]) {
372 {
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);
373 let mut first = [0u8; M];
374 let mut second = [0u8; M];
375 for i in 0..M {
376 first[i] = encoded[2 * i];
377 second[i] = encoded[2 * i + 1];
378 }
379 (first, second)
380}
381
382#[inline]
390fn encode_interleaved<const N: usize, const M: usize>(a: [u8; M], b: [u8; M], dest: &mut [u8; N]) {
391 {
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);
392 for i in 0..M {
393 dest[2 * i] = a[i];
394 dest[2 * i + 1] = b[i];
395 }
396}
397
398impl<T> FixedSizeEncoding for LazyArray<T> {
399 type ByteArray = [u8; 16];
400
401 #[inline]
402 fn from_bytes(b: &[u8; 16]) -> Self {
403 let (position, meta) = decode_interleaved(b);
404
405 if meta == [0; 8] {
406 return Default::default();
407 }
408 LazyArray::from_bytes_impl(&position, &meta).unwrap()
409 }
410
411 #[inline]
412 fn write_to_bytes(self, b: &mut [u8; 16]) {
413 if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};assert!(!self.is_default());
414 self.write_to_bytes_impl(b)
415 }
416}
417
418impl<T> FixedSizeEncoding for Option<LazyArray<T>> {
419 type ByteArray = [u8; 16];
420
421 #[inline]
422 fn from_bytes(b: &[u8; 16]) -> Self {
423 let (position, meta) = decode_interleaved(b);
424
425 LazyArray::from_bytes_impl(&position, &meta)
426 }
427
428 #[inline]
429 fn write_to_bytes(self, b: &mut [u8; 16]) {
430 match self {
431 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
432 Some(lazy) => lazy.write_to_bytes_impl(b),
433 }
434 }
435}
436
437pub(super) struct TableBuilder<I: Idx, T: FixedSizeEncoding> {
439 width: usize,
440 blocks: IndexVec<I, T::ByteArray>,
441 _marker: PhantomData<T>,
442}
443
444impl<I: Idx, T: FixedSizeEncoding> Default for TableBuilder<I, T> {
445 fn default() -> Self {
446 TableBuilder { width: 0, blocks: Default::default(), _marker: PhantomData }
447 }
448}
449
450impl<I: Idx, const N: usize, T> TableBuilder<I, Option<T>>
451where
452 Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
453{
454 pub(crate) fn set_some(&mut self, i: I, value: T) {
455 self.set(i, Some(value))
456 }
457}
458
459impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBuilder<I, T> {
460 pub(crate) fn set(&mut self, i: I, value: T) {
466 #[cfg(debug_assertions)]
467 {
468 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!(
469 T::from_bytes(&[0; N]).is_default(),
470 "expected all-zeroes to decode to the default value, as per the invariant of FixedSizeEncoding"
471 );
472 }
473 if !value.is_default() {
474 let block = self.blocks.ensure_contains_elem(i, || [0; N]);
480 value.write_to_bytes(block);
481 if self.width != N {
482 let width = N - trailing_zeros(block);
483 self.width = self.width.max(width);
484 }
485 }
486 }
487
488 pub(crate) fn encode(&self, buf: &mut FileEncoder<'_>) -> LazyTable<I, T> {
489 let pos = buf.position();
490
491 let width = self.width;
492 for block in &self.blocks {
493 buf.write_with(|dest| {
494 *dest = *block;
495 width
496 });
497 }
498
499 LazyTable::from_position_and_encoded_size(
500 NonZero::new(pos).unwrap(),
501 width,
502 self.blocks.len(),
503 )
504 }
505}
506
507fn trailing_zeros(x: &[u8]) -> usize {
508 x.iter().rev().take_while(|b| **b == 0).count()
509}
510
511impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]> + ParameterizedOverTcx>
512 LazyTable<I, T>
513where
514 for<'tcx> T::Value<'tcx>: FixedSizeEncoding<ByteArray = [u8; N]>,
515{
516 pub(super) fn get<'a, 'tcx, M: MetaBlob<'a>>(&self, metadata: M, i: I) -> T::Value<'tcx> {
518 if i.index() >= self.len {
520 return Default::default();
521 }
522
523 let width = self.width;
524 let start = self.position.get() + (width * i.index());
525 let end = start + width;
526 let bytes = &metadata.blob()[start..end];
527
528 if let Ok(fixed) = bytes.try_into() {
529 FixedSizeEncoding::from_bytes(fixed)
530 } else {
531 let mut fixed = [0u8; N];
532 fixed[..width].copy_from_slice(bytes);
533 FixedSizeEncoding::from_bytes(&fixed)
534 }
535 }
536
537 pub(super) fn size(&self) -> usize {
539 self.len
540 }
541}