Cache more queries on disk.

This commit is contained in:
Camille GILLOT 2022-03-28 19:53:01 +02:00
parent 3a08bd7873
commit 9900ea352b
15 changed files with 104 additions and 83 deletions

View File

@ -2129,7 +2129,7 @@ pub struct FnSig<'hir> {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct TraitItemId {
pub def_id: LocalDefId,
}
@ -2192,7 +2192,7 @@ pub enum TraitItemKind<'hir> {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct ImplItemId {
pub def_id: LocalDefId,
}
@ -2787,7 +2787,7 @@ impl<'hir> VariantData<'hir> {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, Hash, HashStable_Generic)]
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
pub struct ItemId {
pub def_id: LocalDefId,
}
@ -3034,7 +3034,7 @@ pub enum AssocItemKind {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct ForeignItemId {
pub def_id: LocalDefId,
}

View File

@ -65,12 +65,6 @@ impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for IndexVec<I, T> {
}
}
impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for &IndexVec<I, T> {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
Encodable::encode(&self.raw, s)
}
}
impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexVec<I, T> {
fn decode(d: &mut D) -> Self {
IndexVec { raw: Decodable::decode(d), _marker: PhantomData }

View File

@ -25,7 +25,6 @@ use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportInfo,
};
use rustc_middle::mir::interpret;
use rustc_middle::thir;
use rustc_middle::traits::specialization_graph;
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
@ -351,18 +350,6 @@ impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> {
}
}
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
(**self).encode(s)
}
}
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
(**self).encode(s)
}
}
/// Helper trait to allow overloading `EncodeContext::lazy` for iterators.
trait EncodeContentsForLazy<'a, 'tcx, T: ?Sized + LazyMeta> {
fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'a, 'tcx>) -> T::Meta;

View File

