]> git.lizzy.rs Git - rust.git/commitdiff
Rework `rustc_serialize`
authorMatthew Jasper <mjjasper1@gmail.com>
Thu, 11 Jun 2020 14:49:57 +0000 (15:49 +0100)
committerMatthew Jasper <mjjasper1@gmail.com>
Fri, 14 Aug 2020 16:34:30 +0000 (17:34 +0100)
- 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.

116 files changed:
Cargo.lock
src/librustc_ast/ast.rs
src/librustc_ast/crate_disambiguator.rs
src/librustc_ast/lib.rs
src/librustc_ast/node_id.rs
src/librustc_ast/ptr.rs
src/librustc_ast/token.rs
src/librustc_ast/tokenstream.rs
src/librustc_attr/builtin.rs
src/librustc_attr/lib.rs
src/librustc_codegen_ssa/Cargo.toml
src/librustc_codegen_ssa/back/linker.rs
src/librustc_codegen_ssa/lib.rs
src/librustc_data_structures/Cargo.toml
src/librustc_data_structures/fingerprint.rs
src/librustc_data_structures/lib.rs
src/librustc_data_structures/sorted_map.rs
src/librustc_data_structures/svh.rs
src/librustc_data_structures/thin_vec.rs
src/librustc_data_structures/transitive_relation.rs
src/librustc_errors/Cargo.toml
src/librustc_errors/diagnostic.rs
src/librustc_errors/json.rs
src/librustc_errors/json/tests.rs
src/librustc_errors/lib.rs
src/librustc_errors/snippet.rs
src/librustc_expand/Cargo.toml
src/librustc_expand/lib.rs
src/librustc_expand/mbe.rs
src/librustc_hir/def.rs
src/librustc_hir/definitions.rs
src/librustc_hir/hir.rs
src/librustc_hir/hir_id.rs
src/librustc_hir/lang_items.rs
src/librustc_hir/lib.rs
src/librustc_incremental/Cargo.toml
src/librustc_incremental/persist/data.rs
src/librustc_index/Cargo.toml
src/librustc_index/bit_set.rs
src/librustc_index/vec.rs
src/librustc_infer/infer/free_regions.rs
src/librustc_macros/src/lib.rs
src/librustc_macros/src/serialize.rs [new file with mode: 0644]
src/librustc_macros/src/symbols.rs
src/librustc_metadata/Cargo.toml
src/librustc_metadata/lib.rs
src/librustc_metadata/rmeta/decoder.rs
src/librustc_metadata/rmeta/encoder.rs
src/librustc_metadata/rmeta/mod.rs
src/librustc_metadata/rmeta/table.rs
src/librustc_middle/arena.rs
src/librustc_middle/dep_graph/dep_node.rs
src/librustc_middle/hir/exports.rs
src/librustc_middle/hir/place.rs
src/librustc_middle/infer/canonical.rs
src/librustc_middle/middle/codegen_fn_attrs.rs
src/librustc_middle/middle/cstore.rs
src/librustc_middle/middle/dependency_format.rs
src/librustc_middle/middle/exported_symbols.rs
src/librustc_middle/middle/region.rs
src/librustc_middle/middle/resolve_lifetime.rs
src/librustc_middle/mir/interpret/allocation.rs
src/librustc_middle/mir/interpret/error.rs
src/librustc_middle/mir/interpret/mod.rs
src/librustc_middle/mir/interpret/pointer.rs
src/librustc_middle/mir/interpret/value.rs
src/librustc_middle/mir/mod.rs
src/librustc_middle/mir/mono.rs
src/librustc_middle/mir/predecessors.rs
src/librustc_middle/mir/query.rs
src/librustc_middle/mir/terminator/mod.rs
src/librustc_middle/traits/mod.rs
src/librustc_middle/traits/specialization_graph.rs
src/librustc_middle/ty/adjustment.rs
src/librustc_middle/ty/binding.rs
src/librustc_middle/ty/cast.rs
src/librustc_middle/ty/codec.rs
src/librustc_middle/ty/consts.rs
src/librustc_middle/ty/consts/kind.rs
src/librustc_middle/ty/context.rs
src/librustc_middle/ty/fast_reject.rs
src/librustc_middle/ty/instance.rs
src/librustc_middle/ty/layout.rs
src/librustc_middle/ty/list.rs
src/librustc_middle/ty/mod.rs
src/librustc_middle/ty/query/on_disk_cache.rs
src/librustc_middle/ty/sty.rs
src/librustc_middle/ty/subst.rs
src/librustc_middle/ty/trait_def.rs
src/librustc_middle/ty/util.rs
src/librustc_query_system/Cargo.toml
src/librustc_query_system/dep_graph/dep_node.rs
src/librustc_query_system/dep_graph/graph.rs
src/librustc_query_system/dep_graph/prev.rs
src/librustc_query_system/dep_graph/serialized.rs
src/librustc_query_system/lib.rs
src/librustc_serialize/collection_impls.rs
src/librustc_serialize/json.rs
src/librustc_serialize/lib.rs
src/librustc_serialize/serialize.rs
src/librustc_session/Cargo.toml
src/librustc_session/config.rs
src/librustc_session/lib.rs
src/librustc_session/search_paths.rs
src/librustc_session/utils.rs
src/librustc_span/def_id.rs
src/librustc_span/edition.rs
src/librustc_span/hygiene.rs
src/librustc_span/lib.rs
src/librustc_span/source_map.rs
src/librustc_span/symbol.rs
src/librustc_target/abi/mod.rs
src/librustc_target/asm/mod.rs
src/librustc_target/lib.rs
src/librustc_target/spec/abi.rs
src/librustc_target/spec/mod.rs

