about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-04-28 22:56:45 +0200
committerGitHub <noreply@github.com>2023-04-28 22:56:45 +0200
commit37076ebbe51cd5fe3c6013dc47870ded9efdf497 (patch)
treeb0b6437b484b9b2a9238a386bbb1f206844a004d
parent4751c85e50bdb3ecf529fba2b50cff20330085ff (diff)
parent23e91d4d73785f6dfac6b6ac198dc45574cabc88 (diff)
downloadrust-37076ebbe51cd5fe3c6013dc47870ded9efdf497.tar.gz
rust-37076ebbe51cd5fe3c6013dc47870ded9efdf497.zip
Rollup merge of #110927 - nnethercote:Encoder-Decoder-cleanups, r=scottmcm
Encoder/decoder cleanups

Best reviewed one commit at a time.

r? ``@scottmcm``
-rw-r--r--compiler/rustc_hir/src/hir.rs78
-rw-r--r--compiler/rustc_middle/src/middle/region.rs6
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs14
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs2
-rw-r--r--compiler/rustc_serialize/src/opaque.rs136
-rw-r--r--compiler/rustc_serialize/src/serialize.rs69
6 files changed, 130 insertions, 175 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 21b4a3370d3..e220a029339 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -26,7 +26,7 @@ use rustc_target::spec::abi::Abi;
 use smallvec::SmallVec;
 use std::fmt;
 
