From eb5f2d3980aa80fd91173401b167d55ec431a512 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 27 Jan 2023 23:28:33 +0400 Subject: [PATCH] rustc_metadata: Support encoding/decoding `LazyArray` without an `Option` --- compiler/rustc_metadata/src/rmeta/decoder.rs | 18 +++--- compiler/rustc_metadata/src/rmeta/encoder.rs | 6 +- compiler/rustc_metadata/src/rmeta/mod.rs | 10 ++-- compiler/rustc_metadata/src/rmeta/table.rs | 62 +++++++++++++++----- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index bb2dd290c6d..3125111b2bd 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -654,7 +654,7 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self { impl<'a, 'tcx, T> Decodable> for LazyArray { fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self { let len = decoder.read_usize(); - if len == 0 { LazyArray::empty() } else { decoder.read_lazy_array(len) } + if len == 0 { LazyArray::default() } else { decoder.read_lazy_array(len) } } } @@ -864,7 +864,7 @@ fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty:: .tables .children .get(self, index) - .unwrap_or_else(LazyArray::empty) + .unwrap_or_else(LazyArray::default) .decode(self) .map(|index| ty::FieldDef { did: self.local_def_id(index), @@ -896,7 +896,7 @@ fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> { .tables .children .get(self, item_id) - .unwrap_or_else(LazyArray::empty) + .unwrap_or_else(LazyArray::default) .decode(self) .filter_map(|index| { let kind = self.def_kind(index); @@ -1045,7 +1045,7 @@ fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool { .tables .fn_arg_names .get(self, id) - .unwrap_or_else(LazyArray::empty) + .unwrap_or_else(LazyArray::default) .decode((self, sess)) .nth(0) .map_or(false, |ident| ident.name == kw::SelfLower) @@ -1060,7 +1060,7 @@ fn get_associated_item_def_ids( .tables .children .get(self, id) - .unwrap_or_else(LazyArray::empty) + .unwrap_or_else(LazyArray::default) .decode((self, sess)) .map(move |child_index| self.local_def_id(child_index)) } @@ -1131,7 +1131,7 @@ fn get_struct_field_names( .tables .children .get(self, id) - .unwrap_or_else(LazyArray::empty) + .unwrap_or_else(LazyArray::default) .decode(self) .map(move |index| respan(self.get_span(index, sess), self.item_name(index))) } @@ -1144,7 +1144,7 @@ fn get_struct_field_visibilities( .tables .children .get(self, id) - .unwrap_or_else(LazyArray::empty) + .unwrap_or_else(LazyArray::default) .decode(self) .map(move |field_index| self.get_visibility(field_index)) } @@ -1159,7 +1159,7 @@ fn get_inherent_implementations_for_type( .tables .inherent_impls .get(self, id) - .unwrap_or_else(LazyArray::empty) + .unwrap_or_else(LazyArray::default) .decode(self) .map(|index| self.local_def_id(index)), ) @@ -1174,7 +1174,7 @@ fn get_inherent_impls(self) -> impl Iterator + 'a { .tables .inherent_impls .get(self, ty_index) - .unwrap_or_else(LazyArray::empty) + .unwrap_or_else(LazyArray::default) .decode(self) .map(move |impl_index| (ty_def_id, self.local_def_id(impl_index))) }) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 0533aacbd2f..ed63e940965 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -76,13 +76,13 @@ pub(super) struct EncodeContext<'a, 'tcx> { symbol_table: FxHashMap, } -/// If the current crate is a proc-macro, returns early with `LazyArray::empty()`. +/// If the current crate is a proc-macro, returns early with `LazyArray::default()`. /// This is useful for skipping the encoding of things that aren't needed /// for proc-macro crates. macro_rules! empty_proc_macro { ($self:ident) => { if $self.is_proc_macro { - return LazyArray::empty(); + return LazyArray::default(); } }; } @@ -1961,7 +1961,7 @@ fn encode_dylib_dependency_formats(&mut self) -> LazyArray Some(LinkagePreference::RequireStatic), })); } - LazyArray::empty() + LazyArray::default() } fn encode_info_for_foreign_item(&mut self, def_id: DefId, nitem: &hir::ForeignItem<'_>) { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index da82ae253e6..d8c778b935e 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -115,14 +115,16 @@ impl ParameterizedOverTcx for LazyArray { type Value<'tcx> = LazyArray>; } +impl Default for LazyArray { + fn default() -> LazyArray { + LazyArray::from_position_and_num_elems(NonZeroUsize::new(1).unwrap(), 0) + } +} + impl LazyArray { fn from_position_and_num_elems(position: NonZeroUsize, num_elems: usize) -> LazyArray { LazyArray { position, num_elems, _marker: PhantomData } } - - fn empty() -> LazyArray { - LazyArray::from_position_and_num_elems(NonZeroUsize::new(1).unwrap(), 0) - } } /// A list of lazily-decoded values, with the added capability of random access. diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 78cf9149f7d..11916553db5 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -38,6 +38,12 @@ fn is_default(&self) -> bool { } } +impl IsDefault for LazyArray { + fn is_default(&self) -> bool { + self.num_elems == 0 + } +} + /// Helper trait, for encoding to, and decoding from, a fixed number of bytes. /// Used mainly for Lazy positions and lengths. /// Unchecked invariant: `Self::default()` should encode as `[0; BYTE_LEN]`, @@ -286,32 +292,60 @@ impl FixedSizeEncoding for Option> { } } +impl LazyArray { + #[inline] + fn write_to_bytes_impl(self, b: &mut [u8; 8]) { + let ([position_bytes, meta_bytes],[])= b.as_chunks_mut::<4>() else { panic!() }; + + let position = self.position.get(); + let position: u32 = position.try_into().unwrap(); + position.write_to_bytes(position_bytes); + + let len = self.num_elems; + let len: u32 = len.try_into().unwrap(); + len.write_to_bytes(meta_bytes); + } + + fn from_bytes_impl(position_bytes: &[u8; 4], meta_bytes: &[u8; 4]) -> Option> { + let position = NonZeroUsize::new(u32::from_bytes(position_bytes) as usize)?; + let len = u32::from_bytes(meta_bytes) as usize; + Some(LazyArray::from_position_and_num_elems(position, len)) + } +} + +impl FixedSizeEncoding for LazyArray { + type ByteArray = [u8; 8]; + + #[inline] + fn from_bytes(b: &[u8; 8]) -> Self { + let ([position_bytes, meta_bytes],[])= b.as_chunks::<4>() else { panic!() }; + if *meta_bytes == [0; 4] { + return Default::default(); + } + LazyArray::from_bytes_impl(position_bytes, meta_bytes).unwrap() + } + + #[inline] + fn write_to_bytes(self, b: &mut [u8; 8]) { + assert!(!self.is_default()); + self.write_to_bytes_impl(b) + } +} + impl FixedSizeEncoding for Option> { type ByteArray = [u8; 8]; #[inline] fn from_bytes(b: &[u8; 8]) -> Self { let ([position_bytes, meta_bytes],[])= b.as_chunks::<4>() else { panic!() }; - let position = NonZeroUsize::new(u32::from_bytes(position_bytes) as usize)?; - let len = u32::from_bytes(meta_bytes) as usize; - Some(LazyArray::from_position_and_num_elems(position, len)) + LazyArray::from_bytes_impl(position_bytes, meta_bytes) } #[inline] fn write_to_bytes(self, b: &mut [u8; 8]) { match self { None => unreachable!(), - Some(lazy) => { - let ([position_bytes, meta_bytes],[])= b.as_chunks_mut::<4>() else { panic!() }; - - let position = lazy.position.get(); - let position: u32 = position.try_into().unwrap(); - position.write_to_bytes(position_bytes); - - let len = lazy.num_elems; - let len: u32 = len.try_into().unwrap(); - len.write_to_bytes(meta_bytes); - } + Some(lazy) => lazy.write_to_bytes_impl(b), } } }