index f6b5b317646c363daf2d4954297d3fee77abcf5d..564c3da522342071c4d87781d69d96a7e18aa0ff 100644 (file)
@@ -3334,6 +3334,7 @@ dependencies = [
  "rustc_hir",
  "rustc_incremental",
  "rustc_index",
+ "rustc_macros",
  "rustc_middle",
  "rustc_serialize",
  "rustc_session",
@@ -3364,6 +3365,7 @@ dependencies = [
  "rustc-rayon-core",
  "rustc_graphviz",
  "rustc_index",
+ "rustc_macros",
  "rustc_serialize",
  "smallvec 1.4.0",
  "stable_deref_trait",
@@ -3416,6 +3418,7 @@ dependencies = [
  "annotate-snippets 0.8.0",
  "atty",
  "rustc_data_structures",
+ "rustc_macros",
  "rustc_serialize",
  "rustc_span",
  "termcolor",
@@ -3437,6 +3440,7 @@ dependencies = [
  "rustc_errors",
  "rustc_feature",
  "rustc_lexer",
+ "rustc_macros",
  "rustc_parse",
  "rustc_serialize",
  "rustc_session",
@@ -3499,6 +3503,7 @@ dependencies = [
  "rustc_fs_util",
  "rustc_graphviz",
  "rustc_hir",
+ "rustc_macros",
  "rustc_middle",
  "rustc_serialize",
  "rustc_session",
@@ -3511,6 +3516,7 @@ name = "rustc_index"
 version = "0.0.0"
 dependencies = [
  "arrayvec 0.5.1",
+ "rustc_macros",
  "rustc_serialize",
 ]
 
@@ -3640,6 +3646,7 @@ dependencies = [
  "rustc_hir",
  "rustc_hir_pretty",
  "rustc_index",
+ "rustc_macros",
  "rustc_middle",
  "rustc_serialize",
  "rustc_session",
@@ -3815,6 +3822,7 @@ dependencies = [
  "rustc_data_structures",
  "rustc_errors",
  "rustc_index",
+ "rustc_macros",
  "rustc_serialize",
  "rustc_span",
  "smallvec 1.4.0",
@@ -3884,6 +3892,7 @@ dependencies = [
  "rustc_errors",
  "rustc_feature",
  "rustc_fs_util",
+ "rustc_macros",
  "rustc_serialize",
  "rustc_span",
  "rustc_target",
index a0541158bc2c5f500f9f575e482e8dedde8c2ddd..6dff02486ff197a0d58a178b19a0c0d46758fe43 100644 (file)
@@ -53,7 +53,7 @@
 /// ```
 ///
 /// `'outer` is a label.
-#[derive(Clone, RustcEncodable, RustcDecodable, Copy, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic)]
 pub struct Label {
     pub ident: Ident,
 }
@@ -66,7 +66,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 /// A "Lifetime" is an annotation of the scope in which variable
 /// can be used, e.g. `'a` in `&'a i32`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Clone, Encodable, Decodable, Copy)]
 pub struct Lifetime {
     pub id: NodeId,
     pub ident: Ident,
@@ -90,7 +90,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 /// along with a bunch of supporting information.
 ///
 /// E.g., `std::cmp::PartialEq`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Path {
     pub span: Span,
     /// The segments in the path: the things separated by `::`.
@@ -128,7 +128,7 @@ pub fn is_global(&self) -> bool {
 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
 ///
 /// E.g., `std`, `String` or `Box<T>`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct PathSegment {
     /// The identifier portion of this path segment.
     pub ident: Ident,
@@ -156,7 +156,7 @@ pub fn path_root(span: Span) -> Self {
 /// The arguments of a path segment.
 ///
 /// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum GenericArgs {
     /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`.
     AngleBracketed(AngleBracketedArgs),
@@ -188,7 +188,7 @@ pub fn span(&self) -> Span {
 }
 
 /// Concrete argument in the sequence of generic args.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum GenericArg {
     /// `'a` in `Foo<'a>`
     Lifetime(Lifetime),
@@ -209,7 +209,7 @@ pub fn span(&self) -> Span {
 }
 
 /// A path like `Foo<'a, T>`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
+#[derive(Clone, Encodable, Decodable, Debug, Default)]
 pub struct AngleBracketedArgs {
     /// The overall span.
     pub span: Span,
@@ -219,7 +219,7 @@ pub struct AngleBracketedArgs {
 
 /// Either an argument for a parameter e.g., `'a`, `Vec<u8>`, `0`,
 /// or a constraint on an associated item, e.g., `Item = String` or `Item: Bound`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum AngleBracketedArg {
     /// Argument for a generic parameter.
     Arg(GenericArg),
@@ -240,7 +240,7 @@ fn into(self) -> Option<P<GenericArgs>> {
 }
 
 /// A path like `Foo(A, B) -> C`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct ParenthesizedArgs {
     /// Overall span
     pub span: Span,
@@ -269,7 +269,7 @@ pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
 /// A modifier on a bound, e.g., `?Sized` or `?const Trait`.
 ///
 /// Negative bounds should also be handled here.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
 pub enum TraitBoundModifier {
     /// No modifiers
     None,
@@ -290,7 +290,7 @@ pub enum TraitBoundModifier {
 /// `typeck::collect::compute_bounds` matches these against
 /// the "special" built-in traits (see `middle::lang_items`) and
 /// detects `Copy`, `Send` and `Sync`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum GenericBound {
     Trait(PolyTraitRef, TraitBoundModifier),
     Outlives(Lifetime),
@@ -357,7 +357,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum GenericParamKind {
     /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
     Lifetime,
@@ -371,7 +371,7 @@ pub enum GenericParamKind {
     },
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct GenericParam {
     pub id: NodeId,
     pub ident: Ident,
@@ -383,7 +383,7 @@ pub struct GenericParam {
 
 /// Represents lifetime, type and const parameters attached to a declaration of
 /// a function, enum, trait, etc.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Generics {
     pub params: Vec<GenericParam>,
     pub where_clause: WhereClause,
@@ -406,7 +406,7 @@ fn default() -> Generics {
 }
 
 /// A where-clause in a definition.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WhereClause {
     /// `true` if we ate a `where` token: this can happen
     /// if we parsed no predicates (e.g. `struct Foo where {}`).
@@ -418,7 +418,7 @@ pub struct WhereClause {
 }
 
 /// A single predicate in a where-clause.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum WherePredicate {
     /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate),
@@ -441,7 +441,7 @@ pub fn span(&self) -> Span {
 /// A type bound.
 ///
 /// E.g., `for<'c> Foo: Send + Clone + 'c`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WhereBoundPredicate {
     pub span: Span,
     /// Any generics from a `for` binding.
@@ -455,7 +455,7 @@ pub struct WhereBoundPredicate {
 /// A lifetime predicate.
 ///
 /// E.g., `'a: 'b + 'c`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WhereRegionPredicate {
     pub span: Span,
     pub lifetime: Lifetime,
@@ -465,7 +465,7 @@ pub struct WhereRegionPredicate {
 /// An equality predicate (unsupported).
 ///
 /// E.g., `T = int`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WhereEqPredicate {
     pub id: NodeId,
     pub span: Span,
@@ -473,7 +473,7 @@ pub struct WhereEqPredicate {
     pub rhs_ty: P<Ty>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Crate {
     pub module: Mod,
     pub attrs: Vec<Attribute>,
@@ -490,7 +490,7 @@ pub struct Crate {
 /// Possible values inside of compile-time attribute lists.
 ///
 /// E.g., the '..' in `#[name(..)]`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum NestedMetaItem {
     /// A full MetaItem, for recursive meta items.
     MetaItem(MetaItem),
@@ -503,7 +503,7 @@ pub enum NestedMetaItem {
 /// A spanned compile-time attribute item.
 ///
 /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct MetaItem {
     pub path: Path,
     pub kind: MetaItemKind,
@@ -513,7 +513,7 @@ pub struct MetaItem {
 /// A compile-time attribute item.
 ///
 /// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum MetaItemKind {
     /// Word meta item.
     ///
@@ -532,7 +532,7 @@ pub enum MetaItemKind {
 /// A block (`{ .. }`).
 ///
 /// E.g., `{ .. }` as in `fn foo() { .. }`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Block {
     /// The statements in the block.
     pub stmts: Vec<Stmt>,
@@ -545,7 +545,7 @@ pub struct Block {
 /// A match pattern.
 ///
 /// Patterns appear in match statements and some other contexts, such as `let` and `if let`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Pat {
     pub id: NodeId,
     pub kind: PatKind,
@@ -636,7 +636,7 @@ pub fn is_rest(&self) -> bool {
 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
 /// except is_shorthand is true
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct FieldPat {
     /// The identifier for the field
     pub ident: Ident,
@@ -649,19 +649,19 @@ pub struct FieldPat {
     pub is_placeholder: bool,
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
 pub enum BindingMode {
     ByRef(Mutability),
     ByValue(Mutability),
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum RangeEnd {
     Included(RangeSyntax),
     Excluded,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum RangeSyntax {
     /// `...`
     DotDotDot,
@@ -669,7 +669,7 @@ pub enum RangeSyntax {
     DotDotEq,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum PatKind {
     /// Represents a wildcard pattern (`_`).
     Wild,
@@ -736,8 +736,8 @@ pub enum PatKind {
     MacCall(MacCall),
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug, Copy)]
-#[derive(HashStable_Generic)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
+#[derive(HashStable_Generic, Encodable, Decodable)]
 pub enum Mutability {
     Mut,
     Not,
@@ -770,7 +770,7 @@ pub fn prefix_str(&self) -> &'static str {
 /// The kind of borrow in an `AddrOf` expression,
 /// e.g., `&place` or `&raw const place`.
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum BorrowKind {
     /// A normal borrow, `&$expr` or `&mut $expr`.
     /// The resulting type is either `&'a T` or `&'a mut T`
@@ -782,7 +782,7 @@ pub enum BorrowKind {
     Raw,
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
 pub enum BinOpKind {
     /// The `+` operator (addition)
     Add,
@@ -881,7 +881,7 @@ pub fn is_by_value(&self) -> bool {
 /// Unary operator.
 ///
 /// Note that `&data` is not an operator, it's an `AddrOf` expression.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, Encodable, Decodable, Debug, Copy)]
 pub enum UnOp {
     /// The `*` operator for dereferencing
     Deref,
@@ -910,7 +910,7 @@ pub fn to_string(op: UnOp) -> &'static str {
 }
 
 /// A statement
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Stmt {
     pub id: NodeId,
     pub kind: StmtKind,
@@ -944,7 +944,7 @@ pub fn is_expr(&self) -> bool {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum StmtKind {
     /// A local (let) binding.
     Local(P<Local>),
@@ -960,7 +960,7 @@ pub enum StmtKind {
     MacCall(P<(MacCall, MacStmtStyle, AttrVec)>),
 }
 
-#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
 pub enum MacStmtStyle {
     /// The macro statement had a trailing semicolon (e.g., `foo! { ... };`
     /// `foo!(...);`, `foo![...];`).
@@ -974,7 +974,7 @@ pub enum MacStmtStyle {
 }
 
 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Local {
     pub id: NodeId,
     pub pat: P<Pat>,
@@ -995,7 +995,7 @@ pub struct Local {
 ///     _ => { println!("no match!") },
 /// }
 /// ```
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Arm {
     pub attrs: Vec<Attribute>,
     /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`
@@ -1010,7 +1010,7 @@ pub struct Arm {
 }
 
 /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Field {
     pub attrs: AttrVec,
     pub id: NodeId,
@@ -1021,13 +1021,13 @@ pub struct Field {
     pub is_placeholder: bool,
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
 pub enum BlockCheckMode {
     Default,
     Unsafe(UnsafeSource),
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
@@ -1038,14 +1038,14 @@ pub enum UnsafeSource {
 /// These are usually found nested inside types (e.g., array lengths)
 /// or expressions (e.g., repeat counts), and also used to define
 /// explicit discriminant values for enum variants.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct AnonConst {
     pub id: NodeId,
     pub value: P<Expr>,
 }
 
 /// An expression.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Expr {
     pub id: NodeId,
     pub kind: ExprKind,
@@ -1204,7 +1204,7 @@ pub fn precedence(&self) -> ExprPrecedence {
 }
 
 /// Limit types of a range (inclusive or exclusive)
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
 pub enum RangeLimits {
     /// Inclusive at the beginning, exclusive at the end
     HalfOpen,
@@ -1212,7 +1212,7 @@ pub enum RangeLimits {
     Closed,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum ExprKind {
     /// A `box x` expression.
     Box(P<Expr>),
@@ -1369,7 +1369,7 @@ pub enum ExprKind {
 ///  ^~~~~    ^
 ///  ty       position = 0
 /// ```
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct QSelf {
     pub ty: P<Ty>,
 
@@ -1381,7 +1381,7 @@ pub struct QSelf {
 }
 
 /// A capture clause used in closures and `async` blocks.
-#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum CaptureBy {
     /// `move |x| y + x`.
     Value,
@@ -1391,7 +1391,7 @@ pub enum CaptureBy {
 
 /// The movability of a generator / closure literal:
 /// whether a generator contains self-references, causing it to be `!Unpin`.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable, Debug, Copy)]
 #[derive(HashStable_Generic)]
 pub enum Movability {
     /// May contain self-references, `!Unpin`.
@@ -1402,7 +1402,7 @@ pub enum Movability {
 
 /// Represents a macro invocation. The `path` indicates which macro
 /// is being invoked, and the `args` are arguments passed to it.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct MacCall {
     pub path: Path,
     pub args: P<MacArgs>,
@@ -1416,7 +1416,7 @@ pub fn span(&self) -> Span {
 }
 
 /// Arguments passed to an attribute or a function-like macro.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum MacArgs {
     /// No arguments - `#[attr]`.
     Empty,
@@ -1477,7 +1477,7 @@ pub fn need_semicolon(&self) -> bool {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum MacDelimiter {
     Parenthesis,
     Bracket,
@@ -1504,14 +1504,14 @@ pub fn from_token(delim: DelimToken) -> Option<MacDelimiter> {
 }
 
 /// Represents a macro definition.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct MacroDef {
     pub body: P<MacArgs>,
     /// `true` if macro was defined with `macro_rules`.
     pub macro_rules: bool,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, Eq, PartialEq)]
+#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
 #[derive(HashStable_Generic)]
 pub enum StrStyle {
     /// A regular string, like `"foo"`.
@@ -1523,7 +1523,7 @@ pub enum StrStyle {
 }
 
 /// An AST literal.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct Lit {
     /// The original literal token as written in source code.
     pub token: token::Lit,
@@ -1535,7 +1535,7 @@ pub struct Lit {
 }
 
 /// Same as `Lit`, but restricted to string literals.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug)]
 pub struct StrLit {
     /// The original literal token as written in source code.
     pub style: StrStyle,
@@ -1562,7 +1562,7 @@ pub fn as_lit(&self) -> Lit {
 }
 
 /// Type of the integer literal based on provided suffix.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
 #[derive(HashStable_Generic)]
 pub enum LitIntType {
     /// e.g. `42_i32`.
@@ -1574,7 +1574,7 @@ pub enum LitIntType {
 }
 
 /// Type of the float literal based on provided suffix.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
 #[derive(HashStable_Generic)]
 pub enum LitFloatType {
     /// A float literal with a suffix (`1f32` or `1E10f32`).
@@ -1586,7 +1586,7 @@ pub enum LitFloatType {
 /// Literal kind.
 ///
 /// E.g., `"foo"`, `42`, `12.34`, or `bool`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
 pub enum LitKind {
     /// A string literal (`"foo"`).
     Str(Symbol, StrStyle),
@@ -1658,7 +1658,7 @@ pub fn is_suffixed(&self) -> bool {
 
 // N.B., If you change this, you'll probably want to change the corresponding
 // type structure in `middle/ty.rs` as well.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct MutTy {
     pub ty: P<Ty>,
     pub mutbl: Mutability,
@@ -1666,14 +1666,14 @@ pub struct MutTy {
 
 /// Represents a function's signature in a trait declaration,
 /// trait implementation, or free function.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct FnSig {
     pub header: FnHeader,
     pub decl: P<FnDecl>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
-#[derive(HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum FloatTy {
     F32,
     F64,
@@ -1702,8 +1702,8 @@ pub fn bit_width(self) -> u64 {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
-#[derive(HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum IntTy {
     Isize,
     I8,
@@ -1767,8 +1767,8 @@ pub fn normalize(&self, target_width: u32) -> Self {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy, Debug)]
-#[derive(HashStable_Generic)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum UintTy {
     Usize,
     U8,
@@ -1831,7 +1831,7 @@ pub fn normalize(&self, target_width: u32) -> Self {
 
 /// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
 /// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct AssocTyConstraint {
     pub id: NodeId,
     pub ident: Ident,
@@ -1840,7 +1840,7 @@ pub struct AssocTyConstraint {
 }
 
 /// The kinds of an `AssocTyConstraint`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum AssocTyConstraintKind {
     /// E.g., `A = Bar` in `Foo<A = Bar>`.
     Equality { ty: P<Ty> },
@@ -1848,14 +1848,14 @@ pub enum AssocTyConstraintKind {
     Bound { bounds: GenericBounds },
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Ty {
     pub id: NodeId,
     pub kind: TyKind,
     pub span: Span,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct BareFnTy {
     pub unsafety: Unsafe,
     pub ext: Extern,
@@ -1864,7 +1864,7 @@ pub struct BareFnTy {
 }
 
 /// The various kinds of type recognized by the compiler.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum TyKind {
     /// A variable-length slice (`[T]`).
     Slice(P<Ty>),
@@ -1923,7 +1923,7 @@ pub fn is_unit(&self) -> bool {
 }
 
 /// Syntax used to declare a trait object.
-#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
 pub enum TraitObjectSyntax {
     Dyn,
     None,
@@ -1932,14 +1932,14 @@ pub enum TraitObjectSyntax {
 /// Inline assembly operand explicit register or register class.
 ///
 /// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug)]
 pub enum InlineAsmRegOrRegClass {
     Reg(Symbol),
     RegClass(Symbol),
 }
 
 bitflags::bitflags! {
-    #[derive(RustcEncodable, RustcDecodable, HashStable_Generic)]
+    #[derive(Encodable, Decodable, HashStable_Generic)]
     pub struct InlineAsmOptions: u8 {
         const PURE = 1 << 0;
         const NOMEM = 1 << 1;
@@ -1951,7 +1951,7 @@ pub struct InlineAsmOptions: u8 {
     }
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum InlineAsmTemplatePiece {
     String(String),
     Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
@@ -1995,7 +1995,7 @@ pub fn to_string(s: &[Self]) -> String {
 /// Inline assembly operand.
 ///
 /// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum InlineAsmOperand {
     In {
         reg: InlineAsmRegOrRegClass,
@@ -2028,7 +2028,7 @@ pub enum InlineAsmOperand {
 /// Inline assembly.
 ///
 /// E.g., `asm!("NOP");`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct InlineAsm {
     pub template: Vec<InlineAsmTemplatePiece>,
     pub operands: Vec<(InlineAsmOperand, Span)>,
@@ -2039,7 +2039,7 @@ pub struct InlineAsm {
 /// Inline assembly dialect.
 ///
 /// E.g., `"intel"` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
 pub enum LlvmAsmDialect {
     Att,
     Intel,
@@ -2048,7 +2048,7 @@ pub enum LlvmAsmDialect {
 /// LLVM-style inline assembly.
 ///
 /// E.g., `"={eax}"(result)` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct LlvmInlineAsmOutput {
     pub constraint: Symbol,
     pub expr: P<Expr>,
@@ -2059,7 +2059,7 @@ pub struct LlvmInlineAsmOutput {
 /// LLVM-style inline assembly.
 ///
 /// E.g., `llvm_asm!("NOP");`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct LlvmInlineAsm {
     pub asm: Symbol,
     pub asm_str_style: StrStyle,
@@ -2074,7 +2074,7 @@ pub struct LlvmInlineAsm {
 /// A parameter in a function header.
 ///
 /// E.g., `bar: usize` as in `fn foo(bar: usize)`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Param {
     pub attrs: AttrVec,
     pub ty: P<Ty>,
@@ -2087,7 +2087,7 @@ pub struct Param {
 /// Alternative representation for `Arg`s describing `self` parameter of methods.
 ///
 /// E.g., `&mut self` as in `fn foo(&mut self)`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum SelfKind {
     /// `self`, `mut self`
     Value(Mutability),
@@ -2165,7 +2165,7 @@ pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Par
 ///
 /// Please note that it's different from `FnHeader` structure
 /// which contains metadata about function safety, asyncness, constness and ABI.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct FnDecl {
     pub inputs: Vec<Param>,
     pub output: FnRetTy,
@@ -2187,20 +2187,20 @@ pub fn c_variadic(&self) -> bool {
 }
 
 /// Is the trait definition an auto trait?
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum IsAuto {
     Yes,
     No,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable, Debug)]
 #[derive(HashStable_Generic)]
 pub enum Unsafe {
     Yes(Span),
     No,
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug)]
 pub enum Async {
     Yes { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
     No,
@@ -2220,7 +2220,7 @@ pub fn opt_return_id(self) -> Option<NodeId> {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
 #[derive(HashStable_Generic)]
 pub enum Const {
     Yes(Span),
@@ -2229,13 +2229,13 @@ pub enum Const {
 
 /// Item defaultness.
 /// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum Defaultness {
     Default(Span),
     Final,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
 pub enum ImplPolarity {
     /// `impl Trait for Type`
     Positive,
@@ -2252,7 +2252,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum FnRetTy {
     /// Returns type is not specified.
     ///
@@ -2275,7 +2275,7 @@ pub fn span(&self) -> Span {
 /// Module declaration.
 ///
 /// E.g., `mod foo;` or `mod foo { .. }`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
+#[derive(Clone, Encodable, Decodable, Debug, Default)]
 pub struct Mod {
     /// A span from the first token past `{` to the last token until `}`.
     /// For `mod foo;`, the inner span ranges from the first token
@@ -2289,7 +2289,7 @@ pub struct Mod {
 /// Foreign module declaration.
 ///
 /// E.g., `extern { .. }` or `extern C { .. }`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct ForeignMod {
     pub abi: Option<StrLit>,
     pub items: Vec<P<ForeignItem>>,
@@ -2298,17 +2298,17 @@ pub struct ForeignMod {
 /// Global inline assembly.
 ///
 /// Also known as "module-level assembly" or "file-scoped assembly".
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, Encodable, Decodable, Debug, Copy)]
 pub struct GlobalAsm {
     pub asm: Symbol,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct EnumDef {
     pub variants: Vec<Variant>,
 }
 /// Enum variant.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Variant {
     /// Attributes of the variant.
     pub attrs: Vec<Attribute>,
@@ -2330,7 +2330,7 @@ pub struct Variant {
 }
 
 /// Part of `use` item to the right of its prefix.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum UseTreeKind {
     /// `use prefix` or `use prefix as rename`
     ///
@@ -2345,7 +2345,7 @@ pub enum UseTreeKind {
 
 /// A tree of paths sharing common prefixes.
 /// Used in `use` items both at top-level and inside of braces in import groups.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct UseTree {
     pub prefix: Path,
     pub kind: UseTreeKind,
@@ -2367,7 +2367,7 @@ pub fn ident(&self) -> Ident {
 /// Distinguishes between `Attribute`s that decorate items and Attributes that
 /// are contained as statements within items. These two cases need to be
 /// distinguished for pretty-printing.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
 pub enum AttrStyle {
     Outer,
     Inner,
@@ -2380,19 +2380,19 @@ pub struct AttrId {
     }
 }
 
-impl rustc_serialize::Encodable for AttrId {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> rustc_serialize::Encodable<S> for AttrId {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_unit()
     }
 }
 
-impl rustc_serialize::Decodable for AttrId {
-    fn decode<D: Decoder>(d: &mut D) -> Result<AttrId, D::Error> {
+impl<D: Decoder> rustc_serialize::Decodable<D> for AttrId {
+    fn decode(d: &mut D) -> Result<AttrId, D::Error> {
         d.read_nil().map(|_| crate::attr::mk_attr_id())
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct AttrItem {
     pub path: Path,
     pub args: MacArgs,
@@ -2402,7 +2402,7 @@ pub struct AttrItem {
 pub type AttrVec = ThinVec<Attribute>;
 
 /// Metadata associated with an item.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Attribute {
     pub kind: AttrKind,
     pub id: AttrId,
@@ -2412,7 +2412,7 @@ pub struct Attribute {
     pub span: Span,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum AttrKind {
     /// A normal attribute.
     Normal(AttrItem),
@@ -2429,13 +2429,13 @@ pub enum AttrKind {
 /// that the `ref_id` is for. The `impl_id` maps to the "self type" of this impl.
 /// If this impl is an `ItemKind::Impl`, the `impl_id` is redundant (it could be the
 /// same as the impl's `NodeId`).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct TraitRef {
     pub path: Path,
     pub ref_id: NodeId,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct PolyTraitRef {
     /// The `'a` in `<'a> Foo<&'a T>`.
     pub bound_generic_params: Vec<GenericParam>,
@@ -2456,7 +2456,7 @@ pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self {
     }
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum CrateSugar {
     /// Source is `pub(crate)`.
     PubCrate,
@@ -2467,7 +2467,7 @@ pub enum CrateSugar {
 
 pub type Visibility = Spanned<VisibilityKind>;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum VisibilityKind {
     Public,
     Crate(CrateSugar),
@@ -2484,7 +2484,7 @@ pub fn is_pub(&self) -> bool {
 /// Field of a struct.
 ///
 /// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct StructField {
     pub attrs: Vec<Attribute>,
     pub id: NodeId,
@@ -2497,7 +2497,7 @@ pub struct StructField {
 }
 
 /// Fields and constructor ids of enum variants and structs.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum VariantData {
     /// Struct variant.
     ///
@@ -2532,7 +2532,7 @@ pub fn ctor_id(&self) -> Option<NodeId> {
 }
 
 /// An item definition.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Item<K = ItemKind> {
     pub attrs: Vec<Attribute>,
     pub id: NodeId,
@@ -2569,7 +2569,7 @@ pub fn into_item(self) -> Item {
 }
 
 /// `extern` qualifier on a function item or function type.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug)]
 pub enum Extern {
     None,
     Implicit,
@@ -2586,7 +2586,7 @@ pub fn from_abi(abi: Option<StrLit>) -> Extern {
 ///
 /// All the information between the visibility and the name of the function is
 /// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug)]
 pub struct FnHeader {
     pub unsafety: Unsafe,
     pub asyncness: Async,
@@ -2616,7 +2616,7 @@ fn default() -> FnHeader {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum ItemKind {
     /// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
     ///
@@ -2755,7 +2755,7 @@ pub fn generics(&self) -> Option<&Generics> {
 /// In an implementation, all items must be provided.
 /// The `Option`s below denote the bodies, where `Some(_)`
 /// means "provided" and conversely `None` means "required".
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum AssocItemKind {
     /// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`.
     /// If `def` is parsed, then the constant is provided, and otherwise required.
@@ -2803,7 +2803,7 @@ fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
 }
 
 /// An item in `extern` block.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub enum ForeignItemKind {
     /// A foreign static item (`static FOO: u8`).
     Static(P<Ty>, Mutability, Option<P<Expr>>),
index 95d4c09dac3110e3c9ef6de7d34e1375e56d5ff2..bd7d85167140dfe4e28a712edf85a4d17dfbf8dc 100644 (file)
@@ -9,7 +9,7 @@
 /// Hash value constructed out of all the `-C metadata` arguments passed to the
 /// compiler. Together with the crate-name forms a unique global identifier for
 /// the crate.
-#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, Encodable, Decodable)]
 pub struct CrateDisambiguator(Fingerprint);
 
 impl CrateDisambiguator {
index 3f876169d2236e4baddf2c305cf16a7bbaef517d..fb5ce3118262782fc9e264f47a1264fd9f0d7f96 100644 (file)
@@ -18,8 +18,7 @@
 #![feature(unicode_internals)]
 #![recursion_limit = "256"]
 
-// FIXME(#56935): Work around ICEs during cross-compilation.
-#[allow(unused)]
+#[macro_use]
 extern crate rustc_macros;
 
 #[macro_export]
index cd562c48e9115eb24f12bd73bf5eb138d974f533..1035e945538f5b10136b7b4547f8728ed9c6a646 100644 (file)
@@ -1,10 +1,8 @@
-use rustc_serialize::{Decoder, Encoder};
 use rustc_span::ExpnId;
 use std::fmt;
 
 rustc_index::newtype_index! {
     pub struct NodeId {
-        ENCODABLE = custom
         DEBUG_FORMAT = "NodeId({})"
     }
 }
@@ -34,15 +32,3 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(&self.as_u32(), f)
     }
 }
-
-impl rustc_serialize::UseSpecializedEncodable for NodeId {
-    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_u32(self.as_u32())
-    }
-}
-
-impl rustc_serialize::UseSpecializedDecodable for NodeId {
-    fn default_decode<D: Decoder>(d: &mut D) -> Result<NodeId, D::Error> {
-        d.read_u32().map(NodeId::from_u32)
-    }
-}
index 4597624ef88b08d21f55c6d55bac50f39709494b..e4a3cccb7ead1c9c30efed20cb687f30759fac55 100644 (file)
@@ -114,14 +114,14 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-impl<T: 'static + Decodable> Decodable for P<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<P<T>, D::Error> {
+impl<D: Decoder, T: 'static + Decodable<D>> Decodable<D> for P<T> {
+    fn decode(d: &mut D) -> Result<P<T>, D::Error> {
         Decodable::decode(d).map(P)
     }
 }
 
-impl<T: Encodable> Encodable for P<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         (**self).encode(s)
     }
 }
@@ -197,14 +197,14 @@ fn into_iter(self) -> Self::IntoIter {
     }
 }
 
-impl<T: Encodable> Encodable for P<[T]> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<[T]> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         Encodable::encode(&**self, s)
     }
 }
 
-impl<T: Decodable> Decodable for P<[T]> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<P<[T]>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for P<[T]> {
+    fn decode(d: &mut D) -> Result<P<[T]>, D::Error> {
         Ok(P::from_vec(Decodable::decode(d)?))
     }
 }
index bcce881ed48c5deef7423eb8bfa4a8b082c5e1b8..46c4be0a33bf76af3b9ae1e8e287ac4792bda563 100644 (file)
 use std::borrow::Cow;
 use std::{fmt, mem};
 
-#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum CommentKind {
     Line,
     Block,
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Hash, Debug, Copy)]
 #[derive(HashStable_Generic)]
 pub enum BinOpToken {
     Plus,
@@ -39,7 +39,7 @@ pub enum BinOpToken {
 }
 
 /// A delimiter token.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, Copy)]
 #[derive(HashStable_Generic)]
 pub enum DelimToken {
     /// A round parenthesis (i.e., `(` or `)`).
@@ -62,7 +62,7 @@ pub fn is_empty(self) -> bool {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum LitKind {
     Bool, // AST only, must never appear in a `Token`
     Byte,
@@ -77,7 +77,7 @@ pub enum LitKind {
 }
 
 /// A literal token.
-#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct Lit {
     pub kind: LitKind,
     pub symbol: Symbol,
@@ -188,7 +188,7 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool {
             .contains(&name)
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum TokenKind {
     /* Expression-operator symbols. */
     Eq,
@@ -267,7 +267,7 @@ pub enum TokenKind {
 #[cfg(target_arch = "x86_64")]
 rustc_data_structures::static_assert_size!(TokenKind, 16);
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct Token {
     pub kind: TokenKind,
     pub span: Span,
@@ -688,7 +688,7 @@ fn eq(&self, rhs: &TokenKind) -> bool {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Encodable, Decodable)]
 /// For interpolation during macro expansion.
 pub enum Nonterminal {
     NtItem(P<ast::Item>),
@@ -711,7 +711,7 @@ pub enum Nonterminal {
 #[cfg(target_arch = "x86_64")]
 rustc_data_structures::static_assert_size!(Nonterminal, 40);
 
-#[derive(Debug, Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
 pub enum NonterminalKind {
     Item,
     Block,
index 9d0199078fa6a354eb4ee9f51305aa95fbb4e4fa..151acddae840e567c171362311ce6813f6603c5b 100644 (file)
@@ -35,7 +35,7 @@
 ///
 /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
 /// Nothing special happens to misnamed or misplaced `SubstNt`s.
-#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Debug, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
 pub enum TokenTree {
     /// A single token
     Token(Token),
@@ -124,7 +124,7 @@ fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
 /// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s
 /// instead of a representation of the abstract syntax tree.
 /// Today's `TokenTree`s can still contain AST via `token::Interpolated` for back-compat.
-#[derive(Clone, Debug, Default, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Default, Encodable, Decodable)]
 pub struct TokenStream(pub Lrc<Vec<TreeAndJoint>>);
 
 pub type TreeAndJoint = (TokenTree, IsJoint);
@@ -133,7 +133,7 @@ fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
 #[cfg(target_arch = "x86_64")]
 rustc_data_structures::static_assert_size!(TokenStream, 8);
 
-#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable)]
 pub enum IsJoint {
     Joint,
     NonJoint,
@@ -408,7 +408,7 @@ pub fn look_ahead(&self, n: usize) -> Option<TokenTree> {
     }
 }
 
-#[derive(Debug, Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
 pub struct DelimSpan {
     pub open: Span,
     pub close: Span,
index 5f131fae385b08c7d5b3a2c7186f6c5de608d4da..3ddabcc17f8b696a86e088e2cd9fd8430e398993 100644 (file)
@@ -67,7 +67,7 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
     }
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Encodable, Decodable)]
 pub enum InlineAttr {
     None,
     Hint,
@@ -75,7 +75,7 @@ pub enum InlineAttr {
     Never,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Encodable, Decodable)]
 pub enum OptimizeAttr {
     None,
     Speed,
@@ -130,7 +130,7 @@ pub fn find_unwind_attr(sess: &Session, attrs: &[Attribute]) -> Option<UnwindAtt
 ///
 /// - `#[stable]`
 /// - `#[unstable]`
-#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
 #[derive(HashStable_Generic)]
 pub struct Stability {
     pub level: StabilityLevel,
@@ -138,7 +138,7 @@ pub struct Stability {
 }
 
 /// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes.
-#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
 #[derive(HashStable_Generic)]
 pub struct ConstStability {
     pub level: StabilityLevel,
@@ -150,7 +150,7 @@ pub struct ConstStability {
 }
 
 /// The available stability levels.
-#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
+#[derive(Encodable, Decodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
 #[derive(HashStable_Generic)]
 pub enum StabilityLevel {
     // Reason for the current stability level and the relevant rust-lang issue
@@ -632,7 +632,7 @@ pub fn eval_condition(
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Clone, HashStable_Generic)]
+#[derive(Encodable, Decodable, Clone, HashStable_Generic)]
 pub struct Deprecation {
     pub since: Option<Symbol>,
     /// The note to issue a reason.
@@ -797,7 +797,7 @@ fn find_deprecation_generic<'a, I>(
     depr
 }
 
-#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
+#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone)]
 pub enum ReprAttr {
     ReprInt(IntType),
     ReprC,
@@ -808,7 +808,8 @@ pub enum ReprAttr {
     ReprNoNiche,
 }
 
-#[derive(Eq, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone, HashStable_Generic)]
+#[derive(Eq, PartialEq, Debug, Copy, Clone)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum IntType {
     SignedInt(ast::IntTy),
     UnsignedInt(ast::UintTy),
index 5754bb48d24e1c4785d2b9f92512243277be0f3f..149a950f7d417ca3977f15c5bacd141ab5863176 100644 (file)
@@ -6,8 +6,7 @@
 
 #![feature(or_patterns)]
 
-// FIXME(#56935): Work around ICEs during cross-compilation.
-#[allow(unused)]
+#[macro_use]
 extern crate rustc_macros;
 
 mod builtin;
index 8fa0de37648f3649ec68f15a2068804b2c1b52f6..ff9dac372ab956911fd6fcf3124318ef4af12f38 100644 (file)
@@ -33,5 +33,6 @@ rustc_fs_util = { path = "../librustc_fs_util" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_incremental = { path = "../librustc_incremental" }
 rustc_index = { path = "../librustc_index" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_target = { path = "../librustc_target" }
 rustc_session = { path = "../librustc_session" }
index f9a782af24cda7c74b3cb725e69fecd296669db8..5100ef8ad4fd7cb5ab7590c6284c19c0bc59debd 100644 (file)
@@ -35,7 +35,7 @@ pub fn disable_localization(linker: &mut Command) {
 
 /// For all the linkers we support, and information they might
 /// need out of the shared crate context before we get rid of it.
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(Encodable, Decodable)]
 pub struct LinkerInfo {
     exports: FxHashMap<CrateType, Vec<String>>,
 }
index 85260d30a3d7c36292b30580c427e8d392df94ba..6bfbda0f1d7f29d1c21ff75c8e610ee5e1cf8303 100644 (file)
@@ -16,6 +16,8 @@
 //! The backend-agnostic functions of this crate use functions defined in various traits that
 //! have to be implemented by each backends.
 
+#[macro_use]
+extern crate rustc_macros;
 #[macro_use]
 extern crate log;
 #[macro_use]
@@ -74,7 +76,7 @@ pub fn into_compiled_module(
     }
 }
 
-#[derive(Debug, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Encodable, Decodable)]
 pub struct CompiledModule {
     pub name: String,
     pub kind: ModuleKind,
@@ -87,7 +89,7 @@ pub struct CachedModuleCodegen {
     pub source: WorkProduct,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable)]
 pub enum ModuleKind {
     Regular,
     Metadata,
@@ -110,7 +112,7 @@ pub struct MemFlags: u8 {
 /// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own
 /// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource`
 /// and the corresponding properties without referencing information outside of a `CrateInfo`.
-#[derive(Debug, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Encodable, Decodable)]
 pub struct CrateInfo {
     pub panic_runtime: Option<CrateNum>,
     pub compiler_builtins: Option<CrateNum>,
@@ -128,7 +130,7 @@ pub struct CrateInfo {
     pub dependency_formats: Lrc<Dependencies>,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(Encodable, Decodable)]
 pub struct CodegenResults {
     pub crate_name: Symbol,
     pub modules: Vec<CompiledModule>,
index 36c32e600311252bfe5e4629951f747f824568c2..1926dbf06e726aa50e37a9b001d3873602bb0d47 100644 (file)
@@ -17,6 +17,7 @@ jobserver_crate = { version = "0.1.13", package = "jobserver" }
 lazy_static = "1"
 once_cell = { version = "1", features = ["parking_lot"] }
 rustc_serialize = { path = "../librustc_serialize" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_graphviz = { path = "../librustc_graphviz" }
 cfg-if = "0.1.2"
 crossbeam-utils = { version = "0.7", features = ["nightly"] }
index 282626611d50bd92bd0f2d08928ee97410330f2b..f8d631ce01e78139b7dd6c11abc9229a51b76813 100644 (file)
@@ -1,5 +1,8 @@
 use crate::stable_hasher;
-use rustc_serialize::opaque::{Decoder, EncodeResult, Encoder};
+use rustc_serialize::{
+    opaque::{self, EncodeResult},
+    Decodable, Encodable,
+};
 use std::mem;
 
 #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
@@ -49,14 +52,14 @@ pub fn to_hex(&self) -> String {
         format!("{:x}{:x}", self.0, self.1)
     }
 
-    pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
+    pub fn encode_opaque(&self, encoder: &mut opaque::Encoder) -> EncodeResult {
         let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };
 
         encoder.emit_raw_bytes(&bytes);
         Ok(())
     }
 
-    pub fn decode_opaque(decoder: &mut Decoder<'_>) -> Result<Fingerprint, String> {
+    pub fn decode_opaque(decoder: &mut opaque::Decoder<'_>) -> Result<Fingerprint, String> {
         let mut bytes = [0; 16];
 
         decoder.read_raw_bytes(&mut bytes)?;
@@ -83,18 +86,45 @@ fn finish(hasher: stable_hasher::StableHasher) -> Self {
 
 impl_stable_hash_via_hash!(Fingerprint);
 
-impl rustc_serialize::UseSpecializedEncodable for Fingerprint {}
+impl<E: rustc_serialize::Encoder> Encodable<E> for Fingerprint {
+    fn encode(&self, s: &mut E) -> Result<(), E::Error> {
+        s.encode_fingerprint(self)
+    }
+}
 
-impl rustc_serialize::UseSpecializedDecodable for Fingerprint {}
+impl<D: rustc_serialize::Decoder> Decodable<D> for Fingerprint {
+    fn decode(d: &mut D) -> Result<Self, D::Error> {
+        d.decode_fingerprint()
+    }
+}
 
-impl rustc_serialize::SpecializedEncoder<Fingerprint> for Encoder {
-    fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
+pub trait FingerprintEncoder: rustc_serialize::Encoder {
+    fn encode_fingerprint(&mut self, f: &Fingerprint) -> Result<(), Self::Error>;
+}
+
+pub trait FingerprintDecoder: rustc_serialize::Decoder {
+    fn decode_fingerprint(&mut self) -> Result<Fingerprint, Self::Error>;
+}
+
+impl<E: rustc_serialize::Encoder> FingerprintEncoder for E {
+    default fn encode_fingerprint(&mut self, _: &Fingerprint) -> Result<(), E::Error> {
+        panic!("Cannot encode `Fingerprint` with `{}`", std::any::type_name::<E>());
+    }
+}
+
+impl FingerprintEncoder for opaque::Encoder {
+    fn encode_fingerprint(&mut self, f: &Fingerprint) -> EncodeResult {
         f.encode_opaque(self)
     }
 }
 
-impl<'a> rustc_serialize::SpecializedDecoder<Fingerprint> for Decoder<'a> {
-    fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
+impl<D: rustc_serialize::Decoder> FingerprintDecoder for D {
+    default fn decode_fingerprint(&mut self) -> Result<Fingerprint, D::Error> {
+        panic!("Cannot decode `Fingerprint` with `{}`", std::any::type_name::<D>());
+    }
+}
+impl FingerprintDecoder for opaque::Decoder<'_> {
+    fn decode_fingerprint(&mut self) -> Result<Fingerprint, String> {
         Fingerprint::decode_opaque(self)
     }
 }
index 3884fc051056edff3bbbee3da634077916797320..017511cc50d20fd1498ea16a208e2e76f17d91d8 100644 (file)
@@ -29,6 +29,8 @@
 extern crate log;
 #[macro_use]
 extern crate cfg_if;
+#[macro_use]
+extern crate rustc_macros;
 
 #[inline(never)]
 #[cold]
index 652268dcee8842847167f78daec1cfe8ddbffa87..856eb73e6297a79ac5cc48051fb241080baab0c9 100644 (file)
 /// 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,
-    Default,
-    Debug,
-    RustcEncodable,
-    RustcDecodable
-)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug, Encodable, Decodable)]
 pub struct SortedMap<K: Ord, V> {
     data: Vec<(K, V)>,
 }
index 476eb9e14f98f34313346ba153f82ac620683a97..02103de2e8df913d15a8ca458cce1b3e4d7d39c8 100644 (file)
@@ -48,14 +48,14 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-impl Encodable for Svh {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for Svh {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u64(self.as_u64().to_le())
     }
 }
 
-impl Decodable for Svh {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Svh, D::Error> {
+impl<D: Decoder> Decodable<D> for Svh {
+    fn decode(d: &mut D) -> Result<Svh, D::Error> {
         d.read_u64().map(u64::from_le).map(Svh::new)
     }
 }
index 43002178eb9717478e23ca88a3ffad7647adda14..4d673fd5cf98307ddc40b1e96779a6cbabb5e819 100644 (file)
@@ -3,7 +3,7 @@
 /// A vector type optimized for cases where this size is usually 0 (cf. `SmallVector`).
 /// The `Option<Box<..>>` wrapping allows us to represent a zero sized vector with `None`,
 /// which uses only a single (null) pointer.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug)]
 pub struct ThinVec<T>(Option<Box<Vec<T>>>);
 
 impl<T> ThinVec<T> {
index 7d137a55033f7ac89ee6e3a038c3f78a1c451b5f..fe60a99dde07205f2b88c1d5a35c9c5df1d15292 100644 (file)
@@ -1,8 +1,6 @@
 use crate::fx::FxIndexSet;
-use crate::stable_hasher::{HashStable, StableHasher};
 use crate::sync::Lock;
 use rustc_index::bit_set::BitMatrix;
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::fmt::Debug;
 use std::hash::Hash;
 use std::mem;
@@ -42,10 +40,10 @@ fn default() -> Self {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Debug)]
 struct Index(usize);
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, PartialEq, Eq, Debug)]
 struct Edge {
     source: Index,
     target: Index,
@@ -402,66 +400,3 @@ fn pare_down(candidates: &mut Vec<usize>, closure: &BitMatrix<usize, usize>) {
         candidates.truncate(j - dead);
     }
 }
-
-impl<T> Encodable for TransitiveRelation<T>
-where
-    T: Clone + Encodable + Debug + Eq + Hash + Clone,
-{
-    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
-        s.emit_struct("TransitiveRelation", 2, |s| {
-            s.emit_struct_field("elements", 0, |s| self.elements.encode(s))?;
-            s.emit_struct_field("edges", 1, |s| self.edges.encode(s))?;
-            Ok(())
-        })
-    }
-}
-
-impl<T> Decodable for TransitiveRelation<T>
-where
-    T: Clone + Decodable + Debug + Eq + Hash + Clone,
-{
-    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
-        d.read_struct("TransitiveRelation", 2, |d| {
-            Ok(TransitiveRelation {
-                elements: d.read_struct_field("elements", 0, |d| Decodable::decode(d))?,
-                edges: d.read_struct_field("edges", 1, |d| Decodable::decode(d))?,
-                closure: Lock::new(None),
-            })
-        })
-    }
-}
-
-impl<CTX, T> HashStable<CTX> for TransitiveRelation<T>
-where
-    T: HashStable<CTX> + Eq + Debug + Clone + Hash,
-{
-    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        // We are assuming here that the relation graph has been built in a
-        // deterministic way and we can just hash it the way it is.
-        let TransitiveRelation {
-            ref elements,
-            ref edges,
-            // "closure" is just a copy of the data above
-            closure: _,
-        } = *self;
-
-        elements.hash_stable(hcx, hasher);
-        edges.hash_stable(hcx, hasher);
-    }
-}
-
-impl<CTX> HashStable<CTX> for Edge {
-    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        let Edge { ref source, ref target } = *self;
-
-        source.hash_stable(hcx, hasher);
-        target.hash_stable(hcx, hasher);
-    }
-}
-
-impl<CTX> HashStable<CTX> for Index {
-    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        let Index(idx) = *self;
-        idx.hash_stable(hcx, hasher);
-    }
-}
index d0f04c3fe7647187ade03a61f40bee27e06ec084..c17d61dae9faf2be4791631abd44e9ec04b6457a 100644 (file)
@@ -13,6 +13,7 @@ doctest = false
 log = { package = "tracing", version = "0.1" }
 rustc_serialize = { path = "../librustc_serialize" }
 rustc_span = { path = "../librustc_span" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 unicode-width = "0.1.4"
 atty = "0.2"
index acaa26c6ad2fc609b72adbc4c8f79761e3ab902e..cd4b5d56f36e6e7190a075aee564a8bc31e3ebb5 100644 (file)
@@ -9,7 +9,7 @@
 use std::fmt;
 
 #[must_use]
-#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub struct Diagnostic {
     pub level: Level,
     pub message: Vec<(String, Style)>,
@@ -24,14 +24,14 @@ pub struct Diagnostic {
     pub sort_span: Span,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
 pub enum DiagnosticId {
     Error(String),
     Lint(String),
 }
 
 /// For example a note attached to an error.
-#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub struct SubDiagnostic {
     pub level: Level,
     pub message: Vec<(String, Style)>,
index 24186198fd2b15b11c1d8ccd7e9b04b8347a6ebb..750d36d3d891a2804c116894187c1764c38a8dba 100644 (file)
@@ -145,7 +145,7 @@ fn should_show_explain(&self) -> bool {
 
 // The following data types are provided just for serialisation.
 
-#[derive(RustcEncodable)]
+#[derive(Encodable)]
 struct Diagnostic {
     /// The primary error message.
     message: String,
@@ -159,7 +159,7 @@ struct Diagnostic {
     rendered: Option<String>,
 }
 
-#[derive(RustcEncodable)]
+#[derive(Encodable)]
 struct DiagnosticSpan {
     file_name: String,
     byte_start: u32,
@@ -186,7 +186,7 @@ struct DiagnosticSpan {
     expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
 }
 
-#[derive(RustcEncodable)]
+#[derive(Encodable)]
 struct DiagnosticSpanLine {
     text: String,
 
@@ -196,7 +196,7 @@ struct DiagnosticSpanLine {
     highlight_end: usize,
 }
 
-#[derive(RustcEncodable)]
+#[derive(Encodable)]
 struct DiagnosticSpanMacroExpansion {
     /// span where macro was applied to generate this code; note that
     /// this may itself derive from a macro (if
@@ -210,7 +210,7 @@ struct DiagnosticSpanMacroExpansion {
     def_site_span: DiagnosticSpan,
 }
 
-#[derive(RustcEncodable)]
+#[derive(Encodable)]
 struct DiagnosticCode {
     /// The code itself.
     code: String,
@@ -218,7 +218,7 @@ struct DiagnosticCode {
     explanation: Option<&'static str>,
 }
 
-#[derive(RustcEncodable)]
+#[derive(Encodable)]
 struct ArtifactNotification<'a> {
     /// The path of the artifact.
     artifact: &'a Path,
index dcfcdbc63f29f95650d0cd2392dbab94fbf61a4e..e69e868c8ede5fa413a3588540e81f13ee47a94e 100644 (file)
 
 use std::str;
 
-#[derive(RustcDecodable, Debug, PartialEq, Eq)]
+#[derive(Decodable, Debug, PartialEq, Eq)]
 struct TestData {
     spans: Vec<SpanTestData>,
 }
 
-#[derive(RustcDecodable, Debug, PartialEq, Eq)]
+#[derive(Decodable, Debug, PartialEq, Eq)]
 struct SpanTestData {
     pub byte_start: u32,
     pub byte_end: u32,
index 73d71063b23620931cd13ac56ea15e0c8b8e6df9..98e9972530ebd1d0c17a722a6151af22d1f62d4b 100644 (file)
@@ -6,6 +6,9 @@
 #![feature(crate_visibility_modifier)]
 #![feature(nll)]
 
+#[macro_use]
+extern crate rustc_macros;
+
 pub use emitter::ColorConfig;
 
 use log::debug;
@@ -50,7 +53,7 @@
 /// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion
 /// to determine whether it should be automatically applied or if the user should be consulted
 /// before applying the suggestion.
-#[derive(Copy, Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub enum Applicability {
     /// The suggestion is definitely what the user intended. This suggestion should be
     /// automatically applied.
@@ -69,7 +72,7 @@ pub enum Applicability {
     Unspecified,
 }
 
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
 pub enum SuggestionStyle {
     /// Hide the suggested code when displaying this suggestion inline.
     HideCodeInline,
@@ -94,7 +97,7 @@ fn hide_inline(&self) -> bool {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub struct CodeSuggestion {
     /// Each substitute can have multiple variants due to multiple
     /// applicable suggestions
@@ -129,13 +132,13 @@ pub struct CodeSuggestion {
     pub applicability: Applicability,
 }
 
-#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
 /// See the docs on `CodeSuggestion::substitutions`
 pub struct Substitution {
     pub parts: Vec<SubstitutionPart>,
 }
 
-#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub struct SubstitutionPart {
     pub span: Span,
     pub snippet: String,
@@ -943,7 +946,7 @@ fn panic_if_treat_err_as_bug(&self) {
     }
 }
 
-#[derive(Copy, PartialEq, Clone, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, PartialEq, Clone, Hash, Debug, Encodable, Decodable)]
 pub enum Level {
     Bug,
     Fatal,
@@ -1012,7 +1015,7 @@ macro_rules! pluralize {
 
 // Useful type to use with `Result<>` indicate that an error has already
 // been reported to the user, so no need to continue checking.
-#[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable, Hash, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq)]
 pub struct ErrorReported;
 
 rustc_data_structures::impl_stable_hash_via_hash!(ErrorReported);
index 0660590a72570b040602d2b14acd21472b4832cd..160bf57779970a58ab0b6369a5736534c634c5e4 100644 (file)
@@ -173,7 +173,7 @@ pub struct StyledString {
     pub style: Style,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub enum Style {
     MainHeaderMsg,
     HeaderMsg,
index bdf039c36abf6c60e610a1f56db80cfeaac0b9f6..fbdb65b558790d4432003f63fb9f8b37b9aee521 100644 (file)
@@ -20,6 +20,7 @@ rustc_attr = { path = "../librustc_attr" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_feature = { path = "../librustc_feature" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_lexer = { path = "../librustc_lexer" }
 rustc_parse = { path = "../librustc_parse" }
 rustc_session = { path = "../librustc_session" }
index 1e3ab2c5ec2db36ea8d5f890dac75952b8dc5f90..7f631cb71afa86b9ff56b04acc2aadccb5c1854f 100644 (file)
@@ -8,6 +8,9 @@
 #![feature(proc_macro_span)]
 #![feature(try_blocks)]
 
+#[macro_use]
+extern crate rustc_macros;
+
 extern crate proc_macro as pm;
 
 mod placeholders;
index 6f2daaa81c02f5a6b1bd9669539afbce2d7edb83..9920e0650a7f7a1742b2c3c9a30854bb0daec8e5 100644 (file)
@@ -19,7 +19,7 @@
 
 /// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note
 /// that the delimiter itself might be `NoDelim`.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug)]
 struct Delimited {
     delim: token::DelimToken,
     tts: Vec<TokenTree>,
@@ -37,7 +37,7 @@ fn close_tt(&self, span: DelimSpan) -> TokenTree {
     }
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug)]
 struct SequenceRepetition {
     /// The sequence of token trees
     tts: Vec<TokenTree>,
@@ -49,7 +49,7 @@ struct SequenceRepetition {
     num_captures: usize,
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
 struct KleeneToken {
     span: Span,
     op: KleeneOp,
@@ -63,7 +63,7 @@ fn new(op: KleeneOp, span: Span) -> KleeneToken {
 
 /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
 /// for token sequences.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
 enum KleeneOp {
     /// Kleene star (`*`) for zero or more repetitions
     ZeroOrMore,
@@ -75,7 +75,7 @@ enum KleeneOp {
 
 /// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)`
 /// are "first-class" token trees. Useful for parsing macros.
-#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Clone, PartialEq, Encodable, Decodable)]
 enum TokenTree {
     Token(Token),
     Delimited(DelimSpan, Lrc<Delimited>),
index 618f3e99c3f04a3a38617585c1f33bd51e551f80..c4877be3f6415bb2c21b288e3327351805bdf0d6 100644 (file)
@@ -9,7 +9,7 @@
 use std::fmt::Debug;
 
 /// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum CtorOf {
     /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
@@ -18,7 +18,7 @@ pub enum CtorOf {
     Variant,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum CtorKind {
     /// Constructor function automatically created by a tuple struct/variant.
@@ -29,7 +29,7 @@ pub enum CtorKind {
     Fictive,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum NonMacroAttrKind {
     /// Single-segment attribute defined by the language (`#[inline]`)
@@ -42,7 +42,7 @@ pub enum NonMacroAttrKind {
     Registered,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum DefKind {
     // Type namespace
@@ -191,7 +191,7 @@ pub fn ns(&self) -> Option<Namespace> {
 }
 
 /// The resolution of a path or export.
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum Res<Id = hir::HirId> {
     Def(DefKind, DefId),
index 79b70682739326b1ea18c4254e7cbc83fbade8d1..5604e3a8dcaf95b074ad1e688521e44d1a79058a 100644 (file)
@@ -23,7 +23,7 @@
 /// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
 /// stores the `DefIndex` of its parent.
 /// There is one `DefPathTable` for each crate.
-#[derive(Clone, Default, RustcDecodable, RustcEncodable)]
+#[derive(Clone, Default, Decodable, Encodable)]
 pub struct DefPathTable {
     index_to_key: IndexVec<DefIndex, DefKey>,
     def_path_hashes: IndexVec<DefIndex, DefPathHash>,
@@ -92,7 +92,7 @@ pub struct Definitions {
 /// A unique identifier that we can use to lookup a definition
 /// precisely. It combines the index of the definition's parent (if
 /// any) with a `DisambiguatedDefPathData`.
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable)]
 pub struct DefKey {
     /// The parent path.
     pub parent: Option<DefIndex>,
@@ -143,13 +143,13 @@ fn root_parent_stable_hash(
 /// between them. This introduces some artificial ordering dependency
 /// but means that if you have, e.g., two impls for the same type in
 /// the same module, they do get distinct `DefId`s.
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable)]
 pub struct DisambiguatedDefPathData {
     pub data: DefPathData,
     pub disambiguator: u32,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Encodable, Decodable)]
 pub struct DefPath {
     /// The path leading from the crate root to the item.
     pub data: Vec<DisambiguatedDefPathData>,
@@ -244,7 +244,7 @@ pub fn to_filename_friendly_no_crate(&self) -> String {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
 pub enum DefPathData {
     // Root: these should only be used for the root nodes, because
     // they are treated specially by the `def_path` function.
index 6474dc318d329f73854c2c0526b8f075589c7f0b..928235adac30c15685203a59fa7a696e958f35b7 100644 (file)
@@ -23,7 +23,7 @@
 use std::collections::{BTreeMap, BTreeSet};
 use std::fmt;
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Copy, Clone, Encodable, HashStable_Generic)]
 pub struct Lifetime {
     pub hir_id: HirId,
     pub span: Span,
@@ -37,7 +37,7 @@ pub struct Lifetime {
     pub name: LifetimeName,
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
+#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
 #[derive(HashStable_Generic)]
 pub enum ParamName {
     /// Some user-given name like `T` or `'x`.
@@ -83,7 +83,7 @@ pub fn normalize_to_macros_2_0(&self) -> ParamName {
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
+#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
 #[derive(HashStable_Generic)]
 pub enum LifetimeName {
     /// User-given names or fresh (synthetic) names.
@@ -182,7 +182,7 @@ pub fn is_static(&self) -> bool {
 /// A `Path` is essentially Rust's notion of a name; for instance,
 /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
 /// along with a bunch of supporting information.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Path<'hir> {
     pub span: Span,
     /// The resolution for the path.
@@ -199,7 +199,7 @@ pub fn is_global(&self) -> bool {
 
 /// A segment of a path: an identifier, an optional lifetime, and a set of
 /// types.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct PathSegment<'hir> {
     /// The identifier portion of this path segment.
     #[stable_hasher(project(name))]
@@ -242,13 +242,13 @@ pub fn generic_args(&self) -> &GenericArgs<'hir> {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Encodable, Debug, HashStable_Generic)]
 pub struct ConstArg {
     pub value: AnonConst,
     pub span: Span,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum GenericArg<'hir> {
     Lifetime(Lifetime),
     Type(Ty<'hir>),
@@ -288,7 +288,7 @@ pub fn descr(&self) -> &'static str {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct GenericArgs<'hir> {
     /// The generic arguments for this path segment.
     pub args: &'hir [GenericArg<'hir>],
@@ -348,7 +348,7 @@ pub fn own_counts(&self) -> GenericParamCount {
 
 /// A modifier on a bound, currently this is only used for `?Sized`, where the
 /// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum TraitBoundModifier {
     None,
@@ -360,7 +360,7 @@ pub enum TraitBoundModifier {
 /// `typeck::collect::compute_bounds` matches these against
 /// the "special" built-in traits (see `middle::lang_items`) and
 /// detects `Copy`, `Send` and `Sync`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum GenericBound<'hir> {
     Trait(PolyTraitRef<'hir>, TraitBoundModifier),
     Outlives(Lifetime),
@@ -384,7 +384,7 @@ pub fn span(&self) -> Span {
 
 pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
 
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
 pub enum LifetimeParamKind {
     // Indicates that the lifetime definition was explicitly declared (e.g., in
     // `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`).
@@ -403,7 +403,7 @@ pub enum LifetimeParamKind {
     Error,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum GenericParamKind<'hir> {
     /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
     Lifetime {
@@ -418,7 +418,7 @@ pub enum GenericParamKind<'hir> {
     },
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct GenericParam<'hir> {
     pub hir_id: HirId,
     pub name: ParamName,
@@ -448,7 +448,7 @@ pub struct GenericParamCount {
 
 /// Represents lifetimes and type parameters attached to a declaration
 /// of a function, enum, trait, etc.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Generics<'hir> {
     pub params: &'hir [GenericParam<'hir>],
     pub where_clause: WhereClause<'hir>,
@@ -501,14 +501,14 @@ pub fn spans(&self) -> MultiSpan {
 
 /// Synthetic type parameters are converted to another form during lowering; this allows
 /// us to track the original form they had, and is useful for error messages.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum SyntheticTyParamKind {
     ImplTrait,
 }
 
 /// A where-clause in a definition.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct WhereClause<'hir> {
     pub predicates: &'hir [WherePredicate<'hir>],
     // Only valid if predicates aren't empty.
@@ -535,7 +535,7 @@ pub fn tail_span_for_suggestion(&self) -> Span {
 }
 
 /// A single predicate in a where-clause.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum WherePredicate<'hir> {
     /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate<'hir>),
@@ -556,7 +556,7 @@ pub fn span(&self) -> Span {
 }
 
 /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct WhereBoundPredicate<'hir> {
     pub span: Span,
     /// Any generics from a `for` binding.
@@ -568,7 +568,7 @@ pub struct WhereBoundPredicate<'hir> {
 }
 
 /// A lifetime predicate (e.g., `'a: 'b + 'c`).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct WhereRegionPredicate<'hir> {
     pub span: Span,
     pub lifetime: Lifetime,
@@ -576,7 +576,7 @@ pub struct WhereRegionPredicate<'hir> {
 }
 
 /// An equality predicate (e.g., `T = int`); currently unsupported.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct WhereEqPredicate<'hir> {
     pub hir_id: HirId,
     pub span: Span,
@@ -584,7 +584,7 @@ pub struct WhereEqPredicate<'hir> {
     pub rhs_ty: &'hir Ty<'hir>,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Encodable, Debug, HashStable_Generic)]
 pub struct ModuleItems {
     // Use BTreeSets here so items are in the same order as in the
     // list of all items in Crate
@@ -594,7 +594,7 @@ pub struct ModuleItems {
 }
 
 /// A type representing only the top-level module.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Encodable, Debug, HashStable_Generic)]
 pub struct CrateItem<'hir> {
     pub module: Mod<'hir>,
     pub attrs: &'hir [Attribute],
@@ -607,7 +607,7 @@ pub struct CrateItem<'hir> {
 /// For more details, see the [rustc dev guide].
 ///
 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
-#[derive(RustcEncodable, RustcDecodable, Debug)]
+#[derive(Debug)]
 pub struct Crate<'hir> {
     pub item: CrateItem<'hir>,
     pub exported_macros: &'hir [MacroDef<'hir>],
@@ -715,7 +715,7 @@ pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V)
 /// A macro definition, in this crate or imported from another.
 ///
 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct MacroDef<'hir> {
     pub ident: Ident,
     pub vis: Visibility<'hir>,
@@ -728,7 +728,7 @@ pub struct MacroDef<'hir> {
 /// A block of statements `{ .. }`, which may have a label (in this case the
 /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
 /// the `rules` being anything but `DefaultBlock`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Block<'hir> {
     /// Statements in a block.
     pub stmts: &'hir [Stmt<'hir>],
@@ -746,7 +746,7 @@ pub struct Block<'hir> {
     pub targeted_by_break: bool,
 }
 
-#[derive(Debug, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Pat<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -824,7 +824,7 @@ pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
 /// except `is_shorthand` is true.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct FieldPat<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -840,7 +840,7 @@ pub struct FieldPat<'hir> {
 /// Explicit binding annotations given in the HIR for a binding. Note
 /// that this is not the final binding *mode* that we infer after type
 /// inference.
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
 pub enum BindingAnnotation {
     /// No binding annotation given: this means that the final binding mode
     /// will depend on whether we have skipped through a `&` reference
@@ -861,7 +861,7 @@ pub enum BindingAnnotation {
     RefMut,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
 pub enum RangeEnd {
     Included,
     Excluded,
@@ -876,7 +876,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum PatKind<'hir> {
     /// Represents a wildcard pattern (i.e., `_`).
     Wild,
@@ -932,7 +932,7 @@ pub enum PatKind<'hir> {
     Slice(&'hir [&'hir Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [&'hir Pat<'hir>]),
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
 pub enum BinOpKind {
     /// The `+` operator (addition).
     Add,
@@ -1066,7 +1066,7 @@ fn into(self) -> ast::BinOpKind {
 
 pub type BinOp = Spanned<BinOpKind>;
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
 pub enum UnOp {
     /// The `*` operator (deferencing).
     UnDeref,
@@ -1095,7 +1095,7 @@ pub fn is_by_value(self) -> bool {
 }
 
 /// A statement.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Stmt<'hir> {
     pub hir_id: HirId,
     pub kind: StmtKind<'hir>,
@@ -1103,7 +1103,7 @@ pub struct Stmt<'hir> {
 }
 
 /// The contents of a statement.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum StmtKind<'hir> {
     /// A local (`let`) binding.
     Local(&'hir Local<'hir>),
@@ -1129,7 +1129,7 @@ pub fn attrs(&self) -> &'hir [Attribute] {
 }
 
 /// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Local<'hir> {
     pub pat: &'hir Pat<'hir>,
     /// Type annotation, if any (otherwise the type will be inferred).
@@ -1146,7 +1146,7 @@ pub struct Local<'hir> {
 
 /// Represents a single arm of a `match` expression, e.g.
 /// `<pat> (if <guard>) => <body>`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Arm<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -1160,12 +1160,12 @@ pub struct Arm<'hir> {
     pub body: &'hir Expr<'hir>,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum Guard<'hir> {
     If(&'hir Expr<'hir>),
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Field<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -1175,7 +1175,7 @@ pub struct Field<'hir> {
     pub is_shorthand: bool,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
 pub enum BlockCheckMode {
     DefaultBlock,
     UnsafeBlock(UnsafeSource),
@@ -1183,13 +1183,13 @@ pub enum BlockCheckMode {
     PopUnsafeBlock(UnsafeSource),
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Hash, Debug)]
 pub struct BodyId {
     pub hir_id: HirId,
 }
@@ -1215,7 +1215,7 @@ pub struct BodyId {
 ///
 /// All bodies have an **owner**, which can be accessed via the HIR
 /// map using `body_owner_def_id()`.
-#[derive(RustcEncodable, RustcDecodable, Debug)]
+#[derive(Debug)]
 pub struct Body<'hir> {
     pub params: &'hir [Param<'hir>],
     pub value: Expr<'hir>,
@@ -1233,7 +1233,7 @@ pub fn generator_kind(&self) -> Option<GeneratorKind> {
 }
 
 /// The type of source expression that caused this generator to be created.
-#[derive(Clone, PartialEq, Eq, HashStable_Generic, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, HashStable_Generic, Encodable, Decodable, Debug, Copy)]
 pub enum GeneratorKind {
     /// An explicit `async` block or the body of an async function.
     Async(AsyncGeneratorKind),
@@ -1256,7 +1256,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 ///
 /// This helps error messages but is also used to drive coercions in
 /// type-checking (see #60424).
-#[derive(Clone, PartialEq, Eq, HashStable_Generic, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, HashStable_Generic, Encodable, Decodable, Debug, Copy)]
 pub enum AsyncGeneratorKind {
     /// An explicit `async` block written by the user.
     Block,
@@ -1357,14 +1357,14 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 /// These are usually found nested inside types (e.g., array lengths)
 /// or expressions (e.g., repeat counts), and also used to define
 /// explicit discriminant values for enum variants.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
 pub struct AnonConst {
     pub hir_id: HirId,
     pub body: BodyId,
 }
 
 /// An expression.
-#[derive(Debug, RustcEncodable, RustcDecodable)]
+#[derive(Debug)]
 pub struct Expr<'hir> {
     pub hir_id: HirId,
     pub kind: ExprKind<'hir>,
@@ -1543,7 +1543,7 @@ fn is_lit(sm: &SourceMap, span: &Span) -> bool {
     false
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum ExprKind<'hir> {
     /// A `box x` expression.
     Box(&'hir Expr<'hir>),
@@ -1660,7 +1660,7 @@ pub enum ExprKind<'hir> {
 /// To resolve the path to a `DefId`, call [`qpath_res`].
 ///
 /// [`qpath_res`]: ../rustc_middle/ty/struct.TypeckResults.html#method.qpath_res
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum QPath<'hir> {
     /// Path to a definition, optionally "fully-qualified" with a `Self`
     /// type, if the path points to an associated item in a trait.
@@ -1680,7 +1680,7 @@ pub enum QPath<'hir> {
 }
 
 /// Hints at the original code for a let statement.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
 pub enum LocalSource {
     /// A `match _ { .. }`.
     Normal,
@@ -1702,7 +1702,7 @@ pub enum LocalSource {
 }
 
 /// Hints at the original code for a `match _ { .. }`.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum MatchSource {
     /// A `match _ { .. }`.
@@ -1739,7 +1739,7 @@ pub fn name(self) -> &'static str {
 }
 
 /// The loop type that yielded an `ExprKind::Loop`.
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
 pub enum LoopSource {
     /// A `loop { .. }` loop.
     Loop,
@@ -1761,7 +1761,7 @@ pub fn name(self) -> &'static str {
     }
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
 pub enum LoopIdError {
     OutsideLoopScope,
     UnlabeledCfInWhileCondition,
@@ -1780,7 +1780,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
 pub struct Destination {
     // This is `Some(_)` iff there is an explicit user-specified `label
     pub label: Option<Label>,
@@ -1791,7 +1791,7 @@ pub struct Destination {
 }
 
 /// The yield kind that caused an `ExprKind::Yield`.
-#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
 pub enum YieldSource {
     /// An `<expr>.await`.
     Await { expr: Option<HirId> },
@@ -1829,7 +1829,7 @@ fn from(kind: GeneratorKind) -> Self {
 
 // N.B., if you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct MutTy<'hir> {
     pub ty: &'hir Ty<'hir>,
     pub mutbl: Mutability,
@@ -1837,7 +1837,7 @@ pub struct MutTy<'hir> {
 
 /// Represents a function's signature in a trait declaration,
 /// trait implementation, or a free function.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct FnSig<'hir> {
     pub header: FnHeader,
     pub decl: &'hir FnDecl<'hir>,
@@ -1846,7 +1846,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 node-id of the item
 // so it can fetched later.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
 pub struct TraitItemId {
     pub hir_id: HirId,
 }
@@ -1855,7 +1855,7 @@ pub struct TraitItemId {
 /// possibly including a default implementation. A trait item is
 /// either required (meaning it doesn't have an implementation, just a
 /// signature) or provided (meaning it has a default implementation).
-#[derive(RustcEncodable, RustcDecodable, Debug)]
+#[derive(Debug)]
 pub struct TraitItem<'hir> {
     pub ident: Ident,
     pub hir_id: HirId,
@@ -1866,7 +1866,7 @@ pub struct TraitItem<'hir> {
 }
 
 /// Represents a trait method's body (or just argument names).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Encodable, Debug, HashStable_Generic)]
 pub enum TraitFn<'hir> {
     /// No default body in the trait, just a signature.
     Required(&'hir [Ident]),
@@ -1876,7 +1876,7 @@ pub enum TraitFn<'hir> {
 }
 
 /// Represents a trait method or associated constant or type
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum TraitItemKind<'hir> {
     /// An associated constant with an optional value (otherwise `impl`s must contain a value).
     Const(&'hir Ty<'hir>, Option<BodyId>),
@@ -1890,13 +1890,13 @@ 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 node-id of the item
 // so it can fetched later.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
 pub struct ImplItemId {
     pub hir_id: HirId,
 }
 
 /// Represents anything within an `impl` block.
-#[derive(RustcEncodable, RustcDecodable, Debug)]
+#[derive(Debug)]
 pub struct ImplItem<'hir> {
     pub ident: Ident,
     pub hir_id: HirId,
@@ -1909,7 +1909,7 @@ pub struct ImplItem<'hir> {
 }
 
 /// Represents various kinds of content within an `impl`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum ImplItemKind<'hir> {
     /// An associated constant of the given type, set to the constant result
     /// of the expression.
@@ -1947,7 +1947,7 @@ pub fn namespace(&self) -> Namespace {
 ///    Binding(...),
 /// }
 /// ```
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct TypeBinding<'hir> {
     pub hir_id: HirId,
     #[stable_hasher(project(name))]
@@ -1957,7 +1957,7 @@ pub struct TypeBinding<'hir> {
 }
 
 // Represents the two kinds of type bindings.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum TypeBindingKind<'hir> {
     /// E.g., `Foo<Bar: Send>`.
     Constraint { bounds: &'hir [GenericBound<'hir>] },
@@ -1974,7 +1974,7 @@ pub fn ty(&self) -> &Ty<'_> {
     }
 }
 
-#[derive(Debug, RustcEncodable, RustcDecodable)]
+#[derive(Debug)]
 pub struct Ty<'hir> {
     pub hir_id: HirId,
     pub kind: TyKind<'hir>,
@@ -1982,7 +1982,7 @@ pub struct Ty<'hir> {
 }
 
 /// Not represented directly in the AST; referred to by name through a `ty_path`.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum PrimTy {
     Int(IntTy),
@@ -1993,7 +1993,7 @@ pub enum PrimTy {
     Char,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct BareFnTy<'hir> {
     pub unsafety: Unsafety,
     pub abi: Abi,
@@ -2002,7 +2002,7 @@ pub struct BareFnTy<'hir> {
     pub param_names: &'hir [Ident],
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct OpaqueTy<'hir> {
     pub generics: Generics<'hir>,
     pub bounds: GenericBounds<'hir>,
@@ -2011,7 +2011,7 @@ pub struct OpaqueTy<'hir> {
 }
 
 /// From whence the opaque type came.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum OpaqueTyOrigin {
     /// `-> impl Trait`
     FnReturn,
@@ -2024,7 +2024,7 @@ pub enum OpaqueTyOrigin {
 }
 
 /// The various kinds of types recognized by the compiler.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum TyKind<'hir> {
     /// A variable length slice (i.e., `[T]`).
     Slice(&'hir Ty<'hir>),
@@ -2063,7 +2063,7 @@ pub enum TyKind<'hir> {
     Err,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum InlineAsmOperand<'hir> {
     In {
         reg: InlineAsmRegOrRegClass,
@@ -2105,7 +2105,7 @@ pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct InlineAsm<'hir> {
     pub template: &'hir [InlineAsmTemplatePiece],
     pub operands: &'hir [InlineAsmOperand<'hir>],
@@ -2113,7 +2113,7 @@ pub struct InlineAsm<'hir> {
     pub line_spans: &'hir [Span],
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic, PartialEq)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic, PartialEq)]
 pub struct LlvmInlineAsmOutput {
     pub constraint: Symbol,
     pub is_rw: bool,
@@ -2122,8 +2122,9 @@ pub struct LlvmInlineAsmOutput {
 }
 
 // NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR,
-// it needs to be `Clone` and use plain `Vec<T>` instead of arena-allocated slice.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic, PartialEq)]
+// it needs to be `Clone` and `Decodable` and use plain `Vec<T>` instead of
+// arena-allocated slice.
+#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, PartialEq)]
 pub struct LlvmInlineAsmInner {
     pub asm: Symbol,
     pub asm_str_style: StrStyle,
@@ -2135,7 +2136,7 @@ pub struct LlvmInlineAsmInner {
     pub dialect: LlvmAsmDialect,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct LlvmInlineAsm<'hir> {
     pub inner: LlvmInlineAsmInner,
     pub outputs_exprs: &'hir [Expr<'hir>],
@@ -2143,7 +2144,7 @@ pub struct LlvmInlineAsm<'hir> {
 }
 
 /// Represents a parameter in a function header.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Param<'hir> {
     pub attrs: &'hir [Attribute],
     pub hir_id: HirId,
@@ -2153,7 +2154,7 @@ pub struct Param<'hir> {
 }
 
 /// Represents the header (not the body) of a function declaration.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct FnDecl<'hir> {
     /// The types of the function's parameters.
     ///
@@ -2166,7 +2167,7 @@ pub struct FnDecl<'hir> {
 }
 
 /// Represents what type of implicit self a function has, if any.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum ImplicitSelfKind {
     /// Represents a `fn x(self);`.
     Imm,
@@ -2191,24 +2192,14 @@ pub fn has_implicit_self(&self) -> bool {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Debug)]
 #[derive(HashStable_Generic)]
 pub enum IsAsync {
     Async,
     NotAsync,
 }
 
-#[derive(
-    Copy,
-    Clone,
-    PartialEq,
-    RustcEncodable,
-    RustcDecodable,
-    Debug,
-    HashStable_Generic,
-    Eq,
-    Hash
-)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
 pub enum Defaultness {
     Default { has_value: bool },
     Final,
@@ -2234,7 +2225,7 @@ pub fn is_default(&self) -> bool {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum FnRetTy<'hir> {
     /// Return type is not specified.
     ///
@@ -2255,7 +2246,7 @@ pub fn span(&self) -> Span {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug)]
+#[derive(Encodable, Debug)]
 pub struct Mod<'hir> {
     /// A span from the first token past `{` to the last token until `}`.
     /// For `mod foo;`, the inner span ranges from the first token
@@ -2264,23 +2255,23 @@ pub struct Mod<'hir> {
     pub item_ids: &'hir [ItemId],
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct ForeignMod<'hir> {
     pub abi: Abi,
     pub items: &'hir [ForeignItem<'hir>],
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Encodable, Debug, HashStable_Generic)]
 pub struct GlobalAsm {
     pub asm: Symbol,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct EnumDef<'hir> {
     pub variants: &'hir [Variant<'hir>],
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct Variant<'hir> {
     /// Name of the variant.
     #[stable_hasher(project(name))]
@@ -2297,7 +2288,7 @@ pub struct Variant<'hir> {
     pub span: Span,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
 pub enum UseKind {
     /// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
     /// Also produced for each element of a list `use`, e.g.
@@ -2319,7 +2310,7 @@ pub enum UseKind {
 /// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the
 /// trait being referred to but just a unique `HirId` that serves as a key
 /// within the resolution map.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct TraitRef<'hir> {
     pub path: &'hir Path<'hir>,
     // Don't hash the `ref_id`. It is tracked via the thing it is used to access.
@@ -2338,7 +2329,7 @@ pub fn trait_def_id(&self) -> Option<DefId> {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct PolyTraitRef<'hir> {
     /// The `'a` in `for<'a> Foo<&'a T>`.
     pub bound_generic_params: &'hir [GenericParam<'hir>],
@@ -2351,7 +2342,7 @@ pub struct PolyTraitRef<'hir> {
 
 pub type Visibility<'hir> = Spanned<VisibilityKind<'hir>>;
 
-#[derive(RustcEncodable, RustcDecodable, Debug)]
+#[derive(Debug)]
 pub enum VisibilityKind<'hir> {
     Public,
     Crate(CrateSugar),
@@ -2384,7 +2375,7 @@ pub fn descr(&self) -> &'static str {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct StructField<'hir> {
     pub span: Span,
     #[stable_hasher(project(name))]
@@ -2404,7 +2395,7 @@ pub fn is_positional(&self) -> bool {
 }
 
 /// Fields and constructor IDs of enum variants and structs.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum VariantData<'hir> {
     /// A struct variant.
     ///
@@ -2441,7 +2432,7 @@ pub fn ctor_hir_id(&self) -> Option<HirId> {
 // The bodies for items are stored "out of line", in a separate
 // hashmap in the `Crate`. Here we just record the node-id of the item
 // so it can fetched later.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, Encodable, Debug)]
 pub struct ItemId {
     pub id: HirId,
 }
@@ -2449,7 +2440,7 @@ pub struct ItemId {
 /// An item
 ///
 /// The name might be a dummy name in case of anonymous items
-#[derive(RustcEncodable, RustcDecodable, Debug)]
+#[derive(Debug)]
 pub struct Item<'hir> {
     pub ident: Ident,
     pub hir_id: HirId,
@@ -2460,7 +2451,7 @@ pub struct Item<'hir> {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum Unsafety {
     Unsafe,
     Normal,
@@ -2485,13 +2476,13 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum Constness {
     Const,
     NotConst,
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
 pub struct FnHeader {
     pub unsafety: Unsafety,
     pub constness: Constness,
@@ -2508,7 +2499,7 @@ pub fn is_const(&self) -> bool {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum ItemKind<'hir> {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
@@ -2590,7 +2581,7 @@ pub fn generics(&self) -> Option<&Generics<'_>> {
 /// type or method, and whether it is public). This allows other
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Encodable, Debug, HashStable_Generic)]
 pub struct TraitItemRef {
     pub id: TraitItemId,
     #[stable_hasher(project(name))]
@@ -2606,7 +2597,7 @@ pub struct TraitItemRef {
 /// type or method, and whether it is public). This allows other
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct ImplItemRef<'hir> {
     pub id: ImplItemId,
     #[stable_hasher(project(name))]
@@ -2617,14 +2608,14 @@ pub struct ImplItemRef<'hir> {
     pub defaultness: Defaultness,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
 pub enum AssocItemKind {
     Const,
     Fn { has_self: bool },
     Type,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub struct ForeignItem<'hir> {
     #[stable_hasher(project(name))]
     pub ident: Ident,
@@ -2636,7 +2627,7 @@ pub struct ForeignItem<'hir> {
 }
 
 /// An item within an `extern` block.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Debug, HashStable_Generic)]
 pub enum ForeignItemKind<'hir> {
     /// A foreign function.
     Fn(&'hir FnDecl<'hir>, &'hir [Ident], Generics<'hir>),
@@ -2647,7 +2638,7 @@ pub enum ForeignItemKind<'hir> {
 }
 
 /// A variable captured by a closure.
-#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
 pub struct Upvar {
     // First span where it is accessed (there can be multiple).
     pub span: Span,
@@ -2658,7 +2649,7 @@ pub struct Upvar {
 // The TraitCandidate's import_ids is empty if the trait is defined in the same module, and
 // has length > 0 if the trait is found through an chain of imports, starting with the
 // import/use statement in the scope where the trait is used.
-#[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
+#[derive(Encodable, Decodable, Clone, Debug)]
 pub struct TraitCandidate {
     pub def_id: DefId,
     pub import_ids: SmallVec<[LocalDefId; 1]>,
index d782c3dd70a2c53c139020cc4f5dc0f9c1c72b6e..fea850c12d9b0102d0423850ba384e6f50d6f3f4 100644 (file)
@@ -11,7 +11,8 @@
 /// the `local_id` part of the `HirId` changing, which is a very useful property in
 /// incremental compilation where we have to persist things through changes to
 /// the code base.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
+#[derive(Encodable, Decodable)]
 pub struct HirId {
     pub owner: LocalDefId,
     pub local_id: ItemLocalId,
index 2f7edeb405ffec710ef43cf2a9226e7adc5c7bf8..b09657bd9b4a41962e74de68678e5593f0df30cb 100644 (file)
@@ -45,7 +45,7 @@ macro_rules! language_item_table {
 
         enum_from_u32! {
             /// A representation of all the valid language items in Rust.
-            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
             pub enum LangItem {
                 $($variant,)*
             }
index 52131cb3d3d4cab03a12ae46f2ef769aaa9b93f0..a64565b20e7f48d30bf16b0f9a8f9e82776554de 100644 (file)
@@ -7,9 +7,11 @@
 #![feature(const_panic)]
 #![feature(in_band_lifetimes)]
 #![feature(or_patterns)]
-#![feature(min_specialization)]
 #![recursion_limit = "256"]
 
+#[macro_use]
+extern crate rustc_macros;
+
 #[macro_use]
 extern crate rustc_data_structures;
 
index 60a87078d63cfdad911cdced0cb076e3e8ed64f7..2b597c7da80cbcbe7183bdc76c12f801abd54e51 100644 (file)
@@ -18,6 +18,7 @@ rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_serialize = { path = "../librustc_serialize" }
 rustc_ast = { path = "../librustc_ast" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_span = { path = "../librustc_span" }
 rustc_fs_util = { path = "../librustc_fs_util" }
 rustc_session = { path = "../librustc_session" }
index ea0fd4eb7ee737b96d29fd07d9d2d844ecfa782a..81e5410978d5df55b4afa6da578d71ba429bb321 100644 (file)
@@ -1,8 +1,9 @@
 //! The data that we will serialize and deserialize.
 
+use rustc_macros::{Decodable, Encodable};
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 
-#[derive(Debug, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Encodable, Decodable)]
 pub struct SerializedWorkProduct {
     /// node that produced the work-product
     pub id: WorkProductId,
index 00b23760182a229510d25480298bc0abd9ca292f..8aaf1cb9cbc58057037bafedcf082b5810fc2af1 100644 (file)
@@ -10,5 +10,6 @@ path = "lib.rs"
 doctest = false
 
 [dependencies]
-rustc_serialize = { path = "../librustc_serialize" }
 arrayvec = "0.5.1"
+rustc_serialize = { path = "../librustc_serialize" }
+rustc_macros = { path = "../librustc_macros" }
index e4b7c24a24989b3e9adffb533740013db24f773d..c43d1a6830d1d8818887754f8b0b468d832eb2f5 100644 (file)
@@ -7,6 +7,8 @@
 use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Not, Range, Shl};
 use std::slice;
 
+use rustc_macros::{Decodable, Encodable};
+
 #[cfg(test)]
 mod tests;
 
@@ -26,7 +28,7 @@
 /// will panic if the bitsets have differing domain sizes.
 ///
 /// [`GrowableBitSet`]: struct.GrowableBitSet.html
-#[derive(Clone, Eq, PartialEq, RustcDecodable, RustcEncodable)]
+#[derive(Clone, Eq, PartialEq, Decodable, Encodable)]
 pub struct BitSet<T: Idx> {
     domain_size: usize,
     words: Vec<Word>,
@@ -700,7 +702,7 @@ pub fn contains(&self, elem: T) -> bool {
 ///
 /// All operations that involve a row and/or column index will panic if the
 /// index exceeds the relevant bound.
-#[derive(Clone, Eq, PartialEq, RustcDecodable, RustcEncodable)]
+#[derive(Clone, Eq, PartialEq, Decodable, Encodable)]
 pub struct BitMatrix<R: Idx, C: Idx> {
     num_rows: usize,
     num_columns: usize,
@@ -1108,7 +1110,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 /// A fixed-sized bitset type represented by an integer type. Indices outwith than the range
 /// representable by `T` are considered set.
-#[derive(Copy, Clone, Eq, PartialEq, RustcDecodable, RustcEncodable)]
+#[derive(Copy, Clone, Eq, PartialEq, Decodable, Encodable)]
 pub struct FiniteBitSet<T: FiniteBitSetTy>(pub T);
 
 impl<T: FiniteBitSetTy> FiniteBitSet<T> {
index c5dedab979326ab6a6c2657c2db775e317de759c..63f63133a2c95b830f0fae6c17f784c9cf9ef7eb 100644 (file)
@@ -320,14 +320,14 @@ fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                    derive [$($derives:ident,)+]
                    $($tokens:tt)*) => (
         $crate::newtype_index!(
-            @derives      [$($derives,)+ RustcEncodable,]
+            @derives      [$($derives,)+]
             @attrs        [$(#[$attrs])*]
             @type         [$type]
             @max          [$max]
             @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
-        $crate::newtype_index!(@decodable $type);
+        $crate::newtype_index!(@serializable $type);
     );
 
     // The case where no derives are added, but encodable is overridden. Don't
@@ -357,22 +357,27 @@ fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
      @debug_format [$debug_format:tt]
                    $($tokens:tt)*) => (
         $crate::newtype_index!(
-            @derives      [RustcEncodable,]
+            @derives      []
             @attrs        [$(#[$attrs])*]
             @type         [$type]
             @max          [$max]
             @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
-        $crate::newtype_index!(@decodable $type);
+        $crate::newtype_index!(@serializable $type);
     );
 
-    (@decodable $type:ident) => (
-        impl ::rustc_serialize::Decodable for $type {
-            fn decode<D: ::rustc_serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
+    (@serializable $type:ident) => (
+        impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for $type {
+            fn decode(d: &mut D) -> Result<Self, D::Error> {
                 d.read_u32().map(Self::from_u32)
             }
         }
+        impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for $type {
+            fn encode(&self, e: &mut E) -> Result<(), E::Error> {
+                e.emit_u32(self.private)
+            }
+        }
     );
 
     // Rewrite final without comma to one that includes comma
@@ -483,14 +488,20 @@ pub struct IndexVec<I: Idx, T> {
 // not the phantom data.
 unsafe impl<I: Idx, T> Send for IndexVec<I, T> where T: Send {}
 
-impl<I: Idx, T: Encodable> Encodable for IndexVec<I, T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+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<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<I: Idx, T: Decodable> Decodable for IndexVec<I, T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
+impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexVec<I, T> {
+    fn decode(d: &mut D) -> Result<Self, D::Error> {
         Decodable::decode(d).map(|v| IndexVec { raw: v, _marker: PhantomData })
     }
 }
index d975038b010b9dabdd320349117a621a5fc8ad49..ffe5fb172bea3ec4096a6e9d65e8a50414a46420 100644 (file)
@@ -7,17 +7,14 @@
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::{self, Lift, Region, TyCtxt};
 
-/// Combines a `region::ScopeTree` (which governs relationships between
-/// scopes) and a `FreeRegionMap` (which governs relationships between
-/// free regions) to yield a complete relation between concrete
-/// regions.
+/// Combines a `FreeRegionMap` and a `TyCtxt`.
 ///
 /// This stuff is a bit convoluted and should be refactored, but as we
 /// transition to NLL, it'll all go away anyhow.
 pub struct RegionRelations<'a, 'tcx> {
     pub tcx: TyCtxt<'tcx>,
 
-    /// The context used to fetch the region maps.
+    /// The context used for debug messages
     pub context: DefId,
 
     /// Free-region relationships.
@@ -34,7 +31,7 @@ pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default, HashStable)]
+#[derive(Clone, Debug, Default)]
 pub struct FreeRegionMap<'tcx> {
     // Stores the relation `a < b`, where `a` and `b` are regions.
     //
index 6b30ae42a19408f74ece7e4aee69306264592b1e..7fb3b0e7ea6accba63fc307028c7426286fcfe05 100644 (file)
@@ -8,6 +8,7 @@
 mod hash_stable;
 mod lift;
 mod query;
+mod serialize;
 mod symbols;
 mod type_foldable;
 
@@ -27,5 +28,11 @@ pub fn symbols(input: TokenStream) -> TokenStream {
     hash_stable::hash_stable_generic_derive
 );
 
+decl_derive!([Decodable] => serialize::decodable_derive);
+decl_derive!([Encodable] => serialize::encodable_derive);
+decl_derive!([TyDecodable] => serialize::type_decodable_derive);
+decl_derive!([TyEncodable] => serialize::type_encodable_derive);
+decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive);
+decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive);
 decl_derive!([TypeFoldable, attributes(type_foldable)] => type_foldable::type_foldable_derive);
 decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
diff --git a/src/librustc_macros/src/serialize.rs b/src/librustc_macros/src/serialize.rs
new file mode 100644 (file)
index 0000000..dbeb3c7
--- /dev/null
@@ -0,0 +1,290 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::parse_quote;
+
+pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
+    let decoder_ty = quote! { __D };
+    if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
+        s.add_impl_generic(parse_quote! { 'tcx });
+    }
+    s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_middle::ty::codec::TyDecoder<'tcx>});
+    s.add_bounds(synstructure::AddBounds::Generics);
+
+    decodable_body(s, decoder_ty)
+}
+
+pub fn meta_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
+    if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
+        s.add_impl_generic(parse_quote! { 'tcx });
+    }
+    s.add_impl_generic(parse_quote! { '__a });
+    let decoder_ty = quote! { DecodeContext<'__a, 'tcx> };
+    s.add_bounds(synstructure::AddBounds::Generics);
+
+    decodable_body(s, decoder_ty)
+}
+
+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_serialize::Decoder});
+    s.add_bounds(synstructure::AddBounds::Generics);
+
+    decodable_body(s, decoder_ty)
+}
+
+fn decodable_body(
+    s: synstructure::Structure<'_>,
+    decoder_ty: TokenStream,
+) -> proc_macro2::TokenStream {
+    if let syn::Data::Union(_) = s.ast().data {
+        panic!("cannot derive on union")
+    }
+    let ty_name = s.ast().ident.to_string();
+    let decode_body = match s.variants() {
+        [vi] => {
+            let construct = vi.construct(|field, index| decode_field(field, index, true));
+            let n_fields = vi.ast().fields.len();
+            quote! {
+                ::rustc_serialize::Decoder::read_struct(
+                    __decoder,
+                    #ty_name,
+                    #n_fields,
+                    |__decoder| { ::std::result::Result::Ok(#construct) },
+                )
+            }
+        }
+        variants => {
+            let match_inner: TokenStream = variants
+                .iter()
+                .enumerate()
+                .map(|(idx, vi)| {
+                    let construct = vi.construct(|field, index| decode_field(field, index, false));
+                    quote! { #idx => { ::std::result::Result::Ok(#construct) } }
+                })
+                .collect();
+            let names: TokenStream = variants
+                .iter()
+                .map(|vi| {
+                    let variant_name = vi.ast().ident.to_string();
+                    quote!(#variant_name,)
+                })
+                .collect();
+            let message = format!(
+                "invalid enum variant tag while decoding `{}`, expected 0..{}",
+                ty_name,
+                variants.len()
+            );
+            quote! {
+                ::rustc_serialize::Decoder::read_enum(
+                    __decoder,
+                    #ty_name,
+                    |__decoder| {
+                        ::rustc_serialize::Decoder::read_enum_variant(
+                            __decoder,
+                            &[#names],
+                            |__decoder, __variant_idx| {
+                                match __variant_idx {
+                                    #match_inner
+                                    _ => return ::std::result::Result::Err(
+                                        ::rustc_serialize::Decoder::error(__decoder, #message)),
+                                }
+                            })
+                    }
+                )
+            }
+        }
+    };
+
+    s.bound_impl(
+        quote!(::rustc_serialize::Decodable<#decoder_ty>),
+        quote! {
+            fn decode(
+                __decoder: &mut #decoder_ty,
+            ) -> ::std::result::Result<Self, <#decoder_ty as ::rustc_serialize::Decoder>::Error> {
+                #decode_body
+            }
+        },
+    )
+}
+
+fn decode_field(field: &syn::Field, index: usize, is_struct: bool) -> proc_macro2::TokenStream {
+    let decode_inner_method = if let syn::Type::Reference(_) = field.ty {
+        quote! { ::rustc_middle::ty::codec::RefDecodable::decode }
+    } else {
+        quote! { ::rustc_serialize::Decodable::decode }
+    };
+    let (decode_method, opt_field_name) = if is_struct {
+        let field_name = field.ident.as_ref().map_or_else(|| index.to_string(), |i| i.to_string());
+        (
+            proc_macro2::Ident::new("read_struct_field", proc_macro2::Span::call_site()),
+            quote! { #field_name, },
+        )
+    } else {
+        (
+            proc_macro2::Ident::new("read_enum_variant_arg", proc_macro2::Span::call_site()),
+            quote! {},
+        )
+    };
+
+    quote! {
+        match ::rustc_serialize::Decoder::#decode_method(
+            __decoder, #opt_field_name #index, #decode_inner_method) {
+            ::std::result::Result::Ok(__res) => __res,
+            ::std::result::Result::Err(__err) => return ::std::result::Result::Err(__err),
+        }
+    }
+}
+
+pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
+    if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
+        s.add_impl_generic(parse_quote! {'tcx});
+    }
+    let encoder_ty = quote! { __E };
+    s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_middle::ty::codec::TyEncoder<'tcx>});
+    s.add_bounds(synstructure::AddBounds::Generics);
+
+    encodable_body(s, encoder_ty, false)
+}
+
+pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
+    if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
+        s.add_impl_generic(parse_quote! {'tcx});
+    }
+    s.add_impl_generic(parse_quote! { '__a });
+    let encoder_ty = quote! { EncodeContext<'__a, 'tcx> };
+    s.add_bounds(synstructure::AddBounds::Generics);
+
+    encodable_body(s, encoder_ty, true)
+}
+
+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_serialize::Encoder});
+    s.add_bounds(synstructure::AddBounds::Generics);
+
+    encodable_body(s, encoder_ty, false)
+}
+
+fn encodable_body(
+    mut s: synstructure::Structure<'_>,
+    encoder_ty: TokenStream,
+    allow_unreachable_code: bool,
+) -> proc_macro2::TokenStream {
+    if let syn::Data::Union(_) = s.ast().data {
+        panic!("cannot derive on union")
+    }
+
+    s.bind_with(|binding| {
+        // Handle the lack of a blanket reference impl.
+        if let syn::Type::Reference(_) = binding.ast().ty {
+            synstructure::BindStyle::Move
+        } else {
+            synstructure::BindStyle::Ref
+        }
+    });
+
+    let ty_name = s.ast().ident.to_string();
+    let encode_body = match s.variants() {
+        [_] => {
+            let mut field_idx = 0usize;
+            let encode_inner = s.each_variant(|vi| {
+                vi.bindings()
+                    .iter()
+                    .map(|binding| {
+                        let bind_ident = &binding.binding;
+                        let field_name = binding
+                            .ast()
+                            .ident
+                            .as_ref()
+                            .map_or_else(|| field_idx.to_string(), |i| i.to_string());
+                        let result = quote! {
+                            match ::rustc_serialize::Encoder::emit_struct_field(
+                                __encoder,
+                                #field_name,
+                                #field_idx,
+                                |__encoder|
+                                ::rustc_serialize::Encodable::encode(#bind_ident, __encoder),
+                            ) {
+                                ::std::result::Result::Ok(()) => (),
+                                ::std::result::Result::Err(__err)
+                                    => return ::std::result::Result::Err(__err),
+                            }
+                        };
+                        field_idx += 1;
+                        result
+                    })
+                    .collect::<TokenStream>()
+            });
+            quote! {
+                ::rustc_serialize::Encoder::emit_struct(__encoder, #ty_name, #field_idx, |__encoder| {
+                    ::std::result::Result::Ok(match *self { #encode_inner })
+                })
+            }
+        }
+        _ => {
+            let mut variant_idx = 0usize;
+            let encode_inner = s.each_variant(|vi| {
+                let variant_name = vi.ast().ident.to_string();
+                let mut field_idx = 0usize;
+
+                let encode_fields: TokenStream = vi
+                    .bindings()
+                    .iter()
+                    .map(|binding| {
+                        let bind_ident = &binding.binding;
+                        let result = quote! {
+                            match ::rustc_serialize::Encoder::emit_enum_variant_arg(
+                                __encoder,
+                                #field_idx,
+                                |__encoder|
+                                ::rustc_serialize::Encodable::encode(#bind_ident, __encoder),
+                            ) {
+                                ::std::result::Result::Ok(()) => (),
+                                ::std::result::Result::Err(__err)
+                                    => return ::std::result::Result::Err(__err),
+                            }
+                        };
+                        field_idx += 1;
+                        result
+                    })
+                    .collect();
+
+                let result = quote! { ::rustc_serialize::Encoder::emit_enum_variant(
+                    __encoder,
+                   #variant_name,
+                   #variant_idx,
+                   #field_idx,
+                   |__encoder| { ::std::result::Result::Ok({ #encode_fields }) }
+                ) };
+                variant_idx += 1;
+                result
+            });
+            quote! {
+                ::rustc_serialize::Encoder::emit_enum(__encoder, #ty_name, |__encoder| {
+                    match *self {
+                        #encode_inner
+                    }
+                })
+            }
+        }
+    };
+
+    let lints = if allow_unreachable_code {
+        quote! { #![allow(unreachable_code)] }
+    } else {
+        quote! {}
+    };
+
+    s.bound_impl(
+        quote!(::rustc_serialize::Encodable<#encoder_ty>),
+        quote! {
+            fn encode(
+                &self,
+                __encoder: &mut #encoder_ty,
+            ) -> ::std::result::Result<(), <#encoder_ty as ::rustc_serialize::Encoder>::Error> {
+                #lints
+                #encode_body
+            }
+        },
+    )
+}
index 2e9b3a2a2562f276ee8fcd99ca7b9fe06d962f04..352665f0ab199e2d216e31f2b4e0b9d129e340d2 100644 (file)
@@ -167,7 +167,7 @@ macro_rules! keywords {
             }
         }
 
-        macro_rules! symbols {
+        macro_rules! define_symbols {
             () => {
                 #symbols_stream
 
index 2c0e2aa39fd595dcedf398ae40acb5803591258f..6e3e4e55e42fd0539e3e4129cc4c94ad89d1e99d 100644 (file)
@@ -23,6 +23,7 @@ rustc_hir = { path = "../librustc_hir" }
 rustc_hir_pretty = { path = "../librustc_hir_pretty" }
 rustc_target = { path = "../librustc_target" }
 rustc_index = { path = "../librustc_index" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_serialize = { path = "../librustc_serialize" }
 stable_deref_trait = "1.0.0"
 rustc_ast = { path = "../librustc_ast" }
index 059ae340bcfe968821f5f36d99a46165a365a837..e50fa34554d51acbed0fc7e135651bc6d912f045 100644 (file)
@@ -15,6 +15,8 @@
 
 extern crate proc_macro;
 
+#[macro_use]
+extern crate rustc_macros;
 #[macro_use]
 extern crate rustc_middle;
 #[macro_use]
index 8aea9a9f5885061312aa0c18e9710bf22bf57cb9..27f59ec26383f4c5c66ce8911dc6700a0bafc286 100644 (file)
@@ -7,7 +7,7 @@
 use rustc_ast::ast;
 use rustc_attr as attr;
 use rustc_data_structures::captures::Captures;
-use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::{AtomicCell, Lock, LockGuard, Lrc, OnceCell};
@@ -15,7 +15,7 @@
 use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathTable;
 use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc_hir::lang_items;
 use rustc_middle::middle::cstore::{ForeignModule, LinkagePreference, NativeLib};
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
-use rustc_middle::mir::{self, interpret, Body, Promoted};
+use rustc_middle::mir::{self, Body, Promoted};
 use rustc_middle::ty::codec::TyDecoder;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::util::common::record_time;
-use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder, UseSpecializedDecodable};
+use rustc_serialize::{opaque, Decodable, Decoder};
 use rustc_session::Session;
 use rustc_span::hygiene::ExpnDataDecodeMode;
 use rustc_span::source_map::{respan, Spanned};
@@ -229,7 +229,7 @@ fn tcx(self) -> Option<TyCtxt<'tcx>> {
     }
 }
 
-impl<'a, 'tcx, T: Decodable> Lazy<T, ()> {
+impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<T> {
     fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
         let mut dcx = metadata.decoder(self.position.get());
         dcx.lazy_state = LazyState::NodeStart(self.position);
@@ -237,7 +237,7 @@ fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
     }
 }
 
-impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T], usize> {
+impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<[T]> {
     fn decode<M: Metadata<'a, 'tcx>>(
         self,
         metadata: M,
@@ -278,6 +278,8 @@ fn read_lazy_with_meta<T: ?Sized + LazyMeta>(
 }
 
 impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
+    const CLEAR_CROSS_CRATE: bool = true;
+
     #[inline]
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx.expect("missing TyCtxt in DecodeContext")
@@ -351,68 +353,92 @@ fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
     fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
         if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] }
     }
-}
 
-impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T, ()>> for DecodeContext<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> {
-        self.read_lazy_with_meta(())
+    fn decode_alloc_id(&mut self) -> Result<rustc_middle::mir::interpret::AllocId, Self::Error> {
+        if let Some(alloc_decoding_session) = self.alloc_decoding_session {
+            alloc_decoding_session.decode_alloc_id(self)
+        } else {
+            bug!("Attempting to decode interpret::AllocId without CrateMetadata")
+        }
     }
 }
 
-impl<'a, 'tcx, T> SpecializedDecoder<Lazy<[T], usize>> for DecodeContext<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> {
-        let len = self.read_usize()?;
-        if len == 0 { Ok(Lazy::empty()) } else { self.read_lazy_with_meta(len) }
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for CrateNum {
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<CrateNum, String> {
+        let cnum = CrateNum::from_u32(d.read_u32()?);
+        Ok(d.map_encoded_cnum_to_current(cnum))
     }
 }
 
-impl<'a, 'tcx, I: Idx, T> SpecializedDecoder<Lazy<Table<I, T>, usize>> for DecodeContext<'a, 'tcx>
-where
-    Option<T>: FixedSizeEncoding,
-{
-    fn specialized_decode(&mut self) -> Result<Lazy<Table<I, T>>, Self::Error> {
-        let len = self.read_usize()?;
-        self.read_lazy_with_meta(len)
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefIndex {
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<DefIndex, String> {
+        Ok(DefIndex::from_u32(d.read_u32()?))
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<DefId> for DecodeContext<'a, 'tcx> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
-        let krate = CrateNum::decode(self)?;
-        let index = DefIndex::decode(self)?;
-
-        Ok(DefId { krate, index })
+impl<'a, 'tcx> FingerprintDecoder for DecodeContext<'a, 'tcx> {
+    fn decode_fingerprint(&mut self) -> Result<Fingerprint, String> {
+        Fingerprint::decode_opaque(&mut self.opaque)
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<DefIndex> for DecodeContext<'a, 'tcx> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
-        Ok(DefIndex::from_u32(self.read_u32()?))
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<SyntaxContext, String> {
+        let cdata = decoder.cdata();
+        let sess = decoder.sess.unwrap();
+        let cname = cdata.root.name;
+        rustc_span::hygiene::decode_syntax_context(decoder, &cdata.hygiene_context, |_, id| {
+            debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
+            Ok(cdata
+                .root
+                .syntax_contexts
+                .get(&cdata, id)
+                .unwrap_or_else(|| panic!("Missing SyntaxContext {:?} for crate {:?}", id, cname))
+                .decode((&cdata, sess)))
+        })
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<LocalDefId> for DecodeContext<'a, 'tcx> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<LocalDefId, Self::Error> {
-        Ok(DefId::decode(self)?.expect_local())
-    }
-}
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<ExpnId, String> {
+        let local_cdata = decoder.cdata();
+        let sess = decoder.sess.unwrap();
+        let expn_cnum = Cell::new(None);
+        let get_ctxt = |cnum| {
+            expn_cnum.set(Some(cnum));
+            if cnum == LOCAL_CRATE {
+                &local_cdata.hygiene_context
+            } else {
+                &local_cdata.cstore.get_crate_data(cnum).cdata.hygiene_context
+            }
+        };
 
-impl<'a, 'tcx> SpecializedDecoder<interpret::AllocId> for DecodeContext<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
-        if let Some(alloc_decoding_session) = self.alloc_decoding_session {
-            alloc_decoding_session.decode_alloc_id(self)
-        } else {
-            bug!("Attempting to decode interpret::AllocId without CrateMetadata")
-        }
+        rustc_span::hygiene::decode_expn_id(
+            decoder,
+            ExpnDataDecodeMode::Metadata(get_ctxt),
+            |_this, index| {
+                let cnum = expn_cnum.get().unwrap();
+                // Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
+                // are stored in the owning crate, to avoid duplication.
+                let crate_data = if cnum == LOCAL_CRATE {
+                    local_cdata
+                } else {
+                    local_cdata.cstore.get_crate_data(cnum)
+                };
+                Ok(crate_data
+                    .root
+                    .expn_data
+                    .get(&crate_data, index)
+                    .unwrap()
+                    .decode((&crate_data, sess)))
+            },
+        )
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
-        let tag = u8::decode(self)?;
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Span, String> {
+        let tag = u8::decode(decoder)?;
 
         if tag == TAG_INVALID_SPAN {
             return Ok(DUMMY_SP);
@@ -420,12 +446,12 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
 
         debug_assert!(tag == TAG_VALID_SPAN_LOCAL || tag == TAG_VALID_SPAN_FOREIGN);
 
-        let lo = BytePos::decode(self)?;
-        let len = BytePos::decode(self)?;
-        let ctxt = SyntaxContext::decode(self)?;
+        let lo = BytePos::decode(decoder)?;
+        let len = BytePos::decode(decoder)?;
+        let ctxt = SyntaxContext::decode(decoder)?;
         let hi = lo + len;
 
-        let sess = if let Some(sess) = self.sess {
+        let sess = if let Some(sess) = decoder.sess {
             sess
         } else {
             bug!("Cannot decode Span without Session.")
@@ -460,22 +486,22 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
         // we can call `imported_source_files` for the proper crate, and binary search
         // through the returned slice using our span.
         let imported_source_files = if tag == TAG_VALID_SPAN_LOCAL {
-            self.cdata().imported_source_files(sess)
+            decoder.cdata().imported_source_files(sess)
         } else {
             // When we encode a proc-macro crate, all `Span`s should be encoded
             // with `TAG_VALID_SPAN_LOCAL`
-            if self.cdata().root.is_proc_macro_crate() {
+            if decoder.cdata().root.is_proc_macro_crate() {
                 // Decode `CrateNum` as u32 - using `CrateNum::decode` will ICE
                 // since we don't have `cnum_map` populated.
-                let cnum = u32::decode(self)?;
+                let cnum = u32::decode(decoder)?;
                 panic!(
                     "Decoding of crate {:?} tried to access proc-macro dep {:?}",
-                    self.cdata().root.name,
+                    decoder.cdata().root.name,
                     cnum
                 );
             }
             // tag is TAG_VALID_SPAN_FOREIGN, checked by `debug_assert` above
-            let cnum = CrateNum::decode(self)?;
+            let cnum = CrateNum::decode(decoder)?;
             debug!(
                 "SpecializedDecoder<Span>::specialized_decode: loading source files from cnum {:?}",
                 cnum
@@ -485,16 +511,16 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
             // not worth it to maintain a per-CrateNum cache for `last_source_file_index`.
             // We just set it to 0, to ensure that we don't try to access something out
             // of bounds for our initial 'guess'
-            self.last_source_file_index = 0;
+            decoder.last_source_file_index = 0;
 
-            let foreign_data = self.cdata().cstore.get_crate_data(cnum);
+            let foreign_data = decoder.cdata().cstore.get_crate_data(cnum);
             foreign_data.imported_source_files(sess)
         };
 
         let source_file = {
             // Optimize for the case that most spans within a translated item
             // originate from the same source_file.
-            let last_source_file = &imported_source_files[self.last_source_file_index];
+            let last_source_file = &imported_source_files[decoder.last_source_file_index];
 
             if lo >= last_source_file.original_start_pos && lo <= last_source_file.original_end_pos
             {
@@ -507,7 +533,7 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
                 // Don't try to cache the index for foreign spans,
                 // as this would require a map from CrateNums to indices
                 if tag == TAG_VALID_SPAN_LOCAL {
-                    self.last_source_file_index = index;
+                    decoder.last_source_file_index = index;
                 }
                 &imported_source_files[index]
             }
@@ -540,19 +566,37 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
-        Fingerprint::decode_opaque(&mut self.opaque)
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
+        ty::codec::RefDecodable::decode(d)
+    }
+}
+
+impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
+    for Lazy<T>
+{
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
+        decoder.read_lazy_with_meta(())
     }
 }
 
-impl<'a, 'tcx, T> SpecializedDecoder<mir::ClearCrossCrate<T>> for DecodeContext<'a, 'tcx>
+impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
+    for Lazy<[T]>
+{
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
+        let len = decoder.read_usize()?;
+        if len == 0 { Ok(Lazy::empty()) } else { decoder.read_lazy_with_meta(len) }
+    }
+}
+
+impl<'a, 'tcx, I: Idx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
+    for Lazy<Table<I, T>>
 where
-    mir::ClearCrossCrate<T>: UseSpecializedDecodable,
+    Option<T>: FixedSizeEncoding,
 {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
-        Ok(mir::ClearCrossCrate::Clear)
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
+        let len = decoder.read_usize()?;
+        decoder.read_lazy_with_meta(len)
     }
 }
 
@@ -1840,57 +1884,3 @@ fn macro_kind(raw: &ProcMacro) -> MacroKind {
         ProcMacro::Bang { .. } => MacroKind::Bang,
     }
 }
-
-impl<'a, 'tcx> SpecializedDecoder<SyntaxContext> for DecodeContext<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<SyntaxContext, Self::Error> {
-        let cdata = self.cdata();
-        let sess = self.sess.unwrap();
-        let cname = cdata.root.name;
-        rustc_span::hygiene::decode_syntax_context(self, &cdata.hygiene_context, |_, id| {
-            debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
-            Ok(cdata
-                .root
-                .syntax_contexts
-                .get(&cdata, id)
-                .unwrap_or_else(|| panic!("Missing SyntaxContext {:?} for crate {:?}", id, cname))
-                .decode((&cdata, sess)))
-        })
-    }
-}
-
-impl<'a, 'tcx> SpecializedDecoder<ExpnId> for DecodeContext<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<ExpnId, Self::Error> {
-        let local_cdata = self.cdata();
-        let sess = self.sess.unwrap();
-        let expn_cnum = Cell::new(None);
-        let get_ctxt = |cnum| {
-            expn_cnum.set(Some(cnum));
-            if cnum == LOCAL_CRATE {
-                &local_cdata.hygiene_context
-            } else {
-                &local_cdata.cstore.get_crate_data(cnum).cdata.hygiene_context
-            }
-        };
-
-        rustc_span::hygiene::decode_expn_id(
-            self,
-            ExpnDataDecodeMode::Metadata(get_ctxt),
-            |_this, index| {
-                let cnum = expn_cnum.get().unwrap();
-                // Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
-                // are stored in the owning crate, to avoid duplication.
-                let crate_data = if cnum == LOCAL_CRATE {
-                    local_cdata
-                } else {
-                    local_cdata.cstore.get_crate_data(cnum)
-                };
-                Ok(crate_data
-                    .root
-                    .expn_data
-                    .get(&crate_data, index)
-                    .unwrap()
-                    .decode((&crate_data, sess)))
-            },
-        )
-    }
-}
index 6723e236a1fe981e0fb9a9b022eb457231183eb9..e97e598765e98374d363a490a163f9f17e89c507 100644 (file)
@@ -3,7 +3,7 @@
 
 use log::{debug, trace};
 use rustc_ast::ast;
-use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_data_structures::fingerprint::{Fingerprint, FingerprintEncoder};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_data_structures::sync::{join, Lrc};
 use rustc_middle::middle::exported_symbols::{
     metadata_symbol_name, ExportedSymbol, SymbolExportLevel,
 };
-use rustc_middle::mir::{self, interpret};
+use rustc_middle::mir::interpret;
 use rustc_middle::traits::specialization_graph;
-use rustc_middle::ty::codec::{self as ty_codec, TyEncoder};
+use rustc_middle::ty::codec::TyEncoder;
 use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
-use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder, UseSpecializedEncodable};
+use rustc_serialize::{opaque, Encodable, Encoder};
 use rustc_session::config::CrateType;
 use rustc_span::hygiene::{ExpnDataEncodeMode, HygieneEncodeContext};
 use rustc_span::source_map::Spanned;
@@ -38,7 +38,7 @@
 use std::num::NonZeroUsize;
 use std::path::Path;
 
-struct EncodeContext<'a, 'tcx> {
+pub(super) struct EncodeContext<'a, 'tcx> {
     opaque: opaque::Encoder,
     tcx: TyCtxt<'tcx>,
 
@@ -107,100 +107,87 @@ fn emit_unit(&mut self) -> Result<(), Self::Error> {
     }
 }
 
-impl<'a, 'tcx, T> SpecializedEncoder<Lazy<T, ()>> for EncodeContext<'a, 'tcx> {
-    fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> {
-        self.emit_lazy_distance(*lazy)
+impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a, 'tcx>>
+    for Lazy<T>
+{
+    fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
+        e.emit_lazy_distance(*self)
     }
 }
 
-impl<'a, 'tcx, T> SpecializedEncoder<Lazy<[T], usize>> for EncodeContext<'a, 'tcx> {
-    fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> {
-        self.emit_usize(lazy.meta)?;
-        if lazy.meta == 0 {
+impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a, 'tcx>>
+    for Lazy<[T]>
+{
+    fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
+        e.emit_usize(self.meta)?;
+        if self.meta == 0 {
             return Ok(());
         }
-        self.emit_lazy_distance(*lazy)
+        e.emit_lazy_distance(*self)
     }
 }
 
-impl<'a, 'tcx, I: Idx, T> SpecializedEncoder<Lazy<Table<I, T>, usize>> for EncodeContext<'a, 'tcx>
+impl<'a, 'tcx, I: Idx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a, 'tcx>>
+    for Lazy<Table<I, T>>
 where
     Option<T>: FixedSizeEncoding,
 {
-    fn specialized_encode(&mut self, lazy: &Lazy<Table<I, T>>) -> Result<(), Self::Error> {
-        self.emit_usize(lazy.meta)?;
-        self.emit_lazy_distance(*lazy)
-    }
-}
-
-impl<'a, 'tcx> SpecializedEncoder<CrateNum> for EncodeContext<'a, 'tcx> {
-    #[inline]
-    fn specialized_encode(&mut self, cnum: &CrateNum) -> Result<(), Self::Error> {
-        self.emit_u32(cnum.as_u32())
+    fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
+        e.emit_usize(self.meta)?;
+        e.emit_lazy_distance(*self)
     }
 }
 
-impl<'a, 'tcx> SpecializedEncoder<DefId> for EncodeContext<'a, 'tcx> {
-    #[inline]
-    fn specialized_encode(&mut self, def_id: &DefId) -> Result<(), Self::Error> {
-        let DefId { krate, index } = *def_id;
-
-        krate.encode(self)?;
-        index.encode(self)
+impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for DefIndex {
+    fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
+        s.emit_u32(self.as_u32())
     }
 }
 
-impl<'a, 'tcx> SpecializedEncoder<SyntaxContext> for EncodeContext<'a, 'tcx> {
-    fn specialized_encode(&mut self, ctxt: &SyntaxContext) -> Result<(), Self::Error> {
-        rustc_span::hygiene::raw_encode_syntax_context(*ctxt, &self.hygiene_ctxt, self)
+impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SyntaxContext {
+    fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
+        rustc_span::hygiene::raw_encode_syntax_context(*self, &s.hygiene_ctxt, s)
     }
 }
 
-impl<'a, 'tcx> SpecializedEncoder<ExpnId> for EncodeContext<'a, 'tcx> {
-    fn specialized_encode(&mut self, expn: &ExpnId) -> Result<(), Self::Error> {
+impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
+    fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
         rustc_span::hygiene::raw_encode_expn_id(
-            *expn,
-            &self.hygiene_ctxt,
+            *self,
+            &s.hygiene_ctxt,
             ExpnDataEncodeMode::Metadata,
-            self,
+            s,
         )
     }
 }
 
-impl<'a, 'tcx> SpecializedEncoder<DefIndex> for EncodeContext<'a, 'tcx> {
-    #[inline]
-    fn specialized_encode(&mut self, def_index: &DefIndex) -> Result<(), Self::Error> {
-        self.emit_u32(def_index.as_u32())
-    }
-}
-
-impl<'a, 'tcx> SpecializedEncoder<Span> for EncodeContext<'a, 'tcx> {
-    fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
-        if span.is_dummy() {
-            return TAG_INVALID_SPAN.encode(self);
+impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
+    fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
+        if self.is_dummy() {
+            return TAG_INVALID_SPAN.encode(s);
         }
 
-        let span = span.data();
+        let span = self.data();
 
         // The Span infrastructure should make sure that this invariant holds:
         debug_assert!(span.lo <= span.hi);
 
-        if !self.source_file_cache.0.contains(span.lo) {
-            let source_map = self.tcx.sess.source_map();
+        if !s.source_file_cache.0.contains(span.lo) {
+            let source_map = s.tcx.sess.source_map();
             let source_file_index = source_map.lookup_source_file_idx(span.lo);
-            self.source_file_cache =
+            s.source_file_cache =
                 (source_map.files()[source_file_index].clone(), source_file_index);
         }
 
-        if !self.source_file_cache.0.contains(span.hi) {
+        if !s.source_file_cache.0.contains(span.hi) {
             // Unfortunately, macro expansion still sometimes generates Spans
             // that malformed in this way.
-            return TAG_INVALID_SPAN.encode(self);
+            return TAG_INVALID_SPAN.encode(s);
         }
 
-        let source_files = self.required_source_files.as_mut().expect("Already encoded SourceMap!");
+        let source_files = s.required_source_files.as_mut().expect("Already encoded SourceMap!");
         // Record the fact that we need to encode the data for this `SourceFile`
-        source_files.insert(self.source_file_cache.1);
+        source_files.insert(s.source_file_cache.1);
 
         // There are two possible cases here:
         // 1. This span comes from a 'foreign' crate - e.g. some crate upstream of the
@@ -218,7 +205,7 @@ fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
         // if we're a proc-macro crate.
         // This allows us to avoid loading the dependencies of proc-macro crates: all of
         // the information we need to decode `Span`s is stored in the proc-macro crate.
-        let (tag, lo, hi) = if self.source_file_cache.0.is_imported() && !self.is_proc_macro {
+        let (tag, lo, hi) = if s.source_file_cache.0.is_imported() && !s.is_proc_macro {
             // To simplify deserialization, we 'rebase' this span onto the crate it originally came from
             // (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' values
             // are relative to the source map information for the 'foreign' crate whose CrateNum
@@ -230,26 +217,26 @@ fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
             // Span that can be used without any additional trouble.
             let external_start_pos = {
                 // Introduce a new scope so that we drop the 'lock()' temporary
-                match &*self.source_file_cache.0.external_src.lock() {
+                match &*s.source_file_cache.0.external_src.lock() {
                     ExternalSource::Foreign { original_start_pos, .. } => *original_start_pos,
                     src => panic!("Unexpected external source {:?}", src),
                 }
             };
-            let lo = (span.lo - self.source_file_cache.0.start_pos) + external_start_pos;
-            let hi = (span.hi - self.source_file_cache.0.start_pos) + external_start_pos;
+            let lo = (span.lo - s.source_file_cache.0.start_pos) + external_start_pos;
+            let hi = (span.hi - s.source_file_cache.0.start_pos) + external_start_pos;
 
             (TAG_VALID_SPAN_FOREIGN, lo, hi)
         } else {
             (TAG_VALID_SPAN_LOCAL, span.lo, span.hi)
         };
 
-        tag.encode(self)?;
-        lo.encode(self)?;
+        tag.encode(s)?;
+        lo.encode(s)?;
 
         // Encode length which is usually less than span.hi and profits more
         // from the variable-length integer encoding that we use.
         let len = hi - lo;
-        len.encode(self)?;
+        len.encode(s)?;
 
         // Don't serialize any `SyntaxContext`s from a proc-macro crate,
         // since we don't load proc-macro dependencies during serialization.
@@ -282,101 +269,85 @@ fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
         // IMPORTANT: If this is ever changed, be sure to update
         // `rustc_span::hygiene::raw_encode_expn_id` to handle
         // encoding `ExpnData` for proc-macro crates.
-        if self.is_proc_macro {
-            SyntaxContext::root().encode(self)?;
+        if s.is_proc_macro {
+            SyntaxContext::root().encode(s)?;
         } else {
-            span.ctxt.encode(self)?;
+            span.ctxt.encode(s)?;
         }
 
         if tag == TAG_VALID_SPAN_FOREIGN {
-            // This needs to be two lines to avoid holding the `self.source_file_cache`
-            // while calling `cnum.encode(self)`
-            let cnum = self.source_file_cache.0.cnum;
-            cnum.encode(self)?;
+            // This needs to be two lines to avoid holding the `s.source_file_cache`
+            // while calling `cnum.encode(s)`
+            let cnum = s.source_file_cache.0.cnum;
+            cnum.encode(s)?;
         }
 
         Ok(())
     }
 }
 
-impl<'a, 'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'a, 'tcx> {
-    #[inline]
-    fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {
-        self.specialized_encode(&def_id.to_def_id())
+impl<'a, 'tcx> FingerprintEncoder for EncodeContext<'a, 'tcx> {
+    fn encode_fingerprint(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
+        f.encode_opaque(&mut self.opaque)
     }
 }
 
-impl<'a, 'b, 'c, 'tcx> SpecializedEncoder<&'a ty::TyS<'b>> for EncodeContext<'c, 'tcx>
-where
-    &'a ty::TyS<'b>: UseSpecializedEncodable,
-{
-    fn specialized_encode(&mut self, ty: &&'a ty::TyS<'b>) -> Result<(), Self::Error> {
-        debug_assert!(self.tcx.lift(ty).is_some());
-        let ty = unsafe { std::mem::transmute::<&&'a ty::TyS<'b>, &&'tcx ty::TyS<'tcx>>(ty) };
-        ty_codec::encode_with_shorthand(self, ty, |ecx| &mut ecx.type_shorthands)
+impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> {
+    const CLEAR_CROSS_CRATE: bool = true;
+
+    fn position(&self) -> usize {
+        self.opaque.position()
     }
-}
 
-impl<'a, 'b, 'tcx> SpecializedEncoder<ty::Predicate<'b>> for EncodeContext<'a, 'tcx> {
-    fn specialized_encode(&mut self, predicate: &ty::Predicate<'b>) -> Result<(), Self::Error> {
-        debug_assert!(self.tcx.lift(predicate).is_some());
-        let predicate =
-            unsafe { std::mem::transmute::<&ty::Predicate<'b>, &ty::Predicate<'tcx>>(predicate) };
-        ty_codec::encode_with_shorthand(self, predicate, |encoder| {
-            &mut encoder.predicate_shorthands
-        })
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.tcx
     }
-}
 
-impl<'a, 'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'a, 'tcx> {
-    fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
-        let (index, _) = self.interpret_allocs.insert_full(*alloc_id);
-        index.encode(self)
+    fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize> {
+        &mut self.type_shorthands
     }
-}
 
-impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for EncodeContext<'a, 'tcx> {
-    fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
-        f.encode_opaque(&mut self.opaque)
+    fn predicate_shorthands(&mut self) -> &mut FxHashMap<rustc_middle::ty::Predicate<'tcx>, usize> {
+        &mut self.predicate_shorthands
     }
-}
 
-impl<'a, 'tcx, T> SpecializedEncoder<mir::ClearCrossCrate<T>> for EncodeContext<'a, 'tcx>
-where
-    mir::ClearCrossCrate<T>: UseSpecializedEncodable,
-{
-    fn specialized_encode(&mut self, _: &mir::ClearCrossCrate<T>) -> Result<(), Self::Error> {
-        Ok(())
+    fn encode_alloc_id(
+        &mut self,
+        alloc_id: &rustc_middle::mir::interpret::AllocId,
+    ) -> Result<(), Self::Error> {
+        let (index, _) = self.interpret_allocs.insert_full(*alloc_id);
+
+        index.encode(self)
     }
 }
 
-impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> {
-    fn position(&self) -> usize {
-        self.opaque.position()
+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<T: ?Sized + LazyMeta> {
+trait EncodeContentsForLazy<'a, 'tcx, T: ?Sized + LazyMeta> {
     fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'a, 'tcx>) -> T::Meta;
 }
 
-impl<T: Encodable> EncodeContentsForLazy<T> for &T {
+impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> EncodeContentsForLazy<'a, 'tcx, T> for &T {
     fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'a, 'tcx>) {
         self.encode(ecx).unwrap()
     }
 }
 
-impl<T: Encodable> EncodeContentsForLazy<T> for T {
+impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> EncodeContentsForLazy<'a, 'tcx, T> for T {
     fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'a, 'tcx>) {
         self.encode(ecx).unwrap()
     }
 }
 
-impl<I, T: Encodable> EncodeContentsForLazy<[T]> for I
+impl<'a, 'tcx, I, T: Encodable<EncodeContext<'a, 'tcx>>> EncodeContentsForLazy<'a, 'tcx, [T]> for I
 where
     I: IntoIterator,
-    I::Item: EncodeContentsForLazy<T>,
+    I::Item: EncodeContentsForLazy<'a, 'tcx, T>,
 {
     fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'a, 'tcx>) -> usize {
         self.into_iter().map(|value| value.encode_contents_for_lazy(ecx)).count()
@@ -421,7 +392,10 @@ fn emit_lazy_distance<T: ?Sized + LazyMeta>(
         self.emit_usize(distance)
     }
 
-    fn lazy<T: ?Sized + LazyMeta>(&mut self, value: impl EncodeContentsForLazy<T>) -> Lazy<T> {
+    fn lazy<T: ?Sized + LazyMeta>(
+        &mut self,
+        value: impl EncodeContentsForLazy<'a, 'tcx, T>,
+    ) -> Lazy<T> {
         let pos = NonZeroUsize::new(self.position()).unwrap();
 
         assert_eq!(self.lazy_state, LazyState::NoNode);
index 1c287be9f6bbcc238f7b83c38b0858b3f77473f0..b15c20e515f495f2d7454ceee44706ae554a2cd0 100644 (file)
 use std::marker::PhantomData;
 use std::num::NonZeroUsize;
 
+use decoder::DecodeContext;
 pub use decoder::{provide, provide_extern};
 crate use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
+use encoder::EncodeContext;
 use rustc_span::hygiene::SyntaxContextData;
 
 mod decoder;
@@ -141,9 +143,6 @@ fn clone(&self) -> Self {
     }
 }
 
-impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedEncodable for Lazy<T> {}
-impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedDecodable for Lazy<T> {}
-
 /// Encoding / decoding state for `Lazy`.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 enum LazyState {
@@ -172,7 +171,7 @@ macro_rules! Lazy {
 type SyntaxContextTable = Lazy<Table<u32, Lazy<SyntaxContextData>>>;
 type ExpnDataTable = Lazy<Table<u32, Lazy<ExpnData>>>;
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(MetadataEncodable, MetadataDecodable)]
 crate struct CrateRoot<'tcx> {
     name: Symbol,
     triple: TargetTriple,
@@ -221,7 +220,7 @@ macro_rules! Lazy {
     symbol_mangling_version: SymbolManglingVersion,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(Encodable, Decodable)]
 crate struct CrateDep {
     pub name: Symbol,
     pub hash: Svh,
@@ -230,7 +229,7 @@ macro_rules! Lazy {
     pub extra_filename: String,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(MetadataEncodable, MetadataDecodable)]
 crate struct TraitImpls {
     trait_id: (u32, DefIndex),
     impls: Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>,
@@ -239,7 +238,7 @@ macro_rules! Lazy {
 /// Define `LazyTables` and `TableBuilders` at the same time.
 macro_rules! define_tables {
     ($($name:ident: Table<DefIndex, $T:ty>),+ $(,)?) => {
-        #[derive(RustcEncodable, RustcDecodable)]
+        #[derive(MetadataEncodable, MetadataDecodable)]
         crate struct LazyTables<'tcx> {
             $($name: Lazy!(Table<DefIndex, $T>)),+
         }
@@ -288,7 +287,7 @@ fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
     unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
 enum EntryKind {
     AnonConst(mir::ConstQualifs, Lazy<RenderedConst>),
     Const(mir::ConstQualifs, Lazy<RenderedConst>),
@@ -324,23 +323,23 @@ enum EntryKind {
 
 /// Contains a constant which has been rendered to a String.
 /// Used by rustdoc.
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(Encodable, Decodable)]
 struct RenderedConst(String);
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(MetadataEncodable, MetadataDecodable)]
 struct ModData {
     reexports: Lazy<[Export<hir::HirId>]>,
     expansion: ExpnId,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(MetadataEncodable, MetadataDecodable)]
 struct FnData {
     asyncness: hir::IsAsync,
     constness: hir::Constness,
     param_names: Lazy<[Ident]>,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(TyEncodable, TyDecodable)]
 struct VariantData {
     ctor_kind: CtorKind,
     discr: ty::VariantDiscr,
@@ -349,7 +348,7 @@ struct VariantData {
     is_non_exhaustive: bool,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(TyEncodable, TyDecodable)]
 struct TraitData {
     unsafety: hir::Unsafety,
     paren_sugar: bool,
@@ -358,7 +357,7 @@ struct TraitData {
     specialization_kind: ty::trait_def::TraitSpecializationKind,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(TyEncodable, TyDecodable)]
 struct ImplData {
     polarity: ty::ImplPolarity,
     defaultness: hir::Defaultness,
@@ -372,7 +371,7 @@ struct ImplData {
 /// Describes whether the container of an associated item
 /// is a trait or an impl and whether, in a trait, it has
 /// a default, or an in impl, whether it's marked "default".
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, TyEncodable, TyDecodable)]
 enum AssocContainer {
     TraitRequired,
     TraitWithDefault,
@@ -404,14 +403,14 @@ fn defaultness(&self) -> hir::Defaultness {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(MetadataEncodable, MetadataDecodable)]
 struct AssocFnData {
     fn_data: FnData,
     container: AssocContainer,
     has_self: bool,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(TyEncodable, TyDecodable)]
 struct GeneratorData<'tcx> {
     layout: mir::GeneratorLayout<'tcx>,
 }
index e1d0a0dbf2ffa2c77d37bfb554300622a7d425c7..728ab0015d1e4e773618dcff0d967426496af680 100644 (file)
@@ -2,7 +2,7 @@
 
 use log::debug;
 use rustc_index::vec::Idx;
-use rustc_serialize::{opaque::Encoder, Encodable};
+use rustc_serialize::opaque::Encoder;
 use std::convert::TryInto;
 use std::marker::PhantomData;
 use std::num::NonZeroUsize;
@@ -78,7 +78,7 @@ fn write_to_bytes(self, b: &mut [u8]) {
 // NOTE(eddyb) there could be an impl for `usize`, which would enable a more
 // generic `Lazy<T>` impl, but in the general case we might not need / want to
 // fit every `usize` in `u32`.
-impl<T: Encodable> FixedSizeEncoding for Option<Lazy<T>> {
+impl<T> FixedSizeEncoding for Option<Lazy<T>> {
     fixed_size_encoding_byte_len_and_defaults!(u32::BYTE_LEN);
 
     fn from_bytes(b: &[u8]) -> Self {
@@ -93,7 +93,7 @@ fn write_to_bytes(self, b: &mut [u8]) {
     }
 }
 
-impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> {
+impl<T> FixedSizeEncoding for Option<Lazy<[T]>> {
     fixed_size_encoding_byte_len_and_defaults!(u32::BYTE_LEN * 2);
 
     fn from_bytes(b: &[u8]) -> Self {
index f2259e5e9f857bece5a479903f03b361cf0ccb45..a08941469edd9c218e560d828994201b2033d5ff 100644 (file)
@@ -47,7 +47,7 @@ macro_rules! arena_types {
             [decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult, rustc_middle::mir::UnsafetyCheckResult;
             [] const_allocs: rustc_middle::mir::interpret::Allocation, rustc_middle::mir::interpret::Allocation;
             // Required for the incremental on-disk cache
-            [few, decode] mir_keys: rustc_hir::def_id::DefIdSet, rustc_hir::def_id::DefIdSet;
+            [few] mir_keys: rustc_hir::def_id::DefIdSet, rustc_hir::def_id::DefIdSet;
             [] region_scope_tree: rustc_middle::middle::region::ScopeTree, rustc_middle::middle::region::ScopeTree;
             [] dropck_outlives:
                 rustc_middle::infer::canonical::Canonical<'tcx,
index 98eed4045a34ad6d32443b359fb57511fe17cef4..a61b9af9bace43368b821c711dd4d577d520ee17 100644 (file)
@@ -110,8 +110,7 @@ macro_rules! define_dep_nodes {
         $variant:ident $(( $tuple_arg_ty:ty $(,)? ))*
       ,)*
     ) => (
-        #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
-                 RustcEncodable, RustcDecodable)]
+        #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
         #[allow(non_camel_case_types)]
         pub enum DepKind {
             $($variant),*
index af48c9e94ff82a0167a8478ab18200311a7d22af..be9e38aca65d10feeceb8e1d50b7fb208ef86ea5 100644 (file)
@@ -13,7 +13,7 @@
 /// within.
 pub type ExportMap<Id> = FxHashMap<LocalDefId, Vec<Export<Id>>>;
 
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct Export<Id> {
     /// The name of the target.
     pub ident: Ident,
index d85165bcccfdc99cf38fc11348f60787bdc0a9b3..bcb56fae1709d94e2ca05ba1e0b4bed411260d1f 100644 (file)
@@ -4,7 +4,7 @@
 use rustc_hir::HirId;
 use rustc_target::abi::VariantIdx;
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
 pub enum PlaceBase {
     /// A temporary variable
     Rvalue,
@@ -16,7 +16,7 @@ pub enum PlaceBase {
     Upvar(ty::UpvarId),
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
 pub enum ProjectionKind {
     /// A dereference of a pointer, reference or `Box<T>` of the given type
     Deref,
@@ -36,7 +36,7 @@ pub enum ProjectionKind {
     Subslice,
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
 pub struct Projection<'tcx> {
     /// Type after the projection is being applied.
     pub ty: Ty<'tcx>,
@@ -48,7 +48,7 @@ pub struct Projection<'tcx> {
 /// A `Place` represents how a value is located in memory.
 ///
 /// This is an HIR version of `mir::Place`
-#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
 pub struct Place<'tcx> {
     /// The type of the `PlaceBase`
     pub base_ty: Ty<'tcx>,
@@ -61,7 +61,7 @@ pub struct Place<'tcx> {
 /// A `PlaceWithHirId` represents how a value is located in memory.
 ///
 /// This is an HIR version of `mir::Place`
-#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
 pub struct PlaceWithHirId<'tcx> {
     /// `HirId` of the expression or pattern producing this value.
     pub hir_id: HirId,
index 9433d282ad297d04b4768ef6a8cb95ff17e7a1a1..1e15ae49a0c384e1a25ad4fcc6dd9ed5e56b3a16 100644 (file)
 use crate::ty::{self, BoundVar, List, Region, TyCtxt};
 use rustc_index::vec::IndexVec;
 use rustc_macros::HashStable;
-use rustc_serialize::UseSpecializedDecodable;
 use smallvec::SmallVec;
 use std::ops::Index;
 
 /// A "canonicalized" type `V` is one where all free inference
 /// variables have been rewritten to "canonical vars". These are
 /// numbered starting from 0 in order of first appearance.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable)]
 #[derive(HashStable, TypeFoldable, Lift)]
 pub struct Canonical<'tcx, V> {
     pub max_universe: ty::UniverseIndex,
@@ -43,8 +42,6 @@ pub struct Canonical<'tcx, V> {
 
 pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo>;
 
-impl<'tcx> UseSpecializedDecodable for CanonicalVarInfos<'tcx> {}
-
 /// A set of values corresponding to the canonical variables from some
 /// `Canonical`. You can give these values to
 /// `canonical_value.substitute` to substitute them into the canonical
@@ -54,7 +51,7 @@ impl<'tcx> UseSpecializedDecodable for CanonicalVarInfos<'tcx> {}
 /// vectors with the original values that were replaced by canonical
 /// variables. You will need to supply it later to instantiate the
 /// canonicalized query response.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable)]
 #[derive(HashStable, TypeFoldable, Lift)]
 pub struct CanonicalVarValues<'tcx> {
     pub var_values: IndexVec<BoundVar, GenericArg<'tcx>>,
@@ -90,7 +87,7 @@ fn default() -> Self {
 /// canonical value. This is sufficient information for code to create
 /// a copy of the canonical value in some other inference context,
 /// with fresh inference variables replacing the canonical values.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
 pub struct CanonicalVarInfo {
     pub kind: CanonicalVarKind,
 }
@@ -115,7 +112,7 @@ pub fn is_existential(&self) -> bool {
 /// Describes the "kind" of the canonical variable. This is a "kind"
 /// in the type-theory sense of the term -- i.e., a "meta" type system
 /// that analyzes type-like values.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
 pub enum CanonicalVarKind {
     /// Some kind of type inference variable.
     Ty(CanonicalTyVarKind),
@@ -160,7 +157,7 @@ pub fn universe(self) -> ty::UniverseIndex {
 /// 22.) can only be instantiated with integral/float types (e.g.,
 /// usize or f32). In order to faithfully reproduce a type, we need to
 /// know what set of types a given type variable can be unified with.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
 pub enum CanonicalTyVarKind {
     /// General type variable `?T` that can be unified with arbitrary types.
     General(ty::UniverseIndex),
index d2749f8529bed5b34baf7aa92ef5cff4b93d17ab..43712de34e90a51e8646d8e32266bff3b31c9fb6 100644 (file)
@@ -3,7 +3,7 @@
 use rustc_session::config::SanitizerSet;
 use rustc_span::symbol::Symbol;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Encodable, Decodable, HashStable)]
 pub struct CodegenFnAttrs {
     pub flags: CodegenFnAttrFlags,
     /// Parsed representation of the `#[inline]` attribute
@@ -37,7 +37,7 @@ pub struct CodegenFnAttrs {
 }
 
 bitflags! {
-    #[derive(RustcEncodable, RustcDecodable, HashStable)]
+    #[derive(Encodable, Decodable, HashStable)]
     pub struct CodegenFnAttrFlags: u32 {
         /// `#[cold]`: a hint to LLVM that this function, when called, is never on
         /// the hot path.
index 0a34c06adf063bae570f3c72b4b1c98d2bd15ddd..6a8f6c3e202038eb66cfb8c14441e95d1068bf9a 100644 (file)
@@ -25,7 +25,7 @@
 
 /// Where a crate came from on the local filesystem. One of these three options
 /// must be non-None.
-#[derive(PartialEq, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)]
+#[derive(PartialEq, Clone, Debug, HashStable, Encodable, Decodable)]
 pub struct CrateSource {
     pub dylib: Option<(PathBuf, PathKind)>,
     pub rlib: Option<(PathBuf, PathKind)>,
@@ -38,7 +38,7 @@ pub fn paths(&self) -> impl Iterator<Item = &PathBuf> {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
+#[derive(Encodable, Decodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
 #[derive(HashStable)]
 pub enum CrateDepKind {
     /// A dependency that is only used for its macros.
@@ -60,7 +60,7 @@ pub fn macros_only(self) -> bool {
     }
 }
 
-#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(PartialEq, Clone, Debug, Encodable, Decodable)]
 pub enum LibSource {
     Some(PathBuf),
     MetadataOnly,
@@ -80,13 +80,13 @@ pub fn option(&self) -> Option<PathBuf> {
     }
 }
 
-#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Debug, PartialEq, Clone, Encodable, Decodable, HashStable)]
 pub enum LinkagePreference {
     RequireDynamic,
     RequireStatic,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, Encodable, Decodable, HashStable)]
 pub struct NativeLib {
     pub kind: NativeLibKind,
     pub name: Option<Symbol>,
@@ -95,7 +95,7 @@ pub struct NativeLib {
     pub wasm_import_module: Option<Symbol>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, TyEncodable, TyDecodable, HashStable)]
 pub struct ForeignModule {
     pub foreign_items: Vec<DefId>,
     pub def_id: DefId,
@@ -145,7 +145,7 @@ pub enum ExternCrateSource {
     Path,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(Encodable, Decodable)]
 pub struct EncodedMetadata {
     pub raw_data: Vec<u8>,
 }
index 16ce315368a05d139330346b3b894ee8529d07b9..e079843bfbc3c9dbfbf372f6e664576a373ace02 100644 (file)
@@ -19,7 +19,7 @@
 /// This is local to the tcx, and is generally relevant to one session.
 pub type Dependencies = Vec<(CrateType, DependencyList)>;
 
-#[derive(Copy, Clone, PartialEq, Debug, HashStable, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable, Encodable, Decodable)]
 pub enum Linkage {
     NotLinked,
     IncludedFromDylib,
index 569af70c5b5fc5063290ad4678bcb846317b7d54..f961cdd90862f4516cf323abea0fc767f0652223 100644 (file)
@@ -8,7 +8,7 @@
 /// kind of crate, including cdylibs which export very few things.
 /// `Rust` will only be exported if the crate produced is a Rust
 /// dylib.
-#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable)]
 pub enum SymbolExportLevel {
     C,
     Rust,
@@ -21,7 +21,7 @@ pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
     }
 }
 
-#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Eq, PartialEq, Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
 pub enum ExportedSymbol<'tcx> {
     NonGeneric(DefId),
     Generic(DefId, SubstsRef<'tcx>),
index 943a065a8b5e8ef0fed990a8e4bd799bb8fd2eee..4c6ac82060485c9bb0ccb040cc76c6df75c634a3 100644 (file)
@@ -80,7 +80,7 @@
 // placate the same deriving in `ty::FreeRegion`, but we may want to
 // actually attach a more meaningful ordering to scopes than the one
 // generated via deriving here.
-#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Copy, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Copy, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub struct Scope {
     pub id: hir::ItemLocalId,
@@ -104,7 +104,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub enum ScopeData {
     Node,
@@ -324,7 +324,7 @@ pub struct ScopeTree {
     pub body_expr_count: FxHashMap<hir::BodyId, usize>,
 }
 
-#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
 pub struct YieldData {
     /// The `Span` of the yield.
     pub span: Span,
index c21ba1b3bd2db7342785dbf8c0271dd43e60fe3b..3d0144e9c8a9903e4b2d0f4545da5a6f5487fa2a 100644 (file)
@@ -11,7 +11,7 @@
 /// The origin of a named lifetime definition.
 ///
 /// This is used to prevent the usage of in-band lifetimes in `Fn`/`fn` syntax.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
 pub enum LifetimeDefOrigin {
     // Explicit binders like `fn foo<'a>(x: &'a u8)` or elided like `impl Foo<&u32>`
     ExplicitOrElided,
@@ -35,7 +35,7 @@ pub fn from_param(param: &GenericParam<'_>) -> Self {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
 pub enum Region {
     Static,
     EarlyBound(/* index */ u32, /* lifetime decl */ DefId, LifetimeDefOrigin),
@@ -47,7 +47,7 @@ pub enum Region {
 /// A set containing, at most, one known element.
 /// If two distinct values are inserted into a set, then it
 /// becomes `Many`, which can be used to detect ambiguities.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, TyEncodable, TyDecodable, Debug, HashStable)]
 pub enum Set1<T> {
     Empty,
     One(T),
index b23deb2e3bc9b5fe75b368a32dade4c538a0dd72..bee8d13c762f976de14e357366fc8c8f8adec42c 100644 (file)
@@ -14,7 +14,7 @@
     UninitBytesAccess,
 };
 
-#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub struct Allocation<Tag = (), Extra = ()> {
     /// The actual bytes of the allocation.
@@ -172,8 +172,6 @@ pub fn relocations(&self) -> &Relocations<Tag> {
     }
 }
 
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Allocation {}
-
 /// Byte accessors.
 impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
     /// Just a small local helper function to avoid a bit of code repetition.
@@ -666,7 +664,7 @@ pub fn mark_compressed_init_range(
 }
 
 /// Relocations.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 pub struct Relocations<Tag = (), Id = AllocId>(SortedMap<Size, (Tag, Id)>);
 
 impl<Tag, Id> Relocations<Tag, Id> {
@@ -747,7 +745,7 @@ pub fn mark_relocation_range(&mut self, relocations: AllocationRelocations<Tag>)
 
 /// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte
 /// is initialized. If it is `false` the byte is uninitialized.
-#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub struct InitMask {
     blocks: Vec<Block>,
index 5be09c0e9bc2bcaef3eda598d7438b76ee119b5e..059925088ce1d52d66266574111bfe509ba3dccb 100644 (file)
@@ -11,7 +11,7 @@
 use rustc_target::abi::{Align, Size};
 use std::{any::Any, backtrace::Backtrace, fmt, mem};
 
-#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
 pub enum ErrorHandled {
     /// Already reported an error for this evaluation, and the compilation is
     /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`.
@@ -137,7 +137,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 }
 
 /// Details of why a pointer had to be in-bounds.
-#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
 pub enum CheckInAllocMsg {
     MemoryAccessTest,
     NullPointerTest,
index 2507f2184fff1026c54437d9e9a6d5dce1cf31b9..e607da29ce453c76e8ad46ca70b514bcb2cfcdc3 100644 (file)
@@ -108,11 +108,11 @@ macro_rules! throw_machine_stop {
 use rustc_data_structures::tiny_list::TinyList;
 use rustc_hir::def_id::DefId;
 use rustc_macros::HashStable;
-use rustc_serialize::{Decodable, Encodable, Encoder};
+use rustc_serialize::{Decodable, Encodable};
 use rustc_target::abi::{Endian, Size};
 
 use crate::mir;
-use crate::ty::codec::TyDecoder;
+use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::subst::GenericArgKind;
 use crate::ty::{self, Instance, Ty, TyCtxt};
 
@@ -132,7 +132,7 @@ macro_rules! throw_machine_stop {
 /// - A constant
 /// - A static
 /// - A const fn where all arguments (if any) are zero-sized types
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, Lift)]
 pub struct GlobalId<'tcx> {
     /// For a constant or static, the `Instance` of the item itself.
@@ -182,17 +182,14 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-impl rustc_serialize::UseSpecializedEncodable for AllocId {}
-impl rustc_serialize::UseSpecializedDecodable for AllocId {}
-
-#[derive(RustcDecodable, RustcEncodable)]
+#[derive(TyDecodable, TyEncodable)]
 enum AllocDiscriminant {
     Alloc,
     Fn,
     Static,
 }
 
-pub fn specialized_encode_alloc_id<'tcx, E: Encoder>(
+pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<'tcx>>(
     encoder: &mut E,
     tcx: TyCtxt<'tcx>,
     alloc_id: AllocId,
@@ -333,7 +330,7 @@ pub fn decode_alloc_id<D>(&self, decoder: &mut D) -> Result<AllocId, D::Error>
         let alloc_id = decoder.with_position(pos, |decoder| {
             match alloc_kind {
                 AllocDiscriminant::Alloc => {
-                    let alloc = <&'tcx Allocation as Decodable>::decode(decoder)?;
+                    let alloc = <&'tcx Allocation as Decodable<_>>::decode(decoder)?;
                     // We already have a reserved `AllocId`.
                     let alloc_id = alloc_id.unwrap();
                     trace!("decoded alloc {:?}: {:#?}", alloc_id, alloc);
@@ -351,7 +348,7 @@ pub fn decode_alloc_id<D>(&self, decoder: &mut D) -> Result<AllocId, D::Error>
                 AllocDiscriminant::Static => {
                     assert!(alloc_id.is_none());
                     trace!("creating extern static alloc ID");
-                    let did = DefId::decode(decoder)?;
+                    let did = <DefId as Decodable<D>>::decode(decoder)?;
                     trace!("decoded static def-ID: {:?}", did);
                     let alloc_id = decoder.tcx().create_static_alloc(did);
                     Ok(alloc_id)
@@ -369,7 +366,7 @@ pub fn decode_alloc_id<D>(&self, decoder: &mut D) -> Result<AllocId, D::Error>
 
 /// An allocation in the global (tcx-managed) memory can be either a function pointer,
 /// a static, or a "real" allocation with some data in it.
-#[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable, HashStable)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash, TyDecodable, TyEncodable, HashStable)]
 pub enum GlobalAlloc<'tcx> {
     /// The alloc ID is used as a function pointer.
     Function(Instance<'tcx>),
index ccad4f0a135a16d3557c7d5603b6222d39149709..e3d5a085613aaddfacf6fb61e2aca34521349648 100644 (file)
@@ -87,7 +87,7 @@ impl<T: HasDataLayout> PointerArithmetic for T {}
 ///
 /// `Pointer` is generic over the `Tag` associated with each pointer,
 /// which is used to do provenance tracking during execution.
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, TyEncodable, TyDecodable, Hash)]
 #[derive(HashStable)]
 pub struct Pointer<Tag = ()> {
     pub alloc_id: AllocId,
index 50c76e29663f66af14c4355652bd973b3da74030..4c47f25105d0f4eb5d049b5b5e32ab6692e5806e 100644 (file)
@@ -23,7 +23,7 @@ pub struct RawConst<'tcx> {
 
 /// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
 /// array length computations, enum discriminants and the pattern matching logic.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
 #[derive(HashStable)]
 pub enum ConstValue<'tcx> {
     /// Used only for types with `layout::abi::Scalar` ABI and ZSTs.
@@ -108,7 +108,7 @@ pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self {
 /// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
 /// size. Like a range of bytes in an `Allocation`, a `Scalar` can either represent the raw bytes
 /// of a simple value or a pointer into another `Allocation`
-#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, TyEncodable, TyDecodable, Hash)]
 #[derive(HashStable)]
 pub enum Scalar<Tag = ()> {
     /// The raw bytes of a simple value.
@@ -562,7 +562,7 @@ fn from(ptr: Pointer<Tag>) -> Self {
     }
 }
 
-#[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable, HashStable, Hash)]
+#[derive(Clone, Copy, Eq, PartialEq, TyEncodable, TyDecodable, HashStable, Hash)]
 pub enum ScalarMaybeUninit<Tag = ()> {
     Scalar(Scalar<Tag>),
     Uninit,
index 98fd68927f1c20eb37c60785ade4b27f4e4d3880..c53d631568219b23e5cd4e9b31304ffd6587d91a 100644 (file)
@@ -5,6 +5,7 @@
 use crate::mir::interpret::{Allocation, ConstValue, GlobalAlloc, Scalar};
 use crate::mir::visit::MirVisitable;
 use crate::ty::adjustment::PointerCast;
+use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::subst::{Subst, SubstsRef};
@@ -73,7 +74,7 @@ fn local_decls(&self) -> &LocalDecls<'tcx> {
 /// The various "big phases" that MIR goes through.
 ///
 /// Warning: ordering of variants is significant.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
 #[derive(HashStable)]
 pub enum MirPhase {
     Build = 0,
@@ -91,7 +92,7 @@ pub fn phase_index(&self) -> usize {
 }
 
 /// The lowered representation of a single function.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable, TypeFoldable)]
+#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
 pub struct Body<'tcx> {
     /// A list of basic blocks. References to basic block use a newtyped index type `BasicBlock`
     /// that indexes into this vector.
@@ -413,7 +414,7 @@ pub fn dominators(&self) -> Dominators<BasicBlock> {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum Safety {
     Safe,
     /// Unsafe because of a PushUnsafeBlock
@@ -465,9 +466,13 @@ pub fn assert_crate_local(self) -> T {
 const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
 const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
 
-impl<T: Encodable> rustc_serialize::UseSpecializedEncodable for ClearCrossCrate<T> {
+impl<'tcx, E: TyEncoder<'tcx>, T: Encodable<E>> Encodable<E> for ClearCrossCrate<T> {
     #[inline]
-    fn default_encode<E: rustc_serialize::Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
+        if E::CLEAR_CROSS_CRATE {
+            return Ok(());
+        }
+
         match *self {
             ClearCrossCrate::Clear => TAG_CLEAR_CROSS_CRATE_CLEAR.encode(e),
             ClearCrossCrate::Set(ref val) => {
@@ -477,12 +482,13 @@ fn default_encode<E: rustc_serialize::Encoder>(&self, e: &mut E) -> Result<(), E
         }
     }
 }
-impl<T: Decodable> rustc_serialize::UseSpecializedDecodable for ClearCrossCrate<T> {
+impl<'tcx, D: TyDecoder<'tcx>, T: Decodable<D>> Decodable<D> for ClearCrossCrate<T> {
     #[inline]
-    fn default_decode<D>(d: &mut D) -> Result<ClearCrossCrate<T>, D::Error>
-    where
-        D: rustc_serialize::Decoder,
-    {
+    fn decode(d: &mut D) -> Result<ClearCrossCrate<T>, D::Error> {
+        if D::CLEAR_CROSS_CRATE {
+            return Ok(ClearCrossCrate::Clear);
+        }
+
         let discr = u8::decode(d)?;
 
         match discr {
@@ -491,7 +497,7 @@ fn default_decode<D>(d: &mut D) -> Result<ClearCrossCrate<T>, D::Error>
                 let val = T::decode(d)?;
                 Ok(ClearCrossCrate::Set(val))
             }
-            _ => unreachable!(),
+            tag => Err(d.error(&format!("Invalid tag for ClearCrossCrate: {:?}", tag))),
         }
     }
 }
@@ -501,7 +507,7 @@ fn default_decode<D>(d: &mut D) -> Result<ClearCrossCrate<T>, D::Error>
 /// Most passes can work with it as a whole, within a single function.
 // The unofficial Cranelift backend, at least as of #65828, needs `SourceInfo` to implement `Eq` and
 // `Hash`. Please ping @bjorn3 if removing them.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash, HashStable)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
 pub struct SourceInfo {
     /// The source span for the AST pertaining to this MIR entity.
     pub span: Span,
@@ -521,7 +527,7 @@ pub fn outermost(span: Span) -> Self {
 ///////////////////////////////////////////////////////////////////////////
 // Borrow kinds
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub enum BorrowKind {
     /// Data must be immutable and is aliasable.
@@ -632,7 +638,7 @@ pub enum LocalKind {
     ReturnPointer,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct VarBindingForm<'tcx> {
     /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
     pub binding_mode: ty::BindingMode,
@@ -654,7 +660,7 @@ pub struct VarBindingForm<'tcx> {
     pub pat_span: Span,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable)]
 pub enum BindingForm<'tcx> {
     /// This is a binding for a non-`self` binding, or a `self` that has an explicit type.
     Var(VarBindingForm<'tcx>),
@@ -665,7 +671,7 @@ pub enum BindingForm<'tcx> {
 }
 
 /// Represents what type of implicit self a function has, if any.
-#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum ImplicitSelfKind {
     /// Represents a `fn x(self);`.
     Imm,
@@ -708,7 +714,7 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
 /// involved in borrow_check errors, e.g., explanations of where the
 /// temporaries come from, when their destructors are run, and/or how
 /// one might revise the code to satisfy the borrow checker's rules.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct BlockTailInfo {
     /// If `true`, then the value resulting from evaluating this tail
     /// expression is ignored by the block's expression context.
@@ -725,7 +731,7 @@ pub struct BlockTailInfo {
 ///
 /// This can be a binding declared by the user, a temporary inserted by the compiler, a function
 /// argument, or the return place.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct LocalDecl<'tcx> {
     /// Whether this is a mutable minding (i.e., `let x` or `let mut x`).
     ///
@@ -863,7 +869,7 @@ pub struct LocalDecl<'tcx> {
 ///
 /// Not used for non-StaticRef temporaries, the return place, or anonymous
 /// function parameters.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub enum LocalInfo<'tcx> {
     /// A user-defined local variable or function parameter
     ///
@@ -1006,7 +1012,7 @@ pub fn block_tail(mut self, info: BlockTailInfo) -> Self {
 }
 
 /// Debug information pertaining to a user variable.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct VarDebugInfo<'tcx> {
     pub name: Symbol,
 
@@ -1041,7 +1047,7 @@ pub fn start_location(self) -> Location {
 ///////////////////////////////////////////////////////////////////////////
 // BasicBlockData and Terminator
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct BasicBlockData<'tcx> {
     /// List of statements in this block.
     pub statements: Vec<Statement<'tcx>>,
@@ -1064,7 +1070,7 @@ pub struct BasicBlockData<'tcx> {
 }
 
 /// Information about an assertion failure.
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
+#[derive(Clone, TyEncodable, TyDecodable, HashStable, PartialEq)]
 pub enum AssertKind<O> {
     BoundsCheck { len: O, index: O },
     Overflow(BinOp, O, O),
@@ -1075,7 +1081,7 @@ pub enum AssertKind<O> {
     ResumedAfterPanic(GeneratorKind),
 }
 
-#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub enum InlineAsmOperand<'tcx> {
     In {
         reg: InlineAsmRegOrRegClass,
@@ -1320,7 +1326,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 ///////////////////////////////////////////////////////////////////////////
 // Statements
 
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct Statement<'tcx> {
     pub source_info: SourceInfo,
     pub kind: StatementKind<'tcx>,
@@ -1346,7 +1352,7 @@ pub fn replace_nop(&mut self) -> Self {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub enum StatementKind<'tcx> {
     /// Write the RHS Rvalue to the LHS Place.
     Assign(Box<(Place<'tcx>, Rvalue<'tcx>)>),
@@ -1399,7 +1405,7 @@ pub enum StatementKind<'tcx> {
 }
 
 /// Describes what kind of retag is to be performed.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, HashStable)]
+#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, HashStable)]
 pub enum RetagKind {
     /// The initial retag when entering a function.
     FnEntry,
@@ -1412,7 +1418,7 @@ pub enum RetagKind {
 }
 
 /// The `FakeReadCause` describes the type of pattern why a FakeRead statement exists.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable, PartialEq)]
+#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, HashStable, PartialEq)]
 pub enum FakeReadCause {
     /// Inject a fake read of the borrowed input at the end of each guards
     /// code.
@@ -1454,7 +1460,7 @@ pub enum FakeReadCause {
     ForIndex,
 }
 
-#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct LlvmInlineAsm<'tcx> {
     pub asm: hir::LlvmInlineAsmInner,
     pub outputs: Box<[Place<'tcx>]>,
@@ -1499,7 +1505,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
 
 /// A path to a value; something that can be evaluated without
 /// changing or disturbing program state.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
 pub struct Place<'tcx> {
     pub local: Local,
 
@@ -1507,10 +1513,8 @@ pub struct Place<'tcx> {
     pub projection: &'tcx List<PlaceElem<'tcx>>,
 }
 
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {}
-
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
+#[derive(TyEncodable, TyDecodable, HashStable)]
 pub enum ProjectionElem<V, T> {
     Deref,
     Field(Field, T),
@@ -1735,7 +1739,7 @@ pub struct SourceScope {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct SourceScopeData {
     pub span: Span,
     pub parent_scope: Option<SourceScope>,
@@ -1745,7 +1749,7 @@ pub struct SourceScopeData {
     pub local_data: ClearCrossCrate<SourceScopeLocalData>,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct SourceScopeLocalData {
     /// An `HirId` with lint levels equivalent to this scope's lint levels.
     pub lint_root: hir::HirId,
@@ -1758,7 +1762,7 @@ pub struct SourceScopeLocalData {
 
 /// These are values that can appear inside an rvalue. They are intentionally
 /// limited to prevent rvalues from being nested in one another.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable)]
 pub enum Operand<'tcx> {
     /// Copy: The value must be available for use afterwards.
     ///
@@ -1892,7 +1896,7 @@ pub fn place(&self) -> Option<Place<'tcx>> {
 ///////////////////////////////////////////////////////////////////////////
 /// Rvalues
 
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
+#[derive(Clone, TyEncodable, TyDecodable, HashStable, PartialEq)]
 pub enum Rvalue<'tcx> {
     /// x (either a move or copy, depending on type of x)
     Use(Operand<'tcx>),
@@ -1938,13 +1942,13 @@ pub enum Rvalue<'tcx> {
     Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub enum CastKind {
     Misc,
     Pointer(PointerCast),
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub enum AggregateKind<'tcx> {
     /// The type is of the element
     Array(Ty<'tcx>),
@@ -1961,7 +1965,7 @@ pub enum AggregateKind<'tcx> {
     Generator(DefId, SubstsRef<'tcx>, hir::Movability),
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub enum BinOp {
     /// The `+` operator (addition)
     Add,
@@ -2009,7 +2013,7 @@ pub fn is_checkable(self) -> bool {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub enum NullOp {
     /// Returns the size of a value of that type
     SizeOf,
@@ -2017,7 +2021,7 @@ pub enum NullOp {
     Box,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub enum UnOp {
     /// The `!` operator for logical inversion
     Not,
@@ -2187,7 +2191,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
 /// this does not necessarily mean that they are "==" in Rust -- in
 /// particular one must be wary of `NaN`!
 
-#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, HashStable)]
 pub struct Constant<'tcx> {
     pub span: Span,
 
@@ -2248,7 +2252,7 @@ pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
 /// The first will lead to the constraint `w: &'1 str` (for some
 /// inferred region `'1`). The second will lead to the constraint `w:
 /// &'static str`.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct UserTypeProjections {
     pub contents: Vec<(UserTypeProjection, Span)>,
 }
@@ -2325,7 +2329,7 @@ pub fn variant(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx, field: Fi
 /// * `let (x, _): T = ...` -- here, the `projs` vector would contain
 ///   `field[0]` (aka `.0`), indicating that the type of `s` is
 ///   determined by finding the type of the `.0` field from `T`.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, PartialEq)]
 pub struct UserTypeProjection {
     pub base: UserTypeAnnotationIndex,
     pub projs: Vec<ProjectionKind>,
index bb204223b60607ee9079ac6ec8da1e3e02b9d5a1..009240d0561603c070d694420d38f16dca43ade8 100644 (file)
@@ -242,7 +242,7 @@ pub struct CodegenUnit<'tcx> {
 /// Specifies the linkage type for a `MonoItem`.
 ///
 /// See https://llvm.org/docs/LangRef.html#linkage-types for more details about these variants.
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable, HashStable)]
 pub enum Linkage {
     External,
     AvailableExternally,
index 7508c0239397f6fe2d96d82bb2c1842511ea0f6a..b16a1d53fff1cdb2ea5e4f29bcad58e1d9becc1f 100644 (file)
@@ -54,16 +54,16 @@ pub(super) fn compute(
     }
 }
 
-impl serialize::Encodable for PredecessorCache {
+impl<S: serialize::Encoder> serialize::Encodable<S> for PredecessorCache {
     #[inline]
-    fn encode<S: serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         serialize::Encodable::encode(&(), s)
     }
 }
 
-impl serialize::Decodable for PredecessorCache {
+impl<D: serialize::Decoder> serialize::Decodable<D> for PredecessorCache {
     #[inline]
-    fn decode<D: serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
+    fn decode(d: &mut D) -> Result<Self, D::Error> {
         serialize::Decodable::decode(d).map(|_v: ()| Self::new())
     }
 }
index 6ce5d61fbed1b82dcd710540511f874d32e38dc0..0878e9313d8c5d6153a836330fc00fb85eb29de2 100644 (file)
@@ -16,7 +16,7 @@
 
 use super::{Field, SourceInfo};
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable)]
 pub enum UnsafetyViolationKind {
     /// Only permitted in regular `fn`s, prohibited in `const fn`s.
     General,
@@ -35,7 +35,7 @@ pub enum UnsafetyViolationKind {
     UnsafeFnBorrowPacked,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable)]
 pub enum UnsafetyViolationDetails {
     CallToUnsafeFunction,
     UseOfInlineAssembly,
@@ -120,7 +120,7 @@ pub fn description_and_note(&self) -> (&'static str, &'static str) {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable)]
 pub struct UnsafetyViolation {
     pub source_info: SourceInfo,
     pub lint_root: hir::HirId,
@@ -128,7 +128,7 @@ pub struct UnsafetyViolation {
     pub details: UnsafetyViolationDetails,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, TyEncodable, TyDecodable, HashStable)]
 pub struct UnsafetyCheckResult {
     /// Violations that are propagated *upwards* from this function.
     pub violations: Lrc<[UnsafetyViolation]>,
@@ -145,7 +145,7 @@ pub struct GeneratorSavedLocal {
 }
 
 /// The layout of generator state.
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct GeneratorLayout<'tcx> {
     /// The type of every local stored inside the generator.
     pub field_tys: IndexVec<GeneratorSavedLocal, Ty<'tcx>>,
@@ -220,7 +220,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-#[derive(Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct BorrowCheckResult<'tcx> {
     /// All the opaque types that are restricted to concrete types
     /// by this function. Unlike the value in `TypeckResults`, this has
@@ -235,7 +235,7 @@ pub struct BorrowCheckResult<'tcx> {
 /// Each field corresponds to an implementer of the `Qualif` trait in
 /// `librustc_mir/transform/check_consts/qualifs.rs`. See that file for more information on each
 /// `Qualif`.
-#[derive(Clone, Copy, Debug, Default, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, Debug, Default, TyEncodable, TyDecodable, HashStable)]
 pub struct ConstQualifs {
     pub has_mut_interior: bool,
     pub needs_drop: bool,
@@ -291,7 +291,7 @@ pub struct ConstQualifs {
 /// `ReEarlyBound`, `ReFree`). We use these because in a query response we
 /// cannot use `ReVar` (which is what we use internally within the rest of the
 /// NLL code).
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct ClosureRegionRequirements<'tcx> {
     /// The number of external regions defined on the closure. In our
     /// example above, it would be 3 -- one for `'static`, then `'1`
@@ -307,7 +307,7 @@ pub struct ClosureRegionRequirements<'tcx> {
 
 /// Indicates an outlives-constraint between a type or between two
 /// free regions declared on the closure.
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct ClosureOutlivesRequirement<'tcx> {
     // This region or type ...
     pub subject: ClosureOutlivesSubject<'tcx>,
@@ -328,7 +328,7 @@ pub struct ClosureOutlivesRequirement<'tcx> {
 ///
 /// See also `rustc_mir::borrow_check::constraints`.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
+#[derive(TyEncodable, TyDecodable, HashStable)]
 pub enum ConstraintCategory {
     Return(ReturnConstraint),
     Yield,
@@ -365,7 +365,7 @@ pub enum ConstraintCategory {
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
+#[derive(TyEncodable, TyDecodable, HashStable)]
 pub enum ReturnConstraint {
     Normal,
     ClosureUpvar(hir::HirId),
@@ -373,7 +373,7 @@ pub enum ReturnConstraint {
 
 /// The subject of a `ClosureOutlivesRequirement` -- that is, the thing
 /// that must outlive some region.
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum ClosureOutlivesSubject<'tcx> {
     /// Subject is a type, typically a type parameter, but could also
     /// be a projection. Indicates a requirement like `T: 'a` being
@@ -398,7 +398,7 @@ pub struct DestructuredConst<'tcx> {
 /// Coverage information summarized from a MIR if instrumented for source code coverage (see
 /// compiler option `-Zinstrument-coverage`). This information is generated by the
 /// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable)]
 pub struct CoverageInfo {
     /// The total number of coverage region counters added to the MIR `Body`.
     pub num_counters: u32,
index 1f5041141d55b93420b81cf1d3246928b6192bde..0ab783812241e343afe204964f0f614cb131efb2 100644 (file)
@@ -16,7 +16,7 @@
 
 pub use super::query::*;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
+#[derive(Clone, TyEncodable, TyDecodable, HashStable, PartialEq)]
 pub enum TerminatorKind<'tcx> {
     /// Block should have one successor in the graph; we jump there.
     Goto { target: BasicBlock },
@@ -194,7 +194,7 @@ pub enum TerminatorKind<'tcx> {
         destination: Option<BasicBlock>,
     },
 }
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct Terminator<'tcx> {
     pub source_info: SourceInfo,
     pub kind: TerminatorKind<'tcx>,
index 585f29386a8e0e15c06f2595c2213dd72829c9a3..ea9c8b7a415840b15e2adfedca48baea42093e5b 100644 (file)
@@ -426,7 +426,7 @@ pub enum SelectionError<'tcx> {
 /// ### The type parameter `N`
 ///
 /// See explanation on `ImplSourceUserDefinedData`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub enum ImplSource<'tcx, N> {
     /// ImplSource identifying a particular impl.
     ImplSourceUserDefined(ImplSourceUserDefinedData<'tcx, N>),
@@ -557,14 +557,14 @@ pub fn map<M, F>(self, f: F) -> ImplSource<'tcx, M>
 /// is `Obligation`, as one might expect. During codegen, however, this
 /// is `()`, because codegen only requires a shallow resolution of an
 /// impl, and nested obligations are satisfied later.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceUserDefinedData<'tcx, N> {
     pub impl_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceGeneratorData<'tcx, N> {
     pub generator_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
@@ -573,7 +573,7 @@ pub struct ImplSourceGeneratorData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceClosureData<'tcx, N> {
     pub closure_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
@@ -582,18 +582,18 @@ pub struct ImplSourceClosureData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceAutoImplData<N> {
     pub trait_def_id: DefId,
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceBuiltinData<N> {
     pub nested: Vec<N>,
 }
 
-#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceObjectData<'tcx, N> {
     /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
     pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
@@ -606,17 +606,17 @@ pub struct ImplSourceObjectData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceFnPointerData<'tcx, N> {
     pub fn_ty: Ty<'tcx>,
     pub nested: Vec<N>,
 }
 
 // FIXME(@lcnr): This should be  refactored and merged with other builtin vtables.
-#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub struct ImplSourceDiscriminantKindData;
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceTraitAliasData<'tcx, N> {
     pub alias_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
index c9aae8980076f1a81c3446a03b2d88b0c04fbb91..969404c68cab7084513835d141ce4e4c9a5231ab 100644 (file)
@@ -23,7 +23,7 @@
 ///   parents of a given specializing impl, which is needed for extracting
 ///   default items amongst other things. In the simple "chain" rule, every impl
 ///   has at most one parent.
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
+#[derive(TyEncodable, TyDecodable, HashStable)]
 pub struct Graph {
     /// All impls have a parent; the "root" impls have as their parent the `def_id`
     /// of the trait.
@@ -50,7 +50,7 @@ pub fn parent(&self, child: DefId) -> DefId {
 
 /// Children of a given impl, grouped into blanket/non-blanket varieties as is
 /// done in `TraitDef`.
-#[derive(Default, RustcEncodable, RustcDecodable)]
+#[derive(Default, TyEncodable, TyDecodable)]
 pub struct Children {
     // Impls of a trait (or specializations of a given impl). To allow for
     // quicker lookup, the impls are indexed by a simplified version of their
index 52ebcd63e7cda40a5e807cfee3529551ed11d9de..0ab07aea426c3c95d217133c567d291e0c0f8cc0 100644 (file)
@@ -5,7 +5,7 @@
 use rustc_hir::lang_items::{DerefMutTraitLangItem, DerefTraitLangItem};
 use rustc_macros::HashStable;
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub enum PointerCast {
     /// Go from a fn-item type to a fn-pointer type.
     ReifyFnPointer,
@@ -76,7 +76,7 @@ pub enum PointerCast {
 ///    At some point, of course, `Box` should move out of the compiler, in which
 ///    case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
 ///    Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct Adjustment<'tcx> {
     pub kind: Adjust<'tcx>,
     pub target: Ty<'tcx>,
@@ -91,7 +91,7 @@ pub fn is_region_borrow(&self) -> bool {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub enum Adjust<'tcx> {
     /// Go from ! to any type.
     NeverToAny,
@@ -109,7 +109,7 @@ pub enum Adjust<'tcx> {
 /// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
 /// The target type is `U` in both cases, with the region and mutability
 /// being those shared by both the receiver and the returned reference.
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub struct OverloadedDeref<'tcx> {
     pub region: ty::Region<'tcx>,
     pub mutbl: hir::Mutability,
@@ -143,13 +143,13 @@ pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> (DefId, Substs
 /// new code via two-phase borrows, so we try to limit where we create two-phase
 /// capable mutable borrows.
 /// See #49434 for tracking.
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum AllowTwoPhase {
     Yes,
     No,
 }
 
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum AutoBorrowMutability {
     Mut { allow_two_phase_borrow: AllowTwoPhase },
     Not,
@@ -164,7 +164,7 @@ fn from(m: AutoBorrowMutability) -> Self {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
 pub enum AutoBorrow<'tcx> {
     /// Converts from T to &T.
     Ref(ty::Region<'tcx>, AutoBorrowMutability),
@@ -179,7 +179,7 @@ pub enum AutoBorrow<'tcx> {
 /// This struct can be obtained via the `coerce_impl_info` query.
 /// Demanding this struct also has the side-effect of reporting errors
 /// for inappropriate impls.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)]
 pub struct CoerceUnsizedInfo {
     /// If this is a "custom coerce" impl, then what kind of custom
     /// coercion is it? This applies to impls of `CoerceUnsized` for
@@ -188,7 +188,7 @@ pub struct CoerceUnsizedInfo {
     pub custom_kind: Option<CustomCoerceUnsized>,
 }
 
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)]
 pub enum CustomCoerceUnsized {
     /// Records the index of the field being coerced.
     Struct(usize),
index 5ee8811509098e40a885025d38319784620ed7c5..3237147c8ba2f589f8d4478875b88c03d2d975af 100644 (file)
@@ -2,7 +2,7 @@
 use rustc_hir::BindingAnnotation::*;
 use rustc_hir::Mutability;
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
+#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Debug, Copy, HashStable)]
 pub enum BindingMode {
     BindByReference(Mutability),
     BindByValue(Mutability),
index 31c106cb230b43624466384068b65aebbd1c8480..3a3caa55f60776f6a8a5b0bb52ac19cbc4960b0c 100644 (file)
@@ -31,7 +31,7 @@ pub enum CastTy<'tcx> {
 }
 
 /// Cast Kind. See RFC 401 (or librustc_typeck/check/cast.rs)
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum CastKind {
     CoercionCast,
     PtrPtrCast,
index a7c7b16048039386290eef78c30dffe041f5074c..42f55e9f5f9c7e3100b2c0306bdffaef9ae033bd 100644 (file)
@@ -8,12 +8,15 @@
 
 use crate::arena::ArenaAllocatable;
 use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
-use crate::mir::{self, interpret::Allocation};
+use crate::mir::{
+    self,
+    interpret::{AllocId, Allocation},
+};
 use crate::ty::subst::SubstsRef;
 use crate::ty::{self, List, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::{CrateNum, DefId};
-use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
+use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_span::Span;
 use std::convert::{TryFrom, TryInto};
 use std::hash::Hash;
 /// This offset is also chosen so that the first byte is never < 0x80.
 pub const SHORTHAND_OFFSET: usize = 0x80;
 
-pub trait EncodableWithShorthand: Clone + Eq + Hash {
-    type Variant: Encodable;
+pub trait EncodableWithShorthand<'tcx, E: TyEncoder<'tcx>>: Copy + Eq + Hash {
+    type Variant: Encodable<E>;
     fn variant(&self) -> &Self::Variant;
 }
 
 #[allow(rustc::usage_of_ty_tykind)]
-impl<'tcx> EncodableWithShorthand for Ty<'tcx> {
+impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for Ty<'tcx> {
     type Variant = ty::TyKind<'tcx>;
     fn variant(&self) -> &Self::Variant {
         &self.kind
     }
 }
 
-impl<'tcx> EncodableWithShorthand for ty::Predicate<'tcx> {
+impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::Predicate<'tcx> {
     type Variant = ty::PredicateKind<'tcx>;
     fn variant(&self) -> &Self::Variant {
         self.kind()
     }
 }
 
-pub trait TyEncoder: Encoder {
-    fn position(&self) -> usize;
+pub trait OpaqueEncoder: Encoder {
+    fn opaque(&mut self) -> &mut rustc_serialize::opaque::Encoder;
+    fn encoder_position(&self) -> usize;
 }
 
-impl TyEncoder for opaque::Encoder {
+impl OpaqueEncoder for rustc_serialize::opaque::Encoder {
+    #[inline]
+    fn opaque(&mut self) -> &mut rustc_serialize::opaque::Encoder {
+        self
+    }
     #[inline]
-    fn position(&self) -> usize {
+    fn encoder_position(&self) -> usize {
         self.position()
     }
 }
 
+pub trait TyEncoder<'tcx>: Encoder {
+    const CLEAR_CROSS_CRATE: bool;
+
+    fn tcx(&self) -> TyCtxt<'tcx>;
+    fn position(&self) -> usize;
+    fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize>;
+    fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::Predicate<'tcx>, usize>;
+    fn encode_alloc_id(&mut self, alloc_id: &AllocId) -> Result<(), Self::Error>;
+}
+
+pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>> {
+    fn decode(d: &mut D) -> Result<&'tcx Self, D::Error>;
+}
+
 /// Encode the given value or a previously cached shorthand.
 pub fn encode_with_shorthand<E, T, M>(encoder: &mut E, value: &T, cache: M) -> Result<(), E::Error>
 where
-    E: TyEncoder,
+    E: TyEncoder<'tcx>,
     M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<T, usize>,
-    T: EncodableWithShorthand,
+    T: EncodableWithShorthand<'tcx, E>,
     <T::Variant as DiscriminantKind>::Discriminant: Ord + TryFrom<usize>,
 {
-    let existing_shorthand = cache(encoder).get(value).cloned();
+    let existing_shorthand = cache(encoder).get(value).copied();
     if let Some(shorthand) = existing_shorthand {
         return encoder.emit_usize(shorthand);
     }
@@ -89,13 +111,51 @@ pub fn encode_with_shorthand<E, T, M>(encoder: &mut E, value: &T, cache: M) -> R
     // Check that the shorthand is a not longer than the
     // full encoding itself, i.e., it's an obvious win.
     if leb128_bits >= 64 || (shorthand as u64) < (1 << leb128_bits) {
-        cache(encoder).insert(value.clone(), shorthand);
+        cache(encoder).insert(*value, shorthand);
     }
 
     Ok(())
 }
 
+impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Ty<'tcx> {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
+        encode_with_shorthand(e, self, TyEncoder::type_shorthands)
+    }
+}
+
+impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
+        encode_with_shorthand(e, self, TyEncoder::predicate_shorthands)
+    }
+}
+
+impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
+        e.encode_alloc_id(self)
+    }
+}
+
+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>,
+    ty::Region<'tcx>,
+    &'tcx mir::Body<'tcx>,
+    &'tcx mir::UnsafetyCheckResult,
+    &'tcx mir::BorrowCheckResult<'tcx>
+}
+
 pub trait TyDecoder<'tcx>: Decoder {
+    const CLEAR_CROSS_CRATE: bool;
+
     fn tcx(&self) -> TyCtxt<'tcx>;
 
     fn peek_byte(&self) -> u8;
@@ -127,10 +187,12 @@ fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
     fn positioned_at_shorthand(&self) -> bool {
         (self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
     }
+
+    fn decode_alloc_id(&mut self) -> Result<AllocId, Self::Error>;
 }
 
 #[inline]
-pub fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>(
+pub fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
     decoder: &mut D,
 ) -> Result<&'tcx T, D::Error>
 where
@@ -140,172 +202,156 @@ pub fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>(
 }
 
 #[inline]
-pub fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>(
+pub fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
     decoder: &mut D,
 ) -> Result<&'tcx [T], D::Error>
 where
     D: TyDecoder<'tcx>,
 {
-    Ok(decoder.tcx().arena.alloc_from_iter(<Vec<T> as Decodable>::decode(decoder)?))
+    Ok(decoder.tcx().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder)?))
 }
 
-#[inline]
-pub fn decode_cnum<D>(decoder: &mut D) -> Result<CrateNum, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let cnum = CrateNum::from_u32(u32::decode(decoder)?);
-    Ok(decoder.map_encoded_cnum_to_current(cnum))
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
+    #[allow(rustc::usage_of_ty_tykind)]
+    fn decode(decoder: &mut D) -> Result<Ty<'tcx>, D::Error> {
+        // Handle shorthands first, if we have an usize > 0x80.
+        if decoder.positioned_at_shorthand() {
+            let pos = decoder.read_usize()?;
+            assert!(pos >= SHORTHAND_OFFSET);
+            let shorthand = pos - SHORTHAND_OFFSET;
+
+            decoder.cached_ty_for_shorthand(shorthand, |decoder| {
+                decoder.with_position(shorthand, Ty::decode)
+            })
+        } else {
+            let tcx = decoder.tcx();
+            Ok(tcx.mk_ty(ty::TyKind::decode(decoder)?))
+        }
+    }
 }
 
-#[allow(rustc::usage_of_ty_tykind)]
-#[inline]
-pub fn decode_ty<D>(decoder: &mut D) -> Result<Ty<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    // Handle shorthands first, if we have an usize > 0x80.
-    if decoder.positioned_at_shorthand() {
-        let pos = decoder.read_usize()?;
-        assert!(pos >= SHORTHAND_OFFSET);
-        let shorthand = pos - SHORTHAND_OFFSET;
-
-        decoder.cached_ty_for_shorthand(shorthand, |decoder| {
-            decoder.with_position(shorthand, Ty::decode)
-        })
-    } else {
-        let tcx = decoder.tcx();
-        Ok(tcx.mk_ty(ty::TyKind::decode(decoder)?))
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
+    fn decode(decoder: &mut D) -> Result<ty::Predicate<'tcx>, D::Error> {
+        // Handle shorthands first, if we have an usize > 0x80.
+        let predicate_kind = if decoder.positioned_at_shorthand() {
+            let pos = decoder.read_usize()?;
+            assert!(pos >= SHORTHAND_OFFSET);
+            let shorthand = pos - SHORTHAND_OFFSET;
+
+            decoder.with_position(shorthand, ty::PredicateKind::decode)
+        } else {
+            ty::PredicateKind::decode(decoder)
+        }?;
+        let predicate = decoder.tcx().mk_predicate(predicate_kind);
+        Ok(predicate)
     }
 }
 
-#[inline]
-pub fn decode_predicate<D>(decoder: &mut D) -> Result<ty::Predicate<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    // Handle shorthands first, if we have an usize > 0x80.
-    if decoder.positioned_at_shorthand() {
-        let pos = decoder.read_usize()?;
-        assert!(pos >= SHORTHAND_OFFSET);
-        let shorthand = pos - SHORTHAND_OFFSET;
-
-        decoder.cached_predicate_for_shorthand(shorthand, |decoder| {
-            decoder.with_position(shorthand, ty::Predicate::decode)
-        })
-    } else {
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for SubstsRef<'tcx> {
+    fn decode(decoder: &mut D) -> Result<Self, D::Error> {
+        let len = decoder.read_usize()?;
         let tcx = decoder.tcx();
-        Ok(tcx.mk_predicate(ty::PredicateKind::decode(decoder)?))
+        Ok(tcx.mk_substs((0..len).map(|_| Decodable::decode(decoder)))?)
     }
 }
 
-#[inline]
-pub fn decode_spanned_predicates<D>(
-    decoder: &mut D,
-) -> Result<&'tcx [(ty::Predicate<'tcx>, Span)], D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let tcx = decoder.tcx();
-    Ok(tcx.arena.alloc_from_iter(
-        (0..decoder.read_usize()?)
-            .map(|_| Decodable::decode(decoder))
-            .collect::<Result<Vec<_>, _>>()?,
-    ))
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for mir::Place<'tcx> {
+    fn decode(decoder: &mut D) -> Result<Self, D::Error> {
+        let local: mir::Local = Decodable::decode(decoder)?;
+        let len = decoder.read_usize()?;
+        let projection: &'tcx List<mir::PlaceElem<'tcx>> =
+            decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?;
+        Ok(mir::Place { local, projection })
+    }
 }
 
-#[inline]
-pub fn decode_substs<D>(decoder: &mut D) -> Result<SubstsRef<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let len = decoder.read_usize()?;
-    let tcx = decoder.tcx();
-    Ok(tcx.mk_substs((0..len).map(|_| Decodable::decode(decoder)))?)
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Region<'tcx> {
+    fn decode(decoder: &mut D) -> Result<Self, D::Error> {
+        Ok(decoder.tcx().mk_region(Decodable::decode(decoder)?))
+    }
 }
 
-#[inline]
-pub fn decode_place<D>(decoder: &mut D) -> Result<mir::Place<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let local: mir::Local = Decodable::decode(decoder)?;
-    let len = decoder.read_usize()?;
-    let projection: &'tcx List<mir::PlaceElem<'tcx>> =
-        decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?;
-    Ok(mir::Place { local, projection })
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarInfos<'tcx> {
+    fn decode(decoder: &mut D) -> Result<Self, D::Error> {
+        let len = decoder.read_usize()?;
+        let interned: Result<Vec<CanonicalVarInfo>, _> =
+            (0..len).map(|_| Decodable::decode(decoder)).collect();
+        Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice()))
+    }
 }
 
-#[inline]
-pub fn decode_region<D>(decoder: &mut D) -> Result<ty::Region<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    Ok(decoder.tcx().mk_region(Decodable::decode(decoder)?))
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AllocId {
+    fn decode(decoder: &mut D) -> Result<Self, D::Error> {
+        decoder.decode_alloc_id()
+    }
 }
 
-#[inline]
-pub fn decode_ty_slice<D>(decoder: &mut D) -> Result<&'tcx ty::List<Ty<'tcx>>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let len = decoder.read_usize()?;
-    Ok(decoder.tcx().mk_type_list((0..len).map(|_| Decodable::decode(decoder)))?)
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::SymbolName<'tcx> {
+    fn decode(decoder: &mut D) -> Result<Self, D::Error> {
+        Ok(ty::SymbolName::new(decoder.tcx(), &decoder.read_str()?))
+    }
 }
 
-#[inline]
-pub fn decode_adt_def<D>(decoder: &mut D) -> Result<&'tcx ty::AdtDef, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let def_id = DefId::decode(decoder)?;
-    Ok(decoder.tcx().adt_def(def_id))
+macro_rules! impl_decodable_via_ref {
+    ($($t:ty),+) => {
+        $(impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for $t {
+            fn decode(decoder: &mut D) -> Result<Self, D::Error> {
+                RefDecodable::decode(decoder)
+            }
+        })*
+    }
+}
+impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::AdtDef {
+    fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
+        let def_id = <DefId as Decodable<D>>::decode(decoder)?;
+        Ok(decoder.tcx().adt_def(def_id))
+    }
 }
 
-#[inline]
-pub fn decode_symbol_name<D>(decoder: &mut D) -> Result<ty::SymbolName<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    Ok(ty::SymbolName::new(decoder.tcx(), &decoder.read_str()?))
+impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
+    fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
+        let len = decoder.read_usize()?;
+        Ok(decoder.tcx().mk_type_list((0..len).map(|_| Decodable::decode(decoder)))?)
+    }
 }
 
-#[inline]
-pub fn decode_existential_predicate_slice<D>(
-    decoder: &mut D,
-) -> Result<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let len = decoder.read_usize()?;
-    Ok(decoder.tcx().mk_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))?)
+impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::ExistentialPredicate<'tcx>> {
+    fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
+        let len = decoder.read_usize()?;
+        Ok(decoder.tcx().mk_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))?)
+    }
 }
 
-#[inline]
-pub fn decode_canonical_var_infos<D>(decoder: &mut D) -> Result<CanonicalVarInfos<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let len = decoder.read_usize()?;
-    let interned: Result<Vec<CanonicalVarInfo>, _> =
-        (0..len).map(|_| Decodable::decode(decoder)).collect();
-    Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice()))
+impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::Const<'tcx> {
+    fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
+        Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
+    }
 }
 
-#[inline]
-pub fn decode_const<D>(decoder: &mut D) -> Result<&'tcx ty::Const<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
+impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for Allocation {
+    fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
+        Ok(decoder.tcx().intern_const_alloc(Decodable::decode(decoder)?))
+    }
 }
 
-#[inline]
-pub fn decode_allocation<D>(decoder: &mut D) -> Result<&'tcx Allocation, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    Ok(decoder.tcx().intern_const_alloc(Decodable::decode(decoder)?))
+impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, Span)] {
+    fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
+        Ok(decoder.tcx().arena.alloc_from_iter(
+            (0..decoder.read_usize()?)
+                .map(|_| Decodable::decode(decoder))
+                .collect::<Result<Vec<_>, _>>()?,
+        ))
+    }
+}
+
+impl_decodable_via_ref! {
+    &'tcx ty::TypeckResults<'tcx>,
+    &'tcx ty::List<Ty<'tcx>>,
+    &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
+    &'tcx Allocation,
+    &'tcx mir::Body<'tcx>,
+    &'tcx mir::UnsafetyCheckResult,
+    &'tcx mir::BorrowCheckResult<'tcx>
 }
 
 #[macro_export]
@@ -320,42 +366,21 @@ fn $name(&mut self) -> Result<$ty, Self::Error> {
     }
 }
 
-#[macro_export]
 macro_rules! impl_arena_allocatable_decoder {
     ([]$args:tt) => {};
     ([decode $(, $attrs:ident)*]
-     [[$DecoderName:ident [$($typaram:tt),*]], [$name:ident: $ty:ty, $gen_ty:ty], $tcx:lifetime]) => {
-         // FIXME(#36588): These impls are horribly unsound as they allow
-         // the caller to pick any lifetime for `'tcx`, including `'static`.
-        #[allow(unused_lifetimes)]
-        impl<'_x, '_y, '_z, '_w, '_a, $($typaram),*> SpecializedDecoder<&'_a $gen_ty>
-        for $DecoderName<$($typaram),*>
-        where &'_a $gen_ty: UseSpecializedDecodable
-        {
+     [[$name:ident: $ty:ty], $tcx:lifetime]) => {
+        impl<$tcx, D: TyDecoder<$tcx>> RefDecodable<$tcx, D> for $ty {
             #[inline]
-            fn specialized_decode(&mut self) -> Result<&'_a $gen_ty, Self::Error> {
-                unsafe {
-                    std::mem::transmute::<
-                        Result<&$tcx $ty, Self::Error>,
-                        Result<&'_a $gen_ty, Self::Error>,
-                    >(decode_arena_allocable(self))
-                }
+            fn decode(decoder: &mut D) -> Result<&$tcx Self, D::Error> {
+                decode_arena_allocable(decoder)
             }
         }
 
-        #[allow(unused_lifetimes)]
-        impl<'_x, '_y, '_z, '_w, '_a, $($typaram),*> SpecializedDecoder<&'_a [$gen_ty]>
-        for $DecoderName<$($typaram),*>
-        where &'_a [$gen_ty]: UseSpecializedDecodable
-        {
+        impl<$tcx, D: TyDecoder<$tcx>> RefDecodable<$tcx, D> for [$ty] {
             #[inline]
-            fn specialized_decode(&mut self) -> Result<&'_a [$gen_ty], Self::Error> {
-                unsafe {
-                    std::mem::transmute::<
-                        Result<&$tcx [$ty], Self::Error>,
-                        Result<&'_a [$gen_ty], Self::Error>,
-                    >(decode_arena_allocable_slice(self))
-                }
+            fn decode(decoder: &mut D) -> Result<&$tcx Self, D::Error> {
+                decode_arena_allocable_slice(decoder)
             }
         }
     };
@@ -364,38 +389,30 @@ fn specialized_decode(&mut self) -> Result<&'_a [$gen_ty], Self::Error> {
     };
 }
 
-#[macro_export]
 macro_rules! impl_arena_allocatable_decoders {
-    ($args:tt, [$($a:tt $name:ident: $ty:ty, $gen_ty:ty;)*], $tcx:lifetime) => {
+    ([], [$($a:tt $name:ident: $ty:ty, $_gen_ty:ty;)*], $tcx:lifetime) => {
         $(
-            impl_arena_allocatable_decoder!($a [$args, [$name: $ty, $gen_ty], $tcx]);
+            impl_arena_allocatable_decoder!($a [[$name: $ty], $tcx]);
         )*
     }
 }
 
+rustc_hir::arena_types!(impl_arena_allocatable_decoders, [], 'tcx);
+arena_types!(impl_arena_allocatable_decoders, [], 'tcx);
+
 #[macro_export]
 macro_rules! implement_ty_decoder {
     ($DecoderName:ident <$($typaram:tt),*>) => {
         mod __ty_decoder_impl {
             use std::borrow::Cow;
-            use std::mem::transmute;
-
-            use rustc_serialize::{Decoder, SpecializedDecoder, UseSpecializedDecodable};
-
-            use $crate::infer::canonical::CanonicalVarInfos;
-            use $crate::ty;
-            use $crate::ty::codec::*;
-            use $crate::ty::subst::InternalSubsts;
-            use rustc_hir::def_id::CrateNum;
-
-            use rustc_span::Span;
+            use rustc_serialize::Decoder;
 
             use super::$DecoderName;
 
             impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
                 type Error = String;
 
-                __impl_decoder_methods! {
+                $crate::__impl_decoder_methods! {
                     read_nil -> ();
 
                     read_u128 -> u128;
@@ -423,135 +440,6 @@ fn error(&mut self, err: &str) -> Self::Error {
                     self.opaque.error(err)
                 }
             }
-
-            // FIXME(#36588): These impls are horribly unsound as they allow
-            // the caller to pick any lifetime for `'tcx`, including `'static`.
-
-            arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
-
-            impl<$($typaram),*> SpecializedDecoder<CrateNum>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<CrateNum, Self::Error> {
-                    decode_cnum(self)
-                }
-            }
-
-            impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x ty::TyS<'_y>>
-            for $DecoderName<$($typaram),*>
-            where &'_x ty::TyS<'_y>: UseSpecializedDecodable
-            {
-                fn specialized_decode(&mut self) -> Result<&'_x ty::TyS<'_y>, Self::Error> {
-                    unsafe {
-                        transmute::<
-                            Result<ty::Ty<'tcx>, Self::Error>,
-                            Result<&'_x ty::TyS<'_y>, Self::Error>,
-                        >(decode_ty(self))
-                    }
-                }
-            }
-
-            impl<'_x, $($typaram),*> SpecializedDecoder<ty::Predicate<'_x>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<ty::Predicate<'_x>, Self::Error> {
-                    unsafe {
-                        transmute::<
-                            Result<ty::Predicate<'tcx>, Self::Error>,
-                            Result<ty::Predicate<'_x>, Self::Error>,
-                        >(decode_predicate(self))
-                    }
-                }
-            }
-
-            impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x [(ty::Predicate<'_y>, Span)]>
-            for $DecoderName<$($typaram),*>
-            where &'_x [(ty::Predicate<'_y>, Span)]: UseSpecializedDecodable {
-                fn specialized_decode(&mut self)
-                                      -> Result<&'_x [(ty::Predicate<'_y>, Span)], Self::Error>
-                {
-                    unsafe { transmute(decode_spanned_predicates(self)) }
-                }
-            }
-
-            impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x InternalSubsts<'_y>>
-            for $DecoderName<$($typaram),*>
-            where &'_x InternalSubsts<'_y>: UseSpecializedDecodable {
-                fn specialized_decode(&mut self) -> Result<&'_x InternalSubsts<'_y>, Self::Error> {
-                    unsafe { transmute(decode_substs(self)) }
-                }
-            }
-
-            impl<'_x, $($typaram),*> SpecializedDecoder<$crate::mir::Place<'_x>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(
-                    &mut self
-                ) -> Result<$crate::mir::Place<'_x>, Self::Error> {
-                    unsafe { transmute(decode_place(self)) }
-                }
-            }
-
-            impl<'_x, $($typaram),*> SpecializedDecoder<ty::Region<'_x>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<ty::Region<'_x>, Self::Error> {
-                    unsafe { transmute(decode_region(self)) }
-                }
-            }
-
-            impl<'_x, '_y, '_z, $($typaram),*> SpecializedDecoder<&'_x ty::List<&'_y ty::TyS<'_z>>>
-            for $DecoderName<$($typaram),*>
-            where &'_x ty::List<&'_y ty::TyS<'_z>>: UseSpecializedDecodable {
-                fn specialized_decode(&mut self)
-                                      -> Result<&'_x ty::List<&'_y ty::TyS<'_z>>, Self::Error> {
-                    unsafe { transmute(decode_ty_slice(self)) }
-                }
-            }
-
-            impl<'_x, $($typaram),*> SpecializedDecoder<&'_x ty::AdtDef>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<&'_x ty::AdtDef, Self::Error> {
-                    unsafe { transmute(decode_adt_def(self)) }
-                }
-            }
-
-            impl<'_x, $($typaram),*> SpecializedDecoder<ty::SymbolName<'_x>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<ty::SymbolName<'_x>, Self::Error> {
-                    unsafe { transmute(decode_symbol_name(self)) }
-                }
-            }
-
-            impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x ty::List<ty::ExistentialPredicate<'_y>>>
-            for $DecoderName<$($typaram),*>
-            where &'_x ty::List<ty::ExistentialPredicate<'_y>>: UseSpecializedDecodable {
-                fn specialized_decode(&mut self)
-                    -> Result<&'_x ty::List<ty::ExistentialPredicate<'_y>>, Self::Error> {
-                        unsafe { transmute(decode_existential_predicate_slice(self)) }
-                }
-            }
-
-            impl<'_x, $($typaram),*> SpecializedDecoder<CanonicalVarInfos<'_x>>
-                for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self)
-                    -> Result<CanonicalVarInfos<'_x>, Self::Error> {
-                        unsafe { transmute(decode_canonical_var_infos(self)) }
-                }
-            }
-
-            impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x $crate::ty::Const<'_y>>
-            for $DecoderName<$($typaram),*>
-            where &'_x $crate::ty::Const<'_y>: UseSpecializedDecodable {
-                fn specialized_decode(&mut self) -> Result<&'_x ty::Const<'_y>, Self::Error> {
-                    unsafe { transmute(decode_const(self)) }
-                }
-            }
-
-            impl<'_x, $($typaram),*> SpecializedDecoder<&'_x $crate::mir::interpret::Allocation>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(
-                    &mut self
-                ) -> Result<&'_x $crate::mir::interpret::Allocation, Self::Error> {
-                    unsafe { transmute(decode_allocation(self)) }
-                }
-            }
         }
-    };
+    }
 }
index c0b5693dc594e0586498b13fa5e1a1eb4d2700cd..e883c7c6dcd2264de133ae179b31b93356fcb73a 100644 (file)
@@ -15,7 +15,7 @@
 pub use kind::*;
 
 /// Typed constant value.
-#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
+#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]
 #[derive(HashStable)]
 pub struct Const<'tcx> {
     pub ty: Ty<'tcx>,
index e8a1e714a8f43885a9a5c65d39525fe3722930e5..a4c177160f5d039b6b6baefb380e6cf2878e998a 100644 (file)
@@ -10,7 +10,7 @@
 use rustc_target::abi::Size;
 
 /// Represents a constant in Rust.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
 #[derive(HashStable)]
 pub enum ConstKind<'tcx> {
     /// A const generic parameter.
@@ -68,7 +68,7 @@ pub fn try_to_machine_usize(self, tcx: TyCtxt<'tcx>) -> Option<u64> {
 }
 
 /// An inference variable for a const, for use in const generics.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
 #[derive(HashStable)]
 pub enum InferConst<'tcx> {
     /// Infer the value of the const.
index d6bcfbf49cff12b2c67c7800d16231d9f637bc52..ba1f78e337a8311be74df8039b05996b6a3ba6f9 100644 (file)
@@ -263,7 +263,7 @@ pub fn remove(&mut self, id: hir::HirId) -> Option<V> {
 }
 
 /// All information necessary to validate and reveal an `impl Trait`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
 pub struct ResolvedOpaqueTy<'tcx> {
     /// The revealed type as seen by this function.
     pub concrete_type: Ty<'tcx>,
@@ -291,7 +291,7 @@ pub struct ResolvedOpaqueTy<'tcx> {
 ///
 /// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
 /// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
-#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
+#[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
 pub struct GeneratorInteriorTypeCause<'tcx> {
     /// Type of the captured binding.
     pub ty: Ty<'tcx>,
@@ -305,7 +305,7 @@ pub struct GeneratorInteriorTypeCause<'tcx> {
     pub expr: Option<hir::HirId>,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Debug)]
+#[derive(TyEncodable, TyDecodable, Debug)]
 pub struct TypeckResults<'tcx> {
     /// The `HirId::owner` all `ItemLocalId`s in this table are relative to.
     pub hir_owner: LocalDefId,
@@ -728,7 +728,7 @@ pub struct UserTypeAnnotationIndex {
 pub type CanonicalUserTypeAnnotations<'tcx> =
     IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
 pub struct CanonicalUserTypeAnnotation<'tcx> {
     pub user_ty: CanonicalUserType<'tcx>,
     pub span: Span,
@@ -787,7 +787,7 @@ pub fn is_identity(&self) -> bool {
 /// A user-given type annotation attached to a constant. These arise
 /// from constants that are named via paths, like `Foo::<A>::new` and
 /// so forth.
-#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable, Lift)]
 pub enum UserType<'tcx> {
     Ty(Ty<'tcx>),
@@ -1333,7 +1333,7 @@ pub fn allocate_metadata_dep_nodes(self) {
 
     pub fn serialize_query_result_cache<E>(self, encoder: &mut E) -> Result<(), E::Error>
     where
-        E: ty::codec::TyEncoder,
+        E: ty::codec::OpaqueEncoder,
     {
         self.queries.on_disk_cache.serialize(self, encoder)
     }
index b0fb179b18bdfbaecc242c11802e45c46843b99f..7456020ee9b679ff414c7c93c830672e4efcea83 100644 (file)
@@ -17,7 +17,7 @@
 /// because we sometimes need to use SimplifiedTypeGen values as stable sorting
 /// keys (in which case we use a DefPathHash as id-type) but in the general case
 /// the non-stable but fast to construct DefId-version is the better choice.
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
 pub enum SimplifiedTypeGen<D>
 where
     D: Copy + Debug + Ord + Eq,
index 2def000da648086d7acdaf216c7d9fcffd050c00..e6dafd4965bc9fb321568a1af6d9be3e738a7927 100644 (file)
 /// Monomorphization happens on-the-fly and no monomorphized MIR is ever created. Instead, this type
 /// simply couples a potentially generic `InstanceDef` with some substs, and codegen and const eval
 /// will do all required substitution as they run.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, Lift)]
 pub struct Instance<'tcx> {
     pub def: InstanceDef<'tcx>,
     pub substs: SubstsRef<'tcx>,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum InstanceDef<'tcx> {
     /// A user-defined callable item.
     ///
index 5aa94ba3d09fd0b46229b4396b08395f45047994..16e65d2cca4cbcfed06447c84d90c7dcc04053d0 100644 (file)
@@ -165,7 +165,7 @@ fn to_int_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
 /// - For a slice, this is the length.
 pub const FAT_PTR_EXTRA: usize = 1;
 
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable)]
 pub enum LayoutError<'tcx> {
     Unknown(Ty<'tcx>),
     SizeOverflow(Ty<'tcx>),
index 92d6dbb5f90f557fb59ab4d2959a193a0112572c..fe390adf89f9fe70c32c94338f69807f3f7821e3 100644 (file)
@@ -76,9 +76,16 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-impl<T: Encodable> Encodable for List<T> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for List<T> {
     #[inline]
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
+        (**self).encode(s)
+    }
+}
+
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for &List<T> {
+    #[inline]
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         (**self).encode(s)
     }
 }
index 6798addb8aaa3a0c35d653f9347356132be259b6..ff6f0d346f7dc71491bad33d3f0a8ceed9001e2a 100644 (file)
 
 pub use self::consts::{Const, ConstInt, ConstKind, InferConst};
 
+pub mod _match;
 pub mod adjustment;
 pub mod binding;
 pub mod cast;
-#[macro_use]
 pub mod codec;
-pub mod _match;
 mod erase_regions;
 pub mod error;
 pub mod fast_reject;
@@ -171,7 +170,7 @@ pub struct ImplHeader<'tcx> {
     pub predicates: Vec<Predicate<'tcx>>,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable)]
 pub enum ImplPolarity {
     /// `impl Trait for Type`
     Positive,
@@ -316,7 +315,7 @@ pub fn find_by_name_and_namespace(
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable, HashStable, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)]
 pub enum Visibility {
     /// Visible everywhere (including in other crates).
     Public,
@@ -403,7 +402,7 @@ pub fn is_visible_locally(self) -> bool {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, RustcDecodable, RustcEncodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, TyDecodable, TyEncodable, HashStable)]
 pub enum Variance {
     Covariant,     // T<A> <: T<B> iff A <: B -- e.g., function return type
     Invariant,     // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
@@ -652,13 +651,9 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
 #[rustc_diagnostic_item = "Ty"]
 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
 
-impl<'tcx> rustc_serialize::UseSpecializedEncodable for Ty<'tcx> {}
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for Ty<'tcx> {}
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<Ty<'tcx>> {}
-
 pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>;
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
 pub struct UpvarPath {
     pub hir_id: hir::HirId,
 }
@@ -666,13 +661,13 @@ pub struct UpvarPath {
 /// Upvars do not get their own `NodeId`. Instead, we use the pair of
 /// the original var ID (that is, the root variable that is referenced
 /// by the upvar) and the ID of the closure expression.
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
 pub struct UpvarId {
     pub var_path: UpvarPath,
     pub closure_expr_id: LocalDefId,
 }
 
-#[derive(Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, HashStable)]
+#[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, Copy, HashStable)]
 pub enum BorrowKind {
     /// Data must be immutable and is aliasable.
     ImmBorrow,
@@ -720,7 +715,7 @@ pub enum BorrowKind {
 
 /// Information describing the capture of an upvar. This is computed
 /// during `typeck`, specifically by `regionck`.
-#[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)]
 pub enum UpvarCapture<'tcx> {
     /// Upvar is captured by value. This is always true when the
     /// closure is labeled `move`, but can also be true in other cases
@@ -731,7 +726,7 @@ pub enum UpvarCapture<'tcx> {
     ByRef(UpvarBorrow<'tcx>),
 }
 
-#[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(PartialEq, Clone, Copy, TyEncodable, TyDecodable, HashStable)]
 pub struct UpvarBorrow<'tcx> {
     /// The kind of borrow: by-ref upvars have access to shared
     /// immutable borrows, which are not part of the normal language
@@ -766,7 +761,7 @@ pub fn has_name(&self) -> bool {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum GenericParamDefKind {
     Lifetime,
     Type {
@@ -787,7 +782,7 @@ pub fn descr(&self) -> &'static str {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct GenericParamDef {
     pub name: Symbol,
     pub def_id: DefId,
@@ -831,7 +826,7 @@ pub struct GenericParamCount {
 ///
 /// The ordering of parameters is the same as in `Subst` (excluding child generics):
 /// `Self` (optionally), `Lifetime` params..., `Type` params...
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct Generics {
     pub parent: Option<DefId>,
     pub parent_count: usize,
@@ -933,7 +928,7 @@ pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &Generi
 }
 
 /// Bounds on generics.
-#[derive(Copy, Clone, Default, Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct GenericPredicates<'tcx> {
     pub parent: Option<DefId>,
     pub predicates: &'tcx [(Predicate<'tcx>, Span)],
@@ -1025,9 +1020,6 @@ pub struct Predicate<'tcx> {
     inner: &'tcx PredicateInner<'tcx>,
 }
 
-impl rustc_serialize::UseSpecializedEncodable for Predicate<'_> {}
-impl rustc_serialize::UseSpecializedDecodable for Predicate<'_> {}
-
 impl<'tcx> PartialEq for Predicate<'tcx> {
     fn eq(&self, other: &Self) -> bool {
         // `self.kind` is always interned.
@@ -1103,7 +1095,7 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub enum PredicateKind<'tcx> {
     /// `for<'a>: ...`
@@ -1111,7 +1103,7 @@ pub enum PredicateKind<'tcx> {
     Atom(PredicateAtom<'tcx>),
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub enum PredicateAtom<'tcx> {
     /// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
@@ -1261,7 +1253,7 @@ pub fn subst_supertrait(
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub struct TraitPredicate<'tcx> {
     pub trait_ref: TraitRef<'tcx>,
@@ -1286,7 +1278,7 @@ pub fn def_id(self) -> DefId {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B`
 pub type PolyOutlivesPredicate<A, B> = ty::Binder<OutlivesPredicate<A, B>>;
@@ -1295,7 +1287,7 @@ pub fn def_id(self) -> DefId {
 pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<RegionOutlivesPredicate<'tcx>>;
 pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<TypeOutlivesPredicate<'tcx>>;
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub struct SubtypePredicate<'tcx> {
     pub a_is_expected: bool,
@@ -1316,7 +1308,7 @@ pub struct SubtypePredicate<'tcx> {
 /// equality between arbitrary types. Processing an instance of
 /// Form #2 eventually yields one of these `ProjectionPredicate`
 /// instances to normalize the LHS.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub struct ProjectionPredicate<'tcx> {
     pub projection_ty: ProjectionTy<'tcx>,
@@ -1585,7 +1577,7 @@ pub fn cannot_name(self, other: UniverseIndex) -> bool {
 /// basically a name -- distinct bound regions within the same
 /// universe are just two regions with an unknown relationship to one
 /// another.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)]
 pub struct Placeholder<T> {
     pub universe: UniverseIndex,
     pub name: T,
@@ -1635,7 +1627,7 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
 ///     a.foo::<7>();
 /// }
 /// ```
-#[derive(Copy, Clone, Debug, TypeFoldable, Lift, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, TypeFoldable, Lift, TyEncodable, TyDecodable)]
 #[derive(PartialEq, Eq, PartialOrd, Ord)]
 #[derive(Hash, HashStable)]
 pub struct WithOptConstParam<T> {
@@ -2106,7 +2098,7 @@ pub fn transparent_newtype_field(&self, tcx: TyCtxt<'tcx>) -> Option<&FieldDef>
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Encodable, Decodable, HashStable)]
 pub enum VariantDiscr {
     /// Explicit value for this variant, i.e., `X = 123`.
     /// The `DefId` corresponds to the embedded constant.
@@ -2178,14 +2170,12 @@ fn hash<H: Hasher>(&self, s: &mut H) {
     }
 }
 
-impl<'tcx> rustc_serialize::UseSpecializedEncodable for &'tcx AdtDef {
-    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for AdtDef {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         self.did.encode(s)
     }
 }
 
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx AdtDef {}
-
 impl<'a> HashStable<StableHashingContext<'a>> for AdtDef {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         thread_local! {
@@ -2229,7 +2219,7 @@ fn into(self) -> DataTypeKind {
 }
 
 bitflags! {
-    #[derive(RustcEncodable, RustcDecodable, Default, HashStable)]
+    #[derive(TyEncodable, TyDecodable, Default, HashStable)]
     pub struct ReprFlags: u8 {
         const IS_C               = 1 << 0;
         const IS_SIMD            = 1 << 1;
@@ -2246,7 +2236,7 @@ pub struct ReprFlags: u8 {
 }
 
 /// Represents the repr options provided by the user,
-#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Default, HashStable)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Default, HashStable)]
 pub struct ReprOptions {
     pub int: Option<attr::IntType>,
     pub align: Option<Align>,
@@ -2690,7 +2680,7 @@ pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
 ///
 /// You can get the environment type of a closure using
 /// `tcx.closure_env_ty()`.
-#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub enum ClosureKind {
     // Warning: Ordering is significant here! The ordering is chosen
@@ -3141,7 +3131,7 @@ pub struct CrateInherentImpls {
     pub inherent_impls: DefIdMap<Vec<DefId>>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
 pub struct SymbolName<'tcx> {
     /// `&str` gives a consistent ordering, which ensures reproducible builds.
     pub name: &'tcx str,
@@ -3166,12 +3156,3 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(&self.name, fmt)
     }
 }
-
-impl<'tcx> rustc_serialize::UseSpecializedEncodable for SymbolName<'tcx> {
-    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(self.name)
-    }
-}
-
-// The decoding takes place in `decode_symbol_name()`.
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for SymbolName<'tcx> {}
index 08b0bfecf49099ec0642a466c1e3d4c80fdc8dec..007b46b11769413aeb924d68f9404ca52c2b7c9e 100644 (file)
@@ -1,28 +1,24 @@
 use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
-use crate::mir::interpret;
 use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState};
-use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
+use crate::mir::{self, interpret};
+use crate::ty::codec::{OpaqueEncoder, RefDecodable, TyDecoder, TyEncoder};
 use crate::ty::context::TyCtxt;
 use crate::ty::{self, Ty};
-use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
+use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder, FingerprintEncoder};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell};
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_errors::Diagnostic;
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathHash;
 use rustc_index::vec::{Idx, IndexVec};
-use rustc_serialize::{
-    opaque, Decodable, Decoder, Encodable, Encoder, SpecializedDecoder, SpecializedEncoder,
-    UseSpecializedDecodable, UseSpecializedEncodable,
-};
+use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
 use rustc_session::{CrateDisambiguator, Session};
 use rustc_span::hygiene::{
     ExpnDataDecodeMode, ExpnDataEncodeMode, ExpnId, HygieneDecodeContext, HygieneEncodeContext,
     SyntaxContext, SyntaxContextData,
 };
 use rustc_span::source_map::{SourceMap, StableSourceFileId};
-use rustc_span::symbol::Ident;
 use rustc_span::CachingSourceMapView;
 use rustc_span::{BytePos, ExpnData, SourceFile, Span, DUMMY_SP};
 use std::mem;
@@ -87,7 +83,7 @@ pub struct OnDiskCache<'sess> {
 }
 
 // This type is used only for serialization and deserialization.
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(Encodable, Decodable)]
 struct Footer {
     file_index_to_stable_id: FxHashMap<SourceFileIndex, StableSourceFileId>,
     prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
@@ -105,10 +101,10 @@ struct Footer {
 type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
 type EncodedDiagnostics = Vec<Diagnostic>;
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable)]
 struct SourceFileIndex(u32);
 
-#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Encodable, Decodable)]
 struct AbsoluteBytePos(u32);
 
 impl AbsoluteBytePos {
@@ -182,7 +178,7 @@ pub fn new_empty(source_map: &'sess SourceMap) -> Self {
 
     pub fn serialize<'tcx, E>(&self, tcx: TyCtxt<'tcx>, encoder: &mut E) -> Result<(), E::Error>
     where
-        E: TyEncoder,
+        E: OpaqueEncoder,
     {
         // Serializing the `DepGraph` should not modify it.
         tcx.dep_graph.with_ignore(|| {
@@ -333,7 +329,7 @@ macro_rules! encode_queries {
 
             // Encode the position of the footer as the last 8 bytes of the
             // file so we know where to look for it.
-            IntEncodedWithFixedSize(footer_pos).encode(encoder.encoder)?;
+            IntEncodedWithFixedSize(footer_pos).encode(encoder.encoder.opaque())?;
 
             // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
             // of the footer must be the last thing in the data stream.
@@ -380,13 +376,13 @@ pub fn store_diagnostics(
 
     /// Returns the cached query result if there is something in the cache for
     /// the given `SerializedDepNodeIndex`; otherwise returns `None`.
-    pub fn try_load_query_result<T>(
+    crate fn try_load_query_result<'tcx, T>(
         &self,
-        tcx: TyCtxt<'_>,
+        tcx: TyCtxt<'tcx>,
         dep_node_index: SerializedDepNodeIndex,
     ) -> Option<T>
     where
-        T: Decodable,
+        T: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
     {
         self.load_indexed(tcx, dep_node_index, &self.query_result_index, "query result")
     }
@@ -417,7 +413,7 @@ fn load_indexed<'tcx, T>(
         debug_tag: &'static str,
     ) -> Option<T>
     where
-        T: Decodable,
+        T: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
     {
         let pos = index.get(&dep_node_index).cloned()?;
 
@@ -427,14 +423,14 @@ fn load_indexed<'tcx, T>(
         })
     }
 
-    fn with_decoder<'tcx, T, F: FnOnce(&mut CacheDecoder<'sess, 'tcx>) -> T>(
+    fn with_decoder<'a, 'tcx, T, F: FnOnce(&mut CacheDecoder<'sess, 'tcx>) -> T>(
         &'sess self,
         tcx: TyCtxt<'tcx>,
         pos: AbsoluteBytePos,
         f: F,
     ) -> T
     where
-        T: Decodable,
+        T: Decodable<CacheDecoder<'a, 'tcx>>,
     {
         let cnum_map =
             self.cnum_map.get_or_init(|| Self::compute_cnum_map(tcx, &self.prev_cnums[..]));
@@ -492,7 +488,7 @@ fn compute_cnum_map(
 /// A decoder that can read from the incr. comp. cache. It is similar to the one
 /// we use for crate metadata decoding in that it can rebase spans and eventually
 /// will also handle things that contain `Ty` instances.
-struct CacheDecoder<'a, 'tcx> {
+crate struct CacheDecoder<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     opaque: opaque::Decoder<'a>,
     source_map: &'a SourceMap,
@@ -547,8 +543,8 @@ fn position(&self) -> usize {
 // tag matches and the correct amount of bytes was read.
 fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> Result<V, D::Error>
 where
-    T: Decodable + Eq + ::std::fmt::Debug,
-    V: Decodable,
+    T: Decodable<D> + Eq + ::std::fmt::Debug,
+    V: Decodable<D>,
     D: DecoderWithPosition,
 {
     let start_pos = decoder.position();
@@ -565,6 +561,8 @@ fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> Result<V, D::Erro
 }
 
 impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
+    const CLEAR_CROSS_CRATE: bool = false;
+
     #[inline]
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
@@ -642,14 +640,19 @@ fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
     fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
         self.cnum_map[cnum].unwrap_or_else(|| bug!("could not find new `CrateNum` for {:?}", cnum))
     }
+
+    fn decode_alloc_id(&mut self) -> Result<interpret::AllocId, Self::Error> {
+        let alloc_decoding_session = self.alloc_decoding_session;
+        alloc_decoding_session.decode_alloc_id(self)
+    }
 }
 
-implement_ty_decoder!(CacheDecoder<'a, 'tcx>);
+crate::implement_ty_decoder!(CacheDecoder<'a, 'tcx>);
 
-impl<'a, 'tcx> SpecializedDecoder<SyntaxContext> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<SyntaxContext, Self::Error> {
-        let syntax_contexts = self.syntax_contexts;
-        rustc_span::hygiene::decode_syntax_context(self, self.hygiene_context, |this, id| {
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
+    fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        let syntax_contexts = decoder.syntax_contexts;
+        rustc_span::hygiene::decode_syntax_context(decoder, decoder.hygiene_context, |this, id| {
             // 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();
@@ -661,12 +664,12 @@ fn specialized_decode(&mut self) -> Result<SyntaxContext, Self::Error> {
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<ExpnId> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<ExpnId, Self::Error> {
-        let expn_data = self.expn_data;
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
+    fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        let expn_data = decoder.expn_data;
         rustc_span::hygiene::decode_expn_id(
-            self,
-            ExpnDataDecodeMode::incr_comp(self.hygiene_context),
+            decoder,
+            ExpnDataDecodeMode::incr_comp(decoder.hygiene_context),
             |this, index| {
                 // This closure is invoked if we haven't already decoded the data for the `ExpnId` we are deserializing.
                 // We look up the position of the associated `ExpnData` and decode it.
@@ -683,16 +686,9 @@ fn specialized_decode(&mut self) -> Result<ExpnId, Self::Error> {
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<interpret::AllocId> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
-        let alloc_decoding_session = self.alloc_decoding_session;
-        alloc_decoding_session.decode_alloc_id(self)
-    }
-}
-
-impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
-        let tag: u8 = Decodable::decode(self)?;
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
+    fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        let tag: u8 = Decodable::decode(decoder)?;
 
         if tag == TAG_INVALID_SPAN {
             return Ok(DUMMY_SP);
@@ -700,13 +696,13 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
             debug_assert_eq!(tag, TAG_VALID_SPAN);
         }
 
-        let file_lo_index = SourceFileIndex::decode(self)?;
-        let line_lo = usize::decode(self)?;
-        let col_lo = BytePos::decode(self)?;
-        let len = BytePos::decode(self)?;
-        let ctxt = SyntaxContext::decode(self)?;
+        let file_lo_index = SourceFileIndex::decode(decoder)?;
+        let line_lo = usize::decode(decoder)?;
+        let col_lo = BytePos::decode(decoder)?;
+        let len = BytePos::decode(decoder)?;
+        let ctxt = SyntaxContext::decode(decoder)?;
 
-        let file_lo = self.file_index_to_file(file_lo_index);
+        let file_lo = decoder.file_index_to_file(file_lo_index);
         let lo = file_lo.lines[line_lo - 1] + col_lo;
         let hi = lo + len;
 
@@ -714,10 +710,10 @@ fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<Ident> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
-        // FIXME: Handle hygiene in incremental
-        bug!("Trying to decode Ident for incremental");
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        let cnum = CrateNum::from_u32(u32::decode(d)?);
+        Ok(d.map_encoded_cnum_to_current(cnum))
     }
 }
 
@@ -725,43 +721,69 @@ fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
 // `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
 // context.
-impl<'a, 'tcx> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
-        bug!("trying to decode `DefIndex` outside the context of a `DefId`")
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefIndex {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<DefIndex, String> {
+        Err(d.error("trying to decode `DefIndex` outside the context of a `DefId`"))
     }
 }
 
 // Both the `CrateNum` and the `DefIndex` of a `DefId` can change in between two
 // compilation sessions. We use the `DefPathHash`, which is stable across
 // sessions, to map the old `DefId` to the new one.
-impl<'a, 'tcx> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefId {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
         // Load the `DefPathHash` which is was we encoded the `DefId` as.
-        let def_path_hash = DefPathHash::decode(self)?;
+        let def_path_hash = DefPathHash::decode(d)?;
 
         // Using the `DefPathHash`, we can lookup the new `DefId`.
-        Ok(self.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash])
+        Ok(d.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash])
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<LocalDefId> for CacheDecoder<'a, 'tcx> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<LocalDefId, Self::Error> {
-        Ok(DefId::decode(self)?.expect_local())
+impl<'a, 'tcx> FingerprintDecoder for CacheDecoder<'a, 'tcx> {
+    fn decode_fingerprint(&mut self) -> Result<Fingerprint, Self::Error> {
+        Fingerprint::decode_opaque(&mut self.opaque)
     }
 }
 
-impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
-        Fingerprint::decode_opaque(&mut self.opaque)
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId> {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        RefDecodable::decode(d)
+    }
+}
+
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
+    for &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>>
+{
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        RefDecodable::decode(d)
+    }
+}
+
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        RefDecodable::decode(d)
+    }
+}
+
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
+    for &'tcx [rustc_ast::ast::InlineAsmTemplatePiece]
+{
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        RefDecodable::decode(d)
+    }
+}
+
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [Span] {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        RefDecodable::decode(d)
     }
 }
 
 //- ENCODING -------------------------------------------------------------------
 
 /// An encoder that can write the incr. comp. cache.
-struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> {
+struct CacheEncoder<'a, 'tcx, E: OpaqueEncoder> {
     tcx: TyCtxt<'tcx>,
     encoder: &'a mut E,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
@@ -774,7 +796,7 @@ struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> {
 
 impl<'a, 'tcx, E> CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + TyEncoder,
+    E: 'a + OpaqueEncoder,
 {
     fn source_file_index(&mut self, source_file: Lrc<SourceFile>) -> SourceFileIndex {
         self.file_to_file_index[&(&*source_file as *const SourceFile)]
@@ -785,7 +807,7 @@ fn source_file_index(&mut self, source_file: Lrc<SourceFile>) -> SourceFileIndex
     /// 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.
-    fn encode_tagged<T: Encodable, V: Encodable>(
+    fn encode_tagged<T: Encodable<Self>, V: Encodable<Self>>(
         &mut self,
         tag: T,
         value: &V,
@@ -800,170 +822,111 @@ fn encode_tagged<T: Encodable, V: Encodable>(
     }
 }
 
-impl<'a, 'tcx, E> SpecializedEncoder<interpret::AllocId> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
-        let (index, _) = self.interpret_allocs.insert_full(*alloc_id);
-        index.encode(self)
+impl<'a, 'tcx> FingerprintEncoder for CacheEncoder<'a, 'tcx, rustc_serialize::opaque::Encoder> {
+    fn encode_fingerprint(&mut self, f: &Fingerprint) -> opaque::EncodeResult {
+        f.encode_opaque(self.encoder)
     }
 }
 
-impl<'a, 'tcx, E> SpecializedEncoder<SyntaxContext> for CacheEncoder<'a, 'tcx, E>
+impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for SyntaxContext
 where
-    E: 'a + TyEncoder,
+    E: 'a + OpaqueEncoder,
 {
-    fn specialized_encode(&mut self, ctxt: &SyntaxContext) -> Result<(), Self::Error> {
-        rustc_span::hygiene::raw_encode_syntax_context(*ctxt, self.hygiene_context, self)
+    fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
+        rustc_span::hygiene::raw_encode_syntax_context(*self, s.hygiene_context, s)
     }
 }
 
-impl<'a, 'tcx, E> SpecializedEncoder<ExpnId> for CacheEncoder<'a, 'tcx, E>
+impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for ExpnId
 where
-    E: 'a + TyEncoder,
+    E: 'a + OpaqueEncoder,
 {
-    fn specialized_encode(&mut self, expn: &ExpnId) -> Result<(), Self::Error> {
+    fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
         rustc_span::hygiene::raw_encode_expn_id(
-            *expn,
-            self.hygiene_context,
+            *self,
+            s.hygiene_context,
             ExpnDataEncodeMode::IncrComp,
-            self,
+            s,
         )
     }
 }
 
-impl<'a, 'tcx, E> SpecializedEncoder<Span> for CacheEncoder<'a, 'tcx, E>
+impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for Span
 where
-    E: 'a + TyEncoder,
+    E: 'a + OpaqueEncoder,
 {
-    fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
-        if *span == DUMMY_SP {
-            return TAG_INVALID_SPAN.encode(self);
+    fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
+        if *self == DUMMY_SP {
+            return TAG_INVALID_SPAN.encode(s);
         }
 
-        let span_data = span.data();
-        let (file_lo, line_lo, col_lo) =
-            match self.source_map.byte_pos_to_line_and_col(span_data.lo) {
-                Some(pos) => pos,
-                None => return TAG_INVALID_SPAN.encode(self),
-            };
+        let span_data = self.data();
+        let (file_lo, line_lo, col_lo) = match s.source_map.byte_pos_to_line_and_col(span_data.lo) {
+            Some(pos) => pos,
+            None => return TAG_INVALID_SPAN.encode(s),
+        };
 
         if !file_lo.contains(span_data.hi) {
-            return TAG_INVALID_SPAN.encode(self);
+            return TAG_INVALID_SPAN.encode(s);
         }
 
         let len = span_data.hi - span_data.lo;
 
-        let source_file_index = self.source_file_index(file_lo);
+        let source_file_index = s.source_file_index(file_lo);
 
-        TAG_VALID_SPAN.encode(self)?;
-        source_file_index.encode(self)?;
-        line_lo.encode(self)?;
-        col_lo.encode(self)?;
-        len.encode(self)?;
-        span_data.ctxt.encode(self)?;
-        Ok(())
+        TAG_VALID_SPAN.encode(s)?;
+        source_file_index.encode(s)?;
+        line_lo.encode(s)?;
+        col_lo.encode(s)?;
+        len.encode(s)?;
+        span_data.ctxt.encode(s)
     }
 }
 
-impl<'a, 'tcx, E> SpecializedEncoder<Ident> for CacheEncoder<'a, 'tcx, E>
+impl<'a, 'tcx, E> TyEncoder<'tcx> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + OpaqueEncoder,
 {
-    fn specialized_encode(&mut self, _: &Ident) -> Result<(), Self::Error> {
-        // We don't currently encode enough information to ensure hygiene works
-        // with incremental, so panic rather than risk incremental bugs.
+    const CLEAR_CROSS_CRATE: bool = false;
 
-        // FIXME: handle hygiene in incremental.
-        bug!("trying to encode `Ident` for incremental");
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.tcx
     }
-}
-
-impl<'a, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
     fn position(&self) -> usize {
-        self.encoder.position()
+        self.encoder.encoder_position()
     }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<CrateNum> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn specialized_encode(&mut self, cnum: &CrateNum) -> Result<(), Self::Error> {
-        self.emit_u32(cnum.as_u32())
+    fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize> {
+        &mut self.type_shorthands
     }
-}
-
-impl<'a, 'b, 'c, 'tcx, E> SpecializedEncoder<&'b ty::TyS<'c>> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-    &'b ty::TyS<'c>: UseSpecializedEncodable,
-{
-    #[inline]
-    fn specialized_encode(&mut self, ty: &&'b ty::TyS<'c>) -> Result<(), Self::Error> {
-        debug_assert!(self.tcx.lift(ty).is_some());
-        let ty = unsafe { std::mem::transmute::<&&'b ty::TyS<'c>, &&'tcx ty::TyS<'tcx>>(ty) };
-        ty_codec::encode_with_shorthand(self, ty, |encoder| &mut encoder.type_shorthands)
-    }
-}
-
-impl<'a, 'b, 'tcx, E> SpecializedEncoder<ty::Predicate<'b>> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn specialized_encode(&mut self, predicate: &ty::Predicate<'b>) -> Result<(), Self::Error> {
-        debug_assert!(self.tcx.lift(predicate).is_some());
-        let predicate =
-            unsafe { std::mem::transmute::<&ty::Predicate<'b>, &ty::Predicate<'tcx>>(predicate) };
-        ty_codec::encode_with_shorthand(self, predicate, |encoder| {
-            &mut encoder.predicate_shorthands
-        })
+    fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::Predicate<'tcx>, usize> {
+        &mut self.predicate_shorthands
     }
-}
+    fn encode_alloc_id(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
+        let (index, _) = self.interpret_allocs.insert_full(*alloc_id);
 
-impl<'a, 'tcx, E> SpecializedEncoder<DefId> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn specialized_encode(&mut self, id: &DefId) -> Result<(), Self::Error> {
-        let def_path_hash = self.tcx.def_path_hash(*id);
-        def_path_hash.encode(self)
+        index.encode(self)
     }
 }
 
-impl<'a, 'tcx, E> SpecializedEncoder<LocalDefId> for CacheEncoder<'a, 'tcx, E>
+impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for DefId
 where
-    E: 'a + TyEncoder,
+    E: 'a + OpaqueEncoder,
 {
-    #[inline]
-    fn specialized_encode(&mut self, id: &LocalDefId) -> Result<(), Self::Error> {
-        id.to_def_id().encode(self)
+    fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
+        let def_path_hash = s.tcx.def_path_hash(*self);
+        def_path_hash.encode(s)
     }
 }
 
-impl<'a, 'tcx, E> SpecializedEncoder<DefIndex> for CacheEncoder<'a, 'tcx, E>
+impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for DefIndex
 where
-    E: 'a + TyEncoder,
+    E: 'a + OpaqueEncoder,
 {
-    fn specialized_encode(&mut self, _: &DefIndex) -> Result<(), Self::Error> {
+    fn encode(&self, _: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
         bug!("encoding `DefIndex` without context");
     }
 }
 
-impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for CacheEncoder<'a, 'tcx, opaque::Encoder> {
-    fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
-        f.encode_opaque(&mut self.encoder)
-    }
-}
-
 macro_rules! encoder_methods {
     ($($name:ident($ty:ty);)*) => {
         #[inline]
@@ -975,7 +938,7 @@ macro_rules! encoder_methods {
 
 impl<'a, 'tcx, E> Encoder for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + TyEncoder,
+    E: 'a + OpaqueEncoder,
 {
     type Error = E::Error;
 
@@ -1014,32 +977,29 @@ impl IntEncodedWithFixedSize {
     pub const ENCODED_SIZE: usize = 8;
 }
 
-impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
-impl UseSpecializedDecodable for IntEncodedWithFixedSize {}
-
-impl SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder {
-    fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
-        let start_pos = self.position();
+impl Encodable<opaque::Encoder> for IntEncodedWithFixedSize {
+    fn encode(&self, e: &mut opaque::Encoder) -> Result<(), !> {
+        let start_pos = e.position();
         for i in 0..IntEncodedWithFixedSize::ENCODED_SIZE {
-            ((x.0 >> (i * 8)) as u8).encode(self)?;
+            ((self.0 >> (i * 8)) as u8).encode(e)?;
         }
-        let end_pos = self.position();
+        let end_pos = e.position();
         assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
         Ok(())
     }
 }
 
-impl<'a> SpecializedDecoder<IntEncodedWithFixedSize> for opaque::Decoder<'a> {
-    fn specialized_decode(&mut self) -> Result<IntEncodedWithFixedSize, Self::Error> {
+impl<'a> Decodable<opaque::Decoder<'a>> for IntEncodedWithFixedSize {
+    fn decode(decoder: &mut opaque::Decoder<'a>) -> Result<IntEncodedWithFixedSize, String> {
         let mut value: u64 = 0;
-        let start_pos = self.position();
+        let start_pos = decoder.position();
 
         for i in 0..IntEncodedWithFixedSize::ENCODED_SIZE {
-            let byte: u8 = Decodable::decode(self)?;
+            let byte: u8 = Decodable::decode(decoder)?;
             value |= (byte as u64) << (i * 8);
         }
 
-        let end_pos = self.position();
+        let end_pos = decoder.position();
         assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
 
         Ok(IntEncodedWithFixedSize(value))
@@ -1053,8 +1013,8 @@ fn encode_query_results<'a, 'tcx, Q, E>(
 ) -> Result<(), E::Error>
 where
     Q: super::QueryDescription<TyCtxt<'tcx>> + super::QueryAccessors<TyCtxt<'tcx>>,
-    Q::Value: Encodable,
-    E: 'a + TyEncoder,
+    Q::Value: Encodable<CacheEncoder<'a, 'tcx, E>>,
+    E: 'a + OpaqueEncoder,
 {
     let _timer = tcx
         .sess
@@ -1066,15 +1026,16 @@ fn encode_query_results<'a, 'tcx, Q, E>(
 
     state.iter_results(|results| {
         for (key, value, dep_node) in results {
-            if Q::cache_on_disk(tcx, &key, Some(&value)) {
+            if Q::cache_on_disk(tcx, &key, Some(value)) {
                 let dep_node = SerializedDepNodeIndex::new(dep_node.index());
 
                 // Record position of the cache entry.
-                query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position())));
+                query_result_index
+                    .push((dep_node, AbsoluteBytePos::new(encoder.encoder.opaque().position())));
 
                 // Encode the type check tables with the `SerializedDepNodeIndex`
                 // as tag.
-                encoder.encode_tagged(dep_node, &value)?;
+                encoder.encode_tagged(dep_node, value)?;
             }
         }
         Ok(())
index 310ab4f7235ebf8e57fc4d5b8603619b62e6c81a..dc979e52c5761fd1123a7b122544696dea6f2a7f 100644 (file)
 use std::ops::Range;
 use ty::util::IntTypeExt;
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable, Lift)]
 pub struct TypeAndMut<'tcx> {
     pub ty: Ty<'tcx>,
     pub mutbl: hir::Mutability,
 }
 
-#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
 #[derive(HashStable)]
 /// A "free" region `fr` can be interpreted as "some region
 /// at least as big as the scope `fr.scope`".
@@ -43,7 +43,7 @@ pub struct FreeRegion {
     pub bound_region: BoundRegion,
 }
 
-#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
 #[derive(HashStable)]
 pub enum BoundRegion {
     /// An anonymous region parameter for a given fn (&T)
@@ -82,7 +82,7 @@ pub fn assert_bound_var(&self) -> BoundVar {
 
 /// N.B., if you change this, you'll probably want to change the corresponding
 /// AST structure in `librustc_ast/ast.rs` as well.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable, Debug)]
 #[derive(HashStable)]
 #[rustc_diagnostic_item = "TyKind"]
 pub enum TyKind<'tcx> {
@@ -215,7 +215,7 @@ pub fn is_primitive(&self) -> bool {
 /// A type that is not publicly constructable. This prevents people from making `TyKind::Error`
 /// except through `tcx.err*()`.
 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Encodable, Decodable, HashStable)]
 pub struct DelaySpanBugEmitted(pub(super) ());
 
 // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -622,7 +622,7 @@ pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
     }
 }
 
-#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub enum ExistentialPredicate<'tcx> {
     /// E.g., `Iterator`.
@@ -673,8 +673,6 @@ pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicat
     }
 }
 
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}
-
 impl<'tcx> List<ExistentialPredicate<'tcx>> {
     /// Returns the "principal `DefId`" of this set of existential predicates.
     ///
@@ -770,7 +768,7 @@ pub fn iter<'a>(
 ///
 /// Trait references also appear in object types like `Foo<U>`, but in
 /// that case the `Self` parameter is absent from the substitutions.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub struct TraitRef<'tcx> {
     pub def_id: DefId,
@@ -828,7 +826,7 @@ pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
 ///
 /// The substitutions don't include the erased `Self`, only trait
 /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub struct ExistentialTraitRef<'tcx> {
     pub def_id: DefId,
@@ -884,7 +882,7 @@ pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTrai
 /// erase, or otherwise "discharge" these bound vars, we change the
 /// type from `Binder<T>` to just `T` (see
 /// e.g., `liberate_late_bound_regions`).
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 pub struct Binder<T>(T);
 
 impl<T> Binder<T> {
@@ -1016,7 +1014,7 @@ pub fn transpose(self) -> Option<Binder<T>> {
 
 /// Represents the projection of an associated type. In explicit UFCS
 /// form this would be written `<T as Trait<..>>::N`.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub struct ProjectionTy<'tcx> {
     /// The parameters of the associated item.
@@ -1086,7 +1084,7 @@ pub fn return_ty(&self) -> ty::Binder<Ty<'tcx>> {
 /// - `inputs`: is the list of arguments and their modes.
 /// - `output`: is the return type.
 /// - `c_variadic`: indicates whether this is a C-variadic function.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub struct FnSig<'tcx> {
     pub inputs_and_output: &'tcx List<Ty<'tcx>>,
@@ -1147,7 +1145,7 @@ pub fn abi(&self) -> abi::Abi {
 
 pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub struct ParamTy {
     pub index: u32,
@@ -1172,7 +1170,7 @@ pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
+#[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]
 #[derive(HashStable)]
 pub struct ParamConst {
     pub index: u32,
@@ -1345,7 +1343,7 @@ pub struct DebruijnIndex {
 /// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
 /// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
-#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
+#[derive(Clone, PartialEq, Eq, Hash, Copy, TyEncodable, TyDecodable, PartialOrd, Ord)]
 pub enum RegionKind {
     /// Region bound in a type or fn declaration which will be
     /// substituted 'early' -- that is, at the same time when type
@@ -1383,32 +1381,30 @@ pub enum RegionKind {
     ReErased,
 }
 
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for Region<'tcx> {}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, PartialOrd, Ord)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)]
 pub struct EarlyBoundRegion {
     pub def_id: DefId,
     pub index: u32,
     pub name: Symbol,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 pub struct TyVid {
     pub index: u32,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 pub struct ConstVid<'tcx> {
     pub index: u32,
     pub phantom: PhantomData<&'tcx ()>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 pub struct IntVid {
     pub index: u32,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 pub struct FloatVid {
     pub index: u32,
 }
@@ -1425,7 +1421,7 @@ fn index(self) -> usize {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub enum InferTy {
     TyVar(TyVid),
@@ -1444,14 +1440,14 @@ pub enum InferTy {
     pub struct BoundVar { .. }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub struct BoundTy {
     pub var: BoundVar,
     pub kind: BoundTyKind,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub enum BoundTyKind {
     Anon,
@@ -1465,7 +1461,7 @@ fn from(var: BoundVar) -> Self {
 }
 
 /// A `ProjectionPredicate` for an `ExistentialTraitRef`.
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub struct ExistentialProjection<'tcx> {
     pub item_def_id: DefId,
index 866b529f35ec381d4e751e0d835942b167ba859a..acd58ab7f967a6e60af7917aa41c272db3b4c55c 100644 (file)
@@ -1,13 +1,14 @@
 // Type substitutions.
 
 use crate::infer::canonical::Canonical;
+use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use crate::ty::sty::{ClosureSubsts, GeneratorSubsts};
 use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
 
 use rustc_hir::def_id::DefId;
 use rustc_macros::HashStable;
-use rustc_serialize::{self, Decodable, Decoder, Encodable, Encoder};
+use rustc_serialize::{self, Decodable, Encodable};
 use rustc_span::{Span, DUMMY_SP};
 use smallvec::SmallVec;
 
@@ -34,7 +35,7 @@ pub struct GenericArg<'tcx> {
 const REGION_TAG: usize = 0b01;
 const CONST_TAG: usize = 0b10;
 
-#[derive(Debug, RustcEncodable, RustcDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)]
+#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)]
 pub enum GenericArgKind<'tcx> {
     Lifetime(ty::Region<'tcx>),
     Type(Ty<'tcx>),
@@ -168,14 +169,14 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
-impl<'tcx> Encodable for GenericArg<'tcx> {
-    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
+impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for GenericArg<'tcx> {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         self.unpack().encode(e)
     }
 }
 
-impl<'tcx> Decodable for GenericArg<'tcx> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<GenericArg<'tcx>, D::Error> {
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for GenericArg<'tcx> {
+    fn decode(d: &mut D) -> Result<GenericArg<'tcx>, D::Error> {
         Ok(GenericArgKind::decode(d)?.pack())
     }
 }
@@ -396,8 +397,6 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for SubstsRef<'tcx> {}
-
 ///////////////////////////////////////////////////////////////////////////
 // Public trait `Subst`
 //
@@ -653,7 +652,7 @@ fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'
 
 /// Stores the user-given substs to reach some fully qualified path
 /// (e.g., `<T>::Item` or `<T as Trait>::Item`).
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable, Lift)]
 pub struct UserSubsts<'tcx> {
     /// The substitutions for the item as given by the user.
@@ -680,7 +679,7 @@ pub struct UserSubsts<'tcx> {
 /// the impl (with the substs from `UserSubsts`) and apply those to
 /// the self type, giving `Foo<?A>`. Finally, we unify that with
 /// the self type here, which contains `?A` to be `&'static u32`
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable, Lift)]
 pub struct UserSelfTy<'tcx> {
     pub impl_def_id: DefId,
index f93cce3f4da7f1b1f786f3d883a3a94fb2f12526..86fe3ac3751aff2247a57155a3eb50bf8003d181 100644 (file)
@@ -47,7 +47,7 @@ pub struct TraitDef {
 
 /// Whether this trait is treated specially by the standard library
 /// specialization lint.
-#[derive(HashStable, PartialEq, Clone, Copy, RustcEncodable, RustcDecodable)]
+#[derive(HashStable, PartialEq, Clone, Copy, TyEncodable, TyDecodable)]
 pub enum TraitSpecializationKind {
     /// The default. Specializing on this trait is not allowed.
     None,
index 07221082048fbc3603a8995e98d7f670e3e374e1..23507ac830d553c48a31e34a54896968753b7059 100644 (file)
@@ -1143,7 +1143,7 @@ pub fn needs_drop_components(
     }
 }
 
-#[derive(Copy, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)]
 pub struct AlwaysRequiresDrop;
 
 /// Normalizes all opaque types in the given value, replacing them
index 64af9c5f1a15244a1c9b74704e552973a5f0235a..c1ec452e001bb3a84c0575ed3f4ae7177f0c2525 100644 (file)
@@ -15,6 +15,7 @@ log = { package = "tracing", version = "0.1" }
 rustc-rayon-core = "0.3.0"
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_index = { path = "../librustc_index" }
 rustc_serialize = { path = "../librustc_serialize" }
 rustc_span = { path = "../librustc_span" }
index 002b0f9c165dde4f3a967699dc1d72a659dc4773..e302784cc3e5fb5f78820d90b70ca436b0e700a1 100644 (file)
@@ -50,7 +50,7 @@
 use std::fmt;
 use std::hash::Hash;
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
 pub struct DepNode<K> {
     pub kind: K,
     pub hash: Fingerprint,
@@ -152,7 +152,8 @@ fn to_fingerprint(&self, _: Ctxt) -> Fingerprint {
 /// some independent path or string that persists between runs without
 /// the need to be mapped or unmapped. (This ensures we can serialize
 /// them even in the absence of a tcx.)
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Encodable, Decodable)]
 pub struct WorkProductId {
     hash: Fingerprint,
 }
index 04a45090b722675d179f32c4edb4d5282449fc26..d70306b4869218d9ecce39f793ad8e3dbeecd5a4 100644 (file)
@@ -857,7 +857,7 @@ fn next_virtual_depnode_index(&self) -> DepNodeIndex {
 /// may be added -- for example, new monomorphizations -- even if
 /// nothing in P changed!). We will compare that hash against the
 /// previous hash. If it matches up, we can reuse the object file.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Encodable, Decodable)]
 pub struct WorkProduct {
     pub cgu_name: String,
     /// Saved file associated with this CGU.
index 5cba64cac4b3449eb26eddc6c053c460444f6aea..29357ce9449ce26f48df11c3ac0c12c743efa0a2 100644 (file)
@@ -3,7 +3,7 @@
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
 
-#[derive(Debug, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Encodable, Decodable)]
 pub struct PreviousDepGraph<K: DepKind> {
     data: SerializedDepGraph<K>,
     index: FxHashMap<DepNode<K>, SerializedDepNodeIndex>,
index 4a89da23ea6a59239ff9a99834d9bc029e51d2bf..932c6d2a2f184260434bf38989fa5d9626f88dff 100644 (file)
@@ -9,7 +9,7 @@ pub struct SerializedDepNodeIndex { .. }
 }
 
 /// Data for use when recompiling the **current crate**.
-#[derive(Debug, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Encodable, Decodable)]
 pub struct SerializedDepGraph<K: DepKind> {
     /// The set of all DepNodes in the graph
     pub nodes: IndexVec<SerializedDepNodeIndex, DepNode<K>>,
index 4bbba7befe93f00363e03a8b458cca79f19f6e0d..db104398f16efa6bf00deb39e0dc8d1b45782752 100644 (file)
@@ -10,6 +10,8 @@
 extern crate log;
 #[macro_use]
 extern crate rustc_data_structures;
+#[macro_use]
+extern crate rustc_macros;
 
 pub mod cache;
 pub mod dep_graph;
index 49b8094abd0eb5d64f7c491d1c292c0498a23cb1..3d274cb01507b004bcde7191709a66c6c6bb4ed4 100644 (file)
@@ -9,8 +9,8 @@
 
 use smallvec::{Array, SmallVec};
 
-impl<A: Array<Item: Encodable>> Encodable for SmallVec<A> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, A: Array<Item: Encodable<S>>> Encodable<S> for SmallVec<A> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?;
@@ -20,8 +20,8 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<A: Array<Item: Decodable>> Decodable for SmallVec<A> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<SmallVec<A>, D::Error> {
+impl<D: Decoder, A: Array<Item: Decodable<D>>> Decodable<D> for SmallVec<A> {
+    fn decode(d: &mut D) -> Result<SmallVec<A>, D::Error> {
         d.read_seq(|d, len| {
             let mut vec = SmallVec::with_capacity(len);
             // FIXME(#48994) - could just be collected into a Result<SmallVec, D::Error>
@@ -33,8 +33,8 @@ fn decode<D: Decoder>(d: &mut D) -> Result<SmallVec<A>, D::Error> {
     }
 }
 
-impl<T: Encodable> Encodable for LinkedList<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for LinkedList<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?;
@@ -44,8 +44,8 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T: Decodable> Decodable for LinkedList<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<LinkedList<T>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for LinkedList<T> {
+    fn decode(d: &mut D) -> Result<LinkedList<T>, D::Error> {
         d.read_seq(|d, len| {
             let mut list = LinkedList::new();
             for i in 0..len {
@@ -56,8 +56,8 @@ fn decode<D: Decoder>(d: &mut D) -> Result<LinkedList<T>, D::Error> {
     }
 }
 
-impl<T: Encodable> Encodable for VecDeque<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for VecDeque<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?;
@@ -67,8 +67,8 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T: Decodable> Decodable for VecDeque<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<VecDeque<T>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for VecDeque<T> {
+    fn decode(d: &mut D) -> Result<VecDeque<T>, D::Error> {
         d.read_seq(|d, len| {
             let mut deque: VecDeque<T> = VecDeque::with_capacity(len);
             for i in 0..len {
@@ -79,12 +79,12 @@ fn decode<D: Decoder>(d: &mut D) -> Result<VecDeque<T>, D::Error> {
     }
 }
 
-impl<K, V> Encodable for BTreeMap<K, V>
+impl<S: Encoder, K, V> Encodable<S> for BTreeMap<K, V>
 where
-    K: Encodable + PartialEq + Ord,
-    V: Encodable,
+    K: Encodable<S> + PartialEq + Ord,
+    V: Encodable<S>,
 {
-    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
+    fn encode(&self, e: &mut S) -> Result<(), S::Error> {
         e.emit_map(self.len(), |e| {
             for (i, (key, val)) in self.iter().enumerate() {
                 e.emit_map_elt_key(i, |e| key.encode(e))?;
@@ -95,12 +95,12 @@ fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<K, V> Decodable for BTreeMap<K, V>
+impl<D: Decoder, K, V> Decodable<D> for BTreeMap<K, V>
 where
-    K: Decodable + PartialEq + Ord,
-    V: Decodable,
+    K: Decodable<D> + PartialEq + Ord,
+    V: Decodable<D>,
 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<BTreeMap<K, V>, D::Error> {
+    fn decode(d: &mut D) -> Result<BTreeMap<K, V>, D::Error> {
         d.read_map(|d, len| {
             let mut map = BTreeMap::new();
             for i in 0..len {
@@ -113,11 +113,11 @@ fn decode<D: Decoder>(d: &mut D) -> Result<BTreeMap<K, V>, D::Error> {
     }
 }
 
-impl<T> Encodable for BTreeSet<T>
+impl<S: Encoder, T> Encodable<S> for BTreeSet<T>
 where
-    T: Encodable + PartialEq + Ord,
+    T: Encodable<S> + PartialEq + Ord,
 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?;
@@ -127,11 +127,11 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T> Decodable for BTreeSet<T>
+impl<D: Decoder, T> Decodable<D> for BTreeSet<T>
 where
-    T: Decodable + PartialEq + Ord,
+    T: Decodable<D> + PartialEq + Ord,
 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<BTreeSet<T>, D::Error> {
+    fn decode(d: &mut D) -> Result<BTreeSet<T>, D::Error> {
         d.read_seq(|d, len| {
             let mut set = BTreeSet::new();
             for i in 0..len {
@@ -142,13 +142,13 @@ fn decode<D: Decoder>(d: &mut D) -> Result<BTreeSet<T>, D::Error> {
     }
 }
 
-impl<K, V, S> Encodable for HashMap<K, V, S>
+impl<E: Encoder, K, V, S> Encodable<E> for HashMap<K, V, S>
 where
-    K: Encodable + Eq,
-    V: Encodable,
+    K: Encodable<E> + Eq,
+    V: Encodable<E>,
     S: BuildHasher,
 {
-    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         e.emit_map(self.len(), |e| {
             for (i, (key, val)) in self.iter().enumerate() {
                 e.emit_map_elt_key(i, |e| key.encode(e))?;
@@ -159,13 +159,13 @@ fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
     }
 }
 
-impl<K, V, S> Decodable for HashMap<K, V, S>
+impl<D: Decoder, K, V, S> Decodable<D> for HashMap<K, V, S>
 where
-    K: Decodable + Hash + Eq,
-    V: Decodable,
+    K: Decodable<D> + Hash + Eq,
+    V: Decodable<D>,
     S: BuildHasher + Default,
 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<HashMap<K, V, S>, D::Error> {
+    fn decode(d: &mut D) -> Result<HashMap<K, V, S>, D::Error> {
         d.read_map(|d, len| {
             let state = Default::default();
             let mut map = HashMap::with_capacity_and_hasher(len, state);
@@ -179,12 +179,12 @@ fn decode<D: Decoder>(d: &mut D) -> Result<HashMap<K, V, S>, D::Error> {
     }
 }
 
-impl<T, S> Encodable for HashSet<T, S>
+impl<E: Encoder, T, S> Encodable<E> for HashSet<T, S>
 where
-    T: Encodable + Eq,
+    T: Encodable<E> + Eq,
     S: BuildHasher,
 {
-    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
+    fn encode(&self, s: &mut E) -> Result<(), E::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?;
@@ -194,12 +194,22 @@ fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
     }
 }
 
-impl<T, S> Decodable for HashSet<T, S>
+impl<E: Encoder, T, S> Encodable<E> for &HashSet<T, S>
 where
-    T: Decodable + Hash + Eq,
+    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,
     S: BuildHasher + Default,
 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<HashSet<T, S>, D::Error> {
+    fn decode(d: &mut D) -> Result<HashSet<T, S>, D::Error> {
         d.read_seq(|d, len| {
             let state = Default::default();
             let mut set = HashSet::with_capacity_and_hasher(len, state);
@@ -211,13 +221,13 @@ fn decode<D: Decoder>(d: &mut D) -> Result<HashSet<T, S>, D::Error> {
     }
 }
 
-impl<K, V, S> Encodable for indexmap::IndexMap<K, V, S>
+impl<E: Encoder, K, V, S> Encodable<E> for indexmap::IndexMap<K, V, S>
 where
-    K: Encodable + Hash + Eq,
-    V: Encodable,
+    K: Encodable<E> + Hash + Eq,
+    V: Encodable<E>,
     S: BuildHasher,
 {
-    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         e.emit_map(self.len(), |e| {
             for (i, (key, val)) in self.iter().enumerate() {
                 e.emit_map_elt_key(i, |e| key.encode(e))?;
@@ -228,13 +238,13 @@ fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
     }
 }
 
-impl<K, V, S> Decodable for indexmap::IndexMap<K, V, S>
+impl<D: Decoder, K, V, S> Decodable<D> for indexmap::IndexMap<K, V, S>
 where
-    K: Decodable + Hash + Eq,
-    V: Decodable,
+    K: Decodable<D> + Hash + Eq,
+    V: Decodable<D>,
     S: BuildHasher + Default,
 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<indexmap::IndexMap<K, V, S>, D::Error> {
+    fn decode(d: &mut D) -> Result<indexmap::IndexMap<K, V, S>, D::Error> {
         d.read_map(|d, len| {
             let state = Default::default();
             let mut map = indexmap::IndexMap::with_capacity_and_hasher(len, state);
@@ -248,12 +258,12 @@ fn decode<D: Decoder>(d: &mut D) -> Result<indexmap::IndexMap<K, V, S>, D::Error
     }
 }
 
-impl<T, S> Encodable for indexmap::IndexSet<T, S>
+impl<E: Encoder, T, S> Encodable<E> for indexmap::IndexSet<T, S>
 where
-    T: Encodable + Hash + Eq,
+    T: Encodable<E> + Hash + Eq,
     S: BuildHasher,
 {
-    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
+    fn encode(&self, s: &mut E) -> Result<(), E::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?;
@@ -263,12 +273,12 @@ fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
     }
 }
 
-impl<T, S> Decodable for indexmap::IndexSet<T, S>
+impl<D: Decoder, T, S> Decodable<D> for indexmap::IndexSet<T, S>
 where
-    T: Decodable + Hash + Eq,
+    T: Decodable<D> + Hash + Eq,
     S: BuildHasher + Default,
 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<indexmap::IndexSet<T, S>, D::Error> {
+    fn decode(d: &mut D) -> Result<indexmap::IndexSet<T, S>, D::Error> {
         d.read_seq(|d, len| {
             let state = Default::default();
             let mut set = indexmap::IndexSet::with_capacity_and_hasher(len, state);
@@ -280,8 +290,8 @@ fn decode<D: Decoder>(d: &mut D) -> Result<indexmap::IndexSet<T, S>, D::Error> {
     }
 }
 
-impl<T: Encodable> Encodable for Rc<[T]> {
-    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
+impl<E: Encoder, T: Encodable<E>> Encodable<E> for Rc<[T]> {
+    fn encode(&self, s: &mut E) -> Result<(), E::Error> {
         s.emit_seq(self.len(), |s| {
             for (index, e) in self.iter().enumerate() {
                 s.emit_seq_elt(index, |s| e.encode(s))?;
@@ -291,8 +301,8 @@ fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
     }
 }
 
-impl<T: Decodable> Decodable for Rc<[T]> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Rc<[T]>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<[T]> {
+    fn decode(d: &mut D) -> Result<Rc<[T]>, D::Error> {
         d.read_seq(|d, len| {
             let mut vec = Vec::with_capacity(len);
             for index in 0..len {
@@ -303,8 +313,8 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Rc<[T]>, D::Error> {
     }
 }
 
-impl<T: Encodable> Encodable for Arc<[T]> {
-    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
+impl<E: Encoder, T: Encodable<E>> Encodable<E> for Arc<[T]> {
+    fn encode(&self, s: &mut E) -> Result<(), E::Error> {
         s.emit_seq(self.len(), |s| {
             for (index, e) in self.iter().enumerate() {
                 s.emit_seq_elt(index, |s| e.encode(s))?;
@@ -314,8 +324,8 @@ fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
     }
 }
 
-impl<T: Decodable> Decodable for Arc<[T]> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Arc<[T]>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<[T]> {
+    fn decode(d: &mut D) -> Result<Arc<[T]>, D::Error> {
         d.read_seq(|d, len| {
             let mut vec = Vec::with_capacity(len);
             for index in 0..len {
index ab7f6975325bc0ccb403e5fd99483d2829bae210..dafeb053d83d30a932825eb98d0b00cb459d4eba 100644 (file)
@@ -292,7 +292,7 @@ pub fn error_str(error: ErrorCode) -> &'static str {
 }
 
 /// Shortcut function to decode a JSON `&str` into an object
-pub fn decode<T: crate::Decodable>(s: &str) -> DecodeResult<T> {
+pub fn decode<T: crate::Decodable<Decoder>>(s: &str) -> DecodeResult<T> {
     let json = match from_str(s) {
         Ok(x) => x,
         Err(e) => return Err(ParseError(e)),
@@ -303,7 +303,9 @@ pub fn decode<T: crate::Decodable>(s: &str) -> DecodeResult<T> {
 }
 
 /// Shortcut function to encode a `T` into a JSON `String`
-pub fn encode<T: crate::Encodable>(object: &T) -> Result<string::String, EncoderError> {
+pub fn encode<T: for<'r> crate::Encodable<Encoder<'r>>>(
+    object: &T,
+) -> Result<string::String, EncoderError> {
     let mut s = String::new();
     {
         let mut encoder = Encoder::new(&mut s);
@@ -1144,8 +1146,8 @@ fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> EncodeResult
     }
 }
 
-impl Encodable for Json {
-    fn encode<E: crate::Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
+impl<E: crate::Encoder> Encodable<E> for Json {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         match *self {
             Json::I64(v) => v.encode(e),
             Json::U64(v) => v.encode(e),
@@ -2727,7 +2729,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-impl<'a, T: Encodable> fmt::Display for AsJson<'a, T> {
+impl<'a, T: for<'r> Encodable<Encoder<'r>>> fmt::Display for AsJson<'a, T> {
     /// Encodes a json value into a string
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut shim = FormatShim { inner: f };
@@ -2747,7 +2749,7 @@ pub fn indent(mut self, indent: usize) -> AsPrettyJson<'a, T> {
     }
 }
 
-impl<'a, T: Encodable> fmt::Display for AsPrettyJson<'a, T> {
+impl<'a, T: for<'x> Encodable<PrettyEncoder<'x>>> fmt::Display for AsPrettyJson<'a, T> {
     /// Encodes a json value into a string
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut shim = FormatShim { inner: f };
index 3dc3e783820963e4e0dc417c8c44380f92ab0b7a..265b3b95e956a9c0e9505cd3ab71be6cff89c26e 100644 (file)
@@ -10,7 +10,6 @@
     test(attr(allow(unused_variables), deny(warnings)))
 )]
 #![feature(box_syntax)]
-#![feature(min_specialization)]
 #![feature(never_type)]
 #![feature(nll)]
 #![feature(associated_type_bounds)]
@@ -19,9 +18,6 @@
 
 pub use self::serialize::{Decodable, Decoder, Encodable, Encoder};
 
-pub use self::serialize::{SpecializationError, SpecializedDecoder, SpecializedEncoder};
-pub use self::serialize::{UseSpecializedDecodable, UseSpecializedEncodable};
-
 mod collection_impls;
 mod serialize;
 
index 29c5737ad895abc8b834394fcb6f328ddefb1ee4..d279954bf91bff5f18e0979239e2dc40ce672b23 100644 (file)
@@ -4,7 +4,6 @@
 Core encoding and decoding interfaces.
 */
 
-use std::any;
 use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
 use std::marker::PhantomData;
@@ -380,282 +379,288 @@ fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Self::Error
     fn error(&mut self, err: &str) -> Self::Error;
 }
 
-pub trait Encodable {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error>;
+pub trait Encodable<S: Encoder> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error>;
 }
 
-pub trait Decodable: Sized {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error>;
+pub trait Decodable<D: Decoder>: Sized {
+    fn decode(d: &mut D) -> Result<Self, D::Error>;
 }
 
-impl Encodable for usize {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for usize {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_usize(*self)
     }
 }
 
-impl Decodable for usize {
-    fn decode<D: Decoder>(d: &mut D) -> Result<usize, D::Error> {
+impl<D: Decoder> Decodable<D> for usize {
+    fn decode(d: &mut D) -> Result<usize, D::Error> {
         d.read_usize()
     }
 }
 
-impl Encodable for u8 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for u8 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u8(*self)
     }
 }
 
-impl Decodable for u8 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<u8, D::Error> {
+impl<D: Decoder> Decodable<D> for u8 {
+    fn decode(d: &mut D) -> Result<u8, D::Error> {
         d.read_u8()
     }
 }
 
-impl Encodable for u16 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for u16 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u16(*self)
     }
 }
 
-impl Decodable for u16 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<u16, D::Error> {
+impl<D: Decoder> Decodable<D> for u16 {
+    fn decode(d: &mut D) -> Result<u16, D::Error> {
         d.read_u16()
     }
 }
 
-impl Encodable for u32 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for u32 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u32(*self)
     }
 }
 
-impl Decodable for u32 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<u32, D::Error> {
+impl<D: Decoder> Decodable<D> for u32 {
+    fn decode(d: &mut D) -> Result<u32, D::Error> {
         d.read_u32()
     }
 }
 
-impl Encodable for ::std::num::NonZeroU32 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for ::std::num::NonZeroU32 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u32(self.get())
     }
 }
 
-impl Decodable for ::std::num::NonZeroU32 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
+impl<D: Decoder> Decodable<D> for ::std::num::NonZeroU32 {
+    fn decode(d: &mut D) -> Result<Self, D::Error> {
         d.read_u32().map(|d| ::std::num::NonZeroU32::new(d).unwrap())
     }
 }
 
-impl Encodable for u64 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for u64 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u64(*self)
     }
 }
 
-impl Decodable for u64 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<u64, D::Error> {
+impl<D: Decoder> Decodable<D> for u64 {
+    fn decode(d: &mut D) -> Result<u64, D::Error> {
         d.read_u64()
     }
 }
 
-impl Encodable for u128 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for u128 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u128(*self)
     }
 }
 
-impl Decodable for u128 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<u128, D::Error> {
+impl<D: Decoder> Decodable<D> for u128 {
+    fn decode(d: &mut D) -> Result<u128, D::Error> {
         d.read_u128()
     }
 }
 
-impl Encodable for isize {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for isize {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_isize(*self)
     }
 }
 
-impl Decodable for isize {
-    fn decode<D: Decoder>(d: &mut D) -> Result<isize, D::Error> {
+impl<D: Decoder> Decodable<D> for isize {
+    fn decode(d: &mut D) -> Result<isize, D::Error> {
         d.read_isize()
     }
 }
 
-impl Encodable for i8 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for i8 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_i8(*self)
     }
 }
 
-impl Decodable for i8 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<i8, D::Error> {
+impl<D: Decoder> Decodable<D> for i8 {
+    fn decode(d: &mut D) -> Result<i8, D::Error> {
         d.read_i8()
     }
 }
 
-impl Encodable for i16 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for i16 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_i16(*self)
     }
 }
 
-impl Decodable for i16 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<i16, D::Error> {
+impl<D: Decoder> Decodable<D> for i16 {
+    fn decode(d: &mut D) -> Result<i16, D::Error> {
         d.read_i16()
     }
 }
 
-impl Encodable for i32 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for i32 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_i32(*self)
     }
 }
 
-impl Decodable for i32 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<i32, D::Error> {
+impl<D: Decoder> Decodable<D> for i32 {
+    fn decode(d: &mut D) -> Result<i32, D::Error> {
         d.read_i32()
     }
 }
 
-impl Encodable for i64 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for i64 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_i64(*self)
     }
 }
 
-impl Decodable for i64 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<i64, D::Error> {
+impl<D: Decoder> Decodable<D> for i64 {
+    fn decode(d: &mut D) -> Result<i64, D::Error> {
         d.read_i64()
     }
 }
 
-impl Encodable for i128 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for i128 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_i128(*self)
     }
 }
 
-impl Decodable for i128 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<i128, D::Error> {
+impl<D: Decoder> Decodable<D> for i128 {
+    fn decode(d: &mut D) -> Result<i128, D::Error> {
         d.read_i128()
     }
 }
 
-impl Encodable for str {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for str {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_str(self)
     }
 }
 
-impl Encodable for String {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+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[..])
     }
 }
 
-impl Decodable for String {
-    fn decode<D: Decoder>(d: &mut D) -> Result<String, D::Error> {
+impl<D: Decoder> Decodable<D> for String {
+    fn decode(d: &mut D) -> Result<String, D::Error> {
         Ok(d.read_str()?.into_owned())
     }
 }
 
-impl Encodable for f32 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for f32 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_f32(*self)
     }
 }
 
-impl Decodable for f32 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<f32, D::Error> {
+impl<D: Decoder> Decodable<D> for f32 {
+    fn decode(d: &mut D) -> Result<f32, D::Error> {
         d.read_f32()
     }
 }
 
-impl Encodable for f64 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for f64 {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_f64(*self)
     }
 }
 
-impl Decodable for f64 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<f64, D::Error> {
+impl<D: Decoder> Decodable<D> for f64 {
+    fn decode(d: &mut D) -> Result<f64, D::Error> {
         d.read_f64()
     }
 }
 
-impl Encodable for bool {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for bool {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_bool(*self)
     }
 }
 
-impl Decodable for bool {
-    fn decode<D: Decoder>(d: &mut D) -> Result<bool, D::Error> {
+impl<D: Decoder> Decodable<D> for bool {
+    fn decode(d: &mut D) -> Result<bool, D::Error> {
         d.read_bool()
     }
 }
 
-impl Encodable for char {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for char {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_char(*self)
     }
 }
 
-impl Decodable for char {
-    fn decode<D: Decoder>(d: &mut D) -> Result<char, D::Error> {
+impl<D: Decoder> Decodable<D> for char {
+    fn decode(d: &mut D) -> Result<char, D::Error> {
         d.read_char()
     }
 }
 
-impl Encodable for () {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for () {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_unit()
     }
 }
 
-impl Decodable for () {
-    fn decode<D: Decoder>(d: &mut D) -> Result<(), D::Error> {
+impl<D: Decoder> Decodable<D> for () {
+    fn decode(d: &mut D) -> Result<(), D::Error> {
         d.read_nil()
     }
 }
 
-impl<T> Encodable for PhantomData<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T> Encodable<S> for PhantomData<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_unit()
     }
 }
 
-impl<T> Decodable for PhantomData<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<PhantomData<T>, D::Error> {
+impl<D: Decoder, T> Decodable<D> for PhantomData<T> {
+    fn decode(d: &mut D) -> Result<PhantomData<T>, D::Error> {
         d.read_nil()?;
         Ok(PhantomData)
     }
 }
 
-impl<T: Decodable> Decodable for Box<[T]> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Box<[T]>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<[T]> {
+    fn decode(d: &mut D) -> Result<Box<[T]>, D::Error> {
         let v: Vec<T> = Decodable::decode(d)?;
         Ok(v.into_boxed_slice())
     }
 }
 
-impl<T: Encodable> Encodable for Rc<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for Rc<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         (**self).encode(s)
     }
 }
 
-impl<T: Decodable> Decodable for Rc<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Rc<T>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<T> {
+    fn decode(d: &mut D) -> Result<Rc<T>, D::Error> {
         Ok(Rc::new(Decodable::decode(d)?))
     }
 }
 
-impl<T: Encodable> Encodable for [T] {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for [T] {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?
@@ -665,8 +670,8 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T: Encodable> Encodable for Vec<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for Vec<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?
@@ -676,8 +681,8 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T: Decodable> Decodable for Vec<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Vec<T>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
+    fn decode(d: &mut D) -> Result<Vec<T>, D::Error> {
         d.read_seq(|d, len| {
             let mut v = Vec::with_capacity(len);
             for i in 0..len {
@@ -688,8 +693,8 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Vec<T>, D::Error> {
     }
 }
 
-impl Encodable for [u8; 20] {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for [u8; 20] {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?
@@ -699,8 +704,8 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl Decodable for [u8; 20] {
-    fn decode<D: Decoder>(d: &mut D) -> Result<[u8; 20], D::Error> {
+impl<D: Decoder> Decodable<D> for [u8; 20] {
+    fn decode(d: &mut D) -> Result<[u8; 20], D::Error> {
         d.read_seq(|d, len| {
             assert!(len == 20);
             let mut v = [0u8; 20];
@@ -712,11 +717,11 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<'a, T: Encodable> Encodable for Cow<'a, [T]>
+impl<'a, S: Encoder, T: Encodable<S>> Encodable<S> for Cow<'a, [T]>
 where
     [T]: ToOwned<Owned = Vec<T>>,
 {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
                 s.emit_seq_elt(i, |s| e.encode(s))?
@@ -726,11 +731,11 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T: Decodable + ToOwned> Decodable for Cow<'static, [T]>
+impl<D: Decoder, T: Decodable<D> + ToOwned> Decodable<D> for Cow<'static, [T]>
 where
     [T]: ToOwned<Owned = Vec<T>>,
 {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Cow<'static, [T]>, D::Error> {
+    fn decode(d: &mut D) -> Result<Cow<'static, [T]>, D::Error> {
         d.read_seq(|d, len| {
             let mut v = Vec::with_capacity(len);
             for i in 0..len {
@@ -741,8 +746,8 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Cow<'static, [T]>, D::Error> {
     }
 }
 
-impl<T: Encodable> Encodable for Option<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for Option<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_option(|s| match *self {
             None => s.emit_option_none(),
             Some(ref v) => s.emit_option_some(|s| v.encode(s)),
@@ -750,14 +755,14 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T: Decodable> Decodable for Option<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Option<T>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for Option<T> {
+    fn decode(d: &mut D) -> Result<Option<T>, D::Error> {
         d.read_option(|d, b| if b { Ok(Some(Decodable::decode(d)?)) } else { Ok(None) })
     }
 }
 
-impl<T1: Encodable, T2: Encodable> Encodable for Result<T1, T2> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T1: Encodable<S>, T2: Encodable<S>> Encodable<S> for Result<T1, T2> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_enum("Result", |s| match *self {
             Ok(ref v) => {
                 s.emit_enum_variant("Ok", 0, 1, |s| s.emit_enum_variant_arg(0, |s| v.encode(s)))
@@ -769,8 +774,8 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T1: Decodable, T2: Decodable> Decodable for Result<T1, T2> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Result<T1, T2>, D::Error> {
+impl<D: Decoder, T1: Decodable<D>, T2: Decodable<D>> Decodable<D> for Result<T1, T2> {
+    fn decode(d: &mut D) -> Result<Result<T1, T2>, D::Error> {
         d.read_enum("Result", |d| {
             d.read_enum_variant(&["Ok", "Err"], |d, disr| match disr {
                 0 => Ok(Ok(d.read_enum_variant_arg(0, |d| T1::decode(d))?)),
@@ -806,9 +811,9 @@ macro_rules! count {
 macro_rules! tuple {
     () => ();
     ( $($name:ident,)+ ) => (
-        impl<$($name:Decodable),+> Decodable for ($($name,)+) {
+        impl<D: Decoder, $($name: Decodable<D>),+> Decodable<D> for ($($name,)+) {
             #[allow(non_snake_case)]
-            fn decode<D: Decoder>(d: &mut D) -> Result<($($name,)+), D::Error> {
+            fn decode(d: &mut D) -> Result<($($name,)+), D::Error> {
                 let len: usize = count!($($name)+);
                 d.read_tuple(len, |d| {
                     let mut i = 0;
@@ -819,9 +824,9 @@ fn decode<D: Decoder>(d: &mut D) -> Result<($($name,)+), D::Error> {
                 })
             }
         }
-        impl<$($name:Encodable),+> Encodable for ($($name,)+) {
+        impl<S: Encoder, $($name: Encodable<S>),+> Encodable<S> for ($($name,)+) {
             #[allow(non_snake_case)]
-            fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+            fn encode(&self, s: &mut S) -> Result<(), S::Error> {
                 let ($(ref $name,)+) = *self;
                 let mut n = 0;
                 $(let $name = $name; n += 1;)+
@@ -838,33 +843,33 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
 
 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
 
-impl Encodable for path::Path {
-    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for path::Path {
+    fn encode(&self, e: &mut S) -> Result<(), S::Error> {
         self.to_str().unwrap().encode(e)
     }
 }
 
-impl Encodable for path::PathBuf {
-    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder> Encodable<S> for path::PathBuf {
+    fn encode(&self, e: &mut S) -> Result<(), S::Error> {
         path::Path::encode(self, e)
     }
 }
 
-impl Decodable for path::PathBuf {
-    fn decode<D: Decoder>(d: &mut D) -> Result<path::PathBuf, D::Error> {
+impl<D: Decoder> Decodable<D> for path::PathBuf {
+    fn decode(d: &mut D) -> Result<path::PathBuf, D::Error> {
         let bytes: String = Decodable::decode(d)?;
         Ok(path::PathBuf::from(bytes))
     }
 }
 
-impl<T: Encodable + Copy> Encodable for Cell<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S> + Copy> Encodable<S> for Cell<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         self.get().encode(s)
     }
 }
 
-impl<T: Decodable + Copy> Decodable for Cell<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Cell<T>, D::Error> {
+impl<D: Decoder, T: Decodable<D> + Copy> Decodable<D> for Cell<T> {
+    fn decode(d: &mut D) -> Result<Cell<T>, D::Error> {
         Ok(Cell::new(Decodable::decode(d)?))
     }
 }
@@ -874,136 +879,37 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Cell<T>, D::Error> {
 // `encoder.error("attempting to Encode borrowed RefCell")`
 // from `encode` when `try_borrow` returns `None`.
 
-impl<T: Encodable> Encodable for RefCell<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for RefCell<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         self.borrow().encode(s)
     }
 }
 
-impl<T: Decodable> Decodable for RefCell<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<RefCell<T>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for RefCell<T> {
+    fn decode(d: &mut D) -> Result<RefCell<T>, D::Error> {
         Ok(RefCell::new(Decodable::decode(d)?))
     }
 }
 
-impl<T: Encodable> Encodable for Arc<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: Encodable<S>> Encodable<S> for Arc<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         (**self).encode(s)
     }
 }
 
-impl<T: Decodable> Decodable for Arc<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Arc<T>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<T> {
+    fn decode(d: &mut D) -> Result<Arc<T>, D::Error> {
         Ok(Arc::new(Decodable::decode(d)?))
     }
 }
 
-// ___________________________________________________________________________
-// Specialization-based interface for multi-dispatch Encodable/Decodable.
-
-/// Implement this trait on your `{Encodable,Decodable}::Error` types
-/// to override the default panic behavior for missing specializations.
-pub trait SpecializationError {
-    /// Creates an error for a missing method specialization.
-    /// Defaults to panicking with type, trait & method names.
-    /// `S` is the encoder/decoder state type,
-    /// `T` is the type being encoded/decoded, and
-    /// the arguments are the names of the trait
-    /// and method that should've been overridden.
-    fn not_found<S, T: ?Sized>(trait_name: &'static str, method_name: &'static str) -> Self;
-}
-
-impl<E> SpecializationError for E {
-    default fn not_found<S, T: ?Sized>(trait_name: &'static str, method_name: &'static str) -> E {
-        panic!(
-            "missing specialization: `<{} as {}<{}>>::{}` not overridden",
-            any::type_name::<S>(),
-            trait_name,
-            any::type_name::<T>(),
-            method_name
-        );
-    }
-}
-
-/// Implement this trait on encoders, with `T` being the type
-/// you want to encode (employing `UseSpecializedEncodable`),
-/// using a strategy specific to the encoder.
-pub trait SpecializedEncoder<T: ?Sized + UseSpecializedEncodable>: Encoder {
-    /// Encode the value in a manner specific to this encoder state.
-    fn specialized_encode(&mut self, value: &T) -> Result<(), Self::Error>;
-}
-
-impl<E: Encoder, T: ?Sized + UseSpecializedEncodable> SpecializedEncoder<T> for E {
-    default fn specialized_encode(&mut self, value: &T) -> Result<(), E::Error> {
-        value.default_encode(self)
-    }
-}
-
-/// Implement this trait on decoders, with `T` being the type
-/// you want to decode (employing `UseSpecializedDecodable`),
-/// using a strategy specific to the decoder.
-pub trait SpecializedDecoder<T: UseSpecializedDecodable>: Decoder {
-    /// Decode a value in a manner specific to this decoder state.
-    fn specialized_decode(&mut self) -> Result<T, Self::Error>;
-}
-
-impl<D: Decoder, T: UseSpecializedDecodable> SpecializedDecoder<T> for D {
-    default fn specialized_decode(&mut self) -> Result<T, D::Error> {
-        T::default_decode(self)
-    }
-}
-
-/// Implement this trait on your type to get an `Encodable`
-/// implementation which goes through `SpecializedEncoder`.
-pub trait UseSpecializedEncodable {
-    /// Defaults to returning an error (see `SpecializationError`).
-    fn default_encode<E: Encoder>(&self, _: &mut E) -> Result<(), E::Error> {
-        Err(E::Error::not_found::<E, Self>("SpecializedEncoder", "specialized_encode"))
-    }
-}
-
-impl<T: ?Sized + UseSpecializedEncodable> Encodable for T {
-    default fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
-        E::specialized_encode(e, self)
-    }
-}
-
-/// Implement this trait on your type to get an `Decodable`
-/// implementation which goes through `SpecializedDecoder`.
-pub trait UseSpecializedDecodable: Sized {
-    /// Defaults to returning an error (see `SpecializationError`).
-    fn default_decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
-        Err(D::Error::not_found::<D, Self>("SpecializedDecoder", "specialized_decode"))
-    }
-}
-
-impl<T: UseSpecializedDecodable> Decodable for T {
-    default fn decode<D: Decoder>(d: &mut D) -> Result<T, D::Error> {
-        D::specialized_decode(d)
-    }
-}
-
-// Can't avoid specialization for &T and Box<T> impls,
-// as proxy impls on them are blankets that conflict
-// with the Encodable and Decodable impls above,
-// which only have `default` on their methods
-// for this exact reason.
-// May be fixable in a simpler fashion via the
-// more complex lattice model for specialization.
-impl<'a, T: ?Sized + Encodable> UseSpecializedEncodable for &'a T {
-    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        (**self).encode(s)
-    }
-}
-impl<T: ?Sized + Encodable> UseSpecializedEncodable for Box<T> {
-    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+impl<S: Encoder, T: ?Sized + Encodable<S>> Encodable<S> for Box<T> {
+    fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         (**self).encode(s)
     }
 }
-impl<T: Decodable> UseSpecializedDecodable for Box<T> {
-    fn default_decode<D: Decoder>(d: &mut D) -> Result<Box<T>, D::Error> {
+impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<T> {
+    fn decode(d: &mut D) -> Result<Box<T>, D::Error> {
         Ok(box Decodable::decode(d)?)
     }
 }
-impl<'a, T: Decodable> UseSpecializedDecodable for &'a T {}
-impl<'a, T: Decodable> UseSpecializedDecodable for &'a [T] {}
index 35c227df8500a98832284eae2e53009f0b704ab9..cb6626d0f4bd5cd88346058f5b4b1aff81d6a91e 100644 (file)
@@ -12,6 +12,7 @@ path = "lib.rs"
 bitflags = "1.2.1"
 getopts = "0.2"
 log = { package = "tracing", version = "0.1" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_feature = { path = "../librustc_feature" }
 rustc_target = { path = "../librustc_target" }
index 9fcdd46539c46f15aee8c50306f9f58af128ea18..c26c9bde3ee85114472d8f7e18d189d9b398ba7a 100644 (file)
@@ -39,7 +39,7 @@ pub struct Config {
 }
 
 bitflags! {
-    #[derive(Default, RustcEncodable, RustcDecodable)]
+    #[derive(Default, Encodable, Decodable)]
     pub struct SanitizerSet: u8 {
         const ADDRESS = 1 << 0;
         const LEAK    = 1 << 1;
@@ -194,7 +194,8 @@ pub fn enabled(&self) -> bool {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Encodable, Decodable)]
 pub enum SymbolManglingVersion {
     Legacy,
     V0,
@@ -209,7 +210,8 @@ pub enum DebugInfo {
     Full,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
+#[derive(Encodable, Decodable)]
 pub enum OutputType {
     Bitcode,
     Assembly,
@@ -672,7 +674,7 @@ pub enum EntryFnType {
 
 impl_stable_hash_via_hash!(EntryFnType);
 
-#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)]
 pub enum CrateType {
     Executable,
     Dylib,
index be9d2e7be27774ce5da48fb5ccf093ac74a58c18..c2ea141a06fe31b71f9419b9d6155646c3f8bc68 100644 (file)
@@ -3,6 +3,8 @@
 
 #[macro_use]
 extern crate bitflags;
+#[macro_use]
+extern crate rustc_macros;
 
 pub mod cgu_reuse_tracker;
 pub mod utils;
index 4ff06acaa1fd4eedcb7fc5799599a465673c04f6..e12364b7dac7cb355917994aa0855998076e3dec 100644 (file)
@@ -33,7 +33,7 @@ fn new(path: PathBuf) -> SearchPathFile {
     }
 }
 
-#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, RustcEncodable, RustcDecodable)]
+#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, Encodable, Decodable)]
 pub enum PathKind {
     Native,
     Crate,
index b97308c22cb7d0343cdc23e0efa03c360f5968fb..15447c01d1e55a5080e31c53fc84aacf6a3e8baa 100644 (file)
@@ -10,7 +10,7 @@ pub fn time<R>(&self, what: &'static str, f: impl FnOnce() -> R) -> R {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
 pub enum NativeLibKind {
     /// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC) included
     /// when linking a final binary, but not when archiving an rlib.
index a874f81868f153ab6f373101b30136841687b10e..aae778217d3f1116a2b1e02ec4f65d341b9bffe2 100644 (file)
@@ -4,7 +4,7 @@
 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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 /// 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 @@ fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
     }
 }
 
-#[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 @@ fn borrow(&self) -> &Fingerprint {
     /// 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 @@ pub fn is_top_level_module(self) -> bool {
     }
 }
 
-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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-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) {
index b1ac7f04321eb99dd0146c8e24c2b699c9268f1f..4d0c92f51d7ca7063c934486a78c7947e2b4b511 100644 (file)
@@ -5,7 +5,7 @@
 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
index f52b2195c2f6e25d6bc797e24511808c43a08374..e8f4606b518cf3b1d3ed10fd2d28157aadee03d6 100644 (file)
 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 SyntaxContextData {
 
 /// 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 @@ pub fn fresh_expansion_with_transparency(
 
 /// 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 @@ pub fn is_root(&self) -> bool {
 }
 
 /// 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 @@ pub fn descr(&self) -> String {
 }
 
 /// 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 @@ pub fn article(self) -> &'static str {
 }
 
 /// 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 @@ fn descr(self) -> &'static str {
 }
 
 /// 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 @@ fn descr(self) -> &'static str {
     }
 }
 
-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 @@ pub fn incr_comp(ctxt: &'a HygieneDecodeContext) -> Self {
     }
 }
 
-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>());
+    }
+}
index 697d88ad0639598ea392fa345260a1eac0749ce0..c654dade2abd4ae60f9897e5eede270a153e9969 100644 (file)
@@ -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 @@ pub fn with_default_session_globals<R>(f: impl FnOnce() -> R) -> R {
 //
 // 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 @@ pub fn stable_name(&self) -> &Path {
 }
 
 /// 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 @@ fn cmp(&self, rhs: &Self) -> Ordering {
 ///   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 @@ fn default() -> Self {
     }
 }
 
-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 @@ fn from(spans: Vec<Span>) -> 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 @@ fn sub(self, rhs: BytePos) -> Self {
 }
 
 /// 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 @@ pub fn get_source(&self) -> Option<&Lrc<String>> {
 #[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 @@ fn from_str(s: &str) -> Result<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 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-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 @@ fn sub(self, rhs: BytePos) -> 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()?))
     }
 }
index e062c7766e7dcc2774b49c424e8251d6ff0c6ab8..29e589057b5e2945ca1ec038c8fd4a14b3691011 100644 (file)
@@ -75,7 +75,7 @@ fn deref(&self) -> &Self::Target {
     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 @@ fn read_file(&self, path: &Path) -> io::Result<String> {
 // 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
index caa6de09664bcf1a38607114bcd31d980c3b89ae..7843c04f25596e2f70d8cca544b9c918bf9a415d 100644 (file)
@@ -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;
     }
 }
 
-#[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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-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;
index b3e5f5c0c74b163e90d55d521ac17a93e1050059..4b565dd246f6da06feea1d999f18fe13ba63f533 100644 (file)
@@ -235,7 +235,7 @@ pub enum Endian {
 }
 
 /// Size of a type in bytes.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
 #[derive(HashStable_Generic)]
 pub struct Size {
     raw: u64,
@@ -358,7 +358,7 @@ fn add_assign(&mut self, other: Size) {
 }
 
 /// Alignment of a type in bytes (always a power of two).
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
 #[derive(HashStable_Generic)]
 pub struct Align {
     pow2: u8,
@@ -415,7 +415,7 @@ pub fn restrict_for_offset(self, offset: Size) -> Align {
 }
 
 /// A pair of alignments, ABI-mandated and preferred.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable)]
 #[derive(HashStable_Generic)]
 pub struct AbiAndPrefAlign {
     pub abi: Align,
index ccec17817d37df6b0de2920cbe2a7d95fb862fef..c22644bf813a4a0e0ddb6bf6e2b623e1b104e4b3 100644 (file)
@@ -13,7 +13,7 @@ macro_rules! def_reg_class {
             $class:ident,
         )*
     }) => {
-        #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
+        #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
         #[allow(non_camel_case_types)]
         pub enum $arch_regclass {
             $($class,)*
@@ -62,7 +62,7 @@ macro_rules! def_regs {
         )*
     }) => {
         #[allow(unreachable_code)]
-        #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
+        #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
         #[allow(non_camel_case_types)]
         pub enum $arch_reg {
             $($reg,)*
@@ -163,7 +163,7 @@ macro_rules! types {
 pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
 pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, Eq, PartialEq, Hash)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash)]
 pub enum InlineAsmArch {
     X86,
     X86_64,
@@ -193,17 +193,7 @@ fn from_str(s: &str) -> Result<InlineAsmArch, ()> {
     }
 }
 
-#[derive(
-    Copy,
-    Clone,
-    RustcEncodable,
-    RustcDecodable,
-    Debug,
-    Eq,
-    PartialEq,
-    Hash,
-    HashStable_Generic
-)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
 pub enum InlineAsmReg {
     X86(X86InlineAsmReg),
     Arm(ArmInlineAsmReg),
@@ -293,17 +283,7 @@ pub fn overlapping_regs(self, mut cb: impl FnMut(InlineAsmReg)) {
     }
 }
 
-#[derive(
-    Copy,
-    Clone,
-    RustcEncodable,
-    RustcDecodable,
-    Debug,
-    Eq,
-    PartialEq,
-    Hash,
-    HashStable_Generic
-)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
 pub enum InlineAsmRegClass {
     X86(X86InlineAsmRegClass),
     Arm(ArmInlineAsmRegClass),
@@ -429,17 +409,7 @@ pub fn valid_modifiers(self, arch: InlineAsmArch) -> &'static [char] {
     }
 }
 
-#[derive(
-    Copy,
-    Clone,
-    RustcEncodable,
-    RustcDecodable,
-    Debug,
-    Eq,
-    PartialEq,
-    Hash,
-    HashStable_Generic
-)]
+#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash, HashStable_Generic)]
 pub enum InlineAsmRegOrRegClass {
     Reg(InlineAsmReg),
     RegClass(InlineAsmRegClass),
index 1d0dc660ee616ec37d5178ebad623d64958c1a7c..62df63ceb1efd8cf5d890b1dc2266040ac371eeb 100644 (file)
@@ -16,8 +16,7 @@
 #![feature(associated_type_bounds)]
 #![feature(exhaustive_patterns)]
 
-// FIXME(#56935): Work around ICEs during cross-compilation.
-#[allow(unused)]
+#[macro_use]
 extern crate rustc_macros;
 
 #[macro_use]
index a5c874bb4ac050a2c305b4f9b95cd3137d6a0079..1e45739ca22b4a76f61c33be87661d35d4f19f5e 100644 (file)
@@ -5,8 +5,8 @@
 #[cfg(test)]
 mod tests;
 
-#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)]
-#[derive(HashStable_Generic)]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)]
+#[derive(HashStable_Generic, Encodable, Decodable)]
 pub enum Abi {
     // N.B., this ordering MUST match the AbiDatas array below.
     // (This is ensured by the test indices_are_correct().)
index 961a438fd233cc175c5019a5d984ab5a0eb2de58..fa29ff3f8d80f6df5fd1d97ca1602ff97e37a62d 100644 (file)
@@ -161,7 +161,7 @@ pub fn desc(&self) -> &str {
     ((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"),
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable, HashStable_Generic)]
+#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
 pub enum PanicStrategy {
     Unwind,
     Abort,
@@ -185,7 +185,7 @@ fn to_json(&self) -> Json {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub enum RelroLevel {
     Full,
     Partial,
@@ -229,7 +229,7 @@ fn to_json(&self) -> Json {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub enum MergeFunctions {
     Disabled,
     Trampolines,
@@ -1734,7 +1734,7 @@ macro_rules! target_option_val {
 }
 
 /// Either a target triple string or a path to a JSON file.
-#[derive(PartialEq, Clone, Debug, Hash, RustcEncodable, RustcDecodable)]
+#[derive(PartialEq, Clone, Debug, Hash, Encodable, Decodable)]
 pub enum TargetTriple {
     TargetTriple(String),
     TargetPath(PathBuf),