mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-30 12:07:40 +00:00
incr.comp.: Implement TyDecoder for on_disk_cache::CacheDecoder.
This commit is contained in:
parent
3bd333c988
commit
15db1652f8
@ -32,6 +32,10 @@ newtype_index!(CrateNum
|
|||||||
|
|
||||||
/// A CrateNum value that indicates that something is wrong.
|
/// A CrateNum value that indicates that something is wrong.
|
||||||
const INVALID_CRATE = u32::MAX - 1,
|
const INVALID_CRATE = u32::MAX - 1,
|
||||||
|
|
||||||
|
/// A special CrateNum that we use for the tcx.rcache when decoding from
|
||||||
|
/// the incr. comp. cache.
|
||||||
|
const RESERVED_FOR_INCR_COMP_CACHE = u32::MAX - 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
impl CrateNum {
|
impl CrateNum {
|
||||||
|
@ -45,6 +45,7 @@ use ty::AdtKind;
|
|||||||
|
|
||||||
use rustc_data_structures::indexed_vec;
|
use rustc_data_structures::indexed_vec;
|
||||||
|
|
||||||
|
use serialize::{self, Encoder, Encodable, Decoder, Decodable};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@ -85,13 +86,37 @@ pub mod svh;
|
|||||||
/// the local_id part of the HirId changing, which is a very useful property in
|
/// the local_id part of the HirId changing, which is a very useful property in
|
||||||
/// incremental compilation where we have to persist things through changes to
|
/// incremental compilation where we have to persist things through changes to
|
||||||
/// the code base.
|
/// the code base.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug,
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||||
RustcEncodable, RustcDecodable)]
|
|
||||||
pub struct HirId {
|
pub struct HirId {
|
||||||
pub owner: DefIndex,
|
pub owner: DefIndex,
|
||||||
pub local_id: ItemLocalId,
|
pub local_id: ItemLocalId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl serialize::UseSpecializedEncodable for HirId {
|
||||||
|
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
|
let HirId {
|
||||||
|
owner,
|
||||||
|
local_id,
|
||||||
|
} = *self;
|
||||||
|
|
||||||
|
owner.encode(s)?;
|
||||||
|
local_id.encode(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serialize::UseSpecializedDecodable for HirId {
|
||||||
|
fn default_decode<D: Decoder>(d: &mut D) -> Result<HirId, D::Error> {
|
||||||
|
let owner = DefIndex::decode(d)?;
|
||||||
|
let local_id = ItemLocalId::decode(d)?;
|
||||||
|
|
||||||
|
Ok(HirId {
|
||||||
|
owner,
|
||||||
|
local_id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// An `ItemLocalId` uniquely identifies something within a given "item-like",
|
/// An `ItemLocalId` uniquely identifies something within a given "item-like",
|
||||||
/// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
|
/// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
|
||||||
/// guarantee that the numerical value of a given `ItemLocalId` corresponds to
|
/// guarantee that the numerical value of a given `ItemLocalId` corresponds to
|
||||||
|
@ -9,21 +9,29 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
|
use dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
|
||||||
use errors::Diagnostic;
|
use errors::Diagnostic;
|
||||||
|
use hir;
|
||||||
|
use hir::def_id::{CrateNum, DefIndex, DefId, RESERVED_FOR_INCR_COMP_CACHE,
|
||||||
|
LOCAL_CRATE};
|
||||||
|
use hir::map::definitions::{Definitions, DefPathTable};
|
||||||
|
use middle::const_val::ByteArray;
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
|
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
|
||||||
SpecializedDecoder, SpecializedEncoder};
|
SpecializedDecoder, SpecializedEncoder,
|
||||||
|
UseSpecializedDecodable};
|
||||||
use session::Session;
|
use session::Session;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use syntax::ast::NodeId;
|
||||||
use syntax::codemap::{CodeMap, StableFilemapId};
|
use syntax::codemap::{CodeMap, StableFilemapId};
|
||||||
use syntax_pos::{BytePos, Span, NO_EXPANSION, DUMMY_SP};
|
use syntax_pos::{BytePos, Span, NO_EXPANSION, DUMMY_SP};
|
||||||
use ty;
|
use ty;
|
||||||
use ty::codec::{self as ty_codec};
|
use ty::codec::{self as ty_codec, TyDecoder};
|
||||||
use ty::context::TyCtxt;
|
use ty::context::TyCtxt;
|
||||||
|
use ty::subst::Substs;
|
||||||
|
|
||||||
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
|
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
|
||||||
/// previous compilation session. This data will eventually include the results
|
/// previous compilation session. This data will eventually include the results
|
||||||
@ -65,9 +73,12 @@ impl<'sess> OnDiskCache<'sess> {
|
|||||||
|
|
||||||
let prev_diagnostics = {
|
let prev_diagnostics = {
|
||||||
let mut decoder = CacheDecoder {
|
let mut decoder = CacheDecoder {
|
||||||
|
tcx: None,
|
||||||
opaque: decoder,
|
opaque: decoder,
|
||||||
codemap: sess.codemap(),
|
codemap: sess.codemap(),
|
||||||
prev_filemap_starts: &header.prev_filemap_starts,
|
prev_filemap_starts: &header.prev_filemap_starts,
|
||||||
|
cnum_map: &IndexVec::new(),
|
||||||
|
prev_def_path_tables: &Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let prev_diagnostics: FxHashMap<_, _> = {
|
let prev_diagnostics: FxHashMap<_, _> = {
|
||||||
@ -110,6 +121,7 @@ impl<'sess> OnDiskCache<'sess> {
|
|||||||
encoder,
|
encoder,
|
||||||
type_shorthands: FxHashMap(),
|
type_shorthands: FxHashMap(),
|
||||||
predicate_shorthands: FxHashMap(),
|
predicate_shorthands: FxHashMap(),
|
||||||
|
definitions: tcx.hir.definitions(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let prev_filemap_starts: BTreeMap<_, _> = self
|
let prev_filemap_starts: BTreeMap<_, _> = self
|
||||||
@ -174,13 +186,16 @@ impl<'sess> OnDiskCache<'sess> {
|
|||||||
/// A decoder that can read the incr. comp. cache. It is similar to the one
|
/// A decoder that can read the incr. comp. cache. It is similar to the one
|
||||||
/// we use for crate metadata decoding in that it can rebase spans and
|
/// we use for crate metadata decoding in that it can rebase spans and
|
||||||
/// eventually will also handle things that contain `Ty` instances.
|
/// eventually will also handle things that contain `Ty` instances.
|
||||||
struct CacheDecoder<'a> {
|
struct CacheDecoder<'a, 'tcx: 'a, 'x> {
|
||||||
opaque: opaque::Decoder<'a>,
|
tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
|
||||||
codemap: &'a CodeMap,
|
opaque: opaque::Decoder<'x>,
|
||||||
prev_filemap_starts: &'a BTreeMap<BytePos, StableFilemapId>,
|
codemap: &'x CodeMap,
|
||||||
|
prev_filemap_starts: &'x BTreeMap<BytePos, StableFilemapId>,
|
||||||
|
cnum_map: &'x IndexVec<CrateNum, Option<CrateNum>>,
|
||||||
|
prev_def_path_tables: &'x Vec<DefPathTable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CacheDecoder<'a> {
|
impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> {
|
||||||
fn find_filemap_prev_bytepos(&self,
|
fn find_filemap_prev_bytepos(&self,
|
||||||
prev_bytepos: BytePos)
|
prev_bytepos: BytePos)
|
||||||
-> Option<(BytePos, StableFilemapId)> {
|
-> Option<(BytePos, StableFilemapId)> {
|
||||||
@ -200,7 +215,7 @@ macro_rules! decoder_methods {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'sess> Decoder for CacheDecoder<'sess> {
|
impl<'a, 'tcx, 'x> Decoder for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
||||||
decoder_methods! {
|
decoder_methods! {
|
||||||
@ -232,7 +247,65 @@ impl<'sess> Decoder for CacheDecoder<'sess> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> {
|
impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
|
||||||
|
self.tcx.expect("missing TyCtxt in CacheDecoder")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn position(&self) -> usize {
|
||||||
|
self.opaque.position()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn peek_byte(&self) -> u8 {
|
||||||
|
self.opaque.data[self.opaque.position()]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cached_ty_for_shorthand<F>(&mut self,
|
||||||
|
shorthand: usize,
|
||||||
|
or_insert_with: F)
|
||||||
|
-> Result<ty::Ty<'tcx>, Self::Error>
|
||||||
|
where F: FnOnce(&mut Self) -> Result<ty::Ty<'tcx>, Self::Error>
|
||||||
|
{
|
||||||
|
let tcx = self.tcx();
|
||||||
|
|
||||||
|
let cache_key = ty::CReaderCacheKey {
|
||||||
|
cnum: RESERVED_FOR_INCR_COMP_CACHE,
|
||||||
|
pos: shorthand,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(&ty) = tcx.rcache.borrow().get(&cache_key) {
|
||||||
|
return Ok(ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ty = or_insert_with(self)?;
|
||||||
|
tcx.rcache.borrow_mut().insert(cache_key, ty);
|
||||||
|
Ok(ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
|
||||||
|
where F: FnOnce(&mut Self) -> R
|
||||||
|
{
|
||||||
|
debug_assert!(pos < self.opaque.data.len());
|
||||||
|
|
||||||
|
let new_opaque = opaque::Decoder::new(self.opaque.data, pos);
|
||||||
|
let old_opaque = mem::replace(&mut self.opaque, new_opaque);
|
||||||
|
let r = f(self);
|
||||||
|
self.opaque = old_opaque;
|
||||||
|
r
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
|
||||||
|
self.cnum_map[cnum].unwrap_or_else(|| {
|
||||||
|
bug!("Could not find new CrateNum for {:?}", cnum)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
|
||||||
let lo = BytePos::decode(self)?;
|
let lo = BytePos::decode(self)?;
|
||||||
let hi = BytePos::decode(self)?;
|
let hi = BytePos::decode(self)?;
|
||||||
@ -249,6 +322,142 @@ impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<CrateNum> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<CrateNum, Self::Error> {
|
||||||
|
let cnum = CrateNum::from_u32(u32::decode(self)?);
|
||||||
|
let mapped = self.map_encoded_cnum_to_current(cnum);
|
||||||
|
Ok(mapped)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This impl makes sure that we get a runtime error when we try decode a
|
||||||
|
// DefIndex that is not contained in a DefId. Such a case would be problematic
|
||||||
|
// because we would not know how to transform the DefIndex to the current
|
||||||
|
// context.
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
|
||||||
|
bug!("Trying to decode DefIndex outside the context of a DefId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both the CrateNum and the DefIndex of a DefId can change in between two
|
||||||
|
// compilation sessions. We use the DefPathHash, which is stable across
|
||||||
|
// sessions, to map the old DefId to the new one.
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
|
||||||
|
// Decode the unmapped CrateNum
|
||||||
|
let prev_cnum = CrateNum::default_decode(self)?;
|
||||||
|
|
||||||
|
// Decode the unmapped DefIndex
|
||||||
|
let def_index = DefIndex::default_decode(self)?;
|
||||||
|
|
||||||
|
// Unmapped CrateNum and DefIndex are valid keys for the *cached*
|
||||||
|
// DefPathTables, so we use them to look up the DefPathHash.
|
||||||
|
let def_path_hash = self.prev_def_path_tables[prev_cnum.index()]
|
||||||
|
.def_path_hash(def_index);
|
||||||
|
|
||||||
|
// Using the DefPathHash, we can lookup the new DefId
|
||||||
|
Ok(self.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<hir::HirId, Self::Error> {
|
||||||
|
// Decode the unmapped DefIndex of the HirId.
|
||||||
|
let def_index = DefIndex::default_decode(self)?;
|
||||||
|
|
||||||
|
// Use the unmapped DefIndex to look up the DefPathHash in the cached
|
||||||
|
// DefPathTable. For HirIds we know that we always have to look in the
|
||||||
|
// *local* DefPathTable.
|
||||||
|
let def_path_hash = self.prev_def_path_tables[LOCAL_CRATE.index()]
|
||||||
|
.def_path_hash(def_index);
|
||||||
|
|
||||||
|
// Use the DefPathHash to map to the current DefId.
|
||||||
|
let def_id = self.tcx()
|
||||||
|
.def_path_hash_to_def_id
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()[&def_path_hash];
|
||||||
|
|
||||||
|
// The ItemLocalId needs no remapping.
|
||||||
|
let local_id = hir::ItemLocalId::decode(self)?;
|
||||||
|
|
||||||
|
// Reconstruct the HirId and look up the corresponding NodeId in the
|
||||||
|
// context of the current session.
|
||||||
|
Ok(hir::HirId {
|
||||||
|
owner: def_id.index,
|
||||||
|
local_id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeIds are not stable across compilation sessions, so we store them in their
|
||||||
|
// HirId representation. This allows use to map them to the current NodeId.
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
|
||||||
|
let hir_id = hir::HirId::decode(self)?;
|
||||||
|
Ok(self.tcx().hir.hir_to_node_id(hir_id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<ty::Ty<'tcx>> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<ty::Ty<'tcx>, Self::Error> {
|
||||||
|
ty_codec::decode_ty(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<ty::GenericPredicates<'tcx>>
|
||||||
|
for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<ty::GenericPredicates<'tcx>, Self::Error> {
|
||||||
|
ty_codec::decode_predicates(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<&'tcx Substs<'tcx>> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<&'tcx Substs<'tcx>, Self::Error> {
|
||||||
|
ty_codec::decode_substs(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<ty::Region<'tcx>> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||||
|
ty_codec::decode_region(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<&'tcx ty::Slice<ty::Ty<'tcx>>>
|
||||||
|
for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice<ty::Ty<'tcx>>, Self::Error> {
|
||||||
|
ty_codec::decode_ty_slice(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<&'tcx ty::AdtDef> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<&'tcx ty::AdtDef, Self::Error> {
|
||||||
|
ty_codec::decode_adt_def(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>
|
||||||
|
for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self)
|
||||||
|
-> Result<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>, Self::Error> {
|
||||||
|
ty_codec::decode_existential_predicate_slice(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<ByteArray<'tcx>> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<ByteArray<'tcx>, Self::Error> {
|
||||||
|
ty_codec::decode_byte_array(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx, 'x> SpecializedDecoder<&'tcx ty::Const<'tcx>>
|
||||||
|
for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||||
|
ty_codec::decode_const(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//- ENCODING -------------------------------------------------------------------
|
//- ENCODING -------------------------------------------------------------------
|
||||||
|
|
||||||
@ -258,6 +467,7 @@ struct CacheEncoder<'enc, 'tcx, E>
|
|||||||
encoder: &'enc mut E,
|
encoder: &'enc mut E,
|
||||||
type_shorthands: FxHashMap<ty::Ty<'tcx>, usize>,
|
type_shorthands: FxHashMap<ty::Ty<'tcx>, usize>,
|
||||||
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
|
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
|
||||||
|
definitions: &'enc Definitions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'enc, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'enc, 'tcx, E>
|
impl<'enc, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'enc, 'tcx, E>
|
||||||
@ -289,6 +499,17 @@ impl<'enc, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeIds are not stable across compilation sessions, so we store them in their
|
||||||
|
// HirId representation. This allows use to map them to the current NodeId.
|
||||||
|
impl<'enc, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'tcx, E>
|
||||||
|
where E: 'enc + ty_codec::TyEncoder
|
||||||
|
{
|
||||||
|
fn specialized_encode(&mut self, node_id: &NodeId) -> Result<(), Self::Error> {
|
||||||
|
let hir_id = self.definitions.node_to_hir_id(*node_id);
|
||||||
|
hir_id.encode(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! encoder_methods {
|
macro_rules! encoder_methods {
|
||||||
($($name:ident($ty:ty);)*) => {
|
($($name:ident($ty:ty);)*) => {
|
||||||
$(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
|
$(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
|
||||||
|
Loading…
Reference in New Issue
Block a user