2021-06-28 19:12:01 +00:00
|
|
|
use crate::QueryCtxt;
|
2020-06-11 14:49:57 +00:00
|
|
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
2021-03-16 20:39:03 +00:00
|
|
|
use rustc_data_structures::memmap::Mmap;
|
2021-09-08 16:27:06 +00:00
|
|
|
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock};
|
2021-01-02 04:51:07 +00:00
|
|
|
use rustc_data_structures::unhash::UnhashMap;
|
2021-05-30 15:54:49 +00:00
|
|
|
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE};
|
2021-06-08 20:18:53 +00:00
|
|
|
use rustc_hir::definitions::DefPathHash;
|
2019-09-26 05:38:33 +00:00
|
|
|
use rustc_index::vec::{Idx, IndexVec};
|
2021-07-20 12:03:20 +00:00
|
|
|
use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
|
2021-06-28 19:12:01 +00:00
|
|
|
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
|
|
|
|
use rustc_middle::mir::{self, interpret};
|
|
|
|
use rustc_middle::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
|
2022-05-28 03:03:57 +00:00
|
|
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
2021-01-19 19:04:40 +00:00
|
|
|
use rustc_query_system::dep_graph::DepContext;
|
2022-02-20 03:44:19 +00:00
|
|
|
use rustc_query_system::query::{QueryCache, QueryContext, QuerySideEffects};
|
2020-12-07 01:30:55 +00:00
|
|
|
use rustc_serialize::{
|
2022-06-14 04:52:01 +00:00
|
|
|
opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder},
|
2020-12-07 01:30:55 +00:00
|
|
|
Decodable, Decoder, Encodable, Encoder,
|
|
|
|
};
|
2021-05-30 15:54:49 +00:00
|
|
|
use rustc_session::Session;
|
2020-03-17 15:45:02 +00:00
|
|
|
use rustc_span::hygiene::{
|
2021-06-24 19:02:09 +00:00
|
|
|
ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
|
2020-03-17 15:45:02 +00:00
|
|
|
};
|
2020-01-01 18:25:28 +00:00
|
|
|
use rustc_span::source_map::{SourceMap, StableSourceFileId};
|
2021-04-18 12:27:28 +00:00
|
|
|
use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span};
|
2022-07-03 16:18:53 +00:00
|
|
|
use rustc_span::{CachingSourceMapView, Symbol};
|
|
|
|
use std::collections::hash_map::Entry;
|
2022-06-16 06:00:25 +00:00
|
|
|
use std::io;
|
2017-10-19 12:32:39 +00:00
|
|
|
use std::mem;
|
|
|
|
|
2017-11-28 15:58:02 +00:00
|
|
|
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
|
2017-11-14 13:50:03 +00:00
|
|
|
|
2021-01-03 15:09:32 +00:00
|
|
|
// A normal span encoded with both location information and a `SyntaxContext`
|
|
|
|
const TAG_FULL_SPAN: u8 = 0;
|
|
|
|
// A partial span with no location information, encoded only with a `SyntaxContext`
|
|
|
|
const TAG_PARTIAL_SPAN: u8 = 1;
|
2021-04-18 12:27:28 +00:00
|
|
|
const TAG_RELATIVE_SPAN: u8 = 2;
|
2017-11-24 13:00:33 +00:00
|
|
|
|
2020-03-17 15:45:02 +00:00
|
|
|
const TAG_SYNTAX_CONTEXT: u8 = 0;
|
|
|
|
const TAG_EXPN_DATA: u8 = 1;
|
|
|
|
|
2022-07-03 16:18:53 +00:00
|
|
|
// Tags for encoding Symbol's
|
|
|
|
const SYMBOL_STR: u8 = 0;
|
|
|
|
const SYMBOL_OFFSET: u8 = 1;
|
2022-08-20 12:39:21 +00:00
|
|
|
const SYMBOL_PREINTERNED: u8 = 2;
|
2022-07-03 16:18:53 +00:00
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
/// Provides an interface to incremental compilation data cached from the
|
2017-10-24 12:51:26 +00:00
|
|
|
/// previous compilation session. This data will eventually include the results
|
2020-07-17 08:47:04 +00:00
|
|
|
/// of a few selected queries (like `typeck` and `mir_optimized`) and
|
2021-07-23 21:40:26 +00:00
|
|
|
/// any side effects that have been emitted during a query.
|
2017-10-19 12:32:39 +00:00
|
|
|
pub struct OnDiskCache<'sess> {
|
2017-11-14 15:15:45 +00:00
|
|
|
// The complete cache data in serialized form.
|
2021-03-17 21:49:16 +00:00
|
|
|
serialized_data: RwLock<Option<Mmap>>,
|
2017-11-14 15:15:45 +00:00
|
|
|
|
2021-07-23 21:40:26 +00:00
|
|
|
// Collects all `QuerySideEffects` created during the current compilation
|
2019-09-06 02:57:44 +00:00
|
|
|
// session.
|
2021-07-23 21:40:26 +00:00
|
|
|
current_side_effects: Lock<FxHashMap<DepNodeIndex, QuerySideEffects>>,
|
2017-10-24 12:51:26 +00:00
|
|
|
|
2018-08-18 10:14:14 +00:00
|
|
|
source_map: &'sess SourceMap,
|
2021-06-21 13:30:16 +00:00
|
|
|
file_index_to_stable_id: FxHashMap<SourceFileIndex, EncodedSourceFileId>,
|
2017-11-24 13:00:33 +00:00
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
// Caches that are populated lazily during decoding.
|
2018-08-18 10:13:52 +00:00
|
|
|
file_index_to_file: Lock<FxHashMap<SourceFileIndex, Lrc<SourceFile>>>,
|
2017-11-14 15:15:45 +00:00
|
|
|
|
|
|
|
// A map from dep-node to the position of the cached query result in
|
|
|
|
// `serialized_data`.
|
2017-11-28 13:19:44 +00:00
|
|
|
query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
|
2017-11-28 15:58:02 +00:00
|
|
|
|
2021-07-23 21:40:26 +00:00
|
|
|
// A map from dep-node to the position of any associated `QuerySideEffects` in
|
2017-11-28 15:58:02 +00:00
|
|
|
// `serialized_data`.
|
2021-07-23 21:40:26 +00:00
|
|
|
prev_side_effects_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
|
2018-03-16 08:59:42 +00:00
|
|
|
|
2018-05-25 15:19:31 +00:00
|
|
|
alloc_decoding_state: AllocDecodingState,
|
2020-03-17 15:45:02 +00:00
|
|
|
|
|
|
|
// A map from syntax context ids to the position of their associated
|
|
|
|
// `SyntaxContextData`. We use a `u32` instead of a `SyntaxContext`
|
|
|
|
// to represent the fact that we are storing *encoded* ids. When we decode
|
|
|
|
// a `SyntaxContext`, a new id will be allocated from the global `HygieneData`,
|
|
|
|
// which will almost certainly be different than the serialized id.
|
|
|
|
syntax_contexts: FxHashMap<u32, AbsoluteBytePos>,
|
|
|
|
// A map from the `DefPathHash` of an `ExpnId` to the position
|
|
|
|
// of their associated `ExpnData`. Ideally, we would store a `DefId`,
|
|
|
|
// but we need to decode this before we've constructed a `TyCtxt` (which
|
|
|
|
// makes it difficult to decode a `DefId`).
|
|
|
|
|
|
|
|
// Note that these `DefPathHashes` correspond to both local and foreign
|
|
|
|
// `ExpnData` (e.g `ExpnData.krate` may not be `LOCAL_CRATE`). Alternatively,
|
|
|
|
// we could look up the `ExpnData` from the metadata of foreign crates,
|
|
|
|
// but it seemed easier to have `OnDiskCache` be independent of the `CStore`.
|
2021-06-27 13:51:25 +00:00
|
|
|
expn_data: UnhashMap<ExpnHash, AbsoluteBytePos>,
|
2020-03-17 15:45:02 +00:00
|
|
|
// Additional information used when decoding hygiene data.
|
2020-07-24 07:01:07 +00:00
|
|
|
hygiene_context: HygieneDecodeContext,
|
2021-07-21 11:38:29 +00:00
|
|
|
// Maps `ExpnHash`es to their raw value from the *previous*
|
|
|
|
// compilation session. This is used as an initial 'guess' when
|
|
|
|
// we try to map an `ExpnHash` to its value in the current
|
|
|
|
// compilation session.
|
2021-06-27 13:51:25 +00:00
|
|
|
foreign_expn_data: UnhashMap<ExpnHash, u32>,
|
2017-10-19 12:32:39 +00:00
|
|
|
}
|
|
|
|
|
2020-03-17 15:45:02 +00:00
|
|
|
// This type is used only for serialization and deserialization.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Decodable)]
|
2017-11-28 15:58:02 +00:00
|
|
|
struct Footer {
|
2021-06-21 13:30:16 +00:00
|
|
|
file_index_to_stable_id: FxHashMap<SourceFileIndex, EncodedSourceFileId>,
|
2021-07-23 21:40:26 +00:00
|
|
|
query_result_index: EncodedDepNodeIndex,
|
|
|
|
side_effects_index: EncodedDepNodeIndex,
|
2019-09-06 02:57:44 +00:00
|
|
|
// The location of all allocations.
|
2018-05-25 15:19:31 +00:00
|
|
|
interpret_alloc_index: Vec<u32>,
|
2020-03-17 15:45:02 +00:00
|
|
|
// See `OnDiskCache.syntax_contexts`
|
|
|
|
syntax_contexts: FxHashMap<u32, AbsoluteBytePos>,
|
|
|
|
// See `OnDiskCache.expn_data`
|
2021-06-27 13:51:25 +00:00
|
|
|
expn_data: UnhashMap<ExpnHash, AbsoluteBytePos>,
|
|
|
|
foreign_expn_data: UnhashMap<ExpnHash, u32>,
|
2017-10-19 12:32:39 +00:00
|
|
|
}
|
|
|
|
|
2021-07-23 21:40:26 +00:00
|
|
|
pub type EncodedDepNodeIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
|
2017-10-19 12:32:39 +00:00
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable)]
|
2018-08-18 10:13:52 +00:00
|
|
|
struct SourceFileIndex(u32);
|
2017-11-24 13:00:33 +00:00
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Encodable, Decodable)]
|
2020-10-11 08:34:13 +00:00
|
|
|
pub struct AbsoluteBytePos(u32);
|
2017-11-28 13:19:44 +00:00
|
|
|
|
|
|
|
impl AbsoluteBytePos {
|
|
|
|
fn new(pos: usize) -> AbsoluteBytePos {
|
2020-03-04 12:18:08 +00:00
|
|
|
debug_assert!(pos <= u32::MAX as usize);
|
2017-11-28 13:19:44 +00:00
|
|
|
AbsoluteBytePos(pos as u32)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_usize(self) -> usize {
|
|
|
|
self.0 as usize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-21 13:30:16 +00:00
|
|
|
/// An `EncodedSourceFileId` is the same as a `StableSourceFileId` except that
|
|
|
|
/// the source crate is represented as a [StableCrateId] instead of as a
|
|
|
|
/// `CrateNum`. This way `EncodedSourceFileId` can be encoded and decoded
|
|
|
|
/// without any additional context, i.e. with a simple `opaque::Decoder` (which
|
|
|
|
/// is the only thing available when decoding the cache's [Footer].
|
|
|
|
#[derive(Encodable, Decodable, Clone, Debug)]
|
|
|
|
struct EncodedSourceFileId {
|
|
|
|
file_name_hash: u64,
|
|
|
|
stable_crate_id: StableCrateId,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl EncodedSourceFileId {
|
2021-09-08 16:27:06 +00:00
|
|
|
fn translate(&self, tcx: TyCtxt<'_>) -> StableSourceFileId {
|
|
|
|
let cnum = tcx.stable_crate_id_to_crate_num(self.stable_crate_id);
|
2021-06-21 13:30:16 +00:00
|
|
|
StableSourceFileId { file_name_hash: self.file_name_hash, cnum }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn new(tcx: TyCtxt<'_>, file: &SourceFile) -> EncodedSourceFileId {
|
|
|
|
let source_file_id = StableSourceFileId::new(file);
|
|
|
|
EncodedSourceFileId {
|
|
|
|
file_name_hash: source_file_id.file_name_hash,
|
|
|
|
stable_crate_id: tcx.stable_crate_id(source_file_id.cnum),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-28 19:12:01 +00:00
|
|
|
impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
|
2021-03-16 20:39:03 +00:00
|
|
|
/// Creates a new `OnDiskCache` instance from the serialized data in `data`.
|
|
|
|
fn new(sess: &'sess Session, data: Mmap, start_pos: usize) -> Self {
|
2017-10-19 12:32:39 +00:00
|
|
|
debug_assert!(sess.opts.incremental.is_some());
|
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
// Wrap in a scope so we can borrow `data`.
|
2017-11-28 15:58:02 +00:00
|
|
|
let footer: Footer = {
|
2022-06-14 04:52:01 +00:00
|
|
|
let mut decoder = MemDecoder::new(&data, start_pos);
|
2017-10-19 12:32:39 +00:00
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
// Decode the *position* of the footer, which can be found in the
|
2017-11-28 15:58:02 +00:00
|
|
|
// last 8 bytes of the file.
|
|
|
|
decoder.set_position(data.len() - IntEncodedWithFixedSize::ENCODED_SIZE);
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
let footer_pos = IntEncodedWithFixedSize::decode(&mut decoder).0 as usize;
|
2017-11-28 15:58:02 +00:00
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
// Decode the file footer, which contains all the lookup tables, etc.
|
|
|
|
decoder.set_position(footer_pos);
|
2020-03-17 15:45:02 +00:00
|
|
|
|
2017-11-28 15:58:02 +00:00
|
|
|
decode_tagged(&mut decoder, TAG_FILE_FOOTER)
|
2017-10-19 12:32:39 +00:00
|
|
|
};
|
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
Self {
|
2021-03-17 21:49:16 +00:00
|
|
|
serialized_data: RwLock::new(Some(data)),
|
2017-11-28 15:58:02 +00:00
|
|
|
file_index_to_stable_id: footer.file_index_to_stable_id,
|
2018-10-16 14:57:53 +00:00
|
|
|
file_index_to_file: Default::default(),
|
2018-08-18 10:14:14 +00:00
|
|
|
source_map: sess.source_map(),
|
2021-07-23 21:40:26 +00:00
|
|
|
current_side_effects: Default::default(),
|
2017-11-28 15:58:02 +00:00
|
|
|
query_result_index: footer.query_result_index.into_iter().collect(),
|
2021-07-23 21:40:26 +00:00
|
|
|
prev_side_effects_index: footer.side_effects_index.into_iter().collect(),
|
2018-05-25 15:19:31 +00:00
|
|
|
alloc_decoding_state: AllocDecodingState::new(footer.interpret_alloc_index),
|
2020-03-17 15:45:02 +00:00
|
|
|
syntax_contexts: footer.syntax_contexts,
|
|
|
|
expn_data: footer.expn_data,
|
2021-06-27 13:51:25 +00:00
|
|
|
foreign_expn_data: footer.foreign_expn_data,
|
2020-07-24 07:01:07 +00:00
|
|
|
hygiene_context: Default::default(),
|
2017-10-19 12:32:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-28 19:12:01 +00:00
|
|
|
fn new_empty(source_map: &'sess SourceMap) -> Self {
|
2019-09-06 02:57:44 +00:00
|
|
|
Self {
|
2021-03-17 21:49:16 +00:00
|
|
|
serialized_data: RwLock::new(None),
|
2018-10-16 14:57:53 +00:00
|
|
|
file_index_to_stable_id: Default::default(),
|
|
|
|
file_index_to_file: Default::default(),
|
2018-08-18 10:14:14 +00:00
|
|
|
source_map,
|
2021-07-23 21:40:26 +00:00
|
|
|
current_side_effects: Default::default(),
|
2018-10-16 14:57:53 +00:00
|
|
|
query_result_index: Default::default(),
|
2021-07-23 21:40:26 +00:00
|
|
|
prev_side_effects_index: Default::default(),
|
2018-05-25 15:19:31 +00:00
|
|
|
alloc_decoding_state: AllocDecodingState::new(Vec::new()),
|
2020-03-17 15:45:02 +00:00
|
|
|
syntax_contexts: FxHashMap::default(),
|
2021-06-27 13:51:25 +00:00
|
|
|
expn_data: UnhashMap::default(),
|
|
|
|
foreign_expn_data: UnhashMap::default(),
|
2020-07-24 07:01:07 +00:00
|
|
|
hygiene_context: Default::default(),
|
2017-10-24 12:51:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-28 19:49:51 +00:00
|
|
|
/// Execute all cache promotions and release the serialized backing Mmap.
|
|
|
|
///
|
|
|
|
/// Cache promotions require invoking queries, which needs to read the serialized data.
|
|
|
|
/// In order to serialize the new on-disk cache, the former on-disk cache file needs to be
|
|
|
|
/// deleted, hence we won't be able to refer to its memmapped data.
|
2021-12-14 17:13:07 +00:00
|
|
|
fn drop_serialized_data(&self, tcx: TyCtxt<'_>) {
|
2021-03-17 21:49:16 +00:00
|
|
|
// Load everything into memory so we can write it out to the on-disk
|
|
|
|
// cache. The vast majority of cacheable query results should already
|
|
|
|
// be in memory, so this should be a cheap operation.
|
|
|
|
// Do this *before* we clone 'latest_foreign_def_path_hashes', since
|
|
|
|
// loading existing queries may cause us to create new DepNodes, which
|
|
|
|
// may in turn end up invoking `store_foreign_def_id_hash`
|
2021-10-16 18:24:08 +00:00
|
|
|
tcx.dep_graph.exec_cache_promotions(tcx);
|
2021-03-17 21:49:16 +00:00
|
|
|
|
|
|
|
*self.serialized_data.write() = None;
|
|
|
|
}
|
|
|
|
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
fn serialize<'tcx>(&self, tcx: TyCtxt<'tcx>, encoder: FileEncoder) -> FileEncodeResult {
|
2019-09-06 02:57:44 +00:00
|
|
|
// Serializing the `DepGraph` should not modify it.
|
2017-12-28 05:05:45 +00:00
|
|
|
tcx.dep_graph.with_ignore(|| {
|
2019-09-06 02:57:44 +00:00
|
|
|
// Allocate `SourceFileIndex`es.
|
2017-12-28 05:05:45 +00:00
|
|
|
let (file_to_file_index, file_index_to_stable_id) = {
|
2018-10-19 15:18:03 +00:00
|
|
|
let files = tcx.sess.source_map().files();
|
|
|
|
let mut file_to_file_index =
|
|
|
|
FxHashMap::with_capacity_and_hasher(files.len(), Default::default());
|
|
|
|
let mut file_index_to_stable_id =
|
|
|
|
FxHashMap::with_capacity_and_hasher(files.len(), Default::default());
|
2017-12-28 05:05:45 +00:00
|
|
|
|
2018-10-19 15:18:03 +00:00
|
|
|
for (index, file) in files.iter().enumerate() {
|
2018-08-18 10:13:52 +00:00
|
|
|
let index = SourceFileIndex(index as u32);
|
|
|
|
let file_ptr: *const SourceFile = &**file as *const _;
|
2017-12-28 05:05:45 +00:00
|
|
|
file_to_file_index.insert(file_ptr, index);
|
2021-06-21 13:30:16 +00:00
|
|
|
let source_file_id = EncodedSourceFileId::new(tcx, &file);
|
|
|
|
file_index_to_stable_id.insert(index, source_file_id);
|
2017-12-28 05:05:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
(file_to_file_index, file_index_to_stable_id)
|
|
|
|
};
|
|
|
|
|
2020-07-24 07:01:07 +00:00
|
|
|
let hygiene_encode_context = HygieneEncodeContext::default();
|
|
|
|
|
2017-12-28 05:05:45 +00:00
|
|
|
let mut encoder = CacheEncoder {
|
|
|
|
tcx,
|
|
|
|
encoder,
|
2018-10-16 14:57:53 +00:00
|
|
|
type_shorthands: Default::default(),
|
2021-01-17 07:49:30 +00:00
|
|
|
predicate_shorthands: Default::default(),
|
2018-10-16 14:57:53 +00:00
|
|
|
interpret_allocs: Default::default(),
|
2018-08-18 10:14:25 +00:00
|
|
|
source_map: CachingSourceMapView::new(tcx.sess.source_map()),
|
2017-12-28 05:05:45 +00:00
|
|
|
file_to_file_index,
|
2020-07-24 07:01:07 +00:00
|
|
|
hygiene_context: &hygiene_encode_context,
|
2022-07-03 16:18:53 +00:00
|
|
|
symbol_table: Default::default(),
|
2017-12-28 05:05:45 +00:00
|
|
|
};
|
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
// Encode query results.
|
2021-07-23 21:40:26 +00:00
|
|
|
let mut query_result_index = EncodedDepNodeIndex::new();
|
2017-12-28 05:05:45 +00:00
|
|
|
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
tcx.sess.time("encode_query_results", || {
|
2017-12-28 05:05:45 +00:00
|
|
|
let enc = &mut encoder;
|
|
|
|
let qri = &mut query_result_index;
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
QueryCtxt::from_tcx(tcx).encode_query_results(enc, qri);
|
|
|
|
});
|
2018-03-09 06:09:24 +00:00
|
|
|
|
2021-07-23 21:40:26 +00:00
|
|
|
// Encode side effects.
|
|
|
|
let side_effects_index: EncodedDepNodeIndex = self
|
|
|
|
.current_side_effects
|
2018-10-01 13:39:17 +00:00
|
|
|
.borrow()
|
|
|
|
.iter()
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
.map(|(dep_node_index, side_effects)| {
|
|
|
|
let pos = AbsoluteBytePos::new(encoder.position());
|
|
|
|
let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
|
|
|
|
encoder.encode_tagged(dep_node_index, side_effects);
|
2020-12-07 01:30:55 +00:00
|
|
|
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
(dep_node_index, pos)
|
|
|
|
})
|
|
|
|
.collect();
|
2017-12-28 05:05:45 +00:00
|
|
|
|
2018-04-10 07:58:46 +00:00
|
|
|
let interpret_alloc_index = {
|
|
|
|
let mut interpret_alloc_index = Vec::new();
|
|
|
|
let mut n = 0;
|
|
|
|
loop {
|
2020-08-08 03:44:47 +00:00
|
|
|
let new_n = encoder.interpret_allocs.len();
|
2019-09-06 02:57:44 +00:00
|
|
|
// If we have found new IDs, serialize those too.
|
2018-04-13 16:48:41 +00:00
|
|
|
if n == new_n {
|
2019-09-06 02:57:44 +00:00
|
|
|
// Otherwise, abort.
|
2018-04-13 16:48:41 +00:00
|
|
|
break;
|
|
|
|
}
|
2018-11-05 14:30:04 +00:00
|
|
|
interpret_alloc_index.reserve(new_n - n);
|
2018-04-10 07:58:46 +00:00
|
|
|
for idx in n..new_n {
|
2020-08-08 03:44:47 +00:00
|
|
|
let id = encoder.interpret_allocs[idx];
|
2018-05-25 15:19:31 +00:00
|
|
|
let pos = encoder.position() as u32;
|
2018-04-10 07:58:46 +00:00
|
|
|
interpret_alloc_index.push(pos);
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
interpret::specialized_encode_alloc_id(&mut encoder, tcx, id);
|
2018-04-10 07:58:46 +00:00
|
|
|
}
|
|
|
|
n = new_n;
|
|
|
|
}
|
|
|
|
interpret_alloc_index
|
|
|
|
};
|
|
|
|
|
2020-03-17 15:45:02 +00:00
|
|
|
let mut syntax_contexts = FxHashMap::default();
|
2021-06-27 13:51:25 +00:00
|
|
|
let mut expn_data = UnhashMap::default();
|
|
|
|
let mut foreign_expn_data = UnhashMap::default();
|
2020-03-17 15:45:02 +00:00
|
|
|
|
|
|
|
// Encode all hygiene data (`SyntaxContextData` and `ExpnData`) from the current
|
|
|
|
// session.
|
|
|
|
|
2020-07-24 07:01:07 +00:00
|
|
|
hygiene_encode_context.encode(
|
|
|
|
&mut encoder,
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
|encoder, index, ctxt_data| {
|
2020-07-24 07:01:07 +00:00
|
|
|
let pos = AbsoluteBytePos::new(encoder.position());
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
encoder.encode_tagged(TAG_SYNTAX_CONTEXT, ctxt_data);
|
2020-07-24 07:01:07 +00:00
|
|
|
syntax_contexts.insert(index, pos);
|
|
|
|
},
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
|encoder, expn_id, data, hash| {
|
2021-06-27 13:51:25 +00:00
|
|
|
if expn_id.krate == LOCAL_CRATE {
|
2021-07-10 21:34:41 +00:00
|
|
|
let pos = AbsoluteBytePos::new(encoder.position());
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
encoder.encode_tagged(TAG_EXPN_DATA, data);
|
2021-06-27 13:51:25 +00:00
|
|
|
expn_data.insert(hash, pos);
|
|
|
|
} else {
|
|
|
|
foreign_expn_data.insert(hash, expn_id.local_id.as_u32());
|
2021-07-10 21:34:41 +00:00
|
|
|
}
|
2020-07-24 07:01:07 +00:00
|
|
|
},
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
);
|
2020-03-17 15:45:02 +00:00
|
|
|
|
|
|
|
// `Encode the file footer.
|
2017-12-28 05:05:45 +00:00
|
|
|
let footer_pos = encoder.position() as u64;
|
|
|
|
encoder.encode_tagged(
|
|
|
|
TAG_FILE_FOOTER,
|
|
|
|
&Footer {
|
|
|
|
file_index_to_stable_id,
|
|
|
|
query_result_index,
|
2021-07-23 21:40:26 +00:00
|
|
|
side_effects_index,
|
2018-04-10 07:58:46 +00:00
|
|
|
interpret_alloc_index,
|
2020-03-17 15:45:02 +00:00
|
|
|
syntax_contexts,
|
2021-06-27 13:51:25 +00:00
|
|
|
expn_data,
|
|
|
|
foreign_expn_data,
|
2017-12-28 05:05:45 +00:00
|
|
|
},
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
);
|
2017-12-28 05:05:45 +00:00
|
|
|
|
|
|
|
// Encode the position of the footer as the last 8 bytes of the
|
|
|
|
// file so we know where to look for it.
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
IntEncodedWithFixedSize(footer_pos).encode(&mut encoder.encoder);
|
2017-12-28 05:05:45 +00:00
|
|
|
|
|
|
|
// DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
|
|
|
|
// of the footer must be the last thing in the data stream.
|
|
|
|
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
encoder.finish()
|
2017-12-28 05:05:45 +00:00
|
|
|
})
|
2017-10-19 12:32:39 +00:00
|
|
|
}
|
2021-06-28 19:12:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'sess> OnDiskCache<'sess> {
|
|
|
|
pub fn as_dyn(&self) -> &dyn rustc_middle::ty::OnDiskCache<'sess> {
|
|
|
|
self as _
|
|
|
|
}
|
|
|
|
|
2021-07-23 21:40:26 +00:00
|
|
|
/// Loads a `QuerySideEffects` created during the previous compilation session.
|
|
|
|
pub fn load_side_effects(
|
2019-06-11 21:11:55 +00:00
|
|
|
&self,
|
2019-06-21 21:49:03 +00:00
|
|
|
tcx: TyCtxt<'_>,
|
2019-06-11 21:11:55 +00:00
|
|
|
dep_node_index: SerializedDepNodeIndex,
|
2021-07-23 21:40:26 +00:00
|
|
|
) -> QuerySideEffects {
|
|
|
|
let side_effects: Option<QuerySideEffects> =
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index);
|
2017-11-28 15:58:02 +00:00
|
|
|
|
2021-07-23 21:40:26 +00:00
|
|
|
side_effects.unwrap_or_default()
|
2017-10-19 12:32:39 +00:00
|
|
|
}
|
|
|
|
|
2021-07-23 21:40:26 +00:00
|
|
|
/// Stores a `QuerySideEffects` emitted during the current compilation session.
|
|
|
|
/// Anything stored like this will be available via `load_side_effects` in
|
2017-10-24 12:51:26 +00:00
|
|
|
/// the next compilation session.
|
2018-12-07 02:04:23 +00:00
|
|
|
#[inline(never)]
|
|
|
|
#[cold]
|
2021-07-23 21:40:26 +00:00
|
|
|
pub fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) {
|
|
|
|
let mut current_side_effects = self.current_side_effects.borrow_mut();
|
|
|
|
let prev = current_side_effects.insert(dep_node_index, side_effects);
|
2017-10-19 12:32:39 +00:00
|
|
|
debug_assert!(prev.is_none());
|
|
|
|
}
|
|
|
|
|
2017-11-28 16:32:28 +00:00
|
|
|
/// Returns the cached query result if there is something in the cache for
|
2019-02-08 13:53:55 +00:00
|
|
|
/// the given `SerializedDepNodeIndex`; otherwise returns `None`.
|
2021-01-19 19:40:16 +00:00
|
|
|
pub fn try_load_query_result<'tcx, T>(
|
2019-06-11 21:11:55 +00:00
|
|
|
&self,
|
2020-06-11 14:49:57 +00:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2019-06-11 21:11:55 +00:00
|
|
|
dep_node_index: SerializedDepNodeIndex,
|
|
|
|
) -> Option<T>
|
|
|
|
where
|
2020-06-11 14:49:57 +00:00
|
|
|
T: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
|
2017-11-14 15:15:45 +00:00
|
|
|
{
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
self.load_indexed(tcx, dep_node_index, &self.query_result_index)
|
2017-11-28 15:58:02 +00:00
|
|
|
}
|
|
|
|
|
2021-07-23 21:40:26 +00:00
|
|
|
/// Stores side effect emitted during computation of an anonymous query.
|
2017-11-28 15:58:02 +00:00
|
|
|
/// Since many anonymous queries can share the same `DepNode`, we aggregate
|
|
|
|
/// them -- as opposed to regular queries where we assume that there is a
|
|
|
|
/// 1:1 relationship between query-key and `DepNode`.
|
2018-12-07 02:04:23 +00:00
|
|
|
#[inline(never)]
|
|
|
|
#[cold]
|
2021-07-23 21:40:26 +00:00
|
|
|
pub fn store_side_effects_for_anon_node(
|
2017-11-28 15:58:02 +00:00
|
|
|
&self,
|
|
|
|
dep_node_index: DepNodeIndex,
|
2021-07-23 21:40:26 +00:00
|
|
|
side_effects: QuerySideEffects,
|
2018-12-07 02:04:23 +00:00
|
|
|
) {
|
2021-07-23 21:40:26 +00:00
|
|
|
let mut current_side_effects = self.current_side_effects.borrow_mut();
|
2017-11-28 15:58:02 +00:00
|
|
|
|
2021-07-23 21:40:26 +00:00
|
|
|
let x = current_side_effects.entry(dep_node_index).or_default();
|
|
|
|
x.append(side_effects);
|
2017-11-28 15:58:02 +00:00
|
|
|
}
|
|
|
|
|
2019-06-11 21:11:55 +00:00
|
|
|
fn load_indexed<'tcx, T>(
|
|
|
|
&self,
|
2019-06-13 21:48:52 +00:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2019-06-11 21:11:55 +00:00
|
|
|
dep_node_index: SerializedDepNodeIndex,
|
|
|
|
index: &FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
|
|
|
|
) -> Option<T>
|
|
|
|
where
|
2020-06-11 14:49:57 +00:00
|
|
|
T: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
|
2017-11-28 15:58:02 +00:00
|
|
|
{
|
2018-12-19 12:19:48 +00:00
|
|
|
let pos = index.get(&dep_node_index).cloned()?;
|
2017-11-14 15:15:45 +00:00
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
self.with_decoder(tcx, pos, |decoder| Some(decode_tagged(decoder, dep_node_index)))
|
2020-03-17 15:45:02 +00:00
|
|
|
}
|
|
|
|
|
2021-03-17 21:49:16 +00:00
|
|
|
fn with_decoder<'a, 'tcx, T, F: for<'s> FnOnce(&mut CacheDecoder<'s, 'tcx>) -> T>(
|
2020-03-17 15:45:02 +00:00
|
|
|
&'sess self,
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
pos: AbsoluteBytePos,
|
|
|
|
f: F,
|
|
|
|
) -> T
|
|
|
|
where
|
2020-06-11 14:49:57 +00:00
|
|
|
T: Decodable<CacheDecoder<'a, 'tcx>>,
|
2020-03-17 15:45:02 +00:00
|
|
|
{
|
2021-03-17 21:49:16 +00:00
|
|
|
let serialized_data = self.serialized_data.read();
|
2017-11-14 15:15:45 +00:00
|
|
|
let mut decoder = CacheDecoder {
|
2017-11-28 15:58:02 +00:00
|
|
|
tcx,
|
2022-06-14 04:52:01 +00:00
|
|
|
opaque: MemDecoder::new(serialized_data.as_deref().unwrap_or(&[]), pos.to_usize()),
|
2018-08-18 10:14:14 +00:00
|
|
|
source_map: self.source_map,
|
2018-02-13 14:50:37 +00:00
|
|
|
file_index_to_file: &self.file_index_to_file,
|
2017-11-24 13:00:33 +00:00
|
|
|
file_index_to_stable_id: &self.file_index_to_stable_id,
|
2018-05-25 15:19:31 +00:00
|
|
|
alloc_decoding_session: self.alloc_decoding_state.new_decoding_session(),
|
2020-03-17 15:45:02 +00:00
|
|
|
syntax_contexts: &self.syntax_contexts,
|
|
|
|
expn_data: &self.expn_data,
|
2021-06-27 13:51:25 +00:00
|
|
|
foreign_expn_data: &self.foreign_expn_data,
|
2020-03-17 15:45:02 +00:00
|
|
|
hygiene_context: &self.hygiene_context,
|
2017-11-14 15:15:45 +00:00
|
|
|
};
|
2020-03-17 15:45:02 +00:00
|
|
|
f(&mut decoder)
|
2017-11-14 15:15:45 +00:00
|
|
|
}
|
2017-10-19 12:32:39 +00:00
|
|
|
}
|
|
|
|
|
2017-11-13 15:35:51 +00:00
|
|
|
//- DECODING -------------------------------------------------------------------
|
|
|
|
|
2020-12-19 22:25:24 +00:00
|
|
|
/// A decoder that can read from the incremental compilation cache. It is similar to the one
|
2019-09-06 02:57:44 +00:00
|
|
|
/// we use for crate metadata decoding in that it can rebase spans and eventually
|
|
|
|
/// will also handle things that contain `Ty` instances.
|
2021-01-19 19:40:16 +00:00
|
|
|
pub struct CacheDecoder<'a, 'tcx> {
|
2019-06-13 21:48:52 +00:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2022-06-14 04:52:01 +00:00
|
|
|
opaque: MemDecoder<'a>,
|
2019-06-11 19:03:44 +00:00
|
|
|
source_map: &'a SourceMap,
|
|
|
|
file_index_to_file: &'a Lock<FxHashMap<SourceFileIndex, Lrc<SourceFile>>>,
|
2021-06-21 13:30:16 +00:00
|
|
|
file_index_to_stable_id: &'a FxHashMap<SourceFileIndex, EncodedSourceFileId>,
|
2019-06-11 19:03:44 +00:00
|
|
|
alloc_decoding_session: AllocDecodingSession<'a>,
|
2020-03-17 15:45:02 +00:00
|
|
|
syntax_contexts: &'a FxHashMap<u32, AbsoluteBytePos>,
|
2021-06-27 13:51:25 +00:00
|
|
|
expn_data: &'a UnhashMap<ExpnHash, AbsoluteBytePos>,
|
|
|
|
foreign_expn_data: &'a UnhashMap<ExpnHash, u32>,
|
2020-07-24 07:01:07 +00:00
|
|
|
hygiene_context: &'a HygieneDecodeContext,
|
2017-10-19 12:32:39 +00:00
|
|
|
}
|
|
|
|
|
2019-06-11 19:03:44 +00:00
|
|
|
impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
|
2018-08-18 10:13:52 +00:00
|
|
|
fn file_index_to_file(&self, index: SourceFileIndex) -> Lrc<SourceFile> {
|
2017-11-24 13:00:33 +00:00
|
|
|
let CacheDecoder {
|
2021-09-08 16:27:06 +00:00
|
|
|
tcx,
|
2018-02-13 14:50:37 +00:00
|
|
|
ref file_index_to_file,
|
2017-11-24 13:00:33 +00:00
|
|
|
ref file_index_to_stable_id,
|
2018-08-18 10:14:14 +00:00
|
|
|
ref source_map,
|
2017-11-24 13:00:33 +00:00
|
|
|
..
|
|
|
|
} = *self;
|
|
|
|
|
2018-02-13 14:50:37 +00:00
|
|
|
file_index_to_file
|
|
|
|
.borrow_mut()
|
|
|
|
.entry(index)
|
|
|
|
.or_insert_with(|| {
|
2021-09-08 16:27:06 +00:00
|
|
|
let stable_id = file_index_to_stable_id[&index].translate(tcx);
|
2021-12-21 19:01:10 +00:00
|
|
|
|
|
|
|
// If this `SourceFile` is from a foreign crate, then make sure
|
|
|
|
// that we've imported all of the source files from that crate.
|
|
|
|
// This has usually already been done during macro invocation.
|
|
|
|
// However, when encoding query results like `TypeckResults`,
|
|
|
|
// we might encode an `AdtDef` for a foreign type (because it
|
|
|
|
// was referenced in the body of the function). There is no guarantee
|
|
|
|
// that we will load the source files from that crate during macro
|
|
|
|
// expansion, so we use `import_source_files` to ensure that the foreign
|
|
|
|
// source files are actually imported before we call `source_file_by_stable_id`.
|
|
|
|
if stable_id.cnum != LOCAL_CRATE {
|
|
|
|
self.tcx.cstore_untracked().import_source_files(self.tcx.sess, stable_id.cnum);
|
|
|
|
}
|
|
|
|
|
2018-08-18 10:14:14 +00:00
|
|
|
source_map
|
|
|
|
.source_file_by_stable_id(stable_id)
|
2019-09-06 02:57:44 +00:00
|
|
|
.expect("failed to lookup `SourceFile` in new context")
|
2017-11-24 13:00:33 +00:00
|
|
|
})
|
|
|
|
.clone()
|
2017-10-19 12:32:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-06 20:05:37 +00:00
|
|
|
trait DecoderWithPosition: Decoder {
|
2017-11-28 15:58:02 +00:00
|
|
|
fn position(&self) -> usize;
|
|
|
|
}
|
|
|
|
|
2022-06-14 04:52:01 +00:00
|
|
|
impl<'a> DecoderWithPosition for MemDecoder<'a> {
|
2017-11-28 15:58:02 +00:00
|
|
|
fn position(&self) -> usize {
|
|
|
|
self.position()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-11 19:03:44 +00:00
|
|
|
impl<'a, 'tcx> DecoderWithPosition for CacheDecoder<'a, 'tcx> {
|
2017-11-28 15:58:02 +00:00
|
|
|
fn position(&self) -> usize {
|
|
|
|
self.opaque.position()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
// Decodes something that was encoded with `encode_tagged()` and verify that the
|
2017-11-14 13:50:03 +00:00
|
|
|
// tag matches and the correct amount of bytes was read.
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> V
|
2019-06-16 09:41:24 +00:00
|
|
|
where
|
2020-10-13 08:17:05 +00:00
|
|
|
T: Decodable<D> + Eq + std::fmt::Debug,
|
2020-06-11 14:49:57 +00:00
|
|
|
V: Decodable<D>,
|
2019-06-16 09:41:24 +00:00
|
|
|
D: DecoderWithPosition,
|
2017-11-14 13:50:03 +00:00
|
|
|
{
|
|
|
|
let start_pos = decoder.position();
|
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
let actual_tag = T::decode(decoder);
|
2017-11-14 13:50:03 +00:00
|
|
|
assert_eq!(actual_tag, expected_tag);
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
let value = V::decode(decoder);
|
2017-11-14 13:50:03 +00:00
|
|
|
let end_pos = decoder.position();
|
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
let expected_len: u64 = Decodable::decode(decoder);
|
2017-11-14 13:50:03 +00:00
|
|
|
assert_eq!((end_pos - start_pos) as u64, expected_len);
|
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
value
|
2017-11-14 13:50:03 +00:00
|
|
|
}
|
|
|
|
|
2021-01-31 09:32:34 +00:00
|
|
|
impl<'a, 'tcx> TyDecoder for CacheDecoder<'a, 'tcx> {
|
2022-05-28 03:03:57 +00:00
|
|
|
type I = TyCtxt<'tcx>;
|
2020-06-11 14:49:57 +00:00
|
|
|
const CLEAR_CROSS_CRATE: bool = false;
|
|
|
|
|
2017-11-14 11:03:57 +00:00
|
|
|
#[inline]
|
2022-05-28 03:03:57 +00:00
|
|
|
fn interner(&self) -> TyCtxt<'tcx> {
|
|
|
|
self.tcx
|
2017-11-14 11:03:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn position(&self) -> usize {
|
|
|
|
self.opaque.position()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn peek_byte(&self) -> u8 {
|
|
|
|
self.opaque.data[self.opaque.position()]
|
|
|
|
}
|
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
|
2019-04-25 20:54:19 +00:00
|
|
|
where
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
F: FnOnce(&mut Self) -> Ty<'tcx>,
|
2017-11-14 11:03:57 +00:00
|
|
|
{
|
2021-01-31 09:32:34 +00:00
|
|
|
let tcx = self.tcx;
|
2017-11-14 11:03:57 +00:00
|
|
|
|
2021-05-30 12:06:26 +00:00
|
|
|
let cache_key = ty::CReaderCacheKey { cnum: None, pos: shorthand };
|
2017-11-14 11:03:57 +00:00
|
|
|
|
2020-06-10 08:26:54 +00:00
|
|
|
if let Some(&ty) = tcx.ty_rcache.borrow().get(&cache_key) {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
return ty;
|
2017-11-14 11:03:57 +00:00
|
|
|
}
|
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
let ty = or_insert_with(self);
|
2019-09-06 02:57:44 +00:00
|
|
|
// This may overwrite the entry, but it should overwrite with the same value.
|
2020-06-10 08:26:54 +00:00
|
|
|
tcx.ty_rcache.borrow_mut().insert_same(cache_key, ty);
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
ty
|
2017-11-14 11:03:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
|
2022-06-14 04:52:01 +00:00
|
|
|
let new_opaque = MemDecoder::new(self.opaque.data, pos);
|
2017-11-14 11:03:57 +00:00
|
|
|
let old_opaque = mem::replace(&mut self.opaque, new_opaque);
|
|
|
|
let r = f(self);
|
|
|
|
self.opaque = old_opaque;
|
|
|
|
r
|
|
|
|
}
|
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode_alloc_id(&mut self) -> interpret::AllocId {
|
2020-06-11 14:49:57 +00:00
|
|
|
let alloc_decoding_session = self.alloc_decoding_session;
|
|
|
|
alloc_decoding_session.decode_alloc_id(self)
|
|
|
|
}
|
2017-11-14 11:03:57 +00:00
|
|
|
}
|
|
|
|
|
2021-06-28 19:12:01 +00:00
|
|
|
rustc_middle::implement_ty_decoder!(CacheDecoder<'a, 'tcx>);
|
2017-11-16 14:26:00 +00:00
|
|
|
|
2020-12-17 05:03:45 +00:00
|
|
|
// This ensures that the `Decodable<opaque::Decoder>::decode` specialization for `Vec<u8>` is used
|
|
|
|
// when a `CacheDecoder` is passed to `Decodable::decode`. Unfortunately, we have to manually opt
|
|
|
|
// into specializations this way, given how `CacheDecoder` and the decoding traits currently work.
|
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Vec<u8> {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
2020-12-17 05:03:45 +00:00
|
|
|
Decodable::decode(&mut d.opaque)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
2020-06-11 14:49:57 +00:00
|
|
|
let syntax_contexts = decoder.syntax_contexts;
|
|
|
|
rustc_span::hygiene::decode_syntax_context(decoder, decoder.hygiene_context, |this, id| {
|
2020-03-17 15:45:02 +00:00
|
|
|
// This closure is invoked if we haven't already decoded the data for the `SyntaxContext` we are deserializing.
|
|
|
|
// We look up the position of the associated `SyntaxData` and decode it.
|
|
|
|
let pos = syntax_contexts.get(&id).unwrap();
|
|
|
|
this.with_position(pos.to_usize(), |decoder| {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
let data: SyntaxContextData = decode_tagged(decoder, TAG_SYNTAX_CONTEXT);
|
|
|
|
data
|
2020-03-17 15:45:02 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
|
|
|
let hash = ExpnHash::decode(decoder);
|
2021-06-27 13:51:25 +00:00
|
|
|
if hash.is_root() {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
return ExpnId::root();
|
2021-06-27 13:51:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(expn_id) = ExpnId::from_hash(hash) {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
return expn_id;
|
2021-06-27 13:51:25 +00:00
|
|
|
}
|
|
|
|
|
2021-09-08 16:27:06 +00:00
|
|
|
let krate = decoder.tcx.stable_crate_id_to_crate_num(hash.stable_crate_id());
|
2021-06-27 13:51:25 +00:00
|
|
|
|
|
|
|
let expn_id = if krate == LOCAL_CRATE {
|
|
|
|
// We look up the position of the associated `ExpnData` and decode it.
|
|
|
|
let pos = decoder
|
|
|
|
.expn_data
|
|
|
|
.get(&hash)
|
|
|
|
.unwrap_or_else(|| panic!("Bad hash {:?} (map {:?})", hash, decoder.expn_data));
|
|
|
|
|
|
|
|
let data: ExpnData = decoder
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA));
|
2021-10-02 19:14:52 +00:00
|
|
|
let expn_id = rustc_span::hygiene::register_local_expn_id(data, hash);
|
|
|
|
|
|
|
|
#[cfg(debug_assertions)]
|
|
|
|
{
|
|
|
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
2021-07-12 20:19:25 +00:00
|
|
|
let local_hash: u64 = decoder.tcx.with_stable_hashing_context(|mut hcx| {
|
|
|
|
let mut hasher = StableHasher::new();
|
|
|
|
expn_id.expn_data().hash_stable(&mut hcx, &mut hasher);
|
|
|
|
hasher.finish()
|
2021-10-02 19:14:52 +00:00
|
|
|
});
|
|
|
|
debug_assert_eq!(hash.local_hash(), local_hash);
|
|
|
|
}
|
|
|
|
|
|
|
|
expn_id
|
2021-06-27 13:51:25 +00:00
|
|
|
} else {
|
|
|
|
let index_guess = decoder.foreign_expn_data[&hash];
|
2021-10-02 15:35:27 +00:00
|
|
|
decoder.tcx.cstore_untracked().expn_hash_to_expn_id(
|
|
|
|
decoder.tcx.sess,
|
|
|
|
krate,
|
|
|
|
index_guess,
|
|
|
|
hash,
|
|
|
|
)
|
2021-06-27 13:51:25 +00:00
|
|
|
};
|
|
|
|
|
2021-10-02 19:14:52 +00:00
|
|
|
debug_assert_eq!(expn_id.krate, krate);
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
expn_id
|
2020-03-17 15:45:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
|
|
|
let ctxt = SyntaxContext::decode(decoder);
|
|
|
|
let parent = Option::<LocalDefId>::decode(decoder);
|
|
|
|
let tag: u8 = Decodable::decode(decoder);
|
2017-11-24 13:00:33 +00:00
|
|
|
|
2021-01-03 15:09:32 +00:00
|
|
|
if tag == TAG_PARTIAL_SPAN {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
return Span::new(BytePos(0), BytePos(0), ctxt, parent);
|
2021-04-18 12:27:28 +00:00
|
|
|
} else if tag == TAG_RELATIVE_SPAN {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
let dlo = u32::decode(decoder);
|
|
|
|
let dto = u32::decode(decoder);
|
2021-04-18 12:27:28 +00:00
|
|
|
|
2022-05-30 16:49:17 +00:00
|
|
|
let enclosing = decoder.tcx.source_span_untracked(parent.unwrap()).data_untracked();
|
2021-04-18 12:27:28 +00:00
|
|
|
let span = Span::new(
|
|
|
|
enclosing.lo + BytePos::from_u32(dlo),
|
|
|
|
enclosing.lo + BytePos::from_u32(dto),
|
|
|
|
ctxt,
|
|
|
|
parent,
|
|
|
|
);
|
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
return span;
|
2017-11-24 13:00:33 +00:00
|
|
|
} else {
|
2021-01-03 15:09:32 +00:00
|
|
|
debug_assert_eq!(tag, TAG_FULL_SPAN);
|
2017-10-24 12:51:26 +00:00
|
|
|
}
|
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
let file_lo_index = SourceFileIndex::decode(decoder);
|
|
|
|
let line_lo = usize::decode(decoder);
|
|
|
|
let col_lo = BytePos::decode(decoder);
|
|
|
|
let len = BytePos::decode(decoder);
|
2017-11-24 13:00:33 +00:00
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
let file_lo = decoder.file_index_to_file(file_lo_index);
|
2022-05-30 05:59:45 +00:00
|
|
|
let lo = file_lo.lines(|lines| lines[line_lo - 1] + col_lo);
|
2017-11-24 13:00:33 +00:00
|
|
|
let hi = lo + len;
|
|
|
|
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
Span::new(lo, hi, ctxt, parent)
|
2017-10-24 12:51:26 +00:00
|
|
|
}
|
|
|
|
}
|
2017-11-13 15:35:51 +00:00
|
|
|
|
2022-07-03 16:18:53 +00:00
|
|
|
// copy&paste impl from rustc_metadata
|
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Symbol {
|
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
|
|
|
let tag = d.read_u8();
|
|
|
|
|
|
|
|
match tag {
|
|
|
|
SYMBOL_STR => {
|
|
|
|
let s = d.read_str();
|
|
|
|
Symbol::intern(s)
|
|
|
|
}
|
|
|
|
SYMBOL_OFFSET => {
|
|
|
|
// read str offset
|
|
|
|
let pos = d.read_usize();
|
|
|
|
let old_pos = d.opaque.position();
|
|
|
|
|
|
|
|
// move to str ofset and read
|
|
|
|
d.opaque.set_position(pos);
|
|
|
|
let s = d.read_str();
|
|
|
|
let sym = Symbol::intern(s);
|
|
|
|
|
|
|
|
// restore position
|
|
|
|
d.opaque.set_position(old_pos);
|
|
|
|
|
|
|
|
sym
|
|
|
|
}
|
2022-08-20 12:39:21 +00:00
|
|
|
SYMBOL_PREINTERNED => {
|
|
|
|
let symbol_index = d.read_u32();
|
|
|
|
Symbol::new_from_decoded(symbol_index)
|
|
|
|
}
|
2022-07-03 16:18:53 +00:00
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
|
|
|
let stable_id = StableCrateId::decode(d);
|
2021-09-08 16:27:06 +00:00
|
|
|
let cnum = d.tcx.stable_crate_id_to_crate_num(stable_id);
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
cnum
|
2019-08-24 15:25:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-14 11:03:57 +00:00
|
|
|
// This impl makes sure that we get a runtime error when we try decode a
|
2019-09-06 02:57:44 +00:00
|
|
|
// `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
|
2017-11-14 11:03:57 +00:00
|
|
|
// context.
|
2020-06-11 14:49:57 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefIndex {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(_d: &mut CacheDecoder<'a, 'tcx>) -> DefIndex {
|
|
|
|
panic!("trying to decode `DefIndex` outside the context of a `DefId`")
|
2017-11-14 11:03:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
// Both the `CrateNum` and the `DefIndex` of a `DefId` can change in between two
|
|
|
|
// compilation sessions. We use the `DefPathHash`, which is stable across
|
2019-09-19 05:17:36 +00:00
|
|
|
// sessions, to map the old `DefId` to the new one.
|
2020-06-11 14:49:57 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefId {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
2019-09-06 02:57:44 +00:00
|
|
|
// Load the `DefPathHash` which is was we encoded the `DefId` as.
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
let def_path_hash = DefPathHash::decode(d);
|
2017-11-14 11:03:57 +00:00
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
// Using the `DefPathHash`, we can lookup the new `DefId`.
|
2020-07-29 16:26:15 +00:00
|
|
|
// Subtle: We only encode a `DefId` as part of a query result.
|
|
|
|
// If we get to this point, then all of the query inputs were green,
|
|
|
|
// which means that the definition with this hash is guaranteed to
|
|
|
|
// still exist in the current compilation session.
|
2021-01-31 09:32:34 +00:00
|
|
|
d.tcx.def_path_hash_to_def_id(def_path_hash, &mut || {
|
2022-01-19 22:36:44 +00:00
|
|
|
panic!("Failed to convert DefPathHash {:?}", def_path_hash)
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
})
|
2017-11-14 11:03:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId> {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
2020-06-11 14:49:57 +00:00
|
|
|
RefDecodable::decode(d)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-09 15:34:11 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashMap<DefId, Ty<'tcx>> {
|
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
|
|
|
RefDecodable::decode(d)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
|
|
|
|
for &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>>
|
|
|
|
{
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
2020-06-11 14:49:57 +00:00
|
|
|
RefDecodable::decode(d)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-09 09:35:06 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [ty::abstract_const::Node<'tcx>] {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
2020-09-11 19:16:16 +00:00
|
|
|
RefDecodable::decode(d)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
2020-06-11 14:49:57 +00:00
|
|
|
RefDecodable::decode(d)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-27 17:56:11 +00:00
|
|
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsmTemplatePiece] {
|
Make `Decodable` and `Decoder` infallible.
`Decoder` has two impls:
- opaque: this impl is already partly infallible, i.e. in some places it
currently panics on failure (e.g. if the input is too short, or on a
bad `Result` discriminant), and in some places it returns an error
(e.g. on a bad `Option` discriminant). The number of places where
either happens is surprisingly small, just because the binary
representation has very little redundancy and a lot of input reading
can occur even on malformed data.
- json: this impl is fully fallible, but it's only used (a) for the
`.rlink` file production, and there's a `FIXME` comment suggesting it
should change to a binary format, and (b) in a few tests in
non-fundamental ways. Indeed #85993 is open to remove it entirely.
And the top-level places in the compiler that call into decoding just
abort on error anyway. So the fallibility is providing little value, and
getting rid of it leads to some non-trivial performance improvements.
Much of this commit is pretty boring and mechanical. Some notes about
a few interesting parts:
- The commit removes `Decoder::{Error,error}`.
- `InternIteratorElement::intern_with`: the impl for `T` now has the same
optimization for small counts that the impl for `Result<T, E>` has,
because it's now much hotter.
- Decodable impls for SmallVec, LinkedList, VecDeque now all use
`collect`, which is nice; the one for `Vec` uses unsafe code, because
that gave better perf on some benchmarks.
2022-01-18 02:22:50 +00:00
|
|
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
2020-06-11 14:49:57 +00:00
|
|
|
RefDecodable::decode(d)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-28 17:53:01 +00:00
|
|
|
macro_rules! impl_ref_decoder {
|
|
|
|
(<$tcx:tt> $($ty:ty,)*) => {
|
|
|
|
$(impl<'a, $tcx> Decodable<CacheDecoder<'a, $tcx>> for &$tcx [$ty] {
|
|
|
|
fn decode(d: &mut CacheDecoder<'a, $tcx>) -> Self {
|
|
|
|
RefDecodable::decode(d)
|
|
|
|
}
|
|
|
|
})*
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_ref_decoder! {<'tcx>
|
|
|
|
Span,
|
|
|
|
rustc_ast::Attribute,
|
|
|
|
rustc_span::symbol::Ident,
|
|
|
|
ty::Variance,
|
|
|
|
rustc_span::def_id::DefId,
|
|
|
|
rustc_span::def_id::LocalDefId,
|
|
|
|
(rustc_middle::middle::exported_symbols::ExportedSymbol<'tcx>, rustc_middle::middle::exported_symbols::SymbolExportInfo),
|
2017-12-23 03:41:09 +00:00
|
|
|
}
|
|
|
|
|
2017-11-13 15:35:51 +00:00
|
|
|
//- ENCODING -------------------------------------------------------------------
|
|
|
|
|
2020-12-19 22:25:24 +00:00
|
|
|
/// An encoder that can write to the incremental compilation cache.
|
2022-06-16 06:00:25 +00:00
|
|
|
pub struct CacheEncoder<'a, 'tcx> {
|
2019-06-13 21:48:52 +00:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2022-06-16 06:00:25 +00:00
|
|
|
encoder: FileEncoder,
|
2019-04-25 20:54:19 +00:00
|
|
|
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
|
2021-01-17 07:49:30 +00:00
|
|
|
predicate_shorthands: FxHashMap<ty::PredicateKind<'tcx>, usize>,
|
2020-08-08 03:44:47 +00:00
|
|
|
interpret_allocs: FxIndexSet<interpret::AllocId>,
|
2018-08-18 10:14:25 +00:00
|
|
|
source_map: CachingSourceMapView<'tcx>,
|
2018-08-18 10:13:52 +00:00
|
|
|
file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>,
|
2020-07-24 07:01:07 +00:00
|
|
|
hygiene_context: &'a HygieneEncodeContext,
|
2022-07-03 16:18:53 +00:00
|
|
|
symbol_table: FxHashMap<Symbol, usize>,
|
2017-11-13 15:35:51 +00:00
|
|
|
}
|
|
|
|
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> CacheEncoder<'a, 'tcx> {
|
2018-08-18 10:13:56 +00:00
|
|
|
fn source_file_index(&mut self, source_file: Lrc<SourceFile>) -> SourceFileIndex {
|
|
|
|
self.file_to_file_index[&(&*source_file as *const SourceFile)]
|
2017-11-24 13:00:33 +00:00
|
|
|
}
|
|
|
|
|
2017-11-14 13:50:03 +00:00
|
|
|
/// Encode something with additional information that allows to do some
|
|
|
|
/// sanity checks when decoding the data again. This method will first
|
|
|
|
/// encode the specified tag, then the given value, then the number of
|
|
|
|
/// bytes taken up by tag and value. On decoding, we can then verify that
|
|
|
|
/// we get the expected tag and read the expected number of bytes.
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
fn encode_tagged<T: Encodable<Self>, V: Encodable<Self>>(&mut self, tag: T, value: &V) {
|
2017-11-14 13:50:03 +00:00
|
|
|
let start_pos = self.position();
|
|
|
|
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
tag.encode(self);
|
|
|
|
value.encode(self);
|
2017-11-14 13:50:03 +00:00
|
|
|
|
|
|
|
let end_pos = self.position();
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
((end_pos - start_pos) as u64).encode(self);
|
2017-11-14 13:50:03 +00:00
|
|
|
}
|
2022-06-16 06:00:25 +00:00
|
|
|
|
|
|
|
fn finish(self) -> Result<usize, io::Error> {
|
|
|
|
self.encoder.finish()
|
|
|
|
}
|
2017-11-14 13:50:03 +00:00
|
|
|
}
|
|
|
|
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for SyntaxContext {
|
|
|
|
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
rustc_span::hygiene::raw_encode_syntax_context(*self, s.hygiene_context, s);
|
2020-03-17 15:45:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for ExpnId {
|
|
|
|
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
|
2021-06-27 08:38:06 +00:00
|
|
|
s.hygiene_context.schedule_expn_data_for_encoding(*self);
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
self.expn_hash().encode(s);
|
2020-03-17 15:45:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Span {
|
|
|
|
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
|
2021-04-30 18:15:22 +00:00
|
|
|
let span_data = self.data_untracked();
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
span_data.ctxt.encode(s);
|
|
|
|
span_data.parent.encode(s);
|
2021-04-18 12:27:28 +00:00
|
|
|
|
|
|
|
if span_data.is_dummy() {
|
|
|
|
return TAG_PARTIAL_SPAN.encode(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(parent) = span_data.parent {
|
2022-05-30 16:49:17 +00:00
|
|
|
let enclosing = s.tcx.source_span(parent).data_untracked();
|
2021-04-18 12:27:28 +00:00
|
|
|
if enclosing.contains(span_data) {
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
TAG_RELATIVE_SPAN.encode(s);
|
|
|
|
(span_data.lo - enclosing.lo).to_u32().encode(s);
|
|
|
|
(span_data.hi - enclosing.lo).to_u32().encode(s);
|
|
|
|
return;
|
2021-04-18 12:27:28 +00:00
|
|
|
}
|
2017-11-24 13:00:33 +00:00
|
|
|
}
|
|
|
|
|
2021-01-03 15:09:32 +00:00
|
|
|
let pos = s.source_map.byte_pos_to_line_and_col(span_data.lo);
|
|
|
|
let partial_span = match &pos {
|
|
|
|
Some((file_lo, _, _)) => !file_lo.contains(span_data.hi),
|
|
|
|
None => true,
|
2020-06-11 14:49:57 +00:00
|
|
|
};
|
2017-11-24 13:00:33 +00:00
|
|
|
|
2021-01-03 15:09:32 +00:00
|
|
|
if partial_span {
|
2021-04-18 12:27:28 +00:00
|
|
|
return TAG_PARTIAL_SPAN.encode(s);
|
2017-11-24 13:00:33 +00:00
|
|
|
}
|
|
|
|
|
2021-01-03 15:09:32 +00:00
|
|
|
let (file_lo, line_lo, col_lo) = pos.unwrap();
|
|
|
|
|
2017-11-24 13:00:33 +00:00
|
|
|
let len = span_data.hi - span_data.lo;
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
let source_file_index = s.source_file_index(file_lo);
|
2017-11-24 13:00:33 +00:00
|
|
|
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
TAG_FULL_SPAN.encode(s);
|
|
|
|
source_file_index.encode(s);
|
|
|
|
line_lo.encode(s);
|
|
|
|
col_lo.encode(s);
|
|
|
|
len.encode(s);
|
2017-11-22 12:41:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-03 16:18:53 +00:00
|
|
|
// copy&paste impl from rustc_metadata
|
|
|
|
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Symbol {
|
|
|
|
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
|
2022-08-20 12:39:21 +00:00
|
|
|
// if symbol preinterned, emit tag and symbol index
|
|
|
|
if self.is_preinterned() {
|
|
|
|
s.encoder.emit_u8(SYMBOL_PREINTERNED);
|
|
|
|
s.encoder.emit_u32(self.as_u32());
|
|
|
|
} else {
|
|
|
|
// otherwise write it as string or as offset to it
|
|
|
|
match s.symbol_table.entry(*self) {
|
|
|
|
Entry::Vacant(o) => {
|
|
|
|
s.encoder.emit_u8(SYMBOL_STR);
|
|
|
|
let pos = s.encoder.position();
|
|
|
|
o.insert(pos);
|
|
|
|
s.emit_str(self.as_str());
|
|
|
|
}
|
|
|
|
Entry::Occupied(o) => {
|
|
|
|
let x = o.get().clone();
|
|
|
|
s.emit_u8(SYMBOL_OFFSET);
|
|
|
|
s.emit_usize(x);
|
|
|
|
}
|
2022-07-03 16:18:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> {
|
2022-05-28 03:03:57 +00:00
|
|
|
type I = TyCtxt<'tcx>;
|
2020-06-11 14:49:57 +00:00
|
|
|
const CLEAR_CROSS_CRATE: bool = false;
|
2019-08-24 15:25:55 +00:00
|
|
|
|
2017-11-13 15:35:51 +00:00
|
|
|
fn position(&self) -> usize {
|
2020-12-07 01:30:55 +00:00
|
|
|
self.encoder.position()
|
2017-11-13 15:35:51 +00:00
|
|
|
}
|
2020-06-11 14:49:57 +00:00
|
|
|
fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize> {
|
|
|
|
&mut self.type_shorthands
|
2017-11-16 16:13:39 +00:00
|
|
|
}
|
2021-01-17 07:49:30 +00:00
|
|
|
fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::PredicateKind<'tcx>, usize> {
|
|
|
|
&mut self.predicate_shorthands
|
|
|
|
}
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
fn encode_alloc_id(&mut self, alloc_id: &interpret::AllocId) {
|
2020-06-11 14:49:57 +00:00
|
|
|
let (index, _) = self.interpret_allocs.insert_full(*alloc_id);
|
2017-11-13 15:35:51 +00:00
|
|
|
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
index.encode(self);
|
2017-11-16 13:09:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for CrateNum {
|
|
|
|
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
s.tcx.stable_crate_id(*self).encode(s);
|
2021-05-30 15:54:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for DefId {
|
|
|
|
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
s.tcx.def_path_hash(*self).encode(s);
|
2017-11-16 13:09:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for DefIndex {
|
|
|
|
fn encode(&self, _: &mut CacheEncoder<'a, 'tcx>) {
|
2019-09-06 02:57:44 +00:00
|
|
|
bug!("encoding `DefIndex` without context");
|
2017-11-16 13:09:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-13 15:35:51 +00:00
|
|
|
macro_rules! encoder_methods {
|
|
|
|
($($name:ident($ty:ty);)*) => {
|
2020-02-19 05:54:36 +00:00
|
|
|
#[inline]
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
$(fn $name(&mut self, value: $ty) {
|
2017-11-13 15:35:51 +00:00
|
|
|
self.encoder.$name(value)
|
|
|
|
})*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> Encoder for CacheEncoder<'a, 'tcx> {
|
2017-11-13 15:35:51 +00:00
|
|
|
encoder_methods! {
|
|
|
|
emit_usize(usize);
|
|
|
|
emit_u128(u128);
|
|
|
|
emit_u64(u64);
|
|
|
|
emit_u32(u32);
|
|
|
|
emit_u16(u16);
|
|
|
|
emit_u8(u8);
|
|
|
|
|
|
|
|
emit_isize(isize);
|
|
|
|
emit_i128(i128);
|
|
|
|
emit_i64(i64);
|
|
|
|
emit_i32(i32);
|
|
|
|
emit_i16(i16);
|
|
|
|
emit_i8(i8);
|
|
|
|
|
|
|
|
emit_bool(bool);
|
|
|
|
emit_f64(f64);
|
|
|
|
emit_f32(f32);
|
|
|
|
emit_char(char);
|
|
|
|
emit_str(&str);
|
2021-03-11 21:06:45 +00:00
|
|
|
emit_raw_bytes(&[u8]);
|
2017-11-13 15:35:51 +00:00
|
|
|
}
|
|
|
|
}
|
2017-11-14 13:50:03 +00:00
|
|
|
|
2020-12-07 01:30:55 +00:00
|
|
|
// 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`.
|
2020-12-17 03:03:31 +00:00
|
|
|
// Unfortunately, we have to manually opt into specializations this way, given how `CacheEncoder`
|
|
|
|
// and the encoding traits currently work.
|
2022-06-16 06:00:25 +00:00
|
|
|
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for [u8] {
|
|
|
|
fn encode(&self, e: &mut CacheEncoder<'a, 'tcx>) {
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
self.encode(&mut e.encoder);
|
2020-12-17 03:03:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-19 19:04:40 +00:00
|
|
|
pub fn encode_query_results<'a, 'tcx, CTX, Q>(
|
|
|
|
tcx: CTX,
|
2022-06-16 06:00:25 +00:00
|
|
|
encoder: &mut CacheEncoder<'a, 'tcx>,
|
2021-07-23 21:40:26 +00:00
|
|
|
query_result_index: &mut EncodedDepNodeIndex,
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
) where
|
2021-01-19 19:04:40 +00:00
|
|
|
CTX: QueryContext + 'tcx,
|
2021-10-17 15:37:20 +00:00
|
|
|
Q: super::QueryDescription<CTX>,
|
2022-06-16 06:00:25 +00:00
|
|
|
Q::Value: Encodable<CacheEncoder<'a, 'tcx>>,
|
2017-11-15 13:18:00 +00:00
|
|
|
{
|
2020-02-07 14:01:23 +00:00
|
|
|
let _timer = tcx
|
2021-01-19 19:04:40 +00:00
|
|
|
.dep_context()
|
|
|
|
.profiler()
|
Remove `-Ztime` option.
The compiler currently has `-Ztime` and `-Ztime-passes`. I've used
`-Ztime-passes` for years but only recently learned about `-Ztime`.
What's the difference? Let's look at the `-Zhelp` output:
```
-Z time=val -- measure time of rustc processes (default: no)
-Z time-passes=val -- measure time of each rustc pass (default: no)
```
The `-Ztime-passes` description is clear, but the `-Ztime` one is less so.
Sounds like it measures the time for the entire process?
No. The real difference is that `-Ztime-passes` prints out info about passes,
and `-Ztime` does the same, but only for a subset of those passes. More
specifically, there is a distinction in the profiling code between a "verbose
generic activity" and an "extra verbose generic activity". `-Ztime-passes`
prints both kinds, while `-Ztime` only prints the first one. (It took me
a close reading of the source code to determine this difference.)
In practice this distinction has low value. Perhaps in the past the "extra
verbose" output was more voluminous, but now that we only print stats for a
pass if it exceeds 5ms or alters the RSS, `-Ztime-passes` is less spammy. Also,
a lot of the "extra verbose" cases are for individual lint passes, and you need
to also use `-Zno-interleave-lints` to see those anyway.
Therefore, this commit removes `-Ztime` and the associated machinery. One thing
to note is that the existing "extra verbose" activities all have an extra
string argument, so the commit adds the ability to accept an extra argument to
the "verbose" activities.
2022-10-06 03:51:45 +00:00
|
|
|
.verbose_generic_activity_with_arg("encode_query_results_for", std::any::type_name::<Q>());
|
2018-03-15 09:17:04 +00:00
|
|
|
|
2021-02-06 12:49:08 +00:00
|
|
|
assert!(Q::query_state(tcx).all_inactive());
|
|
|
|
let cache = Q::query_cache(tcx);
|
2022-02-20 03:44:19 +00:00
|
|
|
cache.iter(&mut |key, value, dep_node| {
|
2021-10-23 16:12:43 +00:00
|
|
|
if Q::cache_on_disk(*tcx.dep_context(), &key) {
|
2021-04-29 14:23:17 +00:00
|
|
|
let dep_node = SerializedDepNodeIndex::new(dep_node.index());
|
|
|
|
|
|
|
|
// Record position of the cache entry.
|
|
|
|
query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.encoder.position())));
|
|
|
|
|
|
|
|
// Encode the type check tables with the `SerializedDepNodeIndex`
|
|
|
|
// as tag.
|
Use delayed error handling for `Encodable` and `Encoder` infallible.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.
2022-06-07 03:30:45 +00:00
|
|
|
encoder.encode_tagged(dep_node, value);
|
2020-02-08 06:38:00 +00:00
|
|
|
}
|
2021-04-29 14:23:17 +00:00
|
|
|
});
|
2017-11-15 13:18:00 +00:00
|
|
|
}
|