Skip to content

Commit 4fa202d

Browse files
committedNov 30, 2017
Auto merge of #46299 - michaelwoerister:incr-comp-krimskrams, r=nikomatsakis
incr.comp.: Some preparatory work for caching more query results. This PR * adds and updates some encoding/decoding routines for various query result types so they can be cached later, and * adds missing `[input]` annotations for a few `DepNode` variants. The situation around having to explicitly mark dep-nodes/queries as inputs is not really satisfactory. I hope we can find a way of making this more fool-proof in the future. r? @nikomatsakis
2 parents d6b010f + 3bb25d6 commit 4fa202d

File tree

14 files changed

+147
-47
lines changed

14 files changed

+147
-47
lines changed
 

‎src/librustc/dep_graph/dep_node.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ define_dep_nodes!( <'tcx>
562562
[] IsPanicRuntime(CrateNum),
563563
[] IsCompilerBuiltins(CrateNum),
564564
[] HasGlobalAllocator(CrateNum),
565-
[] ExternCrate(DefId),
565+
[input] ExternCrate(DefId),
566566
[eval_always] LintLevels,
567567
[] Specializes { impl1: DefId, impl2: DefId },
568568
[input] InScopeTraits(DefIndex),
@@ -602,8 +602,8 @@ define_dep_nodes!( <'tcx>
602602
[] MissingLangItems(CrateNum),
603603
[] ExternConstBody(DefId),
604604
[] VisibleParentMap,
605-
[] MissingExternCrateItem(CrateNum),
606-
[] UsedCrateSource(CrateNum),
605+
[input] MissingExternCrateItem(CrateNum),
606+
[input] UsedCrateSource(CrateNum),
607607
[input] PostorderCnums,
608608
[input] HasCloneClosures(CrateNum),
609609
[input] HasCopyClosures(CrateNum),
@@ -619,7 +619,7 @@ define_dep_nodes!( <'tcx>
619619
[input] Freevars(DefId),
620620
[input] MaybeUnusedTraitImport(DefId),
621621
[input] MaybeUnusedExternCrates,
622-
[] StabilityIndex,
622+
[eval_always] StabilityIndex,
623623
[input] AllCrateNums,
624624
[] ExportedSymbols(CrateNum),
625625
[eval_always] CollectAndPartitionTranslationItems,

‎src/librustc/ich/impls_mir.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ for mir::Terminator<'gcx> {
9898
}
9999
}
100100

101-
impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearOnDecode<T>
101+
impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearCrossCrate<T>
102102
where T: HashStable<StableHashingContext<'gcx>>
103103
{
104104
#[inline]
@@ -107,8 +107,8 @@ impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearOnDecode<T>
107107
hasher: &mut StableHasher<W>) {
108108
mem::discriminant(self).hash_stable(hcx, hasher);
109109
match *self {
110-
mir::ClearOnDecode::Clear => {}
111-
mir::ClearOnDecode::Set(ref value) => {
110+
mir::ClearCrossCrate::Clear => {}
111+
mir::ClearCrossCrate::Set(ref value) => {
112112
value.hash_stable(hcx, hasher);
113113
}
114114
}

‎src/librustc/middle/borrowck.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use util::nodemap::FxHashSet;
1515
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
1616
StableHasherResult};
1717

18+
#[derive(Debug, RustcEncodable, RustcDecodable)]
1819
pub struct BorrowCheckResult {
1920
pub used_mut_nodes: FxHashSet<HirId>,
2021
}

‎src/librustc/mir/mod.rs

+13-21
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use std::ops::{Index, IndexMut};
3636
use std::rc::Rc;
3737
use std::vec::IntoIter;
3838
use syntax::ast::{self, Name};
39+
use syntax::symbol::InternedString;
3940
use syntax_pos::Span;
4041

4142
mod cache;
@@ -75,7 +76,7 @@ pub struct Mir<'tcx> {
7576

7677
/// Crate-local information for each visibility scope, that can't (and
7778
/// needn't) be tracked across crates.
78-
pub visibility_scope_info: ClearOnDecode<IndexVec<VisibilityScope, VisibilityScopeInfo>>,
79+
pub visibility_scope_info: ClearCrossCrate<IndexVec<VisibilityScope, VisibilityScopeInfo>>,
7980

8081
/// Rvalues promoted from this function, such as borrows of constants.
8182
/// Each of them is the Mir of a constant with the fn's type parameters
@@ -129,8 +130,8 @@ pub const START_BLOCK: BasicBlock = BasicBlock(0);
129130
impl<'tcx> Mir<'tcx> {
130131
pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
131132
visibility_scopes: IndexVec<VisibilityScope, VisibilityScopeData>,
132-
visibility_scope_info: ClearOnDecode<IndexVec<VisibilityScope,
133-
VisibilityScopeInfo>>,
133+
visibility_scope_info: ClearCrossCrate<IndexVec<VisibilityScope,
134+
VisibilityScopeInfo>>,
134135
promoted: IndexVec<Promoted, Mir<'tcx>>,
135136
yield_ty: Option<Ty<'tcx>>,
136137
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
@@ -283,15 +284,15 @@ impl<'tcx> Mir<'tcx> {
283284
}
284285
}
285286

286-
#[derive(Clone, Debug)]
287+
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
287288
pub struct VisibilityScopeInfo {
288289
/// A NodeId with lint levels equivalent to this scope's lint levels.
289290
pub lint_root: ast::NodeId,
290291
/// The unsafe block that contains this node.
291292
pub safety: Safety,
292293
}
293294

294-
#[derive(Copy, Clone, Debug)]
295+
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
295296
pub enum Safety {
296297
Safe,
297298
/// Unsafe because of a PushUnsafeBlock
@@ -335,22 +336,13 @@ impl<'tcx> IndexMut<BasicBlock> for Mir<'tcx> {
335336
}
336337

337338
#[derive(Clone, Debug)]
338-
pub enum ClearOnDecode<T> {
339+
pub enum ClearCrossCrate<T> {
339340
Clear,
340341
Set(T)
341342
}
342343

343-
impl<T> serialize::Encodable for ClearOnDecode<T> {
344-
fn encode<S: serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
345-
serialize::Encodable::encode(&(), s)
346-
}
347-
}
348-
349-
impl<T> serialize::Decodable for ClearOnDecode<T> {
350-
fn decode<D: serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
351-
serialize::Decodable::decode(d).map(|()| ClearOnDecode::Clear)
352-
}
353-
}
344+
impl<T: serialize::Encodable> serialize::UseSpecializedEncodable for ClearCrossCrate<T> {}
345+
impl<T: serialize::Decodable> serialize::UseSpecializedDecodable for ClearCrossCrate<T> {}
354346

355347
/// Grouped information about the source code origin of a MIR entity.
356348
/// Intended to be inspected by diagnostics and debuginfo.
@@ -1733,21 +1725,21 @@ impl Location {
17331725
}
17341726
}
17351727

1736-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1728+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
17371729
pub enum UnsafetyViolationKind {
17381730
General,
17391731
ExternStatic(ast::NodeId),
17401732
BorrowPacked(ast::NodeId),
17411733
}
17421734

1743-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1735+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
17441736
pub struct UnsafetyViolation {
17451737
pub source_info: SourceInfo,
1746-
pub description: &'static str,
1738+
pub description: InternedString,
17471739
pub kind: UnsafetyViolationKind,
17481740
}
17491741

1750-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1742+
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
17511743
pub struct UnsafetyCheckResult {
17521744
/// Violations that are propagated *upwards* from this function
17531745
pub violations: Rc<[UnsafetyViolation]>,

‎src/librustc/ty/context.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1124,11 +1124,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11241124
}
11251125

11261126
pub fn stability(self) -> Rc<stability::Index<'tcx>> {
1127-
// FIXME(#42293) we should actually track this, but fails too many tests
1128-
// today.
1129-
self.dep_graph.with_ignore(|| {
1130-
self.stability_index(LOCAL_CRATE)
1131-
})
1127+
self.stability_index(LOCAL_CRATE)
11321128
}
11331129

