From 6ed37bdc4260bdf64acf0cb2c728d6724c94ac3d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 31 Dec 2023 19:35:32 +0000 Subject: [PATCH] Avoid specialization for the Span Encodable and Decodable impls --- Cargo.lock | 1 + compiler/rustc_abi/src/lib.rs | 14 ++-- compiler/rustc_ast/src/tokenstream.rs | 8 +-- .../rustc_data_structures/src/sorted_map.rs | 2 +- compiler/rustc_data_structures/src/svh.rs | 2 +- compiler/rustc_data_structures/src/unord.rs | 6 +- compiler/rustc_index/src/bit_set.rs | 8 +-- compiler/rustc_macros/src/lib.rs | 2 + compiler/rustc_macros/src/serialize.rs | 16 +++++ compiler/rustc_metadata/src/rmeta/decoder.rs | 18 ++--- compiler/rustc_metadata/src/rmeta/encoder.rs | 22 +++---- .../rustc_middle/src/query/on_disk_cache.rs | 65 ++++++++++--------- compiler/rustc_serialize/tests/opaque.rs | 16 ++--- compiler/rustc_span/src/lib.rs | 46 +++++++++---- compiler/rustc_type_ir/Cargo.toml | 2 + compiler/rustc_type_ir/src/codec.rs | 6 +- 16 files changed, 140 insertions(+), 94 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8192e333fe..1948e6c2e5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4644,6 +4644,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_serialize", + "rustc_span", "smallvec", ] diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 549927d5898..ea194e10def 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -16,7 +16,7 @@ use rustc_data_structures::stable_hasher::StableOrd; #[cfg(feature = "nightly")] use rustc_macros::HashStable_Generic; #[cfg(feature = "nightly")] -use rustc_macros::{Decodable, Encodable}; +use rustc_macros::{Decodable_Generic, Encodable_Generic}; #[cfg(feature = "nightly")] use std::iter::Step; @@ -30,7 +30,7 @@ pub use layout::LayoutCalculator; pub trait HashStableContext {} #[derive(Clone, Copy, PartialEq, Eq, Default)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))] pub struct ReprFlags(u8); bitflags! { @@ -52,7 +52,7 @@ bitflags! { rustc_data_structures::external_bitflags_debug! { ReprFlags } #[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))] pub enum IntegerType { /// Pointer-sized integer type, i.e. `isize` and `usize`. The field shows signedness, e.g. /// `Pointer(true)` means `isize`. @@ -73,7 +73,7 @@ impl IntegerType { /// Represents the repr options provided by the user. #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))] pub struct ReprOptions { pub int: Option, pub align: Option, @@ -412,7 +412,7 @@ impl FromStr for Endian { /// Size of a type in bytes. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))] pub struct Size { raw: u64, } @@ -636,7 +636,7 @@ impl Step for Size { /// Alignment of a type in bytes (always a power of two). #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))] pub struct Align { pow2: u8, } @@ -777,7 +777,7 @@ impl AbiAndPrefAlign { /// Integers, also used for enum discriminants. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] +#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))] pub enum Integer { I8, I16, diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 4c0c496584e..503862e6f01 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -21,8 +21,8 @@ use crate::AttrVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{self, Lrc}; use rustc_macros::HashStable_Generic; -use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; -use rustc_span::{sym, Span, Symbol, DUMMY_SP}; +use rustc_serialize::{Decodable, Encodable}; +use rustc_span::{sym, Span, SpanDecoder, SpanEncoder, Symbol, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; use std::borrow::Cow; @@ -158,14 +158,14 @@ impl fmt::Debug for LazyAttrTokenStream { } } -impl Encodable for LazyAttrTokenStream { +impl Encodable for LazyAttrTokenStream { fn encode(&self, s: &mut S) { // Used by AST json printing. Encodable::encode(&self.to_attr_token_stream(), s); } } -impl Decodable for LazyAttrTokenStream { +impl Decodable for LazyAttrTokenStream { fn decode(_d: &mut D) -> Self { panic!("Attempted to decode LazyAttrTokenStream"); } diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index ed2e558bffa..1436628139f 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -16,7 +16,7 @@ pub use index_map::SortedIndexMultiMap; /// stores data in a more compact way. It also supports accessing contiguous /// ranges of elements as a slice, and slices of already sorted elements can be /// inserted efficiently. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable_Generic, Decodable_Generic)] pub struct SortedMap { data: Vec<(K, V)>, } diff --git a/compiler/rustc_data_structures/src/svh.rs b/compiler/rustc_data_structures/src/svh.rs index 71679086f16..1cfc9fecd47 100644 --- a/compiler/rustc_data_structures/src/svh.rs +++ b/compiler/rustc_data_structures/src/svh.rs @@ -10,7 +10,7 @@ use std::fmt; use crate::stable_hasher; -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable_Generic, Decodable_Generic, Hash)] pub struct Svh { hash: Fingerprint, } diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index 47c56eba7ad..9f8ddbd4256 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs @@ -185,7 +185,7 @@ trait UnordCollection {} /// /// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533) /// for more information. -#[derive(Debug, Eq, PartialEq, Clone, Encodable, Decodable)] +#[derive(Debug, Eq, PartialEq, Clone, Encodable_Generic, Decodable_Generic)] pub struct UnordSet { inner: FxHashSet, } @@ -362,7 +362,7 @@ impl> HashStable for UnordSet { /// /// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533) /// for more information. -#[derive(Debug, Eq, PartialEq, Clone, Encodable, Decodable)] +#[derive(Debug, Eq, PartialEq, Clone, Encodable_Generic, Decodable_Generic)] pub struct UnordMap { inner: FxHashMap, } @@ -558,7 +558,7 @@ impl, V: HashStable> HashStable fo /// /// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533) /// for more information. -#[derive(Default, Debug, Eq, PartialEq, Clone, Encodable, Decodable)] +#[derive(Default, Debug, Eq, PartialEq, Clone, Encodable_Generic, Decodable_Generic)] pub struct UnordBag { inner: Vec, } diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index d730ef58deb..cba02548eb5 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -10,7 +10,7 @@ use arrayvec::ArrayVec; use smallvec::{smallvec, SmallVec}; #[cfg(feature = "nightly")] -use rustc_macros::{Decodable, Encodable}; +use rustc_macros::{Decodable_Generic, Encodable_Generic}; use crate::{Idx, IndexVec}; @@ -112,7 +112,7 @@ macro_rules! bit_relations_inherent_impls { /// to or greater than the domain size. All operations that involve two bitsets /// will panic if the bitsets have differing domain sizes. /// -#[cfg_attr(feature = "nightly", derive(Decodable, Encodable))] +#[cfg_attr(feature = "nightly", derive(Decodable_Generic, Encodable_Generic))] #[derive(Eq, PartialEq, Hash)] pub struct BitSet { domain_size: usize, @@ -1590,7 +1590,7 @@ impl From> for GrowableBitSet { /// /// All operations that involve a row and/or column index will panic if the /// index exceeds the relevant bound. -#[cfg_attr(feature = "nightly", derive(Decodable, Encodable))] +#[cfg_attr(feature = "nightly", derive(Decodable_Generic, Encodable_Generic))] #[derive(Clone, Eq, PartialEq, Hash)] pub struct BitMatrix { num_rows: usize, @@ -2020,7 +2020,7 @@ impl std::fmt::Debug for FiniteBitSet { /// A fixed-sized bitset type represented by an integer type. Indices outwith than the range /// representable by `T` are considered set. -#[cfg_attr(feature = "nightly", derive(Decodable, Encodable))] +#[cfg_attr(feature = "nightly", derive(Decodable_Generic, Encodable_Generic))] #[derive(Copy, Clone, Eq, PartialEq)] pub struct FiniteBitSet(pub T); diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index f558b74be9a..f5d942b924e 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -56,6 +56,8 @@ decl_derive!( hash_stable::hash_stable_no_context_derive ); +decl_derive!([Decodable_Generic] => serialize::decodable_generic_derive); +decl_derive!([Encodable_Generic] => serialize::encodable_generic_derive); decl_derive!([Decodable] => serialize::decodable_derive); decl_derive!([Encodable] => serialize::encodable_derive); decl_derive!([TyDecodable] => serialize::type_decodable_derive); diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index 047066ac681..9ca7ce09ba6 100644 --- a/compiler/rustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs @@ -31,6 +31,14 @@ pub fn meta_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: } pub fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + let decoder_ty = quote! { __D }; + s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_span::SpanDecoder}); + s.add_bounds(synstructure::AddBounds::Generics); + + decodable_body(s, decoder_ty) +} + +pub fn decodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let decoder_ty = quote! { __D }; s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_serialize::Decoder}); s.add_bounds(synstructure::AddBounds::Generics); @@ -129,6 +137,14 @@ pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: } pub fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + let encoder_ty = quote! { __E }; + s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_span::SpanEncoder}); + s.add_bounds(synstructure::AddBounds::Generics); + + encodable_body(s, encoder_ty, false) +} + +pub fn encodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let encoder_ty = quote! { __E }; s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_serialize::Encoder}); s.add_bounds(synstructure::AddBounds::Generics); diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2de29db9e5c..2dffd5446a3 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -26,7 +26,7 @@ use rustc_serialize::{Decodable, Decoder}; use rustc_session::cstore::{CrateSource, ExternCrate}; use rustc_session::Session; use rustc_span::symbol::kw; -use rustc_span::{BytePos, Pos, SpanData, SyntaxContext, DUMMY_SP}; +use rustc_span::{BytePos, Pos, SpanData, SpanDecoder, SyntaxContext, DUMMY_SP}; use proc_macro::bridge::client::ProcMacro; use std::iter::TrustedLen; @@ -505,22 +505,22 @@ impl<'a, 'tcx> Decodable> for ExpnId { } } -impl<'a, 'tcx> Decodable> for Span { - fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Span { - let start = decoder.position(); - let tag = SpanTag(decoder.peek_byte()); +impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> { + fn decode_span(&mut self) -> Span { + let start = self.position(); + let tag = SpanTag(self.peek_byte()); let data = if tag.kind() == SpanKind::Indirect { // Skip past the tag we just peek'd. - decoder.read_u8(); - let offset_or_position = decoder.read_usize(); + self.read_u8(); + let offset_or_position = self.read_usize(); let position = if tag.is_relative_offset() { start - offset_or_position } else { offset_or_position }; - decoder.with_position(position, SpanData::decode) + self.with_position(position, SpanData::decode) } else { - SpanData::decode(decoder) + SpanData::decode(self) }; Span::new(data.lo, data.hi, data.ctxt, data.parent) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index aca7a66596e..dbd82d3ab79 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -27,7 +27,7 @@ use rustc_session::config::{CrateType, OptLevel}; use rustc_span::hygiene::HygieneEncodeContext; use rustc_span::symbol::sym; use rustc_span::{ - ExternalSource, FileName, SourceFile, SpanData, StableSourceFileId, SyntaxContext, + ExternalSource, FileName, SourceFile, SpanData, SpanEncoder, StableSourceFileId, SyntaxContext, }; use std::borrow::Borrow; use std::collections::hash_map::Entry; @@ -166,29 +166,29 @@ impl<'a, 'tcx> Encodable> for ExpnId { } } -impl<'a, 'tcx> Encodable> for Span { - fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) { - match s.span_shorthands.entry(*self) { +impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> { + fn encode_span(&mut self, span: Span) { + match self.span_shorthands.entry(span) { Entry::Occupied(o) => { // If an offset is smaller than the absolute position, we encode with the offset. // This saves space since smaller numbers encode in less bits. let last_location = *o.get(); // This cannot underflow. Metadata is written with increasing position(), so any // previously saved offset must be smaller than the current position. - let offset = s.opaque.position() - last_location; + let offset = self.opaque.position() - last_location; if offset < last_location { - SpanTag::indirect(true).encode(s); - offset.encode(s); + SpanTag::indirect(true).encode(self); + offset.encode(self); } else { - SpanTag::indirect(false).encode(s); - last_location.encode(s); + SpanTag::indirect(false).encode(self); + last_location.encode(self); } } Entry::Vacant(v) => { - let position = s.opaque.position(); + let position = self.opaque.position(); v.insert(position); // Data is encoded with a SpanTag prefix (see below). - self.data().encode(s); + span.data().encode(self); } } } diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index 0577d22d850..f8a34e05eb0 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -22,7 +22,8 @@ use rustc_span::hygiene::{ }; use rustc_span::source_map::SourceMap; use rustc_span::{ - BytePos, ExpnData, ExpnHash, Pos, RelativeBytePos, SourceFile, Span, StableSourceFileId, + BytePos, ExpnData, ExpnHash, Pos, RelativeBytePos, SourceFile, Span, SpanDecoder, SpanEncoder, + StableSourceFileId, }; use rustc_span::{CachingSourceMapView, Symbol}; use std::collections::hash_map::Entry; @@ -648,19 +649,19 @@ impl<'a, 'tcx> Decodable> for ExpnId { } } -impl<'a, 'tcx> Decodable> for Span { - fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self { - let ctxt = SyntaxContext::decode(decoder); - let parent = Option::::decode(decoder); - let tag: u8 = Decodable::decode(decoder); +impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> { + fn decode_span(&mut self) -> Span { + let ctxt = SyntaxContext::decode(self); + let parent = Option::::decode(self); + let tag: u8 = Decodable::decode(self); if tag == TAG_PARTIAL_SPAN { return Span::new(BytePos(0), BytePos(0), ctxt, parent); } else if tag == TAG_RELATIVE_SPAN { - let dlo = u32::decode(decoder); - let dto = u32::decode(decoder); + let dlo = u32::decode(self); + let dto = u32::decode(self); - let enclosing = decoder.tcx.source_span_untracked(parent.unwrap()).data_untracked(); + let enclosing = self.tcx.source_span_untracked(parent.unwrap()).data_untracked(); let span = Span::new( enclosing.lo + BytePos::from_u32(dlo), enclosing.lo + BytePos::from_u32(dto), @@ -673,12 +674,12 @@ impl<'a, 'tcx> Decodable> for Span { debug_assert_eq!(tag, TAG_FULL_SPAN); } - let file_lo_index = SourceFileIndex::decode(decoder); - let line_lo = usize::decode(decoder); - let col_lo = RelativeBytePos::decode(decoder); - let len = BytePos::decode(decoder); + let file_lo_index = SourceFileIndex::decode(self); + let line_lo = usize::decode(self); + let col_lo = RelativeBytePos::decode(self); + let len = BytePos::decode(self); - let file_lo = decoder.file_index_to_file(file_lo_index); + let file_lo = self.file_index_to_file(file_lo_index); let lo = file_lo.lines()[line_lo - 1] + col_lo; let lo = file_lo.absolute_position(lo); let hi = lo + len; @@ -872,47 +873,47 @@ impl<'a, 'tcx> Encodable> for ExpnId { } } -impl<'a, 'tcx> Encodable> for Span { - fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) { - let span_data = self.data_untracked(); - span_data.ctxt.encode(s); - span_data.parent.encode(s); +impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> { + fn encode_span(&mut self, span: Span) { + let span_data = span.data_untracked(); + span_data.ctxt.encode(self); + span_data.parent.encode(self); if span_data.is_dummy() { - return TAG_PARTIAL_SPAN.encode(s); + return TAG_PARTIAL_SPAN.encode(self); } if let Some(parent) = span_data.parent { - let enclosing = s.tcx.source_span_untracked(parent).data_untracked(); + let enclosing = self.tcx.source_span_untracked(parent).data_untracked(); if enclosing.contains(span_data) { - TAG_RELATIVE_SPAN.encode(s); - (span_data.lo - enclosing.lo).to_u32().encode(s); - (span_data.hi - enclosing.lo).to_u32().encode(s); + TAG_RELATIVE_SPAN.encode(self); + (span_data.lo - enclosing.lo).to_u32().encode(self); + (span_data.hi - enclosing.lo).to_u32().encode(self); return; } } - let pos = s.source_map.byte_pos_to_line_and_col(span_data.lo); + let pos = self.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, }; if partial_span { - return TAG_PARTIAL_SPAN.encode(s); + return TAG_PARTIAL_SPAN.encode(self); } let (file_lo, line_lo, col_lo) = pos.unwrap(); let len = span_data.hi - span_data.lo; - let source_file_index = s.source_file_index(file_lo); + let source_file_index = self.source_file_index(file_lo); - TAG_FULL_SPAN.encode(s); - source_file_index.encode(s); - line_lo.encode(s); - col_lo.encode(s); - len.encode(s); + TAG_FULL_SPAN.encode(self); + source_file_index.encode(self); + line_lo.encode(self); + col_lo.encode(self); + len.encode(self); } } diff --git a/compiler/rustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/tests/opaque.rs index 861091688bb..45ff85f38d2 100644 --- a/compiler/rustc_serialize/tests/opaque.rs +++ b/compiler/rustc_serialize/tests/opaque.rs @@ -1,12 +1,12 @@ #![allow(rustc::internal)] -use rustc_macros::{Decodable, Encodable}; -use rustc_serialize::opaque::{MemDecoder, FileEncoder}; +use rustc_macros::{Decodable_Generic, Encodable_Generic}; +use rustc_serialize::opaque::{FileEncoder, MemDecoder}; use rustc_serialize::{Decodable, Encodable}; use std::fmt::Debug; use std::fs; -#[derive(PartialEq, Clone, Debug, Encodable, Decodable)] +#[derive(PartialEq, Clone, Debug, Encodable_Generic, Decodable_Generic)] struct Struct { a: (), b: u8, @@ -209,7 +209,7 @@ fn test_struct() { }]); } -#[derive(PartialEq, Clone, Debug, Encodable, Decodable)] +#[derive(PartialEq, Clone, Debug, Encodable_Generic, Decodable_Generic)] enum Enum { Variant1, Variant2(usize, u32), @@ -258,7 +258,7 @@ fn test_tuples() { #[test] fn test_unit_like_struct() { - #[derive(Encodable, Decodable, PartialEq, Debug)] + #[derive(Encodable_Generic, Decodable_Generic, PartialEq, Debug)] struct UnitLikeStruct; check_round_trip(vec![UnitLikeStruct]); @@ -266,7 +266,7 @@ fn test_unit_like_struct() { #[test] fn test_box() { - #[derive(Encodable, Decodable, PartialEq, Debug)] + #[derive(Encodable_Generic, Decodable_Generic, PartialEq, Debug)] struct A { foo: Box<[bool]>, } @@ -279,12 +279,12 @@ fn test_box() { fn test_cell() { use std::cell::{Cell, RefCell}; - #[derive(Encodable, Decodable, PartialEq, Debug)] + #[derive(Encodable_Generic, Decodable_Generic, PartialEq, Debug)] struct A { baz: isize, } - #[derive(Encodable, Decodable, PartialEq, Debug)] + #[derive(Encodable_Generic, Decodable_Generic, PartialEq, Debug)] struct B { foo: Cell, bar: RefCell, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 8f64eed9a87..0eafbae6e82 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -35,6 +35,8 @@ #![feature(rustdoc_internals)] // tidy-alphabetical-end +extern crate self as rustc_span; + #[macro_use] extern crate rustc_macros; @@ -43,6 +45,7 @@ extern crate tracing; use rustc_data_structures::{outline, AtomicRef}; use rustc_macros::HashStable_Generic; +use rustc_serialize::opaque::{FileEncoder, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; mod caching_source_map_view; @@ -1016,22 +1019,43 @@ impl Default for Span { } } -impl Encodable for Span { - default fn encode(&self, s: &mut E) { - let span = self.data(); - span.lo.encode(s); - span.hi.encode(s); +pub trait SpanEncoder: Encoder { + fn encode_span(&mut self, span: Span); +} + +impl SpanEncoder for FileEncoder { + fn encode_span(&mut self, span: Span) { + let span = span.data(); + span.lo.encode(self); + span.hi.encode(self); } } -impl Decodable for Span { - default fn decode(s: &mut D) -> Span { - let lo = Decodable::decode(s); - let hi = Decodable::decode(s); + +impl Encodable for Span { + fn encode(&self, s: &mut E) { + s.encode_span(*self); + } +} + +pub trait SpanDecoder: Decoder { + fn decode_span(&mut self) -> Span; +} + +impl SpanDecoder for MemDecoder<'_> { + fn decode_span(&mut self) -> Span { + let lo = Decodable::decode(self); + let hi = Decodable::decode(self); Span::new(lo, hi, SyntaxContext::root(), None) } } +impl Decodable for Span { + fn decode(s: &mut D) -> Span { + s.decode_span() + } +} + /// Insert `source_map` into the session globals for the duration of the /// closure's execution. pub fn set_source_map T>(source_map: Lrc, f: F) -> T { @@ -1360,7 +1384,7 @@ impl Clone for SourceFile { } } -impl Encodable for SourceFile { +impl Encodable for SourceFile { fn encode(&self, s: &mut S) { self.name.encode(s); self.src_hash.encode(s); @@ -1434,7 +1458,7 @@ impl Encodable for SourceFile { } } -impl Decodable for SourceFile { +impl Decodable for SourceFile { fn decode(d: &mut D) -> SourceFile { let name: FileName = Decodable::decode(d); let src_hash: SourceFileHash = Decodable::decode(d); diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 38f0eb82180..3a94256f402 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -10,6 +10,7 @@ derivative = "2.2.0" rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } +rustc_span = { path = "../rustc_span", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } smallvec = { version = "1.8.1" } # tidy-alphabetical-end @@ -20,6 +21,7 @@ nightly = [ "smallvec/may_dangle", "smallvec/union", "rustc_index/nightly", + "rustc_span", "rustc_serialize", "rustc_data_structures", "rustc_macros", diff --git a/compiler/rustc_type_ir/src/codec.rs b/compiler/rustc_type_ir/src/codec.rs index 2fbc8f76fa4..71f9eb0ef8a 100644 --- a/compiler/rustc_type_ir/src/codec.rs +++ b/compiler/rustc_type_ir/src/codec.rs @@ -1,7 +1,7 @@ use crate::{Interner, PredicateKind}; use rustc_data_structures::fx::FxHashMap; -use rustc_serialize::{Decoder, Encoder}; +use rustc_span::{SpanDecoder, SpanEncoder}; /// The shorthand encoding uses an enum's variant index `usize` /// and is offset by this value so it never matches a real variant. @@ -22,7 +22,7 @@ pub trait RefDecodable<'tcx, D: TyDecoder> { fn decode(d: &mut D) -> &'tcx Self; } -pub trait TyEncoder: Encoder { +pub trait TyEncoder: SpanEncoder { type I: Interner; const CLEAR_CROSS_CRATE: bool; @@ -35,7 +35,7 @@ pub trait TyEncoder: Encoder { fn encode_alloc_id(&mut self, alloc_id: &::AllocId); } -pub trait TyDecoder: Decoder { +pub trait TyDecoder: SpanDecoder { type I: Interner; const CLEAR_CROSS_CRATE: bool;