@ -82,7 +82,7 @@ macro_rules! arena_types {
[] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
[] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation,
[] codegen_unit: rustc_middle::mir::mono::CodegenUnit<'tcx>,
[] attribute: rustc_ast::Attribute,
[decode] attribute: rustc_ast::Attribute,
[] name_set: rustc_data_structures::fx::FxHashSet<rustc_span::symbol::Symbol>,
[] hir_id_set: rustc_hir::HirIdSet,
@ -95,9 +95,6 @@ macro_rules! arena_types {
// since we need to allocate this type on both the `rustc_hir` arena
// (during lowering) and the `librustc_middle` arena (for decoding MIR)
[decode] asm_template: rustc_ast::InlineAsmTemplatePiece,
// This is used to decode the &'tcx [Span] for InlineAsm's line_spans.
[decode] span: rustc_span::Span,
[decode] used_trait_imports: rustc_data_structures::fx::FxHashSet<rustc_hir::def_id::LocalDefId>,
[decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>,

View File

@ -36,7 +36,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Owner<'tcx> {
/// Gather the LocalDefId for each item-like within a module, including items contained within
/// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
#[derive(Debug, HashStable)]
#[derive(Debug, HashStable, Encodable, Decodable)]
pub struct ModuleItems {
submodules: Box<[LocalDefId]>,
items: Box<[ItemId]>,

View File

@ -29,7 +29,7 @@ pub enum StabilityLevel {
}
/// An entry in the `depr_map`.
#[derive(Copy, Clone, HashStable, Debug)]
#[derive(Copy, Clone, HashStable, Debug, Encodable, Decodable)]
pub struct DeprecationEntry {
/// The metadata of the attribute associated with this entry.
pub attr: Deprecation,

View File

@ -59,6 +59,7 @@ rustc_queries! {
query hir_module_items(key: LocalDefId) -> rustc_middle::hir::ModuleItems {
storage(ArenaCacheSelector<'tcx>)
desc { |tcx| "HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
cache_on_disk_if { true }
}
/// Gives access to the HIR node for the HIR owner `key`.
@ -128,6 +129,7 @@ rustc_queries! {
/// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
query const_param_default(param: DefId) -> ty::Const<'tcx> {
desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
cache_on_disk_if { param.is_local() }
separate_provide_extern
}
@ -223,6 +225,7 @@ rustc_queries! {
/// Bounds from the parent (e.g. with nested impl trait) are not included.
query explicit_item_bounds(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -508,6 +511,7 @@ rustc_queries! {
/// Returns the predicates written explicitly by the user.
query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -515,6 +519,7 @@ rustc_queries! {
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -526,6 +531,7 @@ rustc_queries! {
/// additional acyclicity requirements).
query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -549,6 +555,7 @@ rustc_queries! {
query trait_def(key: DefId) -> ty::TraitDef {
desc { |tcx| "computing trait definition for `{}`", tcx.def_path_str(key) }
storage(ArenaCacheSelector<'tcx>)
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
query adt_def(key: DefId) -> ty::AdtDef<'tcx> {
@ -558,6 +565,7 @@ rustc_queries! {
}
query adt_destructor(key: DefId) -> Option<ty::Destructor> {
desc { |tcx| "computing `Drop` impl for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -587,11 +595,13 @@ rustc_queries! {
/// `is_const_fn` function.
query impl_constness(key: DefId) -> hir::Constness {
desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
query asyncness(key: DefId) -> hir::IsAsync {
desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -609,12 +619,14 @@ rustc_queries! {
/// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
query is_foreign_item(key: DefId) -> bool {
desc { |tcx| "checking if `{}` is a foreign item", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
/// Returns `Some(generator_kind)` if the node pointed to by `def_id` is a generator.
query generator_kind(def_id: DefId) -> Option<hir::GeneratorKind> {
desc { |tcx| "looking up generator kind of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
@ -627,6 +639,7 @@ rustc_queries! {
/// Maps from the `DefId` of a type or region parameter to its (inferred) variance.
query variances_of(def_id: DefId) -> &'tcx [ty::Variance] {
desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
@ -639,6 +652,7 @@ rustc_queries! {
/// Maps from an impl/trait `DefId` to a list of the `DefId`s of its items.
query associated_item_def_ids(key: DefId) -> &'tcx [DefId] {
desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -646,6 +660,7 @@ rustc_queries! {
query associated_item(key: DefId) -> ty::AssocItem {
desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) }
storage(ArenaCacheSelector<'tcx>)
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -685,10 +700,12 @@ rustc_queries! {
/// Return `None` if this is an inherent impl.
query impl_trait_ref(impl_id: DefId) -> Option<ty::TraitRef<'tcx>> {
desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) }
cache_on_disk_if { impl_id.is_local() }
separate_provide_extern
}
query impl_polarity(impl_id: DefId) -> ty::ImplPolarity {
desc { |tcx| "computing implementation polarity of `{}`", tcx.def_path_str(impl_id) }
cache_on_disk_if { impl_id.is_local() }
separate_provide_extern
}
@ -701,6 +718,7 @@ rustc_queries! {
/// Methods in these implementations don't need to be exported.
query inherent_impls(key: DefId) -> &'tcx [DefId] {
desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -745,6 +763,7 @@ rustc_queries! {
/// Computes the signature of the function.
query fn_sig(key: DefId) -> ty::PolyFnSig<'tcx> {
desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -820,6 +839,7 @@ rustc_queries! {
/// Caches `CoerceUnsized` kinds for impls on custom types.
query coerce_unsized_info(key: DefId) -> ty::adjustment::CoerceUnsizedInfo {
desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -1033,28 +1053,33 @@ rustc_queries! {
query opt_def_kind(def_id: DefId) -> Option<DefKind> {
desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
/// Gets the span for the definition.
query def_span(def_id: DefId) -> Span {
desc { |tcx| "looking up span for `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
/// Gets the span for the identifier of the definition.
query def_ident_span(def_id: DefId) -> Option<Span> {
desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
query lookup_stability(def_id: DefId) -> Option<attr::Stability> {
desc { |tcx| "looking up stability of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
query lookup_const_stability(def_id: DefId) -> Option<attr::ConstStability> {
desc { |tcx| "looking up const stability of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
@ -1064,6 +1089,7 @@ rustc_queries! {
query lookup_deprecation_entry(def_id: DefId) -> Option<DeprecationEntry> {
desc { |tcx| "checking whether `{}` is deprecated", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
@ -1074,6 +1100,7 @@ rustc_queries! {
query item_attrs(def_id: DefId) -> &'tcx [ast::Attribute] {
desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
@ -1090,6 +1117,7 @@ rustc_queries! {
query fn_arg_names(def_id: DefId) -> &'tcx [rustc_span::symbol::Ident] {
desc { |tcx| "looking up function parameter names for `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
/// Gets the rendered value of the specified constant or associated constant.
@ -1097,10 +1125,12 @@ rustc_queries! {
query rendered_const(def_id: DefId) -> String {
storage(ArenaCacheSelector<'tcx>)
desc { |tcx| "rendering constant intializer of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
query impl_parent(def_id: DefId) -> Option<DefId> {
desc { |tcx| "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
@ -1108,15 +1138,18 @@ rustc_queries! {
/// Return `None` if the `DefId` is not an associated item.
query trait_of_item(associated_item: DefId) -> Option<DefId> {
desc { |tcx| "finding trait defining `{}`", tcx.def_path_str(associated_item) }
cache_on_disk_if { associated_item.is_local() }
separate_provide_extern
}
query is_ctfe_mir_available(key: DefId) -> bool {
desc { |tcx| "checking if item has ctfe mir available: `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
query is_mir_available(key: DefId) -> bool {
desc { |tcx| "checking if item has mir available: `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
@ -1358,6 +1391,7 @@ rustc_queries! {
query impl_defaultness(def_id: DefId) -> hir::Defaultness {
desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
@ -1391,6 +1425,7 @@ rustc_queries! {
}
query is_reachable_non_generic(def_id: DefId) -> bool {
desc { |tcx| "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) }
cache_on_disk_if { def_id.is_local() }
separate_provide_extern
}
query is_unreachable_local_definition(def_id: LocalDefId) -> bool {
@ -1705,9 +1740,9 @@ rustc_queries! {
/// - All names contained in `exported_symbols(cnum)` are guaranteed to
/// correspond to a publicly visible symbol in `cnum` machine code.
/// - The `exported_symbols` sets of different crates do not intersect.
query exported_symbols(_: CrateNum)
-> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
query exported_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
desc { "exported_symbols" }
cache_on_disk_if { *cnum == LOCAL_CRATE }
separate_provide_extern
}

View File

@ -9,7 +9,7 @@ use rustc_span::symbol::{Ident, Symbol};
use super::{TyCtxt, Visibility};
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash, Encodable, Decodable)]
pub enum AssocItemContainer {
TraitContainer(DefId),
ImplContainer(DefId),
@ -41,7 +41,7 @@ impl AssocItemContainer {
}
/// Information about an associated item
#[derive(Copy, Clone, Debug, PartialEq, HashStable, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, HashStable, Eq, Hash, Encodable, Decodable)]
pub struct AssocItem {
pub def_id: DefId,
pub name: Symbol,
@ -81,7 +81,7 @@ impl AssocItem {
}
}
#[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash)]
#[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)]
pub enum AssocKind {
Const,
Fn,

View File

@ -168,25 +168,6 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
}
}
macro_rules! encodable_via_deref {
($($t:ty),+) => {
$(impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for $t {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
(**self).encode(e)
}
})*
}
}
encodable_via_deref! {
&'tcx ty::TypeckResults<'tcx>,
&'tcx traits::ImplSource<'tcx, ()>,
&'tcx mir::Body<'tcx>,
&'tcx mir::UnsafetyCheckResult,
&'tcx mir::BorrowCheckResult<'tcx>,
&'tcx mir::coverage::CodeRegion
}
pub trait TyDecoder<'tcx>: Decoder {
const CLEAR_CROSS_CRATE: bool;
@ -466,6 +447,33 @@ macro_rules! impl_arena_allocatable_decoders {
rustc_hir::arena_types!(impl_arena_allocatable_decoders);
arena_types!(impl_arena_allocatable_decoders);
macro_rules! impl_arena_copy_decoder {
(<$tcx:tt> $($ty:ty,)*) => {
$(impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
#[inline]
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.tcx().arena.alloc(Decodable::decode(decoder))
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
#[inline]
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.tcx().arena.alloc_from_iter(<Vec<_> as Decodable<D>>::decode(decoder))
}
})*
};
}
impl_arena_copy_decoder! {<'tcx>
Span,
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),
}
#[macro_export]
macro_rules! implement_ty_decoder {
($DecoderName:ident <$($typaram:tt),*>) => {

View File

@ -122,13 +122,6 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for List<T> {
}
}
impl<S: Encoder, T: Encodable<S>> Encodable<S> for &List<T> {
#[inline]
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
(**self).encode(s)
}
}
impl<T: PartialEq> PartialEq for List<T> {
#[inline]
fn eq(&self, other: &List<T>) -> bool {

View File

@ -228,7 +228,7 @@ impl fmt::Display for ImplPolarity {
}
}
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)]
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)]
pub enum Visibility {
/// Visible everywhere (including in other crates).
Public,
@ -1629,7 +1629,7 @@ where
}
}
#[derive(Copy, Clone, Debug, HashStable)]
#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
pub struct Destructor {
/// The `DefId` of the destructor method
pub did: DefId,

View File

@ -21,7 +21,7 @@ use rustc_middle::dep_graph::{self, DepKindStruct, SerializedDepNodeIndex};
use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values};
use rustc_middle::ty::query::{ExternProviders, Providers, QueryEngine};
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::def_id::LocalDefId;
use rustc_span::def_id::{LocalDefId, LOCAL_CRATE};
use rustc_span::Span;
#[macro_use]

View File

@ -788,10 +788,24 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsm
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [Span] {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
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),
}
//- ENCODING -------------------------------------------------------------------

View File

@ -171,16 +171,6 @@ where
}
}
impl<E: Encoder, T, S> Encodable<E> for &HashSet<T, S>
where
T: Encodable<E> + Eq,
S: BuildHasher,
{
fn encode(&self, s: &mut E) -> Result<(), E::Error> {
(**self).encode(s)
}
}
impl<D: Decoder, T, S> Decodable<D> for HashSet<T, S>
where
T: Decodable<D> + Hash + Eq,

View File

@ -268,6 +268,15 @@ direct_serialize_impls! {
char emit_char read_char
}
impl<S: Encoder, T: ?Sized> Encodable<S> for &T
where
T: Encodable<S>,
{
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
(**self).encode(s)
}
}
impl<S: Encoder> Encodable<S> for ! {
fn encode(&self, _s: &mut S) -> Result<(), S::Error> {
unreachable!()
@ -298,12 +307,6 @@ impl<S: Encoder> Encodable<S> for str {
}
}
impl<S: Encoder> Encodable<S> for &str {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_str(self)
}
}
impl<S: Encoder> Encodable<S> for String {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_str(&self[..])