11341130
pub fn crates(self) -> Rc<Vec<CrateNum>> {

‎src/librustc/ty/maps/on_disk_cache.rs

+45
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId,
1515
RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
1616
use hir::map::definitions::DefPathHash;
1717
use middle::cstore::CrateStore;
18+
use mir;
1819
use rustc_data_structures::fx::FxHashMap;
1920
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
2021
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
@@ -36,6 +37,9 @@ use ty::context::TyCtxt;
3637
const PREV_DIAGNOSTICS_TAG: u64 = 0x1234_5678_A1A1_A1A1;
3738
const QUERY_RESULT_INDEX_TAG: u64 = 0x1234_5678_C3C3_C3C3;
3839

40+
const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
41+
const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
42+
3943
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
4044
/// previous compilation session. This data will eventually include the results
4145
/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
@@ -518,12 +522,32 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx, 'x>
518522
// NodeIds are not stable across compilation sessions, so we store them in their
519523
// HirId representation. This allows use to map them to the current NodeId.
520524
impl<'a, 'tcx, 'x> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx, 'x> {
525+
#[inline]
521526
fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
522527
let hir_id = hir::HirId::decode(self)?;
523528
Ok(self.tcx().hir.hir_to_node_id(hir_id))
524529
}
525530
}
526531

