提交 e7ceaa97 编写于 作者: E Eduard-Mihai Burtescu

rustc_metadata: replace LazySeq<T> with Lazy<[T]>.

上级 7858dc23
......@@ -68,9 +68,9 @@ pub struct CrateMetadata {
pub alloc_decoding_state: AllocDecodingState,
// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
// lifetime is only used behind `Lazy` / `LazySeq`, and therefore
// acts like an universal (`for<'tcx>`), that is paired up with
// whichever `TyCtxt` is being used to decode those values.
// lifetime is only used behind `Lazy`, and therefore acts like an
// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
// is being used to decode those values.
pub root: schema::CrateRoot<'static>,
/// For each definition in this crate, we encode a key. When the
......@@ -80,7 +80,7 @@ pub struct CrateMetadata {
/// compilation support.
pub def_path_table: Lrc<DefPathTable>,
pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>,
pub trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>,
pub dep_kind: Lock<DepKind>,
pub source: CrateSource,
......
......@@ -134,14 +134,14 @@ pub fn decode<M: Metadata<'a, 'tcx>>(self, meta: M) -> T {
}
}
impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> LazySeq<T> {
impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> {
pub fn decode<M: Metadata<'a, 'tcx>>(
self,
meta: M,
) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
let mut dcx = meta.decoder(self.position);
dcx.lazy_state = LazyState::NodeStart(self.position);
(0..self.len).map(move |_| T::decode(&mut dcx).unwrap())
(0..self.meta).map(move |_| T::decode(&mut dcx).unwrap())
}
}
......@@ -154,10 +154,14 @@ pub fn cdata(&self) -> &'a CrateMetadata {
self.cdata.expect("missing CrateMetadata in DecodeContext")
}
fn read_lazy_distance(&mut self, min_size: usize) -> Result<usize, <Self as Decoder>::Error> {
fn read_lazy_with_meta<T: ?Sized + LazyMeta>(
&mut self,
meta: T::Meta,
) -> Result<Lazy<T>, <Self as Decoder>::Error> {
let min_size = T::min_size(meta);
let distance = self.read_usize()?;
let position = match self.lazy_state {
LazyState::NoNode => bug!("read_lazy_distance: outside of a metadata node"),
LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
LazyState::NodeStart(start) => {
assert!(distance + min_size <= start);
start - distance - min_size
......@@ -165,7 +169,7 @@ fn read_lazy_distance(&mut self, min_size: usize) -> Result<usize, <Self as Deco
LazyState::Previous(last_min_end) => last_min_end + distance,
};
self.lazy_state = LazyState::Previous(position + min_size);
Ok(position)
Ok(Lazy::from_position_and_meta(position, meta))
}
}
......@@ -230,19 +234,18 @@ fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> {
Ok(Lazy::with_position(self.read_lazy_distance(Lazy::<T>::min_size())?))
self.read_lazy_with_meta(())
}
}
impl<'a, 'tcx, T> SpecializedDecoder<LazySeq<T>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<LazySeq<T>, Self::Error> {
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> {
let len = self.read_usize()?;
let position = if len == 0 {
0
if len == 0 {
Ok(Lazy::empty())
} else {
self.read_lazy_distance(LazySeq::<T>::min_size(len))?
};
Ok(LazySeq::with_position_and_length(position, len))
self.read_lazy_with_meta(len)
}
}
}
......@@ -378,7 +381,7 @@ pub fn is_compatible(&self) -> bool {
}
pub fn get_rustc_version(&self) -> String {
Lazy::with_position(METADATA_HEADER.len() + 4).decode(self)
Lazy::<String>::from_position(METADATA_HEADER.len() + 4).decode(self)
}
pub fn get_root(&self) -> CrateRoot<'tcx> {
......@@ -387,7 +390,7 @@ pub fn get_root(&self) -> CrateRoot<'tcx> {
let pos = (((slice[offset + 0] as u32) << 24) | ((slice[offset + 1] as u32) << 16) |
((slice[offset + 2] as u32) << 8) |
((slice[offset + 3] as u32) << 0)) as usize;
Lazy::with_position(pos).decode(self)
Lazy::<CrateRoot<'tcx>>::from_position(pos).decode(self)
}
pub fn list_crate_metadata(&self,
......@@ -1140,7 +1143,7 @@ pub fn get_fn_arg_names(&self, id: DefIndex) -> Vec<ast::Name> {
EntryKind::Fn(data) |
EntryKind::ForeignFn(data) => data.decode(self).arg_names,
EntryKind::Method(data) => data.decode(self).fn_data.arg_names,
_ => LazySeq::empty(),
_ => Lazy::empty(),
};
arg_names.decode(self).collect()
}
......
此差异已折叠。
......@@ -108,18 +108,18 @@ pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry<'tcx>>) {
position.write_to_bytes_at(positions, array_index)
}
pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Self> {
pub fn write_index(&self, buf: &mut Encoder) -> Lazy<[Self]> {
let pos = buf.position();
// First we write the length of the lower range ...
buf.emit_raw_bytes(&(self.positions.len() as u32 / 4).to_le_bytes());
// ... then the values.
buf.emit_raw_bytes(&self.positions);
LazySeq::with_position_and_length(pos as usize, self.positions.len() / 4 + 1)
Lazy::from_position_and_meta(pos as usize, self.positions.len() / 4 + 1)
}
}
impl LazySeq<Index<'tcx>> {
impl Lazy<[Index<'tcx>]> {
/// Given the metadata, extract out the offset of a particular
/// DefIndex (if any).
#[inline(never)]
......@@ -127,7 +127,7 @@ pub fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<Entry<'tc
let bytes = &bytes[self.position..];
debug!("Index::lookup: index={:?} len={:?}",
def_index,
self.len);
self.meta);
let position = u32::read_from_bytes_at(bytes, 1 + def_index.index());
if position == u32::MAX {
......@@ -135,7 +135,7 @@ pub fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<Entry<'tc
None
} else {
debug!("Index::lookup: position={:?}", position);
Some(Lazy::with_position(position as usize))
Some(Lazy::from_position(position as usize))
}
}
}
......@@ -41,6 +41,33 @@ pub fn rustc_version() -> String {
pub const METADATA_HEADER: &[u8; 12] =
&[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
/// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
/// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
pub trait LazyMeta {
type Meta: Copy + 'static;
/// Returns the minimum encoded size.
// FIXME(eddyb) Give better estimates for certain types.
fn min_size(meta: Self::Meta) -> usize;
}
impl<T> LazyMeta for T {
type Meta = ();
fn min_size(_: ()) -> usize {
assert_ne!(std::mem::size_of::<T>(), 0);
1
}
}
impl<T> LazyMeta for [T] {
type Meta = usize;
fn min_size(len: usize) -> usize {
len * T::min_size(())
}
}
/// A value of type T referred to by its absolute position
/// in the metadata, and which can be decoded lazily.
///
......@@ -56,40 +83,8 @@ pub fn rustc_version() -> String {
/// Distances start at 1, as 0-byte nodes are invalid.
/// Also invalid are nodes being referred in a different
/// order than they were encoded in.
#[must_use]
pub struct Lazy<T> {
pub position: usize,
_marker: PhantomData<T>,
}
impl<T> Lazy<T> {
pub fn with_position(position: usize) -> Lazy<T> {
Lazy {
position,
_marker: PhantomData,
}
}
/// Returns the minimum encoded size of a value of type `T`.
// FIXME(eddyb) Give better estimates for certain types.
pub fn min_size() -> usize {
1
}
}
impl<T> Copy for Lazy<T> {}
impl<T> Clone for Lazy<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> rustc_serialize::UseSpecializedEncodable for Lazy<T> {}
impl<T> rustc_serialize::UseSpecializedDecodable for Lazy<T> {}
/// A sequence of type T referred to by its absolute position
/// in the metadata and length, and which can be decoded lazily.
/// The sequence is a single node for the purposes of `Lazy`.
///
/// # Sequences (`Lazy<[T]>`)
///
/// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
/// position, not at the position, which means that the length
......@@ -100,54 +95,62 @@ impl<T> rustc_serialize::UseSpecializedDecodable for Lazy<T> {}
/// the minimal distance the length of the sequence, i.e.
/// it's assumed there's no 0-byte element in the sequence.
#[must_use]
pub struct LazySeq<T> {
pub len: usize,
// FIXME(#59875) the `Meta` parameter only exists to dodge
// invariance wrt `T` (coming from the `meta: T::Meta` field).
pub struct Lazy<T, Meta = <T as LazyMeta>::Meta>
where T: ?Sized + LazyMeta<Meta = Meta>,
Meta: 'static + Copy,
{
pub position: usize,
pub meta: Meta,
_marker: PhantomData<T>,
}
impl<T> LazySeq<T> {
pub fn empty() -> LazySeq<T> {
LazySeq::with_position_and_length(0, 0)
}
pub fn with_position_and_length(position: usize, len: usize) -> LazySeq<T> {
LazySeq {
len,
impl<T: ?Sized + LazyMeta> Lazy<T> {
pub fn from_position_and_meta(position: usize, meta: T::Meta) -> Lazy<T> {
Lazy {
position,
meta,
_marker: PhantomData,
}
}
}
impl<T> Lazy<T> {
pub fn from_position(position: usize) -> Lazy<T> {
Lazy::from_position_and_meta(position, ())
}
}
/// Returns the minimum encoded size of `length` values of type `T`.
pub fn min_size(length: usize) -> usize {
length
impl<T> Lazy<[T]> {
pub fn empty() -> Lazy<[T]> {
Lazy::from_position_and_meta(0, 0)
}
}
impl<T> Copy for LazySeq<T> {}
impl<T> Clone for LazySeq<T> {
impl<T: ?Sized + LazyMeta> Copy for Lazy<T> {}
impl<T: ?Sized + LazyMeta> Clone for Lazy<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> rustc_serialize::UseSpecializedEncodable for LazySeq<T> {}
impl<T> rustc_serialize::UseSpecializedDecodable for LazySeq<T> {}
impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedEncodable for Lazy<T> {}
impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedDecodable for Lazy<T> {}
/// Encoding / decoding state for `Lazy` and `LazySeq`.
/// Encoding / decoding state for `Lazy`.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum LazyState {
/// Outside of a metadata node.
NoNode,
/// Inside a metadata node, and before any `Lazy` or `LazySeq`.
/// Inside a metadata node, and before any `Lazy`.
/// The position is that of the node itself.
NodeStart(usize),
/// Inside a metadata node, with a previous `Lazy` or `LazySeq`.
/// Inside a metadata node, with a previous `Lazy`.
/// The position is a conservative estimate of where that
/// previous `Lazy` / `LazySeq` would end (see their comments).
/// previous `Lazy` would end (see their comments).
Previous(usize),
}
......@@ -167,24 +170,24 @@ pub struct CrateRoot<'tcx> {
pub proc_macro_decls_static: Option<DefIndex>,
pub proc_macro_stability: Option<attr::Stability>,
pub crate_deps: LazySeq<CrateDep>,
pub dylib_dependency_formats: LazySeq<Option<LinkagePreference>>,
pub lib_features: LazySeq<(Symbol, Option<Symbol>)>,
pub lang_items: LazySeq<(DefIndex, usize)>,
pub lang_items_missing: LazySeq<lang_items::LangItem>,
pub native_libraries: LazySeq<NativeLibrary>,
pub foreign_modules: LazySeq<ForeignModule>,
pub source_map: LazySeq<syntax_pos::SourceFile>,
pub crate_deps: Lazy<[CrateDep]>,
pub dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>,
pub lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
pub lang_items: Lazy<[(DefIndex, usize)]>,
pub lang_items_missing: Lazy<[lang_items::LangItem]>,
pub native_libraries: Lazy<[NativeLibrary]>,
pub foreign_modules: Lazy<[ForeignModule]>,
pub source_map: Lazy<[syntax_pos::SourceFile]>,
pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
pub impls: LazySeq<TraitImpls>,
pub exported_symbols: LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)>,
pub interpret_alloc_index: LazySeq<u32>,
pub impls: Lazy<[TraitImpls]>,
pub exported_symbols: Lazy<[(ExportedSymbol<'tcx>, SymbolExportLevel)]>,
pub interpret_alloc_index: Lazy<[u32]>,
pub entries_index: LazySeq<index::Index<'tcx>>,
pub entries_index: Lazy<[index::Index<'tcx>]>,
/// The DefIndex's of any proc macros delcared by
/// this crate
pub proc_macro_data: Option<LazySeq<DefIndex>>,
pub proc_macro_data: Option<Lazy<[DefIndex]>>,
pub compiler_builtins: bool,
pub needs_allocator: bool,
......@@ -207,7 +210,7 @@ pub struct CrateDep {
#[derive(RustcEncodable, RustcDecodable)]
pub struct TraitImpls {
pub trait_id: (u32, DefIndex),
pub impls: LazySeq<DefIndex>,
pub impls: Lazy<[DefIndex]>,
}
#[derive(RustcEncodable, RustcDecodable)]
......@@ -215,14 +218,14 @@ pub struct Entry<'tcx> {
pub kind: EntryKind<'tcx>,
pub visibility: Lazy<ty::Visibility>,
pub span: Lazy<Span>,
pub attributes: LazySeq<ast::Attribute>,
pub children: LazySeq<DefIndex>,
pub attributes: Lazy<[ast::Attribute]>,
pub children: Lazy<[DefIndex]>,
pub stability: Option<Lazy<attr::Stability>>,
pub deprecation: Option<Lazy<attr::Deprecation>>,
pub ty: Option<Lazy<Ty<'tcx>>>,
pub inherent_impls: LazySeq<DefIndex>,
pub variances: LazySeq<ty::Variance>,
pub inherent_impls: Lazy<[DefIndex]>,
pub variances: Lazy<[ty::Variance]>,
pub generics: Option<Lazy<ty::Generics>>,
pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>,
pub predicates_defined_on: Option<Lazy<ty::GenericPredicates<'tcx>>>,
......@@ -278,7 +281,7 @@ pub struct ConstQualif {
#[derive(RustcEncodable, RustcDecodable)]
pub struct ModData {
pub reexports: LazySeq<def::Export<hir::HirId>>,
pub reexports: Lazy<[def::Export<hir::HirId>]>,
}
#[derive(RustcEncodable, RustcDecodable)]
......@@ -290,7 +293,7 @@ pub struct MacroDef {
#[derive(RustcEncodable, RustcDecodable)]
pub struct FnData<'tcx> {
pub constness: hir::Constness,
pub arg_names: LazySeq<ast::Name>,
pub arg_names: Lazy<[ast::Name]>,
pub sig: Lazy<ty::PolyFnSig<'tcx>>,
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册