about summary refs log tree commit diff
path: root/src/librustc_span
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2020-06-11 15:49:57 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2020-08-14 17:34:30 +0100
commitcbcef3effcf64bd0d89ea2dc8973e18d7fcf94c3 (patch)
treecf11d5e77bdfe87b0a19d5f93ff251b256770325 /src/librustc_span
parent55b9adfafa11b2ced5c0477c949fd875b19b3877 (diff)
Rework `rustc_serialize`
- Move the type parameter from `encode` and `decode` methods to
  the trait.
- Remove `UseSpecialized(En|De)codable` traits.
- Remove blanket impls for references.
- Add `RefDecodable` trait to allow deserializing to arena-allocated
  references safely.
- Remove ability to (de)serialize HIR.
- Create proc-macros `(Ty)?(En|De)codable` to help implement these new
  traits.
Diffstat (limited to 'src/librustc_span')
-rw-r--r--src/librustc_span/def_id.rs73
-rw-r--r--src/librustc_span/edition.rs2
-rw-r--r--src/librustc_span/hygiene.rs49
-rw-r--r--src/librustc_span/lib.rs56
-rw-r--r--src/librustc_span/source_map.rs4
-rw-r--r--src/librustc_span/symbol.rs35
6 files changed, 119 insertions, 100 deletions
diff --git a/src/librustc_span/def_id.rs b/src/librustc_span/def_id.rs
index a874f81868f..aae778217d3 100644
--- a/src/librustc_span/def_id.rs
+++ b/src/librustc_span/def_id.rs
@@ -4,7 +4,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::AtomicRef;
 use rustc_index::vec::Idx;
 use rustc_macros::HashStable_Generic;
-use rustc_serialize::{Decoder, Encoder};
+use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::borrow::Borrow;
 use std::fmt;
 