532+
impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
533+
for CacheDecoder<'a, 'tcx, 'x> {
534+
#[inline]
535+
fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
536+
let discr = u8::decode(self)?;
537+
538+
match discr {
539+
TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(mir::ClearCrossCrate::Clear),
540+
TAG_CLEAR_CROSS_CRATE_SET => {
541+
let val = T::decode(self)?;
542+
Ok(mir::ClearCrossCrate::Set(val))
543+
}
544+
_ => {
545+
unreachable!()
546+
}
547+
}
548+
}
549+
}
550+
527551
//- ENCODING -------------------------------------------------------------------
528552

529553
struct CacheEncoder<'enc, 'a, 'tcx, E>
@@ -658,6 +682,27 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'a, 't
658682
}
659683
}
660684

685+
impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>>
686+
for CacheEncoder<'enc, 'a, 'tcx, E>
687+
where E: 'enc + ty_codec::TyEncoder,
688+
T: Encodable,
689+
{
690+
#[inline]
691+
fn specialized_encode(&mut self,
692+
val: &mir::ClearCrossCrate<T>)
693+
-> Result<(), Self::Error> {
694+
match *val {
695+
mir::ClearCrossCrate::Clear => {
696+
TAG_CLEAR_CROSS_CRATE_CLEAR.encode(self)
697+
}
698+
mir::ClearCrossCrate::Set(ref val) => {
699+
TAG_CLEAR_CROSS_CRATE_SET.encode(self)?;
700+
val.encode(self)
701+
}
702+
}
703+
}
704+
}
705+
661706
macro_rules! encoder_methods {
662707
($($name:ident($ty:ty);)*) => {
663708
$(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {

‎src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2702,7 +2702,7 @@ impl<'tcx> DtorckConstraint<'tcx> {
27022702
}
27032703
}
27042704

2705-
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
2705+
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
27062706
pub struct SymbolName {
27072707
// FIXME: we don't rely on interning or equality here - better have
27082708
// this be a `&'tcx str`.

‎src/librustc_data_structures/indexed_set.rs

+21
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use std::slice;
1717
use bitslice::{BitSlice, Word};
1818
use bitslice::{bitwise, Union, Subtract, Intersect};
1919
use indexed_vec::Idx;
20+
use rustc_serialize;
2021

2122
/// Represents a set (or packed family of sets), of some element type
2223
/// E, where each E is identified by some unique index type `T`.
@@ -35,6 +36,26 @@ impl<T: Idx> Clone for IdxSetBuf<T> {
3536
}
3637
}
3738

39+
impl<T: Idx> rustc_serialize::Encodable for IdxSetBuf<T> {
40+
fn encode<E: rustc_serialize::Encoder>(&self,
41+
encoder: &mut E)
42+
-> Result<(), E::Error> {
43+
self.bits.encode(encoder)
44+
}
45+
}
46+
47+
impl<T: Idx> rustc_serialize::Decodable for IdxSetBuf<T> {
48+
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<IdxSetBuf<T>, D::Error> {
49+
let words: Vec<Word> = rustc_serialize::Decodable::decode(d)?;
50+
51+
Ok(IdxSetBuf {
52+
_pd: PhantomData,
53+
bits: words,
54+
})
55+
}
56+
}
57+
58+
3859
// pnkfelix wants to have this be `IdxSet<T>([Word]) and then pass
3960
// around `&mut IdxSet<T>` or `&IdxSet<T>`.
4061
//

‎src/librustc_metadata/decoder.rs

+9
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc::hir::def::{self, Def, CtorKind};
2121
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
2222
use rustc::ich::Fingerprint;
2323
use rustc::middle::lang_items;
24+
use rustc::mir;
2425
use rustc::session::Session;
2526
use rustc::ty::{self, Ty, TyCtxt};
2627
use rustc::ty::codec::TyDecoder;
@@ -327,6 +328,14 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
327328
}
328329
}
329330

331+
impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
332+
for DecodeContext<'a, 'tcx> {
333+
#[inline]
334+
fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
335+
Ok(mir::ClearCrossCrate::Clear)
336+
}
337+
}
338+
330339
implement_ty_decoder!( DecodeContext<'a, 'tcx> );
331340

