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
143const _: () = if !MacroKinds::DERIVE_ATTR_BANG.is_all() {
::core::panicking::panic("assertion failed: MacroKinds::DERIVE_ATTR_BANG.is_all()")
}assert!(MacroKinds::DERIVE_ATTR_BANG.is_all());
145
146impl 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(MacroKinds::ATTR_BANG)),
43 => Some(Macro(MacroKinds::DERIVE_ATTR)),
44 => Some(Macro(MacroKinds::DERIVE_BANG)),
45 => Some(Macro(MacroKinds::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(MacroKinds::ATTR_BANG)) => 1 + 42,
Some(Macro(MacroKinds::DERIVE_ATTR)) => 1 + 43,
Some(Macro(MacroKinds::DERIVE_BANG)) => 1 + 44,
Some(Macro(MacroKinds::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! {
147 DefKind {
148 ( Mod )
149 ( Struct )
150 ( Union )
151 ( Enum )
152 ( Variant )
153 ( Trait )
154 ( TyAlias )
155 ( ForeignTy )
156 ( TraitAlias )
157 ( AssocTy )
158 ( TyParam )
159 ( Fn )
160 ( Const )
161 ( ConstParam )
162 ( AssocFn )
163 ( AssocConst )
164 ( ExternCrate )
165 ( Use )
166 ( ForeignMod )
167 ( AnonConst )
168 ( OpaqueTy )
169 ( Field )
170 ( LifetimeParam )
171 ( GlobalAsm )
172 ( Impl { of_trait: false } )
173 ( Impl { of_trait: true } )
174 ( Closure )
175 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: false } )
176 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: false } )
177 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: false } )
178 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: false } )
179 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: true } )
180 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: true } )
181 ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: true } )
182 ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: true } )
183 ( Ctor(CtorOf::Struct, CtorKind::Fn) )
184 ( Ctor(CtorOf::Struct, CtorKind::Const) )
185 ( Ctor(CtorOf::Variant, CtorKind::Fn) )
186 ( Ctor(CtorOf::Variant, CtorKind::Const) )
187 ( Macro(MacroKinds::BANG) )
188 ( Macro(MacroKinds::ATTR) )
189 ( Macro(MacroKinds::DERIVE) )
190 ( Macro(MacroKinds::ATTR_BANG) )
191 ( Macro(MacroKinds::DERIVE_ATTR) )
192 ( Macro(MacroKinds::DERIVE_BANG) )
193 ( Macro(MacroKinds::DERIVE_ATTR_BANG) )
194 ( SyntheticCoroutineBody )
195 ( TestBinderConstraints )
196 } unreachable {
197 ( Macro(_) )
198 }
199}
200
201impl 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! {
202 hir::Defaultness {
203 ( Final )
204 ( Default { has_value: false } )
205 ( Default { has_value: true } )
206 }
207}
208
209impl 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! {
210 ty::Asyncness {
211 ( No )
212 ( Yes )
213 }
214}
215
216impl 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! {
217 hir::Constness {
218 ( Const { always: false } )
219 ( NotConst )
220 ( Const { always: true } )
221 }
222}
223
224impl 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! {
225 hir::Safety {
226 ( Unsafe )
227 ( Safe )
228 }
229}
230
231impl 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! {
232 hir::CoroutineKind {
233 ( Coroutine(hir::Movability::Movable) )
234 ( Coroutine(hir::Movability::Static) )
235 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Block) )
236 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Fn) )
237 ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Closure) )
238 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Block) )
239 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Fn) )
240 ( Desugared(hir::CoroutineDesugaring::Async, hir::CoroutineSource::Closure) )
241 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Block) )
242 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Fn) )
243 ( Desugared(hir::CoroutineDesugaring::AsyncGen, hir::CoroutineSource::Closure) )
244 }
245}
246
247impl 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! {
248 MacroKind {
249 ( Attr )
250 ( Bang )
251 ( Derive )
252 }
253}
254
255impl FixedSizeEncoding for Option<RawDefId> {
257 type ByteArray = [u8; 8];
258
259 #[inline]
260 fn from_bytes(encoded: &[u8; 8]) -> Self {
261 let (index, krate) = decode_interleaved(encoded);
262 let krate = u32::from_le_bytes(krate);
263 if krate == 0 {
264 return None;
265 }
266 let index = u32::from_le_bytes(index);
267
268 Some(RawDefId { krate: krate - 1, index })
269 }
270
271 #[inline]
272 fn write_to_bytes(self, dest: &mut [u8; 8]) {
273 match self {
274 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
275 Some(RawDefId { krate, index }) => {
276 if true {
if !(krate < u32::MAX) {
::core::panicking::panic("assertion failed: krate < u32::MAX")
};
};debug_assert!(krate < u32::MAX);
277 let krate = (krate + 1).to_le_bytes();
279 let index = index.to_le_bytes();
280
281 encode_interleaved(index, krate, dest);
284 }
285 }
286 }
287}
288
289impl FixedSizeEncoding for AttrFlags {
290 type ByteArray = [u8; 1];
291
292 #[inline]
293 fn from_bytes(b: &[u8; 1]) -> Self {
294 AttrFlags::from_bits_truncate(b[0])
295 }
296
297 #[inline]
298 fn write_to_bytes(self, b: &mut [u8; 1]) {
299 if true {
if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};
};debug_assert!(!self.is_default());
300 b[0] = self.bits();
301 }
302}
303
304impl FixedSizeEncoding for bool {
305 type ByteArray = [u8; 1];
306
307 #[inline]
308 fn from_bytes(b: &[u8; 1]) -> Self {
309 b[0] != 0
310 }
311
312 #[inline]
313 fn write_to_bytes(self, b: &mut [u8; 1]) {
314 if true {
if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};
};debug_assert!(!self.is_default());
315 b[0] = self as u8
316 }
317}
318
319impl<T> FixedSizeEncoding for Option<LazyValue<T>> {
323 type ByteArray = [u8; 8];
324
325 #[inline]
326 fn from_bytes(b: &[u8; 8]) -> Self {
327 let position = NonZero::new(u64::from_bytes(b) as usize)?;
328 Some(LazyValue::from_position(position))
329 }
330
331 #[inline]
332 fn write_to_bytes(self, b: &mut [u8; 8]) {
333 match self {
334 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
335 Some(lazy) => {
336 let position = lazy.position.get();
337 let position: u64 = position.try_into().unwrap();
338 position.write_to_bytes(b)
339 }
340 }
341 }
342}
343
344impl<T> LazyArray<T> {
345 #[inline]
346 fn write_to_bytes_impl(self, dest: &mut [u8; 16]) {
347 let position = (self.position.get() as u64).to_le_bytes();
348 let len = (self.num_elems as u64).to_le_bytes();
349
350 encode_interleaved(position, len, dest)
351 }
352
353 fn from_bytes_impl(position: &[u8; 8], meta: &[u8; 8]) -> Option<LazyArray<T>> {
354 let position = NonZero::new(u64::from_bytes(position) as usize)?;
355 let len = u64::from_bytes(meta) as usize;
356 Some(LazyArray::from_position_and_num_elems(position, len))
357 }
358}
359
360#[inline]
363fn decode_interleaved<const N: usize, const M: usize>(encoded: &[u8; N]) -> ([u8; M], [u8; M]) {
364 {
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);
365 let mut first = [0u8; M];
366 let mut second = [0u8; M];
367 for i in 0..M {
368 first[i] = encoded[2 * i];
369 second[i] = encoded[2 * i + 1];
370 }
371 (first, second)
372}
373
374#[inline]
382fn encode_interleaved<const N: usize, const M: usize>(a: [u8; M], b: [u8; M], dest: &mut [u8; N]) {
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 for i in 0..M {
385 dest[2 * i] = a[i];
386 dest[2 * i + 1] = b[i];
387 }
388}
389
390impl<T> FixedSizeEncoding for LazyArray<T> {
391 type ByteArray = [u8; 16];
392
393 #[inline]
394 fn from_bytes(b: &[u8; 16]) -> Self {
395 let (position, meta) = decode_interleaved(b);
396
397 if meta == [0; 8] {
398 return Default::default();
399 }
400 LazyArray::from_bytes_impl(&position, &meta).unwrap()
401 }
402
403 #[inline]
404 fn write_to_bytes(self, b: &mut [u8; 16]) {
405 if !!self.is_default() {
::core::panicking::panic("assertion failed: !self.is_default()")
};assert!(!self.is_default());
406 self.write_to_bytes_impl(b)
407 }
408}
409
410impl<T> FixedSizeEncoding for Option<LazyArray<T>> {
411 type ByteArray = [u8; 16];
412
413 #[inline]
414 fn from_bytes(b: &[u8; 16]) -> Self {
415 let (position, meta) = decode_interleaved(b);
416
417 LazyArray::from_bytes_impl(&position, &meta)
418 }
419
420 #[inline]
421 fn write_to_bytes(self, b: &mut [u8; 16]) {
422 match self {
423 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
424 Some(lazy) => lazy.write_to_bytes_impl(b),
425 }
426 }
427}
428
429pub(super) struct TableBuilder<IdxEncode: Idx, IdxDecode: Idx, T: FixedSizeEncoding> {
431 width: usize,
432 blocks: IndexVec<IdxEncode, T::ByteArray>,
433 _marker: PhantomData<(IdxDecode, T)>,
434}
435
436pub(super) type TableBuilderSingleIdx<TIdx, TValue> = TableBuilder<TIdx, TIdx, TValue>;
437
438impl<Ie: Idx, Id: Idx, T: FixedSizeEncoding> Default for TableBuilder<Ie, Id, T> {
439 fn default() -> Self {
440 TableBuilder { width: 0, blocks: Default::default(), _marker: PhantomData }
441 }
442}
443
444impl<Ie: Idx, Id: Idx, const N: usize, T> TableBuilder<Ie, Id, Option<T>>
445where
446 Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
447{
448 pub(crate) fn set_some(&mut self, i: Ie, value: T) {
449 self.set(i, Some(value))
450 }
451}
452
453impl<Ie: Idx, Id: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>>
454 TableBuilder<Ie, Id, T>
455{
456 pub(crate) fn set(&mut self, i: Ie, value: T) {
462 #[cfg(debug_assertions)]
463 {
464 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!(
465 T::from_bytes(&[0; N]).is_default(),
466 "expected all-zeroes to decode to the default value, as per the invariant of FixedSizeEncoding"
467 );
468 }
469 if !value.is_default() {
470 let block = self.blocks.ensure_contains_elem(i, || [0; N]);
476 value.write_to_bytes(block);
477 if self.width != N {
478 let width = N - trailing_zeros(block);
479 self.width = self.width.max(width);
480 }
481 }
482 }
483
484 pub(crate) fn encode(&self, buf: &mut FileEncoder<'_>) -> LazyTable<Ie, Id, T> {
485 let pos = buf.position();
486
487 let width = self.width;
488 for block in &self.blocks {
489 buf.write_with(|dest| {
490 *dest = *block;
491 width
492 });
493 }
494
495 LazyTable::from_position_and_encoded_size(
496 NonZero::new(pos).unwrap(),
497 width,
498 self.blocks.len(),
499 )
500 }
501}
502
503fn trailing_zeros(x: &[u8]) -> usize {
504 x.iter().rev().take_while(|b| **b == 0).count()
505}
506
507impl<
508 Ie: Idx,
509 Id: Idx,
510 const N: usize,
511 T: FixedSizeEncoding<ByteArray = [u8; N]> + ParameterizedOverTcx,
512> LazyTable<Ie, Id, 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: Id) -> 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}