This commit is contained in:
Nicholas Nethercote 2022-06-10 11:58:29 +10:00
parent 7f51a1b976
commit 3186e311e5
13 changed files with 111 additions and 51 deletions

View file

@ -25,7 +25,6 @@ use rustc_span::hygiene::{
use rustc_span::source_map::{SourceMap, StableSourceFileId};
use rustc_span::CachingSourceMapView;
use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span};
use std::io;
use std::mem;
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
@ -808,10 +807,21 @@ impl_ref_decoder! {<'tcx>
//- ENCODING -------------------------------------------------------------------
pub trait OpaqueEncoder: Encoder {
fn position(&self) -> usize;
}
impl OpaqueEncoder for FileEncoder {
#[inline]
fn position(&self) -> usize {
FileEncoder::position(self)
}
}
/// An encoder that can write to the incremental compilation cache.
pub struct CacheEncoder<'a, 'tcx> {
pub struct CacheEncoder<'a, 'tcx, E: OpaqueEncoder> {
tcx: TyCtxt<'tcx>,
encoder: FileEncoder,
encoder: E,
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
predicate_shorthands: FxHashMap<ty::PredicateKind<'tcx>, usize>,
interpret_allocs: FxIndexSet<interpret::AllocId>,
@ -820,7 +830,10 @@ pub struct CacheEncoder<'a, 'tcx> {
hygiene_context: &'a HygieneEncodeContext,
}
impl<'a, 'tcx> CacheEncoder<'a, 'tcx> {
impl<'a, 'tcx, E> CacheEncoder<'a, 'tcx, E>
where
E: OpaqueEncoder,
{
fn source_file_index(&mut self, source_file: Lrc<SourceFile>) -> SourceFileIndex {
self.file_to_file_index[&(&*source_file as *const SourceFile)]
}
@ -839,27 +852,32 @@ impl<'a, 'tcx> CacheEncoder<'a, 'tcx> {
let end_pos = self.position();
((end_pos - start_pos) as u64).encode(self);
}
fn finish(self) -> Result<usize, io::Error> {
self.encoder.finish()
}
}
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for SyntaxContext {
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for SyntaxContext
where
E: OpaqueEncoder,
{
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) {
rustc_span::hygiene::raw_encode_syntax_context(*self, s.hygiene_context, s);
}
}
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for ExpnId {
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for ExpnId
where
E: OpaqueEncoder,
{
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) {
s.hygiene_context.schedule_expn_data_for_encoding(*self);
self.expn_hash().encode(s);
}
}
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Span {
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for Span
where
E: OpaqueEncoder,
{
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) {
let span_data = self.data_untracked();
span_data.ctxt.encode(s);
span_data.parent.encode(s);
@ -902,7 +920,10 @@ impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Span {
}
}
impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> {
impl<'a, 'tcx, E> TyEncoder for CacheEncoder<'a, 'tcx, E>
where
E: OpaqueEncoder,
{
type I = TyCtxt<'tcx>;
const CLEAR_CROSS_CRATE: bool = false;
@ -922,20 +943,29 @@ impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> {
}
}
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for CrateNum {
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for CrateNum
where
E: OpaqueEncoder,
{
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) {
s.tcx.stable_crate_id(*self).encode(s);
}
}
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for DefId {
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for DefId
where
E: OpaqueEncoder,
{
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) {
s.tcx.def_path_hash(*self).encode(s);
}
}
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for DefIndex {
fn encode(&self, _: &mut CacheEncoder<'a, 'tcx>) {
impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for DefIndex
where
E: OpaqueEncoder,
{
fn encode(&self, _: &mut CacheEncoder<'a, 'tcx, E>) {
bug!("encoding `DefIndex` without context");
}
}
@ -949,7 +979,13 @@ macro_rules! encoder_methods {
}
}
impl<'a, 'tcx> Encoder for CacheEncoder<'a, 'tcx> {
impl<'a, 'tcx, E> Encoder for CacheEncoder<'a, 'tcx, E>
where
E: OpaqueEncoder,
{
type Ok = E::Ok;
type Err = E::Err;
encoder_methods! {
emit_usize(usize);
emit_u128(u128);
@ -972,26 +1008,30 @@ impl<'a, 'tcx> Encoder for CacheEncoder<'a, 'tcx> {
emit_str(&str);
emit_raw_bytes(&[u8]);
}
fn finish(self) -> Result<E::Ok, E::Err> {
self.encoder.finish()
}
}
// This ensures that the `Encodable<opaque::FileEncoder>::encode` specialization for byte slices
// is used when a `CacheEncoder` having an `opaque::FileEncoder` is passed to `Encodable::encode`.
// Unfortunately, we have to manually opt into specializations this way, given how `CacheEncoder`
// and the encoding traits currently work.
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for [u8] {
fn encode(&self, e: &mut CacheEncoder<'a, 'tcx>) {
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx, FileEncoder>> for [u8] {
fn encode(&self, e: &mut CacheEncoder<'a, 'tcx, FileEncoder>) {
self.encode(&mut e.encoder);
}
}
pub fn encode_query_results<'a, 'tcx, CTX, Q>(
tcx: CTX,
encoder: &mut CacheEncoder<'a, 'tcx>,
encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>,
query_result_index: &mut EncodedDepNodeIndex,
) where
CTX: QueryContext + 'tcx,
Q: super::QueryDescription<CTX>,
Q::Value: Encodable<CacheEncoder<'a, 'tcx>>,
Q::Value: Encodable<CacheEncoder<'a, 'tcx, FileEncoder>>,
{
let _timer = tcx
.dep_context()

View file

@ -12,6 +12,7 @@ use rustc_query_system::query::{QueryContext, QueryJobId, QueryMap, QuerySideEff
use rustc_data_structures::sync::Lock;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::{Diagnostic, Handler};
use rustc_serialize::opaque;
use std::any::Any;
use std::num::NonZeroU64;
@ -139,7 +140,7 @@ impl<'tcx> QueryCtxt<'tcx> {
pub(super) fn encode_query_results(
self,
encoder: &mut on_disk_cache::CacheEncoder<'_, 'tcx>,
encoder: &mut on_disk_cache::CacheEncoder<'_, 'tcx, opaque::FileEncoder>,
query_result_index: &mut on_disk_cache::EncodedDepNodeIndex,
) {
macro_rules! encode_queries {