332341
impl<'a, 'tcx> MetadataBlob {

‎src/librustc_metadata/encoder.rs

+9
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,15 @@ impl<'a, 'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext
157157
}
158158
}
159159

160+
impl<'a, 'tcx, T: Encodable> SpecializedEncoder<mir::ClearCrossCrate<T>>
161+
for EncodeContext<'a, 'tcx> {
162+
fn specialized_encode(&mut self,
163+
_: &mir::ClearCrossCrate<T>)
164+
-> Result<(), Self::Error> {
165+
Ok(())
166+
}
167+
}
168+
160169
impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> {
161170
fn position(&self) -> usize {
162171
self.opaque.position()

‎src/librustc_mir/build/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
543543

544544
Mir::new(self.cfg.basic_blocks,
545545
self.visibility_scopes,
546-
ClearOnDecode::Set(self.visibility_scope_info),
546+
ClearCrossCrate::Set(self.visibility_scope_info),
547547
IndexVec::new(),
548548
yield_ty,
549549
self.local_decls,

‎src/librustc_mir/shim.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
198198
IndexVec::from_elem_n(
199199
VisibilityScopeData { span: span, parent_scope: None }, 1
200200
),
201-
ClearOnDecode::Clear,
201+
ClearCrossCrate::Clear,
202202
IndexVec::new(),
203203
None,
204204
local_decls_for_sig(&sig, span),
@@ -345,7 +345,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
345345
IndexVec::from_elem_n(
346346
VisibilityScopeData { span: self.span, parent_scope: None }, 1
347347
),
348-
ClearOnDecode::Clear,
348+
ClearCrossCrate::Clear,
349349
IndexVec::new(),
350350
None,
351351
self.local_decls,
@@ -807,7 +807,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
807807
IndexVec::from_elem_n(
808808
VisibilityScopeData { span: span, parent_scope: None }, 1
809809
),
810-
ClearOnDecode::Clear,
810+
ClearCrossCrate::Clear,
811811
IndexVec::new(),
812812
None,
813813
local_decls,
@@ -885,7 +885,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
885885
IndexVec::from_elem_n(
886886
VisibilityScopeData { span: span, parent_scope: None }, 1
887887
),
888-
ClearOnDecode::Clear,
888+
ClearCrossCrate::Clear,
889889
IndexVec::new(),
890890
None,
891891
local_decls,

‎src/librustc_mir/transform/check_unsafety.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc::mir::*;
2020
use rustc::mir::visit::{LvalueContext, Visitor};
2121

2222
use syntax::ast;
23+
use syntax::symbol::Symbol;
2324

2425
use std::rc::Rc;
2526
use util;
@@ -145,7 +146,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
145146
self.visibility_scope_info[source_info.scope].lint_root;
146147
self.register_violations(&[UnsafetyViolation {
147148
source_info,
148-
description: "borrow of packed field",
149+
description: Symbol::intern("borrow of packed field").as_str(),
149150
kind: UnsafetyViolationKind::BorrowPacked(lint_root)
150151
}], &[]);
151152
}
@@ -209,7 +210,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
209210
self.visibility_scope_info[source_info.scope].lint_root;
210211
self.register_violations(&[UnsafetyViolation {
211212
source_info,
212-
description: "use of extern static",
213+
description: Symbol::intern("use of extern static").as_str(),
213214
kind: UnsafetyViolationKind::ExternStatic(lint_root)
214215
}], &[]);
215216
}
@@ -225,7 +226,9 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
225226
{
226227
let source_info = self.source_info;
227228
self.register_violations(&[UnsafetyViolation {
228-
source_info, description, kind: UnsafetyViolationKind::General
229+
source_info,
230+
description: Symbol::intern(description).as_str(),
231+
kind: UnsafetyViolationKind::General,
229232
}], &[]);
230233
}
231234

@@ -320,8 +323,8 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
320323
let mir = &tcx.mir_built(def_id).borrow();
321324

322325
let visibility_scope_info = match mir.visibility_scope_info {
323-
ClearOnDecode::Set(ref data) => data,
324-
ClearOnDecode::Clear => {
326+
ClearCrossCrate::Set(ref data) => data,
327+
ClearCrossCrate::Clear => {
325328
debug!("unsafety_violations: {:?} - remote, skipping", def_id);
326329
return UnsafetyCheckResult {
327330
violations: Rc::new([]),
@@ -433,15 +436,15 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
433436
struct_span_err!(
434437
tcx.sess, source_info.span, E0133,
435438
"{} requires unsafe function or block", description)
436-
.span_label(source_info.span, description)
439+
.span_label(source_info.span, &description[..])
437440
.emit();
438441
}
439442
UnsafetyViolationKind::ExternStatic(lint_node_id) => {
440443
tcx.lint_node(SAFE_EXTERN_STATICS,
441444
lint_node_id,
442445
source_info.span,
443446
&format!("{} requires unsafe function or \
444-
block (error E0133)", description));
447+
block (error E0133)", &description[..]));
445448
}
446449
UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
447450
if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
@@ -451,7 +454,7 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
451454
lint_node_id,
452455
source_info.span,
453456
&format!("{} requires unsafe function or \
454-
block (error E0133)", description));
457+
block (error E0133)", &description[..]));
455458
}
456459
}
457460
}

‎src/libserialize/collection_impls.rs

+24
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use std::hash::{Hash, BuildHasher};
1414

1515
use {Decodable, Encodable, Decoder, Encoder};
1616
use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet};
17+
use std::rc::Rc;
1718

1819
impl<
1920
T: Encodable
@@ -194,3 +195,26 @@ impl<T, S> Decodable for HashSet<T, S>
194195
})
195196
}
196197
}
198+
199+
impl<T: Encodable> Encodable for Rc<[T]> {
200+
fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
201+
s.emit_seq(self.len(), |s| {
202+
for (index, e) in self.iter().enumerate() {
203+
s.emit_seq_elt(index, |s| e.encode(s))?;
204+
}
205+
Ok(())
206+
})
207+
}
208+
}
209+
210+
impl<T: Decodable> Decodable for Rc<[T]> {
211+
fn decode<D: Decoder>(d: &mut D) -> Result<Rc<[T]>, D::Error> {
212+
d.read_seq(|d, len| {
213+
let mut vec = Vec::with_capacity(len);
214+
for index in 0..len {
215+
vec.push(d.read_seq_elt(index, |d| Decodable::decode(d))?);
216+
}
217+
Ok(vec.into())
218+
})
219+
}
220+
}

0 commit comments

Comments
 (0)
Please sign in to comment.