@@ -84,13 +84,14 @@ impl fmt::Display for CrateNum {
 
 /// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx.
 /// Therefore, make sure to include the context when encode a `CrateNum`.
-impl rustc_serialize::UseSpecializedEncodable for CrateNum {
-    fn default_encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
-        e.emit_u32(self.as_u32())
+impl<E: Encoder> Encodable<E> for CrateNum {
+    default fn encode(&self, s: &mut E) -> Result<(), E::Error> {
+        s.emit_u32(self.as_u32())
     }
 }
-impl rustc_serialize::UseSpecializedDecodable for CrateNum {
-    fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
+
+impl<D: Decoder> Decodable<D> for CrateNum {
+    default fn decode(d: &mut D) -> Result<CrateNum, D::Error> {
         Ok(CrateNum::from_u32(d.read_u32()?))
     }
 }
@@ -104,8 +105,8 @@ impl ::std::fmt::Debug for CrateNum {
     }
 }
 
-#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, RustcEncodable, RustcDecodable)]
-#[derive(HashStable_Generic)]
+#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
+#[derive(HashStable_Generic, Encodable, Decodable)]
 pub struct DefPathHash(pub Fingerprint);
 
 impl Borrow<Fingerprint> for DefPathHash {
@@ -120,16 +121,26 @@ rustc_index::newtype_index! {
     /// particular definition. It should really be considered an interned
     /// shorthand for a particular DefPath.
     pub struct DefIndex {
-        DEBUG_FORMAT = "DefIndex({})",
+        ENCODABLE = custom // (only encodable in metadata)
 
+        DEBUG_FORMAT = "DefIndex({})",
         /// The crate root is always assigned index 0 by the AST Map code,
         /// thanks to `NodeCollector::new`.
         const CRATE_DEF_INDEX = 0,
     }
 }
 
-impl rustc_serialize::UseSpecializedEncodable for DefIndex {}
-impl rustc_serialize::UseSpecializedDecodable for DefIndex {}
+impl<E: Encoder> Encodable<E> for DefIndex {
+    default fn encode(&self, _: &mut E) -> Result<(), E::Error> {
+        panic!("cannot encode `DefIndex` with `{}`", std::any::type_name::<E>());
+    }
+}
+
+impl<D: Decoder> Decodable<D> for DefIndex {
+    default fn decode(_: &mut D) -> Result<DefIndex, D::Error> {
+        panic!("cannot decode `DefIndex` with `{}`", std::any::type_name::<D>());
+    }
+}
 
 /// A `DefId` identifies a particular *definition*, by combining a crate
 /// index and a def index.
@@ -168,19 +179,24 @@ impl DefId {
     }
 }
 
-impl rustc_serialize::UseSpecializedEncodable for DefId {
-    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        let krate = u64::from(self.krate.as_u32());
-        let index = u64::from(self.index.as_u32());
-        s.emit_u64((krate << 32) | index)
+impl<E: Encoder> Encodable<E> for DefId {
+    default fn encode(&self, s: &mut E) -> Result<(), E::Error> {
+        s.emit_struct("DefId", 2, |s| {
+            s.emit_struct_field("krate", 0, |s| self.krate.encode(s))?;
+
+            s.emit_struct_field("index", 1, |s| self.index.encode(s))
+        })
     }
 }
-impl rustc_serialize::UseSpecializedDecodable for DefId {
-    fn default_decode<D: Decoder>(d: &mut D) -> Result<DefId, D::Error> {
-        let def_id = d.read_u64()?;
-        let krate = CrateNum::from_u32((def_id >> 32) as u32);
-        let index = DefIndex::from_u32((def_id & 0xffffffff) as u32);
-        Ok(DefId { krate, index })
+
+impl<D: Decoder> Decodable<D> for DefId {
+    default fn decode(d: &mut D) -> Result<DefId, D::Error> {
+        d.read_struct("DefId", 2, |d| {
+            Ok(DefId {
+                krate: d.read_struct_field("krate", 0, Decodable::decode)?,
+                index: d.read_struct_field("index", 1, Decodable::decode)?,
+            })
+        })
     }
 }
 
@@ -239,8 +255,17 @@ impl fmt::Debug for LocalDefId {
     }
 }
 
-impl rustc_serialize::UseSpecializedEncodable for LocalDefId {}
-impl rustc_serialize::UseSpecializedDecodable for LocalDefId {}
+impl<E: Encoder> Encodable<E> for LocalDefId {
+    fn encode(&self, s: &mut E) -> Result<(), E::Error> {
+        self.to_def_id().encode(s)
+    }
+}
+
+impl<D: Decoder> Decodable<D> for LocalDefId {
+    fn decode(d: &mut D) -> Result<LocalDefId, D::Error> {
+        DefId::decode(d).map(|d| d.expect_local())
+    }
+}
 
 impl<CTX: HashStableContext> HashStable<CTX> for DefId {
     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
diff --git a/src/librustc_span/edition.rs b/src/librustc_span/edition.rs
index b1ac7f04321..4d0c92f51d7 100644
--- a/src/librustc_span/edition.rs
+++ b/src/librustc_span/edition.rs
@@ -5,7 +5,7 @@ use std::str::FromStr;
 use rustc_macros::HashStable_Generic;
 
 /// The edition of the compiler (RFC 2052)
-#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, RustcEncodable, RustcDecodable, Eq)]
+#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, Decodable, Eq)]
 #[derive(HashStable_Generic)]
 pub enum Edition {
     // editions must be kept in order, oldest to newest
diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs
index f52b2195c2f..e8f4606b518 100644
--- a/src/librustc_span/hygiene.rs
+++ b/src/librustc_span/hygiene.rs
@@ -34,16 +34,14 @@ use log::*;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_macros::HashStable_Generic;
-use rustc_serialize::{
-    Decodable, Decoder, Encodable, Encoder, UseSpecializedDecodable, UseSpecializedEncodable,
-};
+use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::fmt;
 
 /// A `SyntaxContext` represents a chain of pairs `(ExpnId, Transparency)` named "marks".
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct SyntaxContext(u32);
 
-#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
+#[derive(Debug, Encodable, Decodable, Clone)]
 pub struct SyntaxContextData {
     outer_expn: ExpnId,
     outer_transparency: Transparency,
@@ -62,7 +60,7 @@ pub struct ExpnId(u32);
 
 /// A property of a macro expansion that determines how identifiers
 /// produced by that expansion are resolved.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug, Encodable, Decodable)]
 #[derive(HashStable_Generic)]
 pub enum Transparency {
     /// Identifier produced by a transparent expansion is always resolved at call-site.
@@ -664,7 +662,7 @@ impl Span {
 
 /// A subset of properties from both macro definition and macro call available through global data.
 /// Avoid using this if you have access to the original definition or call structures.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
 pub struct ExpnData {
     // --- The part unique to each expansion.
     /// The kind of this expansion - macro or compiler desugaring.
@@ -766,7 +764,7 @@ impl ExpnData {
 }
 
 /// Expansion kind.
-#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Clone, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
 pub enum ExpnKind {
     /// No expansion, aka root expansion. Only `ExpnId::root()` has this kind.
     Root,
@@ -794,7 +792,7 @@ impl ExpnKind {
 }
 
 /// The kind of macro invocation or definition.
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum MacroKind {
     /// A bang macro `foo!()`.
@@ -830,7 +828,7 @@ impl MacroKind {
 }
 
 /// The kind of AST transform.
-#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
 pub enum AstPass {
     StdImports,
     TestHarness,
@@ -848,7 +846,7 @@ impl AstPass {
 }
 
 /// The kind of compiler desugaring.
-#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Debug, Encodable, Decodable, HashStable_Generic)]
 pub enum DesugaringKind {
     /// We desugar `if c { i } else { e }` to `match $ExprKind::Use(c) { true => i, _ => e }`.
     /// However, we do not want to blame `c` for unreachability but rather say that `i`
@@ -867,7 +865,7 @@ pub enum DesugaringKind {
 }
 
 /// A location in the desugaring of a `for` loop
-#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Debug, Encodable, Decodable, HashStable_Generic)]
 pub enum ForLoopLoc {
     Head,
     IntoIter,
@@ -888,9 +886,6 @@ impl DesugaringKind {
     }
 }
 
-impl UseSpecializedEncodable for ExpnId {}
-impl UseSpecializedDecodable for ExpnId {}
-
 #[derive(Default)]
 pub struct HygieneEncodeContext {
     /// All `SyntaxContexts` for which we have written `SyntaxContextData` into crate metadata.
@@ -1137,6 +1132,7 @@ pub fn for_all_expns_in<E, F: FnMut(u32, ExpnId, &ExpnData) -> Result<(), E>>(
     }
     Ok(())
 }
+
 pub fn for_all_data<E, F: FnMut((u32, SyntaxContext, &SyntaxContextData)) -> Result<(), E>>(
     mut f: F,
 ) -> Result<(), E> {
@@ -1147,6 +1143,18 @@ pub fn for_all_data<E, F: FnMut((u32, SyntaxContext, &SyntaxContextData)) -> Res
     Ok(())
 }
 
+impl<E: Encoder> Encodable<E> for ExpnId {
+    default fn encode(&self, _: &mut E) -> Result<(), E::Error> {
+        panic!("cannot encode `ExpnId` with `{}`", std::any::type_name::<E>());
+    }
+}
+
+impl<D: Decoder> Decodable<D> for ExpnId {
+    default fn decode(_: &mut D) -> Result<Self, D::Error> {
+        panic!("cannot decode `ExpnId` with `{}`", std::any::type_name::<D>());
+    }
+}
+
 pub fn for_all_expn_data<E, F: FnMut(u32, &ExpnData) -> Result<(), E>>(mut f: F) -> Result<(), E> {
     let all_data = HygieneData::with(|data| data.expn_data.clone());
     for (i, data) in all_data.into_iter().enumerate() {
@@ -1218,5 +1226,14 @@ impl<'a> ExpnDataDecodeMode<'a, Box<dyn FnOnce(CrateNum) -> &'a HygieneDecodeCon
     }
 }
 
-impl UseSpecializedEncodable for SyntaxContext {}
-impl UseSpecializedDecodable for SyntaxContext {}
+impl<E: Encoder> Encodable<E> for SyntaxContext {
+    default fn encode(&self, _: &mut E) -> Result<(), E::Error> {
+        panic!("cannot encode `SyntaxContext` with `{}`", std::any::type_name::<E>());
+    }
+}
+
+impl<D: Decoder> Decodable<D> for SyntaxContext {
+    default fn decode(_: &mut D) -> Result<Self, D::Error> {
+        panic!("cannot decode `SyntaxContext` with `{}`", std::any::type_name::<D>());
+    }
+}
diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs
index 697d88ad063..c654dade2ab 100644
--- a/src/librustc_span/lib.rs
+++ b/src/librustc_span/lib.rs
@@ -15,8 +15,7 @@
 #![feature(option_expect_none)]
 #![feature(refcell_take)]
 
-// FIXME(#56935): Work around ICEs during cross-compilation.
-#[allow(unused)]
+#[macro_use]
 extern crate rustc_macros;
 
 use rustc_data_structures::AtomicRef;
@@ -105,8 +104,8 @@ scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: SessionGlobals);
 //
 // FIXME: We should use this enum or something like it to get rid of the
 // use of magic `/rust/1.x/...` paths across the board.
-#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
-#[derive(HashStable_Generic)]
+#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)]
+#[derive(HashStable_Generic, Decodable, Encodable)]
 pub enum RealFileName {
     Named(PathBuf),
     /// For de-virtualized paths (namely paths into libstd that have been mapped
@@ -152,8 +151,8 @@ impl RealFileName {
 }
 
 /// Differentiates between real files and common virtual files.
-#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
-#[derive(HashStable_Generic)]
+#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)]
+#[derive(HashStable_Generic, Decodable, Encodable)]
 pub enum FileName {
     Real(RealFileName),
     /// Call to `quote!`.
@@ -333,7 +332,7 @@ impl Ord for Span {
 ///   the error, and would be rendered with `^^^`.
 /// - They can have a *label*. In this case, the label is written next
 ///   to the mark in the snippet when we render.
-#[derive(Clone, Debug, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Hash, PartialEq, Eq, Encodable, Decodable)]
 pub struct MultiSpan {
     primary_spans: Vec<Span>,
     span_labels: Vec<(Span, String)>,
@@ -698,23 +697,22 @@ impl Default for Span {
     }
 }
 
-impl rustc_serialize::UseSpecializedEncodable for Span {
-    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<E: Encoder> Encodable<E> for Span {
+    default fn encode(&self, s: &mut E) -> Result<(), E::Error> {
         let span = self.data();
         s.emit_struct("Span", 2, |s| {
             s.emit_struct_field("lo", 0, |s| span.lo.encode(s))?;
-
             s.emit_struct_field("hi", 1, |s| span.hi.encode(s))
         })
     }
 }
-
-impl rustc_serialize::UseSpecializedDecodable for Span {
-    fn default_decode<D: Decoder>(d: &mut D) -> Result<Span, D::Error> {
-        d.read_struct("Span", 2, |d| {
+impl<D: Decoder> Decodable<D> for Span {
+    default fn decode(s: &mut D) -> Result<Span, D::Error> {
+        s.read_struct("Span", 2, |d| {
             let lo = d.read_struct_field("lo", 0, Decodable::decode)?;
             let hi = d.read_struct_field("hi", 1, Decodable::decode)?;
-            Ok(Span::with_root_ctxt(lo, hi))
+
+            Ok(Span::new(lo, hi, SyntaxContext::root()))
         })
     }
 }
@@ -889,7 +887,7 @@ impl From<Vec<Span>> for MultiSpan {
 }
 
 /// Identifies an offset of a multi-byte character in a `SourceFile`.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
+#[derive(Copy, Clone, Encodable, Decodable, Eq, PartialEq, Debug)]
 pub struct MultiByteChar {
     /// The absolute offset of the character in the `SourceMap`.
     pub pos: BytePos,
@@ -898,7 +896,7 @@ pub struct MultiByteChar {
 }
 
 /// Identifies an offset of a non-narrow character in a `SourceFile`.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
+#[derive(Copy, Clone, Encodable, Decodable, Eq, PartialEq, Debug)]
 pub enum NonNarrowChar {
     /// Represents a zero-width character.
     ZeroWidth(BytePos),
@@ -960,7 +958,7 @@ impl Sub<BytePos> for NonNarrowChar {
 }
 
 /// Identifies an offset of a character that was normalized away from `SourceFile`.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
+#[derive(Copy, Clone, Encodable, Decodable, Eq, PartialEq, Debug)]
 pub struct NormalizedPos {
     /// The absolute offset of the character in the `SourceMap`.
     pub pos: BytePos,
@@ -1012,7 +1010,7 @@ impl ExternalSource {
 #[derive(Debug)]
 pub struct OffsetOverflowError;
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
 pub enum SourceFileHashAlgorithm {
     Md5,
     Sha1,
@@ -1033,8 +1031,8 @@ impl FromStr for SourceFileHashAlgorithm {
 rustc_data_structures::impl_stable_hash_via_hash!(SourceFileHashAlgorithm);
 
 /// The hash of the on-disk source file used for debug info.
-#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
-#[derive(HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[derive(HashStable_Generic, Encodable, Decodable)]
 pub struct SourceFileHash {
     pub kind: SourceFileHashAlgorithm,
     value: [u8; 20],
@@ -1113,8 +1111,8 @@ pub struct SourceFile {
     pub cnum: CrateNum,
 }
 
-impl Encodable for SourceFile {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for SourceFile {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_struct("SourceFile", 8, |s| {
             s.emit_struct_field("name", 0, |s| self.name.encode(s))?;
             s.emit_struct_field("name_was_remapped", 1, |s| self.name_was_remapped.encode(s))?;
@@ -1183,8 +1181,8 @@ impl Encodable for SourceFile {
     }
 }
 
-impl Decodable for SourceFile {
-    fn decode<D: Decoder>(d: &mut D) -> Result<SourceFile, D::Error> {
+impl<D: Decoder> Decodable<D> for SourceFile {
+    fn decode(d: &mut D) -> Result<SourceFile, D::Error> {
         d.read_struct("SourceFile", 8, |d| {
             let name: FileName = d.read_struct_field("name", 0, |d| Decodable::decode(d))?;
             let name_was_remapped: bool =
@@ -1585,14 +1583,14 @@ impl Sub for BytePos {
     }
 }
 
-impl Encodable for BytePos {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: rustc_serialize::Encoder> Encodable<S> for BytePos {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u32(self.0)
     }
 }
 
-impl Decodable for BytePos {
-    fn decode<D: Decoder>(d: &mut D) -> Result<BytePos, D::Error> {
+impl<D: rustc_serialize::Decoder> Decodable<D> for BytePos {
+    fn decode(d: &mut D) -> Result<BytePos, D::Error> {
         Ok(BytePos(d.read_u32()?))
     }
 }
diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs
index e062c7766e7..29e589057b5 100644
--- a/src/librustc_span/source_map.rs
+++ b/src/librustc_span/source_map.rs
@@ -75,7 +75,7 @@ pub mod monotonic {
     impl<T> !DerefMut for MonotonicVec<T> {}
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
 pub struct Spanned<T> {
     pub node: T,
     pub span: Span,
@@ -118,7 +118,7 @@ impl FileLoader for RealFileLoader {
 // This is a `SourceFile` identifier that is used to correlate `SourceFile`s between
 // subsequent compilation sessions (which is something we need to do during
 // incremental compilation).
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
 pub struct StableSourceFileId(u128);
 
 // FIXME: we need a more globally consistent approach to the problem solved by
diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs
index caa6de09664..7843c04f255 100644
--- a/src/librustc_span/symbol.rs
+++ b/src/librustc_span/symbol.rs
@@ -5,9 +5,8 @@
 use rustc_arena::DroplessArena;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
-use rustc_macros::{symbols, HashStable_Generic};
+use rustc_macros::HashStable_Generic;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
-use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable};
 
 use std::cmp::{Ord, PartialEq, PartialOrd};
 use std::fmt;
@@ -1192,7 +1191,7 @@ symbols! {
     }
 }
 
-#[derive(Copy, Clone, Eq, HashStable_Generic)]
+#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
 pub struct Ident {
     pub name: Symbol,
     pub span: Span,
@@ -1289,26 +1288,6 @@ impl fmt::Display for Ident {
     }
 }
 
-impl UseSpecializedEncodable for Ident {
-    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_struct("Ident", 2, |s| {
-            s.emit_struct_field("name", 0, |s| self.name.encode(s))?;
-            s.emit_struct_field("span", 1, |s| self.span.encode(s))
-        })
-    }
-}
-
-impl UseSpecializedDecodable for Ident {
-    fn default_decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
-        d.read_struct("Ident", 2, |d| {
-            Ok(Ident {
-                name: d.read_struct_field("name", 0, Decodable::decode)?,
-                span: d.read_struct_field("span", 1, Decodable::decode)?,
-            })
-        })
-    }
-}
-
 /// This is the most general way to print identifiers.
 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
@@ -1452,15 +1431,15 @@ impl fmt::Display for Symbol {
     }
 }
 
-impl Encodable for Symbol {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for Symbol {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         self.with(|string| s.emit_str(string))
     }
 }
 
-impl Decodable for Symbol {
+impl<D: Decoder> Decodable<D> for Symbol {
     #[inline]
-    fn decode<D: Decoder>(d: &mut D) -> Result<Symbol, D::Error> {
+    fn decode(d: &mut D) -> Result<Symbol, D::Error> {
         Ok(Symbol::intern(&d.read_str()?))
     }
 }
@@ -1549,7 +1528,7 @@ pub mod sym {
     use super::Symbol;
     use std::convert::TryInto;
 
-    symbols!();
+    define_symbols!();
 
     // Used from a macro in `librustc_feature/accepted.rs`
     pub use super::kw::MacroRules as macro_rules;