-#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
+#[derive(Debug, Copy, Clone, HashStable_Generic)]
 pub struct Lifetime {
     pub hir_id: HirId,
 
@@ -41,8 +41,7 @@ pub struct Lifetime {
     pub res: LifetimeName,
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
-#[derive(HashStable_Generic)]
+#[derive(Debug, Copy, Clone, HashStable_Generic)]
 pub enum ParamName {
     /// Some user-given name like `T` or `'x`.
     Plain(Ident),
@@ -85,8 +84,7 @@ impl ParamName {
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
-#[derive(HashStable_Generic)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
 pub enum LifetimeName {
     /// User-given names or fresh (synthetic) names.
     Param(LocalDefId),
@@ -243,13 +241,13 @@ impl<'hir> PathSegment<'hir> {
     }
 }
 
-#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, Debug, HashStable_Generic)]
 pub struct ConstArg {
     pub value: AnonConst,
     pub span: Span,
 }
 
-#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, Debug, HashStable_Generic)]
 pub struct InferArg {
     pub hir_id: HirId,
     pub span: Span,
@@ -422,8 +420,7 @@ impl<'hir> GenericArgs<'hir> {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
-#[derive(HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
 pub enum GenericArgsParentheses {
     No,
     /// Bounds for `feature(return_type_notation)`, like `T: Trait<method(..): Send>`,
@@ -435,8 +432,7 @@ pub enum GenericArgsParentheses {
 
 /// 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, Encodable, Hash, Debug)]
-#[derive(HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
 pub enum TraitBoundModifier {
     None,
     Maybe,
@@ -474,7 +470,7 @@ impl GenericBound<'_> {
 
 pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
 
-#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, 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 }`).
@@ -539,7 +535,7 @@ impl<'hir> GenericParam<'hir> {
 /// early-bound (but can be a late-bound lifetime in functions, for example),
 /// or from a `for<...>` binder, in which case it's late-bound (and notably,
 /// does not show up in the parent item's generics).
-#[derive(Debug, HashStable_Generic, PartialEq, Eq, Copy, Clone)]
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum GenericParamSource {
     // Early or late-bound parameters defined on an item
     Generics,
@@ -1097,7 +1093,7 @@ pub struct PatField<'hir> {
     pub span: Span,
 }
 
-#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
 pub enum RangeEnd {
     Included,
     Excluded,
@@ -1197,7 +1193,7 @@ pub enum PatKind<'hir> {
     Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
 }
 
-#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
 pub enum BinOpKind {
     /// The `+` operator (addition).
     Add,
@@ -1325,7 +1321,7 @@ impl Into<ast::BinOpKind> for BinOpKind {
 
 pub type BinOp = Spanned<BinOpKind>;
 
-#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
 pub enum UnOp {
     /// The `*` operator (dereferencing).
     Deref,
@@ -1450,19 +1446,19 @@ pub struct ExprField<'hir> {
     pub is_shorthand: bool,
 }
 
-#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
 pub enum BlockCheckMode {
     DefaultBlock,
     UnsafeBlock(UnsafeSource),
 }
 
-#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct BodyId {
     pub hir_id: HirId,
 }
@@ -1506,7 +1502,7 @@ impl<'hir> Body<'hir> {
 }
 
 /// The type of source expression that caused this generator to be created.
-#[derive(Clone, PartialEq, PartialOrd, Eq, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash)]
 #[derive(HashStable_Generic, Encodable, Decodable)]
 pub enum GeneratorKind {
     /// An explicit `async` block or the body of an async function.
@@ -1539,7 +1535,7 @@ impl GeneratorKind {
 ///
 /// This helps error messages but is also used to drive coercions in
 /// type-checking (see #60424).
-#[derive(Clone, PartialEq, PartialOrd, Eq, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy)]
 #[derive(HashStable_Generic, Encodable, Decodable)]
 pub enum AsyncGeneratorKind {
     /// An explicit `async` block written by the user.
@@ -1649,7 +1645,7 @@ impl fmt::Display for ConstContext {
 /// A literal.
 pub type Lit = Spanned<LitKind>;
 
-#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub enum ArrayLen {
     Infer(HirId, Span),
     Body(AnonConst),
@@ -1671,7 +1667,7 @@ impl ArrayLen {
 ///
 /// You can check if this anon const is a default in a const param
 /// `const N: usize = { ... }` with `tcx.hir().opt_const_param_default_param_def_id(..)`
-#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub struct AnonConst {
     pub hir_id: HirId,
     pub def_id: LocalDefId,
@@ -2105,7 +2101,7 @@ impl<'hir> QPath<'hir> {
 }
 
 /// Hints at the original code for a let statement.
-#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub enum LocalSource {
     /// A `match _ { .. }`.
     Normal,
@@ -2158,7 +2154,7 @@ impl MatchSource {
 }
 
 /// The loop type that yielded an `ExprKind::Loop`.
-#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
 pub enum LoopSource {
     /// A `loop { .. }` loop.
     Loop,
@@ -2178,7 +2174,7 @@ impl LoopSource {
     }
 }
 
-#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub enum LoopIdError {
     OutsideLoopScope,
     UnlabeledCfInWhileCondition,
@@ -2197,7 +2193,7 @@ impl fmt::Display for LoopIdError {
     }
 }
 
-#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub struct Destination {
     /// This is `Some(_)` iff there is an explicit user-specified 'label
     pub label: Option<Label>,
@@ -2208,7 +2204,7 @@ pub struct Destination {
 }
 
 /// The yield kind that caused an `ExprKind::Yield`.
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub enum YieldSource {
     /// An `<expr>.await`.
     Await { expr: Option<HirId> },
@@ -2327,7 +2323,7 @@ impl<'hir> TraitItem<'hir> {
 }
 
 /// Represents a trait method's body (or just argument names).
-#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)]
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum TraitFn<'hir> {
     /// No default body in the trait, just a signature.
     Required(&'hir [Ident]),
@@ -2658,7 +2654,7 @@ pub struct OpaqueTy<'hir> {
 }
 
 /// From whence the opaque type came.
-#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
 pub enum OpaqueTyOrigin {
     /// `-> impl Trait`
     FnReturn(LocalDefId),
@@ -2818,7 +2814,7 @@ impl ImplicitSelfKind {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
 #[derive(HashStable_Generic)]
 pub enum IsAsync {
     Async,
@@ -2831,7 +2827,7 @@ impl IsAsync {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
 pub enum Defaultness {
     Default { has_value: bool },
     Final,
@@ -2887,13 +2883,13 @@ pub enum ClosureBinder {
     For { span: Span },
 }
 
-#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)]
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct Mod<'hir> {
     pub spans: ModSpans,
     pub item_ids: &'hir [ItemId],
 }
 
-#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable)]
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub struct ModSpans {
     /// A span from the first token past `{` to the last token until `}`.
     /// For `mod foo;`, the inner span ranges from the first token
@@ -2922,7 +2918,7 @@ pub struct Variant<'hir> {
     pub span: Span,
 }
 
-#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, 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.
@@ -3233,7 +3229,7 @@ impl fmt::Display for Unsafety {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
 #[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum Constness {
     Const,
@@ -3249,7 +3245,7 @@ impl fmt::Display for Constness {
     }
 }
 
-#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub struct FnHeader {
     pub unsafety: Unsafety,
     pub constness: Constness,
@@ -3381,7 +3377,7 @@ impl ItemKind<'_> {
 /// 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(Encodable, Debug, Clone, Copy, HashStable_Generic)]
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct TraitItemRef {
     pub id: TraitItemId,
     pub ident: Ident,
@@ -3405,7 +3401,7 @@ pub struct ImplItemRef {
     pub trait_item_def_id: Option<DefId>,
 }
 
-#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
 pub enum AssocItemKind {
     Const,
     Fn { has_self: bool },
@@ -3474,7 +3470,7 @@ pub enum ForeignItemKind<'hir> {
 }
 
 /// A variable captured by a closure.
-#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
+#[derive(Debug, Copy, Clone, HashStable_Generic)]
 pub struct Upvar {
     /// First span where it is accessed (there can be multiple).
     pub span: Span,
@@ -3483,7 +3479,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(Encodable, Decodable, Debug, Clone, HashStable_Generic)]
+#[derive(Debug, Clone, HashStable_Generic)]
 pub struct TraitCandidate {
     pub def_id: DefId,
     pub import_ids: SmallVec<[LocalDefId; 1]>,
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 94ca38c0e75..10712e14686 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -203,7 +203,7 @@ impl Scope {
 pub type ScopeDepth = u32;
 
 /// The region scope tree encodes information about region relationships.
-#[derive(TyEncodable, TyDecodable, Default, Debug)]
+#[derive(Default, Debug)]
 pub struct ScopeTree {
     /// If not empty, this body is the root of this region hierarchy.
     pub root_body: Option<hir::HirId>,
@@ -317,13 +317,13 @@ pub struct ScopeTree {
 /// candidates in general). In constants, the `lifetime` field is None
 /// to indicate that certain expressions escape into 'static and
 /// should have no local cleanup scope.
-#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
+#[derive(Debug, Copy, Clone, HashStable)]
 pub enum RvalueCandidateType {
     Borrow { target: hir::ItemLocalId, lifetime: Option<Scope> },
     Pattern { target: hir::ItemLocalId, lifetime: Option<Scope> },
 }
 
-#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
+#[derive(Debug, Copy, Clone, HashStable)]
 pub struct YieldData {
     /// The `Span` of the yield.
     pub span: Span,
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 02433026266..d69d42bb5d3 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -199,7 +199,7 @@ impl<'tcx> ObligationCause<'tcx> {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
 #[derive(TypeVisitable, TypeFoldable)]
 pub struct UnifyReceiverContext<'tcx> {
     pub assoc_item: ty::AssocItem,
@@ -207,7 +207,7 @@ pub struct UnifyReceiverContext<'tcx> {
     pub substs: SubstsRef<'tcx>,
 }
 
-#[derive(Clone, PartialEq, Eq, Hash, Lift, Default, HashStable)]
+#[derive(Clone, PartialEq, Eq, Lift, Default, HashStable)]
 #[derive(TypeVisitable, TypeFoldable, TyEncodable, TyDecodable)]
 pub struct InternedObligationCauseCode<'tcx> {
     /// `None` for `ObligationCauseCode::MiscObligation` (a common case, occurs ~60% of
@@ -243,7 +243,7 @@ impl<'tcx> std::ops::Deref for InternedObligationCauseCode<'tcx> {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
 #[derive(TypeVisitable, TypeFoldable)]
 pub enum ObligationCauseCode<'tcx> {
     /// Not well classified or should be obvious from the span.
@@ -468,7 +468,7 @@ pub enum WellFormedLoc {
     },
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
 #[derive(TypeVisitable, TypeFoldable)]
 pub struct ImplDerivedObligationCause<'tcx> {
     pub derived: DerivedObligationCause<'tcx>,
@@ -529,7 +529,7 @@ impl<'tcx> ty::Lift<'tcx> for StatementAsExpression {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
 #[derive(TypeVisitable, TypeFoldable)]
 pub struct MatchExpressionArmCause<'tcx> {
     pub arm_block_id: Option<hir::HirId>,
@@ -545,7 +545,7 @@ pub struct MatchExpressionArmCause<'tcx> {
     pub opt_suggest_box_span: Option<Span>,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 #[derive(Lift, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
 pub struct IfExpressionCause<'tcx> {
     pub then_id: hir::HirId,
@@ -556,7 +556,7 @@ pub struct IfExpressionCause<'tcx> {
     pub opt_suggest_box_span: Option<Span>,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)]
 #[derive(TypeVisitable, TypeFoldable)]
 pub struct DerivedObligationCause<'tcx> {
     /// The trait predicate of the parent obligation that led to the
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index 30e488a9e47..6187fc43cf8 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -188,7 +188,7 @@ impl<'tcx> AdtDef<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, HashStable, TyEncodable, TyDecodable)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, TyEncodable, TyDecodable)]
 pub enum AdtKind {
     Struct,
     Union,
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index b7976ea3b1c..0f6e4b329b8 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -51,13 +51,6 @@ macro_rules! write_leb128 {
     }};
 }
 
-/// A byte that [cannot occur in UTF8 sequences][utf8]. Used to mark the end of a string.
-/// This way we can skip validation and still be relatively sure that deserialization
-/// did not desynchronize.
-///
-/// [utf8]: https://en.wikipedia.org/w/index.php?title=UTF-8&oldid=1058865525#Codepage_layout
-const STR_SENTINEL: u8 = 0xC1;
-
 impl Encoder for MemEncoder {
     #[inline]
     fn emit_usize(&mut self, v: usize) {
@@ -115,28 +108,6 @@ impl Encoder for MemEncoder {
     }
 
     #[inline]
-    fn emit_i8(&mut self, v: i8) {
-        self.emit_u8(v as u8);
-    }
-
-    #[inline]
-    fn emit_bool(&mut self, v: bool) {
-        self.emit_u8(if v { 1 } else { 0 });
-    }
-
-    #[inline]
-    fn emit_char(&mut self, v: char) {
-        self.emit_u32(v as u32);
-    }
-
-    #[inline]
-    fn emit_str(&mut self, v: &str) {
-        self.emit_usize(v.len());
-        self.emit_raw_bytes(v.as_bytes());
-        self.emit_u8(STR_SENTINEL);
-    }
-
-    #[inline]
     fn emit_raw_bytes(&mut self, s: &[u8]) {
         self.data.extend_from_slice(s);
     }
@@ -481,28 +452,6 @@ impl Encoder for FileEncoder {
     }
 
     #[inline]
-    fn emit_i8(&mut self, v: i8) {
-        self.emit_u8(v as u8);
-    }
-
-    #[inline]
-    fn emit_bool(&mut self, v: bool) {
-        self.emit_u8(if v { 1 } else { 0 });
-    }
-
-    #[inline]
-    fn emit_char(&mut self, v: char) {
-        self.emit_u32(v as u32);
-    }
-
-    #[inline]
-    fn emit_str(&mut self, v: &str) {
-        self.emit_usize(v.len());
-        self.emit_raw_bytes(v.as_bytes());
-        self.emit_u8(STR_SENTINEL);
-    }
-
-    #[inline]
     fn emit_raw_bytes(&mut self, s: &[u8]) {
         self.write_all(s);
     }
@@ -556,39 +505,10 @@ impl<'a> MemDecoder<'a> {
     }
 
     #[inline]
-    fn read_byte(&mut self) -> u8 {
-        if self.current == self.end {
-            Self::decoder_exhausted();
-        }
-        // SAFETY: This type guarantees current <= end, and we just checked current == end.
-        unsafe {
-            let byte = *self.current;
-            self.current = self.current.add(1);
-            byte
-        }
-    }
-
-    #[inline]
     fn read_array<const N: usize>(&mut self) -> [u8; N] {
         self.read_raw_bytes(N).try_into().unwrap()
     }
 
-    // The trait method doesn't have a lifetime parameter, and we need a version of this
-    // that definitely returns a slice based on the underlying storage as opposed to
-    // the Decoder itself in order to implement read_str efficiently.
-    #[inline]
-    fn read_raw_bytes_inherent(&mut self, bytes: usize) -> &'a [u8] {
-        if bytes > self.remaining() {
-            Self::decoder_exhausted();
-        }
-        // SAFETY: We just checked if this range is in-bounds above.
-        unsafe {
-            let slice = std::slice::from_raw_parts(self.current, bytes);
-            self.current = self.current.add(bytes);
-            slice
-        }
-    }
-
     /// While we could manually expose manipulation of the decoder position,
     /// all current users of that method would need to reset the position later,
     /// incurring the bounds check of set_position twice.
@@ -653,7 +573,15 @@ impl<'a> Decoder for MemDecoder<'a> {
 
     #[inline]
     fn read_u8(&mut self) -> u8 {
-        self.read_byte()
+        if self.current == self.end {
+            Self::decoder_exhausted();
+        }
+        // SAFETY: This type guarantees current <= end, and we just checked current == end.
+        unsafe {
+            let byte = *self.current;
+            self.current = self.current.add(1);
+            byte
+        }
     }
 
     #[inline]
@@ -682,38 +610,21 @@ impl<'a> Decoder for MemDecoder<'a> {
     }
 
     #[inline]
-    fn read_i8(&mut self) -> i8 {
-        self.read_byte() as i8
-    }
-
-    #[inline]
     fn read_isize(&mut self) -> isize {
         read_leb128!(self, read_isize_leb128)
     }
 
     #[inline]
-    fn read_bool(&mut self) -> bool {
-        let value = self.read_u8();
-        value != 0
-    }
-
-    #[inline]
-    fn read_char(&mut self) -> char {
-        let bits = self.read_u32();
-        std::char::from_u32(bits).unwrap()
-    }
-
-    #[inline]
-    fn read_str(&mut self) -> &str {
-        let len = self.read_usize();
-        let bytes = self.read_raw_bytes_inherent(len + 1);
-        assert!(bytes[len] == STR_SENTINEL);
-        unsafe { std::str::from_utf8_unchecked(&bytes[..len]) }
-    }
-
-    #[inline]
-    fn read_raw_bytes(&mut self, bytes: usize) -> &[u8] {
-        self.read_raw_bytes_inherent(bytes)
+    fn read_raw_bytes(&mut self, bytes: usize) -> &'a [u8] {
+        if bytes > self.remaining() {
+            Self::decoder_exhausted();
+        }
+        // SAFETY: We just checked if this range is in-bounds above.
+        unsafe {
+            let slice = std::slice::from_raw_parts(self.current, bytes);
+            self.current = self.current.add(bytes);
+            slice
+        }
     }
 
     #[inline]
@@ -787,12 +698,7 @@ impl Encodable<FileEncoder> for IntEncodedWithFixedSize {
 impl<'a> Decodable<MemDecoder<'a>> for IntEncodedWithFixedSize {
     #[inline]
     fn decode(decoder: &mut MemDecoder<'a>) -> IntEncodedWithFixedSize {
-        let _start_pos = decoder.position();
-        let bytes = decoder.read_raw_bytes(IntEncodedWithFixedSize::ENCODED_SIZE);
-        let value = u64::from_le_bytes(bytes.try_into().unwrap());
-        let _end_pos = decoder.position();
-        debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
-
-        IntEncodedWithFixedSize(value)
+        let bytes = decoder.read_array::<{ IntEncodedWithFixedSize::ENCODED_SIZE }>();
+        IntEncodedWithFixedSize(u64::from_le_bytes(bytes))
     }
 }
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index a6d9c7b7d42..e1bc598736f 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -12,6 +12,13 @@ use std::path;
 use std::rc::Rc;
 use std::sync::Arc;
 
+/// A byte that [cannot occur in UTF8 sequences][utf8]. Used to mark the end of a string.
+/// This way we can skip validation and still be relatively sure that deserialization
+/// did not desynchronize.
+///
+/// [utf8]: https://en.wikipedia.org/w/index.php?title=UTF-8&oldid=1058865525#Codepage_layout
+const STR_SENTINEL: u8 = 0xC1;
+
 /// A note about error handling.
 ///
 /// Encoders may be fallible, but in practice failure is rare and there are so
@@ -40,10 +47,29 @@ pub trait Encoder {
     fn emit_i64(&mut self, v: i64);
     fn emit_i32(&mut self, v: i32);
     fn emit_i16(&mut self, v: i16);
-    fn emit_i8(&mut self, v: i8);
-    fn emit_bool(&mut self, v: bool);
-    fn emit_char(&mut self, v: char);
-    fn emit_str(&mut self, v: &str);
+
+    #[inline]
+    fn emit_i8(&mut self, v: i8) {
+        self.emit_u8(v as u8);
+    }
+
+    #[inline]
+    fn emit_bool(&mut self, v: bool) {
+        self.emit_u8(if v { 1 } else { 0 });
+    }
+
+    #[inline]
+    fn emit_char(&mut self, v: char) {
+        self.emit_u32(v as u32);
+    }
+
+    #[inline]
+    fn emit_str(&mut self, v: &str) {
+        self.emit_usize(v.len());
+        self.emit_raw_bytes(v.as_bytes());
+        self.emit_u8(STR_SENTINEL);
+    }
+
     fn emit_raw_bytes(&mut self, s: &[u8]);
 
     fn emit_enum_variant<F>(&mut self, v_id: usize, f: F)
@@ -79,11 +105,38 @@ pub trait Decoder {
     fn read_i64(&mut self) -> i64;
     fn read_i32(&mut self) -> i32;
     fn read_i16(&mut self) -> i16;
-    fn read_i8(&mut self) -> i8;
-    fn read_bool(&mut self) -> bool;
-    fn read_char(&mut self) -> char;
-    fn read_str(&mut self) -> &str;
+
+    #[inline]
+    fn read_i8(&mut self) -> i8 {
+        self.read_u8() as i8
+    }
+
+    #[inline]
+    fn read_bool(&mut self) -> bool {
+        let value = self.read_u8();
+        value != 0
+    }
+
+    #[inline]
+    fn read_char(&mut self) -> char {
+        let bits = self.read_u32();
+        std::char::from_u32(bits).unwrap()
+    }
+
+    #[inline]
+    fn read_str(&mut self) -> &str {
+        let len = self.read_usize();
+        let bytes = self.read_raw_bytes(len + 1);
+        assert!(bytes[len] == STR_SENTINEL);
+        unsafe { std::str::from_utf8_unchecked(&bytes[..len]) }
+    }
+
     fn read_raw_bytes(&mut self, len: usize) -> &[u8];
+
+    // Although there is an `emit_enum_variant` method in `Encoder`, the code
+    // patterns in decoding are different enough to encoding that there is no
+    // need for a corresponding `read_enum_variant` method here.
+
     fn peek_byte(&self) -> u8;
     fn position(&self) -> usize;
 }