about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/ast.rs5
-rw-r--r--compiler/rustc_ast/src/ptr.rs8
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs20
-rw-r--r--compiler/rustc_data_structures/src/fingerprint.rs10
-rw-r--r--compiler/rustc_data_structures/src/svh.rs4
-rw-r--r--compiler/rustc_driver/src/lib.rs5
-rw-r--r--compiler/rustc_errors/src/json/tests.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs4
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs15
-rw-r--r--compiler/rustc_index/src/vec.rs8
-rw-r--r--compiler/rustc_macros/src/serialize.rs18
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs91
-rw-r--r--compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs10
-rw-r--r--compiler/rustc_middle/src/mir/graph_cyclic_cache.rs5
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs30
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs14
-rw-r--r--compiler/rustc_middle/src/mir/predecessors.rs7
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs182
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs45
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs4
-rw-r--r--compiler/rustc_query_impl/src/on_disk_cache.rs117
-rw-r--r--compiler/rustc_query_system/src/dep_graph/serialized.rs17
-rw-r--r--compiler/rustc_serialize/src/collection_impls.rs85
-rw-r--r--compiler/rustc_serialize/src/json.rs185
-rw-r--r--compiler/rustc_serialize/src/opaque.rs88
-rw-r--r--compiler/rustc_serialize/src/serialize.rs221
-rw-r--r--compiler/rustc_serialize/tests/json.rs208
-rw-r--r--compiler/rustc_serialize/tests/opaque.rs2
-rw-r--r--compiler/rustc_span/src/def_id.rs20
-rw-r--r--compiler/rustc_span/src/hygiene.rs25
-rw-r--r--compiler/rustc_span/src/lib.rs52
-rw-r--r--compiler/rustc_span/src/symbol.rs4
-rw-r--r--library/alloc/src/rc.rs44
-rw-r--r--library/alloc/src/sync.rs49
-rw-r--r--library/core/src/ops/bit.rs11
-rw-r--r--library/core/tests/ops.rs6
-rw-r--r--src/bootstrap/builder.rs6
-rw-r--r--src/build_helper/lib.rs16
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md2
-rw-r--r--src/librustdoc/clean/types.rs20
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/librustdoc/html/render/mod.rs2
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css84
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css12
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css11
-rw-r--r--src/librustdoc/html/static/css/themes/light.css13
-rw-r--r--src/librustdoc/html/templates/page.html20
-rw-r--r--src/librustdoc/html/templates/print_item.html2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/librustdoc/scrape_examples.rs2
-rw-r--r--src/test/rustdoc/source-version-separator.rs5
-rw-r--r--src/test/ui-fulldeps/deriving-encodable-decodable-box.rs2
-rw-r--r--src/test/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs2
-rw-r--r--src/test/ui-fulldeps/issue-14021.rs2
-rw-r--r--src/test/ui-fulldeps/issue-4016.rs2
-rw-r--r--src/test/ui-fulldeps/issue-4036.rs2
-rw-r--r--src/test/ui/async-await/proper-span-for-type-error.fixed11
-rw-r--r--src/test/ui/async-await/proper-span-for-type-error.rs11
-rw-r--r--src/test/ui/async-await/proper-span-for-type-error.stderr16
-rw-r--r--src/test/ui/reachable/expr_unary.rs4
-rw-r--r--src/test/ui/reachable/expr_unary.stderr10
65 files changed, 922 insertions, 971 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 438168f4fcc..7c19559ed91 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2418,8 +2418,9 @@ impl<S: Encoder> rustc_serialize::Encodable<S> for AttrId {
 }
 
 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())
+    fn decode(d: &mut D) -> AttrId {
+        d.read_unit();
+        crate::attr::mk_attr_id()
     }
 }
 
diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs
index 9fe87a0a637..70dbda82224 100644
--- a/compiler/rustc_ast/src/ptr.rs
+++ b/compiler/rustc_ast/src/ptr.rs
@@ -115,8 +115,8 @@ impl<T> fmt::Pointer for P<T> {
 }
 
 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)
+    fn decode(d: &mut D) -> P<T> {
+        P(Decodable::decode(d))
     }
 }
 
@@ -204,8 +204,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<[T]> {
 }
 
 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)?))
+    fn decode(d: &mut D) -> P<[T]> {
+        P::from_vec(Decodable::decode(d))
     }
 }
 
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 51cabb50cd3..2174378a560 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -163,7 +163,7 @@ impl<S: Encoder> Encodable<S> for LazyTokenStream {
 }
 
 impl<D: Decoder> Decodable<D> for LazyTokenStream {
-    fn decode(_d: &mut D) -> Result<Self, D::Error> {
+    fn decode(_d: &mut D) -> Self {
         panic!("Attempted to decode LazyTokenStream");
     }
 }
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index f04dc85b28a..17bc8d7591b 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -625,18 +625,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
     ///     }
     /// }
     /// ```
-    fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
-        let dot_await_span = expr.span.shrink_to_hi().to(await_span);
+    fn lower_expr_await(&mut self, dot_await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
+        let full_span = expr.span.to(dot_await_span);
         match self.generator_kind {
             Some(hir::GeneratorKind::Async(_)) => {}
             Some(hir::GeneratorKind::Gen) | None => {
                 let mut err = struct_span_err!(
                     self.sess,
-                    await_span,
+                    dot_await_span,
                     E0728,
                     "`await` is only allowed inside `async` functions and blocks"
                 );
-                err.span_label(await_span, "only allowed inside `async` functions and blocks");
+                err.span_label(dot_await_span, "only allowed inside `async` functions and blocks");
                 if let Some(item_sp) = self.current_item {
                     err.span_label(item_sp, "this is not `async`");
                 }
@@ -646,7 +646,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None);
         let gen_future_span = self.mark_span_with_reason(
             DesugaringKind::Await,
-            await_span,
+            full_span,
             self.allow_gen_future.clone(),
         );
         let expr = self.lower_expr_mut(expr);
@@ -699,9 +699,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let loop_hir_id = self.lower_node_id(loop_node_id);
         let ready_arm = {
             let x_ident = Ident::with_dummy_span(sym::result);
-            let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
-            let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
-            let ready_field = self.single_pat_field(span, x_pat);
+            let (x_pat, x_pat_hid) = self.pat_ident(gen_future_span, x_ident);
+            let x_expr = self.expr_ident(gen_future_span, x_ident, x_pat_hid);
+            let ready_field = self.single_pat_field(gen_future_span, x_pat);
             let ready_pat = self.pat_lang_item_variant(
                 span,
                 hir::LangItem::PollReady,
@@ -711,7 +711,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             let break_x = self.with_loop_scope(loop_node_id, move |this| {
                 let expr_break =
                     hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
-                this.arena.alloc(this.expr(span, expr_break, ThinVec::new()))
+                this.arena.alloc(this.expr(gen_future_span, expr_break, ThinVec::new()))
             });
             self.arm(ready_pat, break_x)
         };
@@ -783,7 +783,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         // `match ::std::future::IntoFuture::into_future(<expr>) { ... }`
         let into_future_span = self.mark_span_with_reason(
             DesugaringKind::Await,
-            await_span,
+            dot_await_span,
             self.allow_into_future.clone(),
         );
         let into_future_expr = self.expr_call_lang_item_fn(
diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs
index c9af35da4bc..525cd650dd2 100644
--- a/compiler/rustc_data_structures/src/fingerprint.rs
+++ b/compiler/rustc_data_structures/src/fingerprint.rs
@@ -149,10 +149,10 @@ impl<E: rustc_serialize::Encoder> Encodable<E> for Fingerprint {
 
 impl<D: rustc_serialize::Decoder> Decodable<D> for Fingerprint {
     #[inline]
-    fn decode(d: &mut D) -> Result<Self, D::Error> {
+    fn decode(d: &mut D) -> Self {
         let mut bytes = [0u8; 16];
-        d.read_raw_bytes_into(&mut bytes)?;
-        Ok(Fingerprint::from_le_bytes(bytes))
+        d.read_raw_bytes_into(&mut bytes);
+        Fingerprint::from_le_bytes(bytes)
     }
 }
 
@@ -195,8 +195,8 @@ impl<E: rustc_serialize::Encoder> Encodable<E> for PackedFingerprint {
 
 impl<D: rustc_serialize::Decoder> Decodable<D> for PackedFingerprint {
     #[inline]
-    fn decode(d: &mut D) -> Result<Self, D::Error> {
-        Fingerprint::decode(d).map(PackedFingerprint)
+    fn decode(d: &mut D) -> Self {
+        Self(Fingerprint::decode(d))
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/svh.rs b/compiler/rustc_data_structures/src/svh.rs
index ce90fbacaa4..12ef286091c 100644
--- a/compiler/rustc_data_structures/src/svh.rs
+++ b/compiler/rustc_data_structures/src/svh.rs
@@ -55,8 +55,8 @@ impl<S: Encoder> Encodable<S> for Svh {
 }
 
 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)
+    fn decode(d: &mut D) -> Svh {
+        Svh::new(u64::from_le(d.read_u64()))
     }
 }
 
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index 19fa6812b45..2b64312dbef 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -597,10 +597,7 @@ impl RustcDefaultCalls {
                 let rlink_data = fs::read_to_string(file).unwrap_or_else(|err| {
                     sess.fatal(&format!("failed to read rlink file: {}", err));
                 });
-                let codegen_results: CodegenResults =
-                    json::decode(&rlink_data).unwrap_or_else(|err| {
-                        sess.fatal(&format!("failed to decode rlink: {}", err));
-                    });
+                let codegen_results: CodegenResults = json::decode(&rlink_data);
                 let result = compiler.codegen_backend().link(sess, codegen_results, &outputs);
                 abort_on_err(result, sess);
             } else {
diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs
index d055937ac36..c5b3d204407 100644
--- a/compiler/rustc_errors/src/json/tests.rs
+++ b/compiler/rustc_errors/src/json/tests.rs
@@ -64,7 +64,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
 
         let bytes = output.lock().unwrap();
         let actual_output = str::from_utf8(&bytes).unwrap();
-        let actual_output: TestData = decode(actual_output).unwrap();
+        let actual_output: TestData = decode(actual_output);
 
         assert_eq!(expected_output, actual_output)
     })
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index a681298301a..dbacbba2ce0 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -99,8 +99,8 @@ impl Hash for ToolMetadata {
 
 // Doesn't really need to round-trip
 impl<D: Decoder> Decodable<D> for ToolMetadata {
-    fn decode(_d: &mut D) -> Result<Self, D::Error> {
-        Ok(ToolMetadata(None))
+    fn decode(_d: &mut D) -> Self {
+        ToolMetadata(None)
     }
 }
 
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index d563a6ca478..870c3f80682 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -158,14 +158,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
             // Decode the list of work_products
             let mut work_product_decoder = Decoder::new(&work_products_data[..], start_pos);
             let work_products: Vec<SerializedWorkProduct> =
-                Decodable::decode(&mut work_product_decoder).unwrap_or_else(|e| {
-                    let msg = format!(
-                        "Error decoding `work-products` from incremental \
-                                    compilation session directory: {}",
-                        e
-                    );
-                    sess.fatal(&msg)
-                });
+                Decodable::decode(&mut work_product_decoder);
 
             for swp in work_products {
                 let mut all_files_exist = true;
@@ -203,8 +196,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
             LoadResult::Error { message } => LoadResult::Error { message },
             LoadResult::Ok { data: (bytes, start_pos) } => {
                 let mut decoder = Decoder::new(&bytes, start_pos);
-                let prev_commandline_args_hash = u64::decode(&mut decoder)
-                    .expect("Error reading commandline arg hash from cached dep-graph");
+                let prev_commandline_args_hash = u64::decode(&mut decoder);
 
                 if prev_commandline_args_hash != expected_hash {
                     if report_incremental_info {
@@ -220,8 +212,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
                     return LoadResult::DataOutOfDate;
                 }
 
-                let dep_graph = SerializedDepGraph::decode(&mut decoder)
-                    .expect("Error reading cached dep-graph");
+                let dep_graph = SerializedDepGraph::decode(&mut decoder);
 
                 LoadResult::Ok { data: (dep_graph, prev_work_products) }
             }
diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs
index e3c6528b218..8b61530577d 100644
--- a/compiler/rustc_index/src/vec.rs
+++ b/compiler/rustc_index/src/vec.rs
@@ -395,8 +395,8 @@ macro_rules! newtype_index {
 
     (@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)
+            fn decode(d: &mut D) -> Self {
+                Self::from_u32(d.read_u32())
             }
         }
         impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for $type {
@@ -527,8 +527,8 @@ impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for &IndexVec<I, T> {
 }
 
 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 })
+    fn decode(d: &mut D) -> Self {
+        IndexVec { raw: Decodable::decode(d), _marker: PhantomData }
     }
 }
 
diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs
index 3351564299c..6c5461505fa 100644
--- a/compiler/rustc_macros/src/serialize.rs
+++ b/compiler/rustc_macros/src/serialize.rs
@@ -47,7 +47,7 @@ fn decodable_body(
             quote! {
                 ::rustc_serialize::Decoder::read_struct(
                     __decoder,
-                    |__decoder| { ::std::result::Result::Ok(#construct) },
+                    |__decoder| { #construct },
                 )
             }
         }
@@ -57,7 +57,7 @@ fn decodable_body(
                 .enumerate()
                 .map(|(idx, vi)| {
                     let construct = vi.construct(|field, index| decode_field(field, index, false));
-                    quote! { #idx => { ::std::result::Result::Ok(#construct) } }
+                    quote! { #idx => { #construct } }
                 })
                 .collect();
             let names: TokenStream = variants
@@ -82,8 +82,7 @@ fn decodable_body(
                             |__decoder, __variant_idx| {
                                 match __variant_idx {
                                     #match_inner
-                                    _ => return ::std::result::Result::Err(
-                                        ::rustc_serialize::Decoder::error(__decoder, #message)),
+                                    _ => panic!(#message),
                                 }
                             })
                     }
@@ -95,9 +94,7 @@ fn decodable_body(
     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> {
+            fn decode(__decoder: &mut #decoder_ty) -> Self {
                 #decode_body
             }
         },
@@ -127,12 +124,7 @@ fn decode_field(field: &syn::Field, index: usize, is_struct: bool) -> proc_macro
                 #__decoder, #opt_field_name #decode_inner_method)
     };
 
-    quote! {
-        match #decode_call  {
-            ::std::result::Result::Ok(__res) => __res,
-            ::std::result::Result::Err(__err) => return ::std::result::Result::Err(__err),
-        }
-    }
+    quote! { #decode_call }
 }
 
 pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 220bc9c5f75..5474d92072e 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -263,7 +263,7 @@ 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);
-        T::decode(&mut dcx).unwrap()
+        T::decode(&mut dcx)
     }
 }
 
@@ -274,7 +274,7 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<[T]> {
     ) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
         let mut dcx = metadata.decoder(self.position.get());
         dcx.lazy_state = LazyState::NodeStart(self.position);
-        (0..self.meta).map(move |_| T::decode(&mut dcx).unwrap())
+        (0..self.meta).map(move |_| T::decode(&mut dcx))
     }
 }
 
@@ -300,11 +300,8 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
         if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] }
     }
 
-    fn read_lazy_with_meta<T: ?Sized + LazyMeta>(
-        &mut self,
-        meta: T::Meta,
-    ) -> Result<Lazy<T>, <Self as Decoder>::Error> {
-        let distance = self.read_usize()?;
+    fn read_lazy_with_meta<T: ?Sized + LazyMeta>(&mut self, meta: T::Meta) -> Lazy<T> {
+        let distance = self.read_usize();
         let position = match self.lazy_state {
             LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
             LazyState::NodeStart(start) => {
@@ -315,7 +312,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
             LazyState::Previous(last_pos) => last_pos.get() + distance,
         };
         self.lazy_state = LazyState::Previous(NonZeroUsize::new(position).unwrap());
-        Ok(Lazy::from_position_and_meta(NonZeroUsize::new(position).unwrap(), meta))
+        Lazy::from_position_and_meta(NonZeroUsize::new(position).unwrap(), meta)
     }
 
     #[inline]
@@ -342,25 +339,21 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
         self.opaque.position()
     }
 
-    fn cached_ty_for_shorthand<F>(
-        &mut self,
-        shorthand: usize,
-        or_insert_with: F,
-    ) -> Result<Ty<'tcx>, Self::Error>
+    fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
     where
-        F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>,
+        F: FnOnce(&mut Self) -> Ty<'tcx>,
     {
         let tcx = self.tcx();
 
         let key = ty::CReaderCacheKey { cnum: Some(self.cdata().cnum), pos: shorthand };
 
         if let Some(&ty) = tcx.ty_rcache.borrow().get(&key) {
-            return Ok(ty);
+            return ty;
         }
 
-        let ty = or_insert_with(self)?;
+        let ty = or_insert_with(self);
         tcx.ty_rcache.borrow_mut().insert(key, ty);
-        Ok(ty)
+        ty
     }
 
     fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
@@ -376,7 +369,7 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
         r
     }
 
-    fn decode_alloc_id(&mut self) -> Result<rustc_middle::mir::interpret::AllocId, Self::Error> {
+    fn decode_alloc_id(&mut self) -> rustc_middle::mir::interpret::AllocId {
         if let Some(alloc_decoding_session) = self.alloc_decoding_session {
             alloc_decoding_session.decode_alloc_id(self)
         } else {
@@ -386,48 +379,48 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
 }
 
 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))
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> CrateNum {
+        let cnum = CrateNum::from_u32(d.read_u32());
+        d.map_encoded_cnum_to_current(cnum)
     }
 }
 
 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()?))
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefIndex {
+        DefIndex::from_u32(d.read_u32())
     }
 }
 
 impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnIndex {
-    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<ExpnIndex, String> {
-        Ok(ExpnIndex::from_u32(d.read_u32()?))
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> ExpnIndex {
+        ExpnIndex::from_u32(d.read_u32())
     }
 }
 
 impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
-    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<SyntaxContext, String> {
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SyntaxContext {
         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
+            cdata
                 .root
                 .syntax_contexts
                 .get(cdata, id)
                 .unwrap_or_else(|| panic!("Missing SyntaxContext {:?} for crate {:?}", id, cname))
-                .decode((cdata, sess)))
+                .decode((cdata, sess))
         })
     }
 }
 
 impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
-    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<ExpnId, String> {
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> ExpnId {
         let local_cdata = decoder.cdata();
         let sess = decoder.sess.unwrap();
 
-        let cnum = CrateNum::decode(decoder)?;
-        let index = u32::decode(decoder)?;
+        let cnum = CrateNum::decode(decoder);
+        let index = u32::decode(decoder);
 
         let expn_id = rustc_span::hygiene::decode_expn_id(cnum, index, |expn_id| {
             let ExpnId { krate: cnum, local_id: index } = expn_id;
@@ -453,23 +446,23 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
                 .decode((crate_data, sess));
             (expn_data, expn_hash)
         });
-        Ok(expn_id)
+        expn_id
     }
 }
 
 impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
-    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Span, String> {
-        let ctxt = SyntaxContext::decode(decoder)?;
-        let tag = u8::decode(decoder)?;
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Span {
+        let ctxt = SyntaxContext::decode(decoder);
+        let tag = u8::decode(decoder);
 
         if tag == TAG_PARTIAL_SPAN {
-            return Ok(DUMMY_SP.with_ctxt(ctxt));
+            return DUMMY_SP.with_ctxt(ctxt);
         }
 
         debug_assert!(tag == TAG_VALID_SPAN_LOCAL || tag == TAG_VALID_SPAN_FOREIGN);
 
-        let lo = BytePos::decode(decoder)?;
-        let len = BytePos::decode(decoder)?;
+        let lo = BytePos::decode(decoder);
+        let len = BytePos::decode(decoder);
         let hi = lo + len;
 
         let Some(sess) = decoder.sess else {
@@ -512,7 +505,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
             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(decoder)?;
+                let cnum = u32::decode(decoder);
                 panic!(
                     "Decoding of crate {:?} tried to access proc-macro dep {:?}",
                     decoder.cdata().root.name,
@@ -520,7 +513,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
                 );
             }
             // tag is TAG_VALID_SPAN_FOREIGN, checked by `debug_assert` above
-            let cnum = CrateNum::decode(decoder)?;
+            let cnum = CrateNum::decode(decoder);
             debug!(
                 "SpecializedDecoder<Span>::specialized_decode: loading source files from cnum {:?}",
                 cnum
@@ -582,18 +575,18 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
             (hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
 
         // Do not try to decode parent for foreign spans.
-        Ok(Span::new(lo, hi, ctxt, None))
+        Span::new(lo, hi, ctxt, None)
     }
 }
 
 impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
-    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
         ty::codec::RefDecodable::decode(d)
     }
 }
 
 impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
-    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
         ty::codec::RefDecodable::decode(d)
     }
 }
@@ -601,7 +594,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'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> {
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
         decoder.read_lazy_with_meta(())
     }
 }
@@ -609,9 +602,9 @@ impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a
 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) }
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
+        let len = decoder.read_usize();
+        if len == 0 { Lazy::empty() } else { decoder.read_lazy_with_meta(len) }
     }
 }
 
@@ -620,8 +613,8 @@ impl<'a, 'tcx, I: Idx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeCo
 where
     Option<T>: FixedSizeEncoding,
 {
-    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
-        let len = decoder.read_usize()?;
+    fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
+        let len = decoder.read_usize();
         decoder.read_lazy_with_meta(len)
     }
 }
diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
index 054431169a2..d66f2b031a8 100644
--- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
+++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
@@ -39,11 +39,11 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for DefPathHashMapRef<'tcx> {
 }
 
 impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static> {
-    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<DefPathHashMapRef<'static>, String> {
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> {
         // Import TyDecoder so we can access the DecodeContext::position() method
         use crate::rustc_middle::ty::codec::TyDecoder;
 
-        let len = d.read_usize()?;
+        let len = d.read_usize();
         let pos = d.position();
         let o = OwningRef::new(d.blob().clone()).map(|x| &x[pos..pos + len]);
 
@@ -52,7 +52,9 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static>
         // the method. We use read_raw_bytes() for that.
         let _ = d.read_raw_bytes(len);
 
-        let inner = odht::HashTable::from_raw_bytes(o).map_err(|e| format!("{}", e))?;
-        Ok(DefPathHashMapRef::OwnedFromMetadata(inner))
+        let inner = odht::HashTable::from_raw_bytes(o).unwrap_or_else(|e| {
+            panic!("decode error: {}", e);
+        });
+        DefPathHashMapRef::OwnedFromMetadata(inner)
     }
 }
diff --git a/compiler/rustc_middle/src/mir/graph_cyclic_cache.rs b/compiler/rustc_middle/src/mir/graph_cyclic_cache.rs
index 5f028975bd0..e2f3d6e078f 100644
--- a/compiler/rustc_middle/src/mir/graph_cyclic_cache.rs
+++ b/compiler/rustc_middle/src/mir/graph_cyclic_cache.rs
@@ -45,8 +45,9 @@ impl<S: serialize::Encoder> serialize::Encodable<S> for GraphIsCyclicCache {
 
 impl<D: serialize::Decoder> serialize::Decodable<D> for GraphIsCyclicCache {
     #[inline]
-    fn decode(d: &mut D) -> Result<Self, D::Error> {
-        serialize::Decodable::decode(d).map(|_v: ()| Self::new())
+    fn decode(d: &mut D) -> Self {
+        let () = serialize::Decodable::decode(d);
+        Self::new()
     }
 }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index b762a10da84..66f2c6e78a2 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -273,20 +273,20 @@ pub struct AllocDecodingSession<'s> {
 
 impl<'s> AllocDecodingSession<'s> {
     /// Decodes an `AllocId` in a thread-safe way.
-    pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> Result<AllocId, D::Error>
+    pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> AllocId
     where
         D: TyDecoder<'tcx>,
     {
         // Read the index of the allocation.
-        let idx = usize::try_from(decoder.read_u32()?).unwrap();
+        let idx = usize::try_from(decoder.read_u32()).unwrap();
         let pos = usize::try_from(self.state.data_offsets[idx]).unwrap();
 
         // Decode the `AllocDiscriminant` now so that we know if we have to reserve an
         // `AllocId`.
         let (alloc_kind, pos) = decoder.with_position(pos, |decoder| {
-            let alloc_kind = AllocDiscriminant::decode(decoder)?;
-            Ok((alloc_kind, decoder.position()))
-        })?;
+            let alloc_kind = AllocDiscriminant::decode(decoder);
+            (alloc_kind, decoder.position())
+        });
 
         // Check the decoding state to see if it's already decoded or if we should
         // decode it here.
@@ -295,7 +295,7 @@ impl<'s> AllocDecodingSession<'s> {
 
             match *entry {
                 State::Done(alloc_id) => {
-                    return Ok(alloc_id);
+                    return alloc_id;
                 }
                 ref mut entry @ State::Empty => {
                     // We are allowed to decode.
@@ -329,7 +329,7 @@ impl<'s> AllocDecodingSession<'s> {
                 State::InProgress(ref mut sessions, alloc_id) => {
                     if sessions.contains(&self.session_id) {
                         // Don't recurse.
-                        return Ok(alloc_id);
+                        return alloc_id;
                     } else {
                         // Start decoding concurrently.
                         sessions.insert(self.session_id);
@@ -343,37 +343,37 @@ impl<'s> AllocDecodingSession<'s> {
         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);
                     decoder.tcx().set_alloc_id_same_memory(alloc_id, alloc);
-                    Ok(alloc_id)
+                    alloc_id
                 }
                 AllocDiscriminant::Fn => {
                     assert!(alloc_id.is_none());
                     trace!("creating fn alloc ID");
-                    let instance = ty::Instance::decode(decoder)?;
+                    let instance = ty::Instance::decode(decoder);
                     trace!("decoded fn alloc instance: {:?}", instance);
                     let alloc_id = decoder.tcx().create_fn_alloc(instance);
-                    Ok(alloc_id)
+                    alloc_id
                 }
                 AllocDiscriminant::Static => {
                     assert!(alloc_id.is_none());
                     trace!("creating extern static alloc ID");
-                    let did = <DefId as Decodable<D>>::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)
+                    alloc_id
                 }
             }
-        })?;
+        });
 
         self.state.decoding_state[idx].with_lock(|entry| {
             *entry = State::Done(alloc_id);
         });
 
-        Ok(alloc_id)
+        alloc_id
     }
 }
 
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 48f39b26152..c7b1e25b993 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -619,20 +619,20 @@ impl<'tcx, E: TyEncoder<'tcx>, T: Encodable<E>> Encodable<E> for ClearCrossCrate
 }
 impl<'tcx, D: TyDecoder<'tcx>, T: Decodable<D>> Decodable<D> for ClearCrossCrate<T> {
     #[inline]
-    fn decode(d: &mut D) -> Result<ClearCrossCrate<T>, D::Error> {
+    fn decode(d: &mut D) -> ClearCrossCrate<T> {
         if D::CLEAR_CROSS_CRATE {
-            return Ok(ClearCrossCrate::Clear);
+            return ClearCrossCrate::Clear;
         }
 
-        let discr = u8::decode(d)?;
+        let discr = u8::decode(d);
 
         match discr {
-            TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(ClearCrossCrate::Clear),
+            TAG_CLEAR_CROSS_CRATE_CLEAR => ClearCrossCrate::Clear,
             TAG_CLEAR_CROSS_CRATE_SET => {
-                let val = T::decode(d)?;
-                Ok(ClearCrossCrate::Set(val))
+                let val = T::decode(d);
+                ClearCrossCrate::Set(val)
             }
-            tag => Err(d.error(&format!("Invalid tag for ClearCrossCrate: {:?}", tag))),
+            tag => panic!("Invalid tag for ClearCrossCrate: {:?}", tag),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/mir/predecessors.rs b/compiler/rustc_middle/src/mir/predecessors.rs
index fd6bb76dc43..2562baac911 100644
--- a/compiler/rustc_middle/src/mir/predecessors.rs
+++ b/compiler/rustc_middle/src/mir/predecessors.rs
@@ -57,14 +57,15 @@ impl PredecessorCache {
 impl<S: serialize::Encoder> serialize::Encodable<S> for PredecessorCache {
     #[inline]
     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
-        serialize::Encodable::encode(&(), s)
+        s.emit_unit()
     }
 }
 
 impl<D: serialize::Decoder> serialize::Decodable<D> for PredecessorCache {
     #[inline]
-    fn decode(d: &mut D) -> Result<Self, D::Error> {
-        serialize::Decodable::decode(d).map(|_v: ()| Self::new())
+    fn decode(d: &mut D) -> Self {
+        let () = d.read_unit();
+        Self::new()
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index db37d98614e..65b91eedf8a 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -14,7 +14,7 @@ use crate::mir::{
 };
 use crate::thir;
 use crate::ty::subst::SubstsRef;
-use crate::ty::{self, List, Ty, TyCtxt};
+use crate::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_span::Span;
@@ -71,7 +71,7 @@ pub trait TyEncoder<'tcx>: Encoder {
 /// `Decodable` can still be implemented in cases where `Decodable` is required
 /// by a trait bound.
 pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>> {
-    fn decode(d: &mut D) -> Result<&'tcx Self, D::Error>;
+    fn decode(d: &mut D) -> &'tcx Self;
 }
 
 /// Encode the given value or a previously cached shorthand.
@@ -172,13 +172,9 @@ pub trait TyDecoder<'tcx>: Decoder {
 
     fn position(&self) -> usize;
 
-    fn cached_ty_for_shorthand<F>(
-        &mut self,
-        shorthand: usize,
-        or_insert_with: F,
-    ) -> Result<Ty<'tcx>, Self::Error>
+    fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
     where
-        F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>;
+        F: FnOnce(&mut Self) -> Ty<'tcx>;
 
     fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
     where
@@ -188,35 +184,35 @@ pub trait TyDecoder<'tcx>: Decoder {
         (self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
     }
 
-    fn decode_alloc_id(&mut self) -> Result<AllocId, Self::Error>;
+    fn decode_alloc_id(&mut self) -> AllocId;
 }
 
 #[inline]
 fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
     decoder: &mut D,
-) -> Result<&'tcx T, D::Error>
+) -> &'tcx T
 where
     D: TyDecoder<'tcx>,
 {
-    Ok(decoder.tcx().arena.alloc(Decodable::decode(decoder)?))
+    decoder.tcx().arena.alloc(Decodable::decode(decoder))
 }
 
 #[inline]
 fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
     decoder: &mut D,
-) -> Result<&'tcx [T], D::Error>
+) -> &'tcx [T]
 where
     D: TyDecoder<'tcx>,
 {
-    Ok(decoder.tcx().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder)?))
+    decoder.tcx().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder))
 }
 
 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> {
+    fn decode(decoder: &mut D) -> Ty<'tcx> {
         // Handle shorthands first, if we have a usize > 0x80.
         if decoder.positioned_at_shorthand() {
-            let pos = decoder.read_usize()?;
+            let pos = decoder.read_usize();
             assert!(pos >= SHORTHAND_OFFSET);
             let shorthand = pos - SHORTHAND_OFFSET;
 
@@ -225,87 +221,89 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
             })
         } else {
             let tcx = decoder.tcx();
-            Ok(tcx.mk_ty(ty::TyKind::decode(decoder)?))
+            tcx.mk_ty(ty::TyKind::decode(decoder))
         }
     }
 }
 
 impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
-    fn decode(decoder: &mut D) -> Result<ty::Binder<'tcx, ty::PredicateKind<'tcx>>, D::Error> {
-        let bound_vars = Decodable::decode(decoder)?;
+    fn decode(decoder: &mut D) -> ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
+        let bound_vars = Decodable::decode(decoder);
         // Handle shorthands first, if we have a usize > 0x80.
-        Ok(ty::Binder::bind_with_vars(
+        ty::Binder::bind_with_vars(
             if decoder.positioned_at_shorthand() {
-                let pos = decoder.read_usize()?;
+                let pos = decoder.read_usize();
                 assert!(pos >= SHORTHAND_OFFSET);
                 let shorthand = pos - SHORTHAND_OFFSET;
 
-                decoder.with_position(shorthand, ty::PredicateKind::decode)?
+                decoder.with_position(shorthand, ty::PredicateKind::decode)
             } else {
-                ty::PredicateKind::decode(decoder)?
+                ty::PredicateKind::decode(decoder)
             },
             bound_vars,
-        ))
+        )
     }
 }
 
 impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
-    fn decode(decoder: &mut D) -> Result<ty::Predicate<'tcx>, D::Error> {
-        let predicate_kind = Decodable::decode(decoder)?;
-        let predicate = decoder.tcx().mk_predicate(predicate_kind);
-        Ok(predicate)
+    fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
+        let predicate_kind = Decodable::decode(decoder);
+        decoder.tcx().mk_predicate(predicate_kind)
     }
 }
 
 impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for SubstsRef<'tcx> {
-    fn decode(decoder: &mut D) -> Result<Self, D::Error> {
-        let len = decoder.read_usize()?;
+    fn decode(decoder: &mut D) -> Self {
+        let len = decoder.read_usize();
         let tcx = decoder.tcx();
-        tcx.mk_substs((0..len).map(|_| Decodable::decode(decoder)))
+        tcx.mk_substs(
+            (0..len).map::<ty::subst::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
+        )
     }
 }
 
 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 })
+    fn decode(decoder: &mut D) -> Self {
+        let local: mir::Local = Decodable::decode(decoder);
+        let len = decoder.read_usize();
+        let projection = decoder.tcx().mk_place_elems(
+            (0..len).map::<mir::PlaceElem<'tcx>, _>(|_| Decodable::decode(decoder)),
+        );
+        mir::Place { local, projection }
     }
 }
 
 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)?))
+    fn decode(decoder: &mut D) -> Self {
+        decoder.tcx().mk_region(Decodable::decode(decoder))
     }
 }
 
 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<'tcx>>, _> =
+    fn decode(decoder: &mut D) -> Self {
+        let len = decoder.read_usize();
+        let interned: Vec<CanonicalVarInfo<'tcx>> =
             (0..len).map(|_| Decodable::decode(decoder)).collect();
-        Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice()))
+        decoder.tcx().intern_canonical_var_infos(interned.as_slice())
     }
 }
 
 impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AllocId {
-    fn decode(decoder: &mut D) -> Result<Self, D::Error> {
+    fn decode(decoder: &mut D) -> Self {
         decoder.decode_alloc_id()
     }
 }
 
 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()?))
+    fn decode(decoder: &mut D) -> Self {
+        ty::SymbolName::new(decoder.tcx(), &decoder.read_str())
     }
 }
 
 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> {
+            fn decode(decoder: &mut D) -> Self {
                 RefDecodable::decode(decoder)
             }
         })*
@@ -313,77 +311,73 @@ macro_rules! impl_decodable_via_ref {
 }
 
 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()?;
-        decoder.tcx().mk_type_list((0..len).map(|_| Decodable::decode(decoder)))
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        let len = decoder.read_usize();
+        decoder.tcx().mk_type_list((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
     }
 }
 
 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
     for ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>
 {
-    fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
-        let len = decoder.read_usize()?;
-        decoder.tcx().mk_poly_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        let len = decoder.read_usize();
+        decoder.tcx().mk_poly_existential_predicates(
+            (0..len).map::<ty::Binder<'tcx, _>, _>(|_| Decodable::decode(decoder)),
+        )
     }
 }
 
 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)?))
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        decoder.tcx().mk_const(Decodable::decode(decoder))
     }
 }
 
 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] {
-    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<_>, _>>()?,
-        ))
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        decoder.tcx().arena.alloc_from_iter(
+            (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
+        )
     }
 }
 
 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)?))
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        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<_>, _>>()?,
-        ))
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        decoder.tcx().arena.alloc_from_iter(
+            (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
+        )
     }
 }
 
 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::Node<'tcx>] {
-    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<_>, _>>()?,
-        ))
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        decoder.tcx().arena.alloc_from_iter(
+            (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
+        )
     }
 }
 
 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::NodeId] {
-    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<_>, _>>()?,
-        ))
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        decoder.tcx().arena.alloc_from_iter(
+            (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
+        )
     }
 }
 
 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::BoundVariableKind> {
-    fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
-        let len = decoder.read_usize()?;
-        decoder.tcx().mk_bound_variable_kinds((0..len).map(|_| Decodable::decode(decoder)))
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        let len = decoder.read_usize();
+        decoder.tcx().mk_bound_variable_kinds(
+            (0..len).map::<ty::BoundVariableKind, _>(|_| Decodable::decode(decoder)),
+        )
     }
 }
 
@@ -405,7 +399,7 @@ macro_rules! __impl_decoder_methods {
     ($($name:ident -> $ty:ty;)*) => {
         $(
             #[inline]
-            fn $name(&mut self) -> Result<$ty, Self::Error> {
+            fn $name(&mut self) -> $ty {
                 self.opaque.$name()
             }
         )*
@@ -418,14 +412,14 @@ macro_rules! impl_arena_allocatable_decoder {
      [$name:ident: $ty:ty]) => {
         impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
             #[inline]
-            fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
+            fn decode(decoder: &mut D) -> &'tcx Self {
                 decode_arena_allocable(decoder)
             }
         }
 
         impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
             #[inline]
-            fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
+            fn decode(decoder: &mut D) -> &'tcx Self {
                 decode_arena_allocable_slice(decoder)
             }
         }
@@ -456,10 +450,8 @@ macro_rules! implement_ty_decoder {
             use super::$DecoderName;
 
             impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
-                type Error = String;
-
                 $crate::__impl_decoder_methods! {
-                    read_nil -> ();
+                    read_unit -> ();
 
                     read_u128 -> u128;
                     read_u64 -> u64;
@@ -483,13 +475,9 @@ macro_rules! implement_ty_decoder {
                 }
 
                 #[inline]
-                fn read_raw_bytes_into(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error> {
+                fn read_raw_bytes_into(&mut self, bytes: &mut [u8]) {
                     self.opaque.read_raw_bytes_into(bytes)
                 }
-
-                fn error(&mut self, err: &str) -> Self::Error {
-                    self.opaque.error(err)
-                }
             }
         }
     }
@@ -505,9 +493,9 @@ macro_rules! impl_binder_encode_decode {
                 }
             }
             impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, $t> {
-                fn decode(decoder: &mut D) -> Result<Self, D::Error> {
-                    let bound_vars = Decodable::decode(decoder)?;
-                    Ok(ty::Binder::bind_with_vars(Decodable::decode(decoder)?, bound_vars))
+                fn decode(decoder: &mut D) -> Self {
+                    let bound_vars = Decodable::decode(decoder);
+                    ty::Binder::bind_with_vars(Decodable::decode(decoder), bound_vars)
                 }
             }
         )*
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index 1f4ebd03676..de45e1bb851 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -147,8 +147,8 @@ impl<S: Encoder> Encodable<S> for ScalarInt {
 }
 
 impl<D: Decoder> Decodable<D> for ScalarInt {
-    fn decode(d: &mut D) -> Result<ScalarInt, D::Error> {
-        Ok(ScalarInt { data: d.read_u128()?, size: d.read_u8()? })
+    fn decode(d: &mut D) -> ScalarInt {
+        ScalarInt { data: d.read_u128(), size: d.read_u8() }
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index f613cd0d450..6c8573805cb 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2794,8 +2794,33 @@ pub trait InternIteratorElement<T, R>: Sized {
 
 impl<T, R> InternIteratorElement<T, R> for T {
     type Output = R;
-    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
-        f(&iter.collect::<SmallVec<[_; 8]>>())
+    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(
+        mut iter: I,
+        f: F,
+    ) -> Self::Output {
+        // This code is hot enough that it's worth specializing for the most
+        // common length lists, to avoid the overhead of `SmallVec` creation.
+        // Lengths 0, 1, and 2 typically account for ~95% of cases. If
+        // `size_hint` is incorrect a panic will occur via an `unwrap` or an
+        // `assert`.
+        match iter.size_hint() {
+            (0, Some(0)) => {
+                assert!(iter.next().is_none());
+                f(&[])
+            }
+            (1, Some(1)) => {
+                let t0 = iter.next().unwrap();
+                assert!(iter.next().is_none());
+                f(&[t0])
+            }
+            (2, Some(2)) => {
+                let t0 = iter.next().unwrap();
+                let t1 = iter.next().unwrap();
+                assert!(iter.next().is_none());
+                f(&[t0, t1])
+            }
+            _ => f(&iter.collect::<SmallVec<[_; 8]>>()),
+        }
     }
 }
 
@@ -2805,6 +2830,7 @@ where
 {
     type Output = R;
     fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
+        // This code isn't hot.
         f(&iter.cloned().collect::<SmallVec<[_; 8]>>())
     }
 }
@@ -2817,10 +2843,15 @@ impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
     ) -> Self::Output {
         // This code is hot enough that it's worth specializing for the most
         // common length lists, to avoid the overhead of `SmallVec` creation.
-        // The match arms are in order of frequency. The 1, 2, and 0 cases are
-        // typically hit in ~95% of cases. We assume that if the upper and
-        // lower bounds from `size_hint` agree they are correct.
+        // Lengths 0, 1, and 2 typically account for ~95% of cases. If
+        // `size_hint` is incorrect a panic will occur via an `unwrap` or an
+        // `assert`, unless a failure happens first, in which case the result
+        // will be an error anyway.
         Ok(match iter.size_hint() {
+            (0, Some(0)) => {
+                assert!(iter.next().is_none());
+                f(&[])
+            }
             (1, Some(1)) => {
                 let t0 = iter.next().unwrap()?;
                 assert!(iter.next().is_none());
@@ -2832,10 +2863,6 @@ impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
                 assert!(iter.next().is_none());
                 f(&[t0, t1])
             }
-            (0, Some(0)) => {
-                assert!(iter.next().is_none());
-                f(&[])
-            }
             _ => f(&iter.collect::<Result<SmallVec<[_; 8]>, _>>()?),
         })
     }
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index 63e9b58584c..cf97344f18e 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -180,8 +180,8 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for GenericArg<'tcx> {
 }
 
 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())
+    fn decode(d: &mut D) -> GenericArg<'tcx> {
+        GenericArgKind::decode(d).pack()
     }
 }
 
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index 5f6d9b050b2..06e276ab42b 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -163,15 +163,12 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
             // Decode the *position* of the footer, which can be found in the
             // last 8 bytes of the file.
             decoder.set_position(data.len() - IntEncodedWithFixedSize::ENCODED_SIZE);
-            let footer_pos = IntEncodedWithFixedSize::decode(&mut decoder)
-                .expect("error while trying to decode footer position")
-                .0 as usize;
+            let footer_pos = IntEncodedWithFixedSize::decode(&mut decoder).0 as usize;
 
             // Decode the file footer, which contains all the lookup tables, etc.
             decoder.set_position(footer_pos);
 
             decode_tagged(&mut decoder, TAG_FILE_FOOTER)
-                .expect("error while trying to decode footer position")
         };
 
         Self {
@@ -372,7 +369,7 @@ impl<'sess> OnDiskCache<'sess> {
         dep_node_index: SerializedDepNodeIndex,
     ) -> QuerySideEffects {
         let side_effects: Option<QuerySideEffects> =
-            self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index, "side_effects");
+            self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index);
 
         side_effects.unwrap_or_default()
     }
@@ -398,7 +395,7 @@ impl<'sess> OnDiskCache<'sess> {
     where
         T: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
     {
-        self.load_indexed(tcx, dep_node_index, &self.query_result_index, "query result")
+        self.load_indexed(tcx, dep_node_index, &self.query_result_index)
     }
 
     /// Stores side effect emitted during computation of an anonymous query.
@@ -423,17 +420,13 @@ impl<'sess> OnDiskCache<'sess> {
         tcx: TyCtxt<'tcx>,
         dep_node_index: SerializedDepNodeIndex,
         index: &FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
-        debug_tag: &'static str,
     ) -> Option<T>
     where
         T: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
     {
         let pos = index.get(&dep_node_index).cloned()?;
 
-        self.with_decoder(tcx, pos, |decoder| match decode_tagged(decoder, dep_node_index) {
-            Ok(v) => Some(v),
-            Err(e) => bug!("could not decode cached {}: {}", debug_tag, e),
-        })
+        self.with_decoder(tcx, pos, |decoder| Some(decode_tagged(decoder, dep_node_index)))
     }
 
     fn with_decoder<'a, 'tcx, T, F: for<'s> FnOnce(&mut CacheDecoder<'s, 'tcx>) -> T>(
@@ -535,7 +528,7 @@ impl<'a, 'tcx> DecoderWithPosition for CacheDecoder<'a, 'tcx> {
 
 // Decodes something that was encoded with `encode_tagged()` and verify that the
 // 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>
+fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> V
 where
     T: Decodable<D> + Eq + std::fmt::Debug,
     V: Decodable<D>,
@@ -543,15 +536,15 @@ where
 {
     let start_pos = decoder.position();
 
-    let actual_tag = T::decode(decoder)?;
+    let actual_tag = T::decode(decoder);
     assert_eq!(actual_tag, expected_tag);
-    let value = V::decode(decoder)?;
+    let value = V::decode(decoder);
     let end_pos = decoder.position();
 
-    let expected_len: u64 = Decodable::decode(decoder)?;
+    let expected_len: u64 = Decodable::decode(decoder);
     assert_eq!((end_pos - start_pos) as u64, expected_len);
 
-    Ok(value)
+    value
 }
 
 impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
@@ -572,26 +565,22 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
         self.opaque.data[self.opaque.position()]
     }
 
-    fn cached_ty_for_shorthand<F>(
-        &mut self,
-        shorthand: usize,
-        or_insert_with: F,
-    ) -> Result<Ty<'tcx>, Self::Error>
+    fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
     where
-        F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>,
+        F: FnOnce(&mut Self) -> Ty<'tcx>,
     {
         let tcx = self.tcx();
 
         let cache_key = ty::CReaderCacheKey { cnum: None, pos: shorthand };
 
         if let Some(&ty) = tcx.ty_rcache.borrow().get(&cache_key) {
-            return Ok(ty);
+            return ty;
         }
 
-        let ty = or_insert_with(self)?;
+        let ty = or_insert_with(self);
         // This may overwrite the entry, but it should overwrite with the same value.
         tcx.ty_rcache.borrow_mut().insert_same(cache_key, ty);
-        Ok(ty)
+        ty
     }
 
     fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
@@ -607,7 +596,7 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
         r
     }
 
-    fn decode_alloc_id(&mut self) -> Result<interpret::AllocId, Self::Error> {
+    fn decode_alloc_id(&mut self) -> interpret::AllocId {
         let alloc_decoding_session = self.alloc_decoding_session;
         alloc_decoding_session.decode_alloc_id(self)
     }
@@ -619,35 +608,35 @@ rustc_middle::implement_ty_decoder!(CacheDecoder<'a, 'tcx>);
 // when a `CacheDecoder` is passed to `Decodable::decode`. Unfortunately, we have to manually opt
 // into specializations this way, given how `CacheDecoder` and the decoding traits currently work.
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Vec<u8> {
-    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         Decodable::decode(&mut d.opaque)
     }
 }
 
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
-    fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+    fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self {
         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();
             this.with_position(pos.to_usize(), |decoder| {
-                let data: SyntaxContextData = decode_tagged(decoder, TAG_SYNTAX_CONTEXT)?;
-                Ok(data)
+                let data: SyntaxContextData = decode_tagged(decoder, TAG_SYNTAX_CONTEXT);
+                data
             })
         })
     }
 }
 
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
-    fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
-        let hash = ExpnHash::decode(decoder)?;
+    fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self {
+        let hash = ExpnHash::decode(decoder);
         if hash.is_root() {
-            return Ok(ExpnId::root());
+            return ExpnId::root();
         }
 
         if let Some(expn_id) = ExpnId::from_hash(hash) {
-            return Ok(expn_id);
+            return expn_id;
         }
 
         let krate = decoder.tcx.stable_crate_id_to_crate_num(hash.stable_crate_id());
@@ -660,7 +649,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
                 .unwrap_or_else(|| panic!("Bad hash {:?} (map {:?})", hash, decoder.expn_data));
 
             let data: ExpnData = decoder
-                .with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA))?;
+                .with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA));
             let expn_id = rustc_span::hygiene::register_local_expn_id(data, hash);
 
             #[cfg(debug_assertions)]
@@ -687,21 +676,21 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
         };
 
         debug_assert_eq!(expn_id.krate, krate);
-        Ok(expn_id)
+        expn_id
     }
 }
 
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
-    fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
-        let ctxt = SyntaxContext::decode(decoder)?;
-        let parent = Option::<LocalDefId>::decode(decoder)?;
-        let tag: u8 = Decodable::decode(decoder)?;
+    fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self {
+        let ctxt = SyntaxContext::decode(decoder);
+        let parent = Option::<LocalDefId>::decode(decoder);
+        let tag: u8 = Decodable::decode(decoder);
 
         if tag == TAG_PARTIAL_SPAN {
-            return Ok(Span::new(BytePos(0), BytePos(0), ctxt, parent));
+            return Span::new(BytePos(0), BytePos(0), ctxt, parent);
         } else if tag == TAG_RELATIVE_SPAN {
-            let dlo = u32::decode(decoder)?;
-            let dto = u32::decode(decoder)?;
+            let dlo = u32::decode(decoder);
+            let dto = u32::decode(decoder);
 
             let enclosing =
                 decoder.tcx.definitions_untracked().def_span(parent.unwrap()).data_untracked();
@@ -712,29 +701,29 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
                 parent,
             );
 
-            return Ok(span);
+            return span;
         } else {
             debug_assert_eq!(tag, TAG_FULL_SPAN);
         }
 
-        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 file_lo_index = SourceFileIndex::decode(decoder);
+        let line_lo = usize::decode(decoder);
+        let col_lo = BytePos::decode(decoder);
+        let len = BytePos::decode(decoder);
 
         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;
 
-        Ok(Span::new(lo, hi, ctxt, parent))
+        Span::new(lo, hi, ctxt, parent)
     }
 }
 
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
-    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
-        let stable_id = StableCrateId::decode(d)?;
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+        let stable_id = StableCrateId::decode(d);
         let cnum = d.tcx.stable_crate_id_to_crate_num(stable_id);
-        Ok(cnum)
+        cnum
     }
 }
 
@@ -743,8 +732,8 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
 // because we would not know how to transform the `DefIndex` to the current
 // context.
 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`"))
+    fn decode(_d: &mut CacheDecoder<'a, 'tcx>) -> DefIndex {
+        panic!("trying to decode `DefIndex` outside the context of a `DefId`")
     }
 }
 
@@ -752,23 +741,23 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefIndex {
 // compilation sessions. We use the `DefPathHash`, which is stable across
 // sessions, to map the old `DefId` to the new one.
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefId {
-    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         // Load the `DefPathHash` which is was we encoded the `DefId` as.
-        let def_path_hash = DefPathHash::decode(d)?;
+        let def_path_hash = DefPathHash::decode(d);
 
         // Using the `DefPathHash`, we can lookup the new `DefId`.
         // Subtle: We only encode a `DefId` as part of a query result.
         // If we get to this point, then all of the query inputs were green,
         // which means that the definition with this hash is guaranteed to
         // still exist in the current compilation session.
-        Ok(d.tcx().def_path_hash_to_def_id(def_path_hash, &mut || {
+        d.tcx().def_path_hash_to_def_id(def_path_hash, &mut || {
             panic!("Failed to convert DefPathHash {:?}", def_path_hash)
-        }))
+        })
     }
 }
 
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId> {
-    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         RefDecodable::decode(d)
     }
 }
@@ -776,31 +765,31 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId>
 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> {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         RefDecodable::decode(d)
     }
 }
 
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
-    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         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> {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         RefDecodable::decode(d)
     }
 }
 
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsmTemplatePiece] {
-    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         RefDecodable::decode(d)
     }
 }
 
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [Span] {
-    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         RefDecodable::decode(d)
     }
 }
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index 47197a1e492..283eda7c85e 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -100,7 +100,7 @@ impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<
     for SerializedDepGraph<K>
 {
     #[instrument(level = "debug", skip(d))]
-    fn decode(d: &mut opaque::Decoder<'a>) -> Result<SerializedDepGraph<K>, String> {
+    fn decode(d: &mut opaque::Decoder<'a>) -> SerializedDepGraph<K> {
         let start_position = d.position();
 
         // The last 16 bytes are the node count and edge count.
@@ -108,8 +108,8 @@ impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<
         d.set_position(d.data.len() - 2 * IntEncodedWithFixedSize::ENCODED_SIZE);
         debug!("position: {:?}", d.position());
 
-        let node_count = IntEncodedWithFixedSize::decode(d)?.0 as usize;
-        let edge_count = IntEncodedWithFixedSize::decode(d)?.0 as usize;
+        let node_count = IntEncodedWithFixedSize::decode(d).0 as usize;
+        let edge_count = IntEncodedWithFixedSize::decode(d).0 as usize;
         debug!(?node_count, ?edge_count);
 
         debug!("position: {:?}", d.position());
@@ -123,12 +123,12 @@ impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<
 
         for _index in 0..node_count {
             d.read_struct(|d| {
-                let dep_node: DepNode<K> = d.read_struct_field("node", Decodable::decode)?;
+                let dep_node: DepNode<K> = d.read_struct_field("node", Decodable::decode);
                 let _i: SerializedDepNodeIndex = nodes.push(dep_node);
                 debug_assert_eq!(_i.index(), _index);
 
                 let fingerprint: Fingerprint =
-                    d.read_struct_field("fingerprint", Decodable::decode)?;
+                    d.read_struct_field("fingerprint", Decodable::decode);
                 let _i: SerializedDepNodeIndex = fingerprints.push(fingerprint);
                 debug_assert_eq!(_i.index(), _index);
 
@@ -136,22 +136,21 @@ impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<
                     d.read_seq(|d, len| {
                         let start = edge_list_data.len().try_into().unwrap();
                         for _ in 0..len {
-                            let edge = d.read_seq_elt(Decodable::decode)?;
+                            let edge = d.read_seq_elt(Decodable::decode);
                             edge_list_data.push(edge);
                         }
                         let end = edge_list_data.len().try_into().unwrap();
                         let _i: SerializedDepNodeIndex = edge_list_indices.push((start, end));
                         debug_assert_eq!(_i.index(), _index);
-                        Ok(())
                     })
                 })
-            })?;
+            });
         }
 
         let index: FxHashMap<_, _> =
             nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect();
 
-        Ok(SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index })
+        SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index }
     }
 }
 
diff --git a/compiler/rustc_serialize/src/collection_impls.rs b/compiler/rustc_serialize/src/collection_impls.rs
index 80a7f650188..02b28f7c626 100644
--- a/compiler/rustc_serialize/src/collection_impls.rs
+++ b/compiler/rustc_serialize/src/collection_impls.rs
@@ -17,15 +17,8 @@ impl<S: Encoder, A: Array<Item: Encodable<S>>> Encodable<S> for SmallVec<A> {
 }
 
 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>
-            for _ in 0..len {
-                vec.push(d.read_seq_elt(|d| Decodable::decode(d))?);
-            }
-            Ok(vec)
-        })
+    fn decode(d: &mut D) -> SmallVec<A> {
+        d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
     }
 }
 
@@ -41,14 +34,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for LinkedList<T> {
 }
 
 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 _ in 0..len {
-                list.push_back(d.read_seq_elt(|d| Decodable::decode(d))?);
-            }
-            Ok(list)
-        })
+    fn decode(d: &mut D) -> LinkedList<T> {
+        d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
     }
 }
 
@@ -64,14 +51,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for VecDeque<T> {
 }
 
 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 _ in 0..len {
-                deque.push_back(d.read_seq_elt(|d| Decodable::decode(d))?);
-            }
-            Ok(deque)
-        })
+    fn decode(d: &mut D) -> VecDeque<T> {
+        d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
     }
 }
 
@@ -96,15 +77,15 @@ where
     K: Decodable<D> + PartialEq + Ord,
     V: Decodable<D>,
 {
-    fn decode(d: &mut D) -> Result<BTreeMap<K, V>, D::Error> {
+    fn decode(d: &mut D) -> BTreeMap<K, V> {
         d.read_map(|d, len| {
             let mut map = BTreeMap::new();
             for _ in 0..len {
-                let key = d.read_map_elt_key(|d| Decodable::decode(d))?;
-                let val = d.read_map_elt_val(|d| Decodable::decode(d))?;
+                let key = d.read_map_elt_key(|d| Decodable::decode(d));
+                let val = d.read_map_elt_val(|d| Decodable::decode(d));
                 map.insert(key, val);
             }
-            Ok(map)
+            map
         })
     }
 }
@@ -127,13 +108,13 @@ impl<D: Decoder, T> Decodable<D> for BTreeSet<T>
 where
     T: Decodable<D> + PartialEq + Ord,
 {
-    fn decode(d: &mut D) -> Result<BTreeSet<T>, D::Error> {
+    fn decode(d: &mut D) -> BTreeSet<T> {
         d.read_seq(|d, len| {
             let mut set = BTreeSet::new();
             for _ in 0..len {
-                set.insert(d.read_seq_elt(|d| Decodable::decode(d))?);
+                set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
             }
-            Ok(set)
+            set
         })
     }
 }
@@ -161,16 +142,16 @@ where
     V: Decodable<D>,
     S: BuildHasher + Default,
 {
-    fn decode(d: &mut D) -> Result<HashMap<K, V, S>, D::Error> {
+    fn decode(d: &mut D) -> HashMap<K, V, S> {
         d.read_map(|d, len| {
             let state = Default::default();
             let mut map = HashMap::with_capacity_and_hasher(len, state);
             for _ in 0..len {
-                let key = d.read_map_elt_key(|d| Decodable::decode(d))?;
-                let val = d.read_map_elt_val(|d| Decodable::decode(d))?;
+                let key = d.read_map_elt_key(|d| Decodable::decode(d));
+                let val = d.read_map_elt_val(|d| Decodable::decode(d));
                 map.insert(key, val);
             }
-            Ok(map)
+            map
         })
     }
 }
@@ -205,14 +186,14 @@ where
     T: Decodable<D> + Hash + Eq,
     S: BuildHasher + Default,
 {
-    fn decode(d: &mut D) -> Result<HashSet<T, S>, D::Error> {
+    fn decode(d: &mut D) -> HashSet<T, S> {
         d.read_seq(|d, len| {
             let state = Default::default();
             let mut set = HashSet::with_capacity_and_hasher(len, state);
             for _ in 0..len {
-                set.insert(d.read_seq_elt(|d| Decodable::decode(d))?);
+                set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
             }
-            Ok(set)
+            set
         })
     }
 }
@@ -240,16 +221,16 @@ where
     V: Decodable<D>,
     S: BuildHasher + Default,
 {
-    fn decode(d: &mut D) -> Result<indexmap::IndexMap<K, V, S>, D::Error> {
+    fn decode(d: &mut D) -> indexmap::IndexMap<K, V, S> {
         d.read_map(|d, len| {
             let state = Default::default();
             let mut map = indexmap::IndexMap::with_capacity_and_hasher(len, state);
             for _ in 0..len {
-                let key = d.read_map_elt_key(|d| Decodable::decode(d))?;
-                let val = d.read_map_elt_val(|d| Decodable::decode(d))?;
+                let key = d.read_map_elt_key(|d| Decodable::decode(d));
+                let val = d.read_map_elt_val(|d| Decodable::decode(d));
                 map.insert(key, val);
             }
-            Ok(map)
+            map
         })
     }
 }
@@ -274,14 +255,14 @@ where
     T: Decodable<D> + Hash + Eq,
     S: BuildHasher + Default,
 {
-    fn decode(d: &mut D) -> Result<indexmap::IndexSet<T, S>, D::Error> {
+    fn decode(d: &mut D) -> indexmap::IndexSet<T, S> {
         d.read_seq(|d, len| {
             let state = Default::default();
             let mut set = indexmap::IndexSet::with_capacity_and_hasher(len, state);
             for _ in 0..len {
-                set.insert(d.read_seq_elt(|d| Decodable::decode(d))?);
+                set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
             }
-            Ok(set)
+            set
         })
     }
 }
@@ -294,9 +275,9 @@ impl<E: Encoder, T: Encodable<E>> Encodable<E> for Rc<[T]> {
 }
 
 impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<[T]> {
-    fn decode(d: &mut D) -> Result<Rc<[T]>, D::Error> {
-        let vec: Vec<T> = Decodable::decode(d)?;
-        Ok(vec.into())
+    fn decode(d: &mut D) -> Rc<[T]> {
+        let vec: Vec<T> = Decodable::decode(d);
+        vec.into()
     }
 }
 
@@ -308,8 +289,8 @@ impl<E: Encoder, T: Encodable<E>> Encodable<E> for Arc<[T]> {
 }
 
 impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<[T]> {
-    fn decode(d: &mut D) -> Result<Arc<[T]>, D::Error> {
-        let vec: Vec<T> = Decodable::decode(d)?;
-        Ok(vec.into())
+    fn decode(d: &mut D) -> Arc<[T]> {
+        let vec: Vec<T> = Decodable::decode(d);
+        vec.into()
     }
 }
diff --git a/compiler/rustc_serialize/src/json.rs b/compiler/rustc_serialize/src/json.rs
index cb9df3c3389..044de8e4e24 100644
--- a/compiler/rustc_serialize/src/json.rs
+++ b/compiler/rustc_serialize/src/json.rs
@@ -89,7 +89,7 @@
 //! let encoded = json::encode(&object).unwrap();
 //!
 //! // Deserialize using `json::decode`
-//! let decoded: TestStruct = json::decode(&encoded[..]).unwrap();
+//! let decoded: TestStruct = json::decode(&encoded[..]);
 //! ```
 //!
 //! ## Using the `ToJson` trait
@@ -173,7 +173,7 @@
 //! let json_str: String = json_obj.to_string();
 //!
 //! // Deserialize like before
-//! let decoded: TestStruct = json::decode(&json_str).unwrap();
+//! let decoded: TestStruct = json::decode(&json_str);
 //! ```
 
 use self::DecoderError::*;
@@ -265,6 +265,12 @@ pub enum DecoderError {
     ApplicationError(string::String),
 }
 
+macro_rules! bad {
+    ($e:expr) => {{
+        panic!("json decode error: {:?}", $e);
+    }};
+}
+
 #[derive(Copy, Clone, Debug)]
 pub enum EncoderError {
     FmtError(fmt::Error),
@@ -295,10 +301,10 @@ pub fn error_str(error: ErrorCode) -> &'static str {
 }
 
 /// Shortcut function to decode a JSON `&str` into an object
-pub fn decode<T: crate::Decodable<Decoder>>(s: &str) -> DecodeResult<T> {
+pub fn decode<T: crate::Decodable<Decoder>>(s: &str) -> T {
     let json = match from_str(s) {
         Ok(x) => x,
-        Err(e) => return Err(ParseError(e)),
+        Err(e) => bad!(ParseError(e)),
     };
 
     let mut decoder = Decoder::new(json);
@@ -334,15 +340,6 @@ impl fmt::Display for ParserError {
     }
 }
 
-impl fmt::Display for DecoderError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // FIXME this should be a nicer error
-        fmt::Debug::fmt(self, f)
-    }
-}
-
-impl std::error::Error for DecoderError {}
-
 impl fmt::Display for EncoderError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // FIXME this should be a nicer error
@@ -2206,41 +2203,39 @@ impl Decoder {
 macro_rules! expect {
     ($e:expr, Null) => {{
         match $e {
-            Json::Null => Ok(()),
-            other => Err(ExpectedError("Null".to_owned(), other.to_string())),
+            Json::Null => (),
+            other => bad!(ExpectedError("Null".to_owned(), other.to_string())),
         }
     }};
     ($e:expr, $t:ident) => {{
         match $e {
-            Json::$t(v) => Ok(v),
-            other => Err(ExpectedError(stringify!($t).to_owned(), other.to_string())),
+            Json::$t(v) => v,
+            other => bad!(ExpectedError(stringify!($t).to_owned(), other.to_string())),
         }
     }};
 }
 
 macro_rules! read_primitive {
     ($name:ident, $ty:ty) => {
-        fn $name(&mut self) -> DecodeResult<$ty> {
+        fn $name(&mut self) -> $ty {
             match self.pop() {
-                Json::I64(f) => Ok(f as $ty),
-                Json::U64(f) => Ok(f as $ty),
-                Json::F64(f) => Err(ExpectedError("Integer".to_owned(), f.to_string())),
+                Json::I64(f) => f as $ty,
+                Json::U64(f) => f as $ty,
+                Json::F64(f) => bad!(ExpectedError("Integer".to_owned(), f.to_string())),
                 // re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
                 // is going to have a string here, as per JSON spec.
                 Json::String(s) => match s.parse().ok() {
-                    Some(f) => Ok(f),
-                    None => Err(ExpectedError("Number".to_owned(), s)),
+                    Some(f) => f,
+                    None => bad!(ExpectedError("Number".to_owned(), s)),
                 },
-                value => Err(ExpectedError("Number".to_owned(), value.to_string())),
+                value => bad!(ExpectedError("Number".to_owned(), value.to_string())),
             }
         }
     };
 }
 
 impl crate::Decoder for Decoder {
-    type Error = DecoderError;
-
-    fn read_nil(&mut self) -> DecodeResult<()> {
+    fn read_unit(&mut self) -> () {
         expect!(self.pop(), Null)
     }
 
@@ -2257,156 +2252,150 @@ impl crate::Decoder for Decoder {
     read_primitive! { read_i64, i64 }
     read_primitive! { read_i128, i128 }
 
-    fn read_f32(&mut self) -> DecodeResult<f32> {
-        self.read_f64().map(|x| x as f32)
+    fn read_f32(&mut self) -> f32 {
+        self.read_f64() as f32
     }
 
-    fn read_f64(&mut self) -> DecodeResult<f64> {
+    fn read_f64(&mut self) -> f64 {
         match self.pop() {
-            Json::I64(f) => Ok(f as f64),
-            Json::U64(f) => Ok(f as f64),
-            Json::F64(f) => Ok(f),
+            Json::I64(f) => f as f64,
+            Json::U64(f) => f as f64,
+            Json::F64(f) => f,
             Json::String(s) => {
                 // re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
                 // is going to have a string here, as per JSON spec.
                 match s.parse().ok() {
-                    Some(f) => Ok(f),
-                    None => Err(ExpectedError("Number".to_owned(), s)),
+                    Some(f) => f,
+                    None => bad!(ExpectedError("Number".to_owned(), s)),
                 }
             }
-            Json::Null => Ok(f64::NAN),
-            value => Err(ExpectedError("Number".to_owned(), value.to_string())),
+            Json::Null => f64::NAN,
+            value => bad!(ExpectedError("Number".to_owned(), value.to_string())),
         }
     }
 
-    fn read_bool(&mut self) -> DecodeResult<bool> {
+    fn read_bool(&mut self) -> bool {
         expect!(self.pop(), Boolean)
     }
 
-    fn read_char(&mut self) -> DecodeResult<char> {
-        let s = self.read_str()?;
-        {
-            let mut it = s.chars();
-            if let (Some(c), None) = (it.next(), it.next()) {
-                // exactly one character
-                return Ok(c);
-            }
+    fn read_char(&mut self) -> char {
+        let s = self.read_str();
+        let mut it = s.chars();
+        if let (Some(c), None) = (it.next(), it.next()) {
+            // exactly one character
+            return c;
         }
-        Err(ExpectedError("single character string".to_owned(), s.to_string()))
+        bad!(ExpectedError("single character string".to_owned(), s.to_string()));
     }
 
-    fn read_str(&mut self) -> DecodeResult<Cow<'_, str>> {
-        expect!(self.pop(), String).map(Cow::Owned)
+    fn read_str(&mut self) -> Cow<'_, str> {
+        Cow::Owned(expect!(self.pop(), String))
     }
 
-    fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), Self::Error> {
+    fn read_raw_bytes_into(&mut self, s: &mut [u8]) {
         for c in s.iter_mut() {
-            *c = self.read_u8()?;
+            *c = self.read_u8();
         }
-        Ok(())
     }
 
-    fn read_enum<T, F>(&mut self, f: F) -> DecodeResult<T>
+    fn read_enum<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder) -> T,
     {
         f(self)
     }
 
-    fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F) -> DecodeResult<T>
+    fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F) -> T
     where
-        F: FnMut(&mut Decoder, usize) -> DecodeResult<T>,
+        F: FnMut(&mut Decoder, usize) -> T,
     {
         let name = match self.pop() {
             Json::String(s) => s,
             Json::Object(mut o) => {
                 let n = match o.remove("variant") {
                     Some(Json::String(s)) => s,
-                    Some(val) => return Err(ExpectedError("String".to_owned(), val.to_string())),
-                    None => return Err(MissingFieldError("variant".to_owned())),
+                    Some(val) => bad!(ExpectedError("String".to_owned(), val.to_string())),
+                    None => bad!(MissingFieldError("variant".to_owned())),
                 };
                 match o.remove("fields") {
                     Some(Json::Array(l)) => {
                         self.stack.extend(l.into_iter().rev());
                     }
-                    Some(val) => return Err(ExpectedError("Array".to_owned(), val.to_string())),
-                    None => return Err(MissingFieldError("fields".to_owned())),
+                    Some(val) => bad!(ExpectedError("Array".to_owned(), val.to_string())),
+                    None => bad!(MissingFieldError("fields".to_owned())),
                 }
                 n
             }
-            json => return Err(ExpectedError("String or Object".to_owned(), json.to_string())),
+            json => bad!(ExpectedError("String or Object".to_owned(), json.to_string())),
         };
         let idx = match names.iter().position(|n| *n == &name[..]) {
             Some(idx) => idx,
-            None => return Err(UnknownVariantError(name)),
+            None => bad!(UnknownVariantError(name)),
         };
         f(self, idx)
     }
 
-    fn read_enum_variant_arg<T, F>(&mut self, f: F) -> DecodeResult<T>
+    fn read_enum_variant_arg<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder) -> T,
     {
         f(self)
     }
 
-    fn read_struct<T, F>(&mut self, f: F) -> DecodeResult<T>
+    fn read_struct<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder) -> T,
     {
-        let value = f(self)?;
+        let value = f(self);
         self.pop();
-        Ok(value)
+        value
     }
 
-    fn read_struct_field<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T>
+    fn read_struct_field<T, F>(&mut self, name: &str, f: F) -> T
     where
-        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder) -> T,
     {
-        let mut obj = expect!(self.pop(), Object)?;
+        let mut obj = expect!(self.pop(), Object);
 
         let value = match obj.remove(name) {
             None => {
                 // Add a Null and try to parse it as an Option<_>
                 // to get None as a default value.
                 self.stack.push(Json::Null);
-                match f(self) {
-                    Ok(x) => x,
-                    Err(_) => return Err(MissingFieldError(name.to_string())),
-                }
+                f(self)
             }
             Some(json) => {
                 self.stack.push(json);
-                f(self)?
+                f(self)
             }
         };
         self.stack.push(Json::Object(obj));
-        Ok(value)
+        value
     }
 
-    fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> DecodeResult<T>
+    fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> T
     where
-        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder) -> T,
     {
         self.read_seq(move |d, len| {
             if len == tuple_len {
                 f(d)
             } else {
-                Err(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len)))
+                bad!(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len)));
             }
         })
     }
 
-    fn read_tuple_arg<T, F>(&mut self, f: F) -> DecodeResult<T>
+    fn read_tuple_arg<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder) -> T,
     {
         self.read_seq_elt(f)
     }
 
-    fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T>
+    fn read_option<T, F>(&mut self, mut f: F) -> T
     where
-        F: FnMut(&mut Decoder, bool) -> DecodeResult<T>,
+        F: FnMut(&mut Decoder, bool) -> T,
     {
         match self.pop() {
             Json::Null => f(self, false),
@@ -2417,28 +2406,28 @@ impl crate::Decoder for Decoder {
         }
     }
 
-    fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T>
+    fn read_seq<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder, usize) -> T,
     {
-        let array = expect!(self.pop(), Array)?;
+        let array = expect!(self.pop(), Array);
         let len = array.len();
         self.stack.extend(array.into_iter().rev());
         f(self, len)
     }
 
-    fn read_seq_elt<T, F>(&mut self, f: F) -> DecodeResult<T>
+    fn read_seq_elt<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder) -> T,
     {
         f(self)
     }
 
-    fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T>
+    fn read_map<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder, usize) -> T,
     {
-        let obj = expect!(self.pop(), Object)?;
+        let obj = expect!(self.pop(), Object);
         let len = obj.len();
         for (key, value) in obj {
             self.stack.push(value);
@@ -2447,23 +2436,19 @@ impl crate::Decoder for Decoder {
         f(self, len)
     }
 
-    fn read_map_elt_key<T, F>(&mut self, f: F) -> DecodeResult<T>
+    fn read_map_elt_key<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder) -> T,
     {
         f(self)
     }
 
-    fn read_map_elt_val<T, F>(&mut self, f: F) -> DecodeResult<T>
+    fn read_map_elt_val<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder) -> T,
     {
         f(self)
     }
-
-    fn error(&mut self, err: &str) -> DecoderError {
-        ApplicationError(err.to_string())
-    }
 }
 
 /// A trait for converting values to JSON
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index 078237801be..c272c687a7e 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -560,134 +560,126 @@ impl<'a> Decoder<'a> {
 }
 
 macro_rules! read_leb128 {
-    ($dec:expr, $fun:ident) => {{ Ok(leb128::$fun($dec.data, &mut $dec.position)) }};
+    ($dec:expr, $fun:ident) => {{ leb128::$fun($dec.data, &mut $dec.position) }};
 }
 
 impl<'a> serialize::Decoder for Decoder<'a> {
-    type Error = String;
-
     #[inline]
-    fn read_nil(&mut self) -> Result<(), Self::Error> {
-        Ok(())
+    fn read_unit(&mut self) -> () {
+        ()
     }
 
     #[inline]
-    fn read_u128(&mut self) -> Result<u128, Self::Error> {
+    fn read_u128(&mut self) -> u128 {
         read_leb128!(self, read_u128_leb128)
     }
 
     #[inline]
-    fn read_u64(&mut self) -> Result<u64, Self::Error> {
+    fn read_u64(&mut self) -> u64 {
         read_leb128!(self, read_u64_leb128)
     }
 
     #[inline]
-    fn read_u32(&mut self) -> Result<u32, Self::Error> {
+    fn read_u32(&mut self) -> u32 {
         read_leb128!(self, read_u32_leb128)
     }
 
     #[inline]
-    fn read_u16(&mut self) -> Result<u16, Self::Error> {
+    fn read_u16(&mut self) -> u16 {
         let bytes = [self.data[self.position], self.data[self.position + 1]];
         let value = u16::from_le_bytes(bytes);
         self.position += 2;
-        Ok(value)
+        value
     }
 
     #[inline]
-    fn read_u8(&mut self) -> Result<u8, Self::Error> {
+    fn read_u8(&mut self) -> u8 {
         let value = self.data[self.position];
         self.position += 1;
-        Ok(value)
+        value
     }
 
     #[inline]
-    fn read_usize(&mut self) -> Result<usize, Self::Error> {
+    fn read_usize(&mut self) -> usize {
         read_leb128!(self, read_usize_leb128)
     }
 
     #[inline]
-    fn read_i128(&mut self) -> Result<i128, Self::Error> {
+    fn read_i128(&mut self) -> i128 {
         read_leb128!(self, read_i128_leb128)
     }
 
     #[inline]
-    fn read_i64(&mut self) -> Result<i64, Self::Error> {
+    fn read_i64(&mut self) -> i64 {
         read_leb128!(self, read_i64_leb128)
     }
 
     #[inline]
-    fn read_i32(&mut self) -> Result<i32, Self::Error> {
+    fn read_i32(&mut self) -> i32 {
         read_leb128!(self, read_i32_leb128)
     }
 
     #[inline]
-    fn read_i16(&mut self) -> Result<i16, Self::Error> {
+    fn read_i16(&mut self) -> i16 {
         let bytes = [self.data[self.position], self.data[self.position + 1]];
         let value = i16::from_le_bytes(bytes);
         self.position += 2;
-        Ok(value)
+        value
     }
 
     #[inline]
-    fn read_i8(&mut self) -> Result<i8, Self::Error> {
+    fn read_i8(&mut self) -> i8 {
         let as_u8 = self.data[self.position];
         self.position += 1;
-        unsafe { Ok(::std::mem::transmute(as_u8)) }
+        unsafe { ::std::mem::transmute(as_u8) }
     }
 
     #[inline]
-    fn read_isize(&mut self) -> Result<isize, Self::Error> {
+    fn read_isize(&mut self) -> isize {
         read_leb128!(self, read_isize_leb128)
     }
 
     #[inline]
-    fn read_bool(&mut self) -> Result<bool, Self::Error> {
-        let value = self.read_u8()?;
-        Ok(value != 0)
+    fn read_bool(&mut self) -> bool {
+        let value = self.read_u8();
+        value != 0
     }
 
     #[inline]
-    fn read_f64(&mut self) -> Result<f64, Self::Error> {
-        let bits = self.read_u64()?;
-        Ok(f64::from_bits(bits))
+    fn read_f64(&mut self) -> f64 {
+        let bits = self.read_u64();
+        f64::from_bits(bits)
     }
 
     #[inline]
-    fn read_f32(&mut self) -> Result<f32, Self::Error> {
-        let bits = self.read_u32()?;
-        Ok(f32::from_bits(bits))
+    fn read_f32(&mut self) -> f32 {
+        let bits = self.read_u32();
+        f32::from_bits(bits)
     }
 
     #[inline]
-    fn read_char(&mut self) -> Result<char, Self::Error> {
-        let bits = self.read_u32()?;
-        Ok(std::char::from_u32(bits).unwrap())
+    fn read_char(&mut self) -> char {
+        let bits = self.read_u32();
+        std::char::from_u32(bits).unwrap()
     }
 
     #[inline]
-    fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error> {
-        let len = self.read_usize()?;
+    fn read_str(&mut self) -> Cow<'_, str> {
+        let len = self.read_usize();
         let sentinel = self.data[self.position + len];
         assert!(sentinel == STR_SENTINEL);
         let s = unsafe {
             std::str::from_utf8_unchecked(&self.data[self.position..self.position + len])
         };
         self.position += len + 1;
-        Ok(Cow::Borrowed(s))
-    }
-
-    #[inline]
-    fn error(&mut self, err: &str) -> Self::Error {
-        err.to_string()
+        Cow::Borrowed(s)
     }
 
     #[inline]
-    fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), String> {
+    fn read_raw_bytes_into(&mut self, s: &mut [u8]) {
         let start = self.position;
         self.position += s.len();
         s.copy_from_slice(&self.data[start..self.position]);
-        Ok(())
     }
 }
 
@@ -715,9 +707,9 @@ impl serialize::Encodable<FileEncoder> for [u8] {
 // Specialize decoding `Vec<u8>`. This specialization also applies to decoding `Box<[u8]>`s, etc.,
 // since the default implementations call `decode` to produce a `Vec<u8>` internally.
 impl<'a> serialize::Decodable<Decoder<'a>> for Vec<u8> {
-    fn decode(d: &mut Decoder<'a>) -> Result<Self, String> {
-        let len = serialize::Decoder::read_usize(d)?;
-        Ok(d.read_raw_bytes(len).to_owned())
+    fn decode(d: &mut Decoder<'a>) -> Self {
+        let len = serialize::Decoder::read_usize(d);
+        d.read_raw_bytes(len).to_owned()
     }
 }
 
@@ -752,13 +744,13 @@ impl serialize::Encodable<FileEncoder> for IntEncodedWithFixedSize {
 
 impl<'a> serialize::Decodable<Decoder<'a>> for IntEncodedWithFixedSize {
     #[inline]
-    fn decode(decoder: &mut Decoder<'a>) -> Result<IntEncodedWithFixedSize, String> {
+    fn decode(decoder: &mut Decoder<'a>) -> IntEncodedWithFixedSize {
         let _start_pos = decoder.position();
         let bytes = decoder.read_raw_bytes(IntEncodedWithFixedSize::ENCODED_SIZE);
         let _end_pos = decoder.position();
         debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
 
         let value = u64::from_le_bytes(bytes.try_into().unwrap());
-        Ok(IntEncodedWithFixedSize(value))
+        IntEncodedWithFixedSize(value)
     }
 }
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index 96a2231b590..a6172403fd6 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -173,144 +173,145 @@ pub trait Encoder {
     }
 }
 
+// Note: all the methods in this trait are infallible, which may be surprising.
+// They used to be fallible (i.e. return a `Result`) but many of the impls just
+// panicked when something went wrong, and for the cases that didn't the
+// top-level invocation would also just panic on failure. Switching to
+// infallibility made things faster and lots of code a little simpler and more
+// concise.
 pub trait Decoder {
-    type Error;
-
     // Primitive types:
-    fn read_nil(&mut self) -> Result<(), Self::Error>;
-    fn read_usize(&mut self) -> Result<usize, Self::Error>;
-    fn read_u128(&mut self) -> Result<u128, Self::Error>;
-    fn read_u64(&mut self) -> Result<u64, Self::Error>;
-    fn read_u32(&mut self) -> Result<u32, Self::Error>;
-    fn read_u16(&mut self) -> Result<u16, Self::Error>;
-    fn read_u8(&mut self) -> Result<u8, Self::Error>;
-    fn read_isize(&mut self) -> Result<isize, Self::Error>;
-    fn read_i128(&mut self) -> Result<i128, Self::Error>;
-    fn read_i64(&mut self) -> Result<i64, Self::Error>;
-    fn read_i32(&mut self) -> Result<i32, Self::Error>;
-    fn read_i16(&mut self) -> Result<i16, Self::Error>;
-    fn read_i8(&mut self) -> Result<i8, Self::Error>;
-    fn read_bool(&mut self) -> Result<bool, Self::Error>;
-    fn read_f64(&mut self) -> Result<f64, Self::Error>;
-    fn read_f32(&mut self) -> Result<f32, Self::Error>;
-    fn read_char(&mut self) -> Result<char, Self::Error>;
-    fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error>;
-    fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), Self::Error>;
+    fn read_unit(&mut self) -> ();
+    fn read_usize(&mut self) -> usize;
+    fn read_u128(&mut self) -> u128;
+    fn read_u64(&mut self) -> u64;
+    fn read_u32(&mut self) -> u32;
+    fn read_u16(&mut self) -> u16;
+    fn read_u8(&mut self) -> u8;
+    fn read_isize(&mut self) -> isize;
+    fn read_i128(&mut self) -> i128;
+    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_f64(&mut self) -> f64;
+    fn read_f32(&mut self) -> f32;
+    fn read_char(&mut self) -> char;
+    fn read_str(&mut self) -> Cow<'_, str>;
+    fn read_raw_bytes_into(&mut self, s: &mut [u8]);
 
     // Compound types:
     #[inline]
-    fn read_enum<T, F>(&mut self, f: F) -> Result<T, Self::Error>
+    fn read_enum<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Self) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self) -> T,
     {
         f(self)
     }
 
     #[inline]
-    fn read_enum_variant<T, F>(&mut self, _names: &[&str], mut f: F) -> Result<T, Self::Error>
+    fn read_enum_variant<T, F>(&mut self, _names: &[&str], mut f: F) -> T
     where
-        F: FnMut(&mut Self, usize) -> Result<T, Self::Error>,
+        F: FnMut(&mut Self, usize) -> T,
     {
-        let disr = self.read_usize()?;
+        let disr = self.read_usize();
         f(self, disr)
     }
 
     #[inline]
-    fn read_enum_variant_arg<T, F>(&mut self, f: F) -> Result<T, Self::Error>
+    fn read_enum_variant_arg<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Self) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self) -> T,
     {
         f(self)
     }
 
     #[inline]
-    fn read_struct<T, F>(&mut self, f: F) -> Result<T, Self::Error>
+    fn read_struct<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Self) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self) -> T,
     {
         f(self)
     }
 
     #[inline]
-    fn read_struct_field<T, F>(&mut self, _f_name: &str, f: F) -> Result<T, Self::Error>
+    fn read_struct_field<T, F>(&mut self, _f_name: &str, f: F) -> T
     where
-        F: FnOnce(&mut Self) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self) -> T,
     {
         f(self)
     }
 
     #[inline]
-    fn read_tuple<T, F>(&mut self, _len: usize, f: F) -> Result<T, Self::Error>
+    fn read_tuple<T, F>(&mut self, _len: usize, f: F) -> T
     where
-        F: FnOnce(&mut Self) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self) -> T,
     {
         f(self)
     }
 
     #[inline]
-    fn read_tuple_arg<T, F>(&mut self, f: F) -> Result<T, Self::Error>
+    fn read_tuple_arg<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Self) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self) -> T,
     {
         f(self)
     }
 
     // Specialized types:
-    fn read_option<T, F>(&mut self, mut f: F) -> Result<T, Self::Error>
+    fn read_option<T, F>(&mut self, mut f: F) -> T
     where
-        F: FnMut(&mut Self, bool) -> Result<T, Self::Error>,
+        F: FnMut(&mut Self, bool) -> T,
     {
         self.read_enum(move |this| {
             this.read_enum_variant(&["None", "Some"], move |this, idx| match idx {
                 0 => f(this, false),
                 1 => f(this, true),
-                _ => Err(this.error("read_option: expected 0 for None or 1 for Some")),
+                _ => panic!("read_option: expected 0 for None or 1 for Some"),
             })
         })
     }
 
-    fn read_seq<T, F>(&mut self, f: F) -> Result<T, Self::Error>
+    fn read_seq<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Self, usize) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self, usize) -> T,
     {
-        let len = self.read_usize()?;
+        let len = self.read_usize();
         f(self, len)
     }
 
     #[inline]
-    fn read_seq_elt<T, F>(&mut self, f: F) -> Result<T, Self::Error>
+    fn read_seq_elt<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Self) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self) -> T,
     {
         f(self)
     }
 
-    fn read_map<T, F>(&mut self, f: F) -> Result<T, Self::Error>
+    fn read_map<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Self, usize) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self, usize) -> T,
     {
-        let len = self.read_usize()?;
+        let len = self.read_usize();
         f(self, len)
     }
 
     #[inline]
-    fn read_map_elt_key<T, F>(&mut self, f: F) -> Result<T, Self::Error>
+    fn read_map_elt_key<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Self) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self) -> T,
     {
         f(self)
     }
 
     #[inline]
-    fn read_map_elt_val<T, F>(&mut self, f: F) -> Result<T, Self::Error>
+    fn read_map_elt_val<T, F>(&mut self, f: F) -> T
     where
-        F: FnOnce(&mut Self) -> Result<T, Self::Error>,
+        F: FnOnce(&mut Self) -> T,
     {
         f(self)
     }
-
-    // Failure
-    fn error(&mut self, err: &str) -> Self::Error;
 }
 
 /// Trait for types that can be serialized
@@ -340,7 +341,7 @@ pub trait Encodable<S: Encoder> {
 /// * `TyDecodable` should be used for types that are only serialized in crate
 ///   metadata or the incremental cache. This is most types in `rustc_middle`.
 pub trait Decodable<D: Decoder>: Sized {
-    fn decode(d: &mut D) -> Result<Self, D::Error>;
+    fn decode(d: &mut D) -> Self;
 }
 
 macro_rules! direct_serialize_impls {
@@ -353,7 +354,7 @@ macro_rules! direct_serialize_impls {
             }
 
             impl<D: Decoder> Decodable<D> for $ty {
-                fn decode(d: &mut D) -> Result<$ty, D::Error> {
+                fn decode(d: &mut D) -> $ty {
                     d.$read_method()
                 }
             }
@@ -387,7 +388,7 @@ impl<S: Encoder> Encodable<S> for ! {
 }
 
 impl<D: Decoder> Decodable<D> for ! {
-    fn decode(_d: &mut D) -> Result<!, D::Error> {
+    fn decode(_d: &mut D) -> ! {
         unreachable!()
     }
 }
@@ -399,8 +400,8 @@ impl<S: Encoder> Encodable<S> for ::std::num::NonZeroU32 {
 }
 
 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())
+    fn decode(d: &mut D) -> Self {
+        ::std::num::NonZeroU32::new(d.read_u32()).unwrap()
     }
 }
 
@@ -423,8 +424,8 @@ impl<S: Encoder> Encodable<S> for String {
 }
 
 impl<D: Decoder> Decodable<D> for String {
-    fn decode(d: &mut D) -> Result<String, D::Error> {
-        Ok(d.read_str()?.into_owned())
+    fn decode(d: &mut D) -> String {
+        d.read_str().into_owned()
     }
 }
 
@@ -435,8 +436,8 @@ impl<S: Encoder> Encodable<S> for () {
 }
 
 impl<D: Decoder> Decodable<D> for () {
-    fn decode(d: &mut D) -> Result<(), D::Error> {
-        d.read_nil()
+    fn decode(d: &mut D) -> () {
+        d.read_unit()
     }
 }
 
@@ -447,16 +448,16 @@ impl<S: Encoder, T> Encodable<S> for PhantomData<T> {
 }
 
 impl<D: Decoder, T> Decodable<D> for PhantomData<T> {
-    fn decode(d: &mut D) -> Result<PhantomData<T>, D::Error> {
-        d.read_nil()?;
-        Ok(PhantomData)
+    fn decode(d: &mut D) -> PhantomData<T> {
+        d.read_unit();
+        PhantomData
     }
 }
 
 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())
+    fn decode(d: &mut D) -> Box<[T]> {
+        let v: Vec<T> = Decodable::decode(d);
+        v.into_boxed_slice()
     }
 }
 
@@ -467,8 +468,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Rc<T> {
 }
 
 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)?))
+    fn decode(d: &mut D) -> Rc<T> {
+        Rc::new(Decodable::decode(d))
     }
 }
 
@@ -491,13 +492,22 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Vec<T> {
 }
 
 impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
-    default fn decode(d: &mut D) -> Result<Vec<T>, D::Error> {
+    default fn decode(d: &mut D) -> Vec<T> {
         d.read_seq(|d, len| {
-            let mut v = Vec::with_capacity(len);
-            for _ in 0..len {
-                v.push(d.read_seq_elt(|d| Decodable::decode(d))?);
+            // SAFETY: we set the capacity in advance, only write elements, and
+            // only set the length at the end once the writing has succeeded.
+            let mut vec = Vec::with_capacity(len);
+            unsafe {
+                let ptr: *mut T = vec.as_mut_ptr();
+                for i in 0..len {
+                    std::ptr::write(
+                        ptr.offset(i as isize),
+                        d.read_seq_elt(|d| Decodable::decode(d)),
+                    );
+                }
+                vec.set_len(len);
             }
-            Ok(v)
+            vec
         })
     }
 }
@@ -510,14 +520,14 @@ impl<S: Encoder, T: Encodable<S>, const N: usize> Encodable<S> for [T; N] {
 }
 
 impl<D: Decoder, const N: usize> Decodable<D> for [u8; N] {
-    fn decode(d: &mut D) -> Result<[u8; N], D::Error> {
+    fn decode(d: &mut D) -> [u8; N] {
         d.read_seq(|d, len| {
             assert!(len == N);
             let mut v = [0u8; N];
             for i in 0..len {
-                v[i] = d.read_seq_elt(|d| Decodable::decode(d))?;
+                v[i] = d.read_seq_elt(|d| Decodable::decode(d));
             }
-            Ok(v)
+            v
         })
     }
 }
@@ -536,9 +546,9 @@ impl<D: Decoder, T: Decodable<D> + ToOwned> Decodable<D> for Cow<'static, [T]>
 where
     [T]: ToOwned<Owned = Vec<T>>,
 {
-    fn decode(d: &mut D) -> Result<Cow<'static, [T]>, D::Error> {
-        let v: Vec<T> = Decodable::decode(d)?;
-        Ok(Cow::Owned(v))
+    fn decode(d: &mut D) -> Cow<'static, [T]> {
+        let v: Vec<T> = Decodable::decode(d);
+        Cow::Owned(v)
     }
 }
 
@@ -552,8 +562,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Option<T> {
 }
 
 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) })
+    fn decode(d: &mut D) -> Option<T> {
+        d.read_option(|d, b| if b { Some(Decodable::decode(d)) } else { None })
     }
 }
 
@@ -571,17 +581,12 @@ impl<S: Encoder, T1: Encodable<S>, T2: Encodable<S>> Encodable<S> for Result<T1,
 }
 
 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> {
+    fn decode(d: &mut D) -> Result<T1, T2> {
         d.read_enum(|d| {
             d.read_enum_variant(&["Ok", "Err"], |d, disr| match disr {
-                0 => Ok(Ok(d.read_enum_variant_arg(|d| T1::decode(d))?)),
-                1 => Ok(Err(d.read_enum_variant_arg(|d| T2::decode(d))?)),
-                _ => {
-                    panic!(
-                        "Encountered invalid discriminant while \
-                                decoding `Result`."
-                    );
-                }
+                0 => Ok(d.read_enum_variant_arg(|d| T1::decode(d))),
+                1 => Err(d.read_enum_variant_arg(|d| T2::decode(d))),
+                _ => panic!("Encountered invalid discriminant while decoding `Result`."),
             })
         })
     }
@@ -609,13 +614,13 @@ macro_rules! tuple {
     ( $($name:ident,)+ ) => (
         impl<D: Decoder, $($name: Decodable<D>),+> Decodable<D> for ($($name,)+) {
             #[allow(non_snake_case)]
-            fn decode(d: &mut D) -> Result<($($name,)+), D::Error> {
+            fn decode(d: &mut D) -> ($($name,)+) {
                 let len: usize = count!($($name)+);
                 d.read_tuple(len, |d| {
-                    let ret = ($(d.read_tuple_arg(|d| -> Result<$name, D::Error> {
+                    let ret = ($(d.read_tuple_arg(|d| -> $name {
                         Decodable::decode(d)
-                    })?,)+);
-                    Ok(ret)
+                    }),)+);
+                    ret
                 })
             }
         }
@@ -651,9 +656,9 @@ impl<S: Encoder> Encodable<S> for path::PathBuf {
 }
 
 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))
+    fn decode(d: &mut D) -> path::PathBuf {
+        let bytes: String = Decodable::decode(d);
+        path::PathBuf::from(bytes)
     }
 }
 
@@ -664,8 +669,8 @@ impl<S: Encoder, T: Encodable<S> + Copy> Encodable<S> for Cell<T> {
 }
 
 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)?))
+    fn decode(d: &mut D) -> Cell<T> {
+        Cell::new(Decodable::decode(d))
     }
 }
 
@@ -681,8 +686,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for RefCell<T> {
 }
 
 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)?))
+    fn decode(d: &mut D) -> RefCell<T> {
+        RefCell::new(Decodable::decode(d))
     }
 }
 
@@ -693,8 +698,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Arc<T> {
 }
 
 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)?))
+    fn decode(d: &mut D) -> Arc<T> {
+        Arc::new(Decodable::decode(d))
     }
 }
 
@@ -704,7 +709,7 @@ impl<S: Encoder, T: ?Sized + Encodable<S>> Encodable<S> for Box<T> {
     }
 }
 impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<T> {
-    fn decode(d: &mut D) -> Result<Box<T>, D::Error> {
-        Ok(Box::new(Decodable::decode(d)?))
+    fn decode(d: &mut D) -> Box<T> {
+        Box::new(Decodable::decode(d))
     }
 }
diff --git a/compiler/rustc_serialize/tests/json.rs b/compiler/rustc_serialize/tests/json.rs
index a759fa1bf1a..ede912bdfb6 100644
--- a/compiler/rustc_serialize/tests/json.rs
+++ b/compiler/rustc_serialize/tests/json.rs
@@ -1,14 +1,10 @@
 #![allow(rustc::internal)]
 
-use json::DecoderError::*;
 use json::ErrorCode::*;
 use json::Json::*;
 use json::JsonEvent::*;
 use json::ParserError::*;
-use json::{
-    from_str, DecodeResult, Decoder, DecoderError, Encoder, EncoderError, Json, JsonEvent, Parser,
-    StackElement,
-};
+use json::{from_str, Decoder, Encoder, EncoderError, Json, JsonEvent, Parser, StackElement};
 use rustc_macros::{Decodable, Encodable};
 use rustc_serialize::json;
 use rustc_serialize::{Decodable, Encodable};
@@ -26,27 +22,27 @@ struct OptionData {
 #[test]
 fn test_decode_option_none() {
     let s = "{}";
-    let obj: OptionData = json::decode(s).unwrap();
+    let obj: OptionData = json::decode(s);
     assert_eq!(obj, OptionData { opt: None });
 }
 
 #[test]
 fn test_decode_option_some() {
     let s = "{ \"opt\": 10 }";
-    let obj: OptionData = json::decode(s).unwrap();
+    let obj: OptionData = json::decode(s);
     assert_eq!(obj, OptionData { opt: Some(10) });
 }
 
 #[test]
-fn test_decode_option_malformed() {
-    check_err::<OptionData>(
-        "{ \"opt\": [] }",
-        ExpectedError("Number".to_string(), "[]".to_string()),
-    );
-    check_err::<OptionData>(
-        "{ \"opt\": false }",
-        ExpectedError("Number".to_string(), "false".to_string()),
-    );
+#[should_panic(expected = r#"ExpectedError("Number", "[]")"#)]
+fn test_decode_option_malformed1() {
+    check_err::<OptionData>(r#"{ "opt": [] }"#);
+}
+
+#[test]
+#[should_panic(expected = r#"ExpectedError("Number", "false")"#)]
+fn test_decode_option_malformed2() {
+    check_err::<OptionData>(r#"{ "opt": false }"#);
 }
 
 #[derive(PartialEq, Encodable, Decodable, Debug)]
@@ -329,13 +325,13 @@ fn test_read_identifiers() {
 
 #[test]
 fn test_decode_identifiers() {
-    let v: () = json::decode("null").unwrap();
+    let v: () = json::decode("null");
     assert_eq!(v, ());
 
-    let v: bool = json::decode("true").unwrap();
+    let v: bool = json::decode("true");
     assert_eq!(v, true);
 
-    let v: bool = json::decode("false").unwrap();
+    let v: bool = json::decode("false");
     assert_eq!(v, false);
 }
 
@@ -368,42 +364,42 @@ fn test_read_number() {
 }
 
 #[test]
+#[should_panic(expected = r#"ExpectedError("Integer", "765.25")"#)]
 fn test_decode_numbers() {
-    let v: f64 = json::decode("3").unwrap();
+    let v: f64 = json::decode("3");
     assert_eq!(v, 3.0);
 
-    let v: f64 = json::decode("3.1").unwrap();
+    let v: f64 = json::decode("3.1");
     assert_eq!(v, 3.1);
 
-    let v: f64 = json::decode("-1.2").unwrap();
+    let v: f64 = json::decode("-1.2");
     assert_eq!(v, -1.2);
 
-    let v: f64 = json::decode("0.4").unwrap();
+    let v: f64 = json::decode("0.4");
     assert_eq!(v, 0.4);
 
-    let v: f64 = json::decode("0.4e5").unwrap();
+    let v: f64 = json::decode("0.4e5");
     assert_eq!(v, 0.4e5);
 
-    let v: f64 = json::decode("0.4e15").unwrap();
+    let v: f64 = json::decode("0.4e15");
     assert_eq!(v, 0.4e15);
 
-    let v: f64 = json::decode("0.4e-01").unwrap();
+    let v: f64 = json::decode("0.4e-01");
     assert_eq!(v, 0.4e-01);
 
-    let v: u64 = json::decode("0").unwrap();
+    let v: u64 = json::decode("0");
     assert_eq!(v, 0);
 
-    let v: u64 = json::decode("18446744073709551615").unwrap();
+    let v: u64 = json::decode("18446744073709551615");
     assert_eq!(v, u64::MAX);
 
-    let v: i64 = json::decode("-9223372036854775808").unwrap();
+    let v: i64 = json::decode("-9223372036854775808");
     assert_eq!(v, i64::MIN);
 
-    let v: i64 = json::decode("9223372036854775807").unwrap();
+    let v: i64 = json::decode("9223372036854775807");
     assert_eq!(v, i64::MAX);
 
-    let res: DecodeResult<i64> = json::decode("765.25");
-    assert_eq!(res, Err(ExpectedError("Integer".to_string(), "765.25".to_string())));
+    json::decode::<i64>("765.25");
 }
 
 #[test]
@@ -438,7 +434,7 @@ fn test_decode_str() {
     ];
 
     for (i, o) in s {
-        let v: string::String = json::decode(i).unwrap();
+        let v: string::String = json::decode(i);
         assert_eq!(v, o);
     }
 }
@@ -463,39 +459,41 @@ fn test_read_array() {
 
 #[test]
 fn test_decode_array() {
-    let v: Vec<()> = json::decode("[]").unwrap();
+    let v: Vec<()> = json::decode("[]");
     assert_eq!(v, []);
 
-    let v: Vec<()> = json::decode("[null]").unwrap();
+    let v: Vec<()> = json::decode("[null]");
     assert_eq!(v, [()]);
 
-    let v: Vec<bool> = json::decode("[true]").unwrap();
+    let v: Vec<bool> = json::decode("[true]");
     assert_eq!(v, [true]);
 
-    let v: Vec<isize> = json::decode("[3, 1]").unwrap();
+    let v: Vec<isize> = json::decode("[3, 1]");
     assert_eq!(v, [3, 1]);
 
-    let v: Vec<Vec<usize>> = json::decode("[[3], [1, 2]]").unwrap();
+    let v: Vec<Vec<usize>> = json::decode("[[3], [1, 2]]");
     assert_eq!(v, [vec![3], vec![1, 2]]);
 }
 
 #[test]
 fn test_decode_tuple() {
-    let t: (usize, usize, usize) = json::decode("[1, 2, 3]").unwrap();
+    let t: (usize, usize, usize) = json::decode("[1, 2, 3]");
     assert_eq!(t, (1, 2, 3));
 
-    let t: (usize, string::String) = json::decode("[1, \"two\"]").unwrap();
+    let t: (usize, string::String) = json::decode("[1, \"two\"]");
     assert_eq!(t, (1, "two".to_string()));
 }
 
 #[test]
+#[should_panic]
 fn test_decode_tuple_malformed_types() {
-    assert!(json::decode::<(usize, string::String)>("[1, 2]").is_err());
+    json::decode::<(usize, string::String)>("[1, 2]");
 }
 
 #[test]
+#[should_panic]
 fn test_decode_tuple_malformed_length() {
-    assert!(json::decode::<(usize, usize)>("[1, 2, 3]").is_err());
+    json::decode::<(usize, usize)>("[1, 2, 3]");
 }
 
 #[test]
@@ -562,7 +560,7 @@ fn test_decode_struct() {
         ]
     }";
 
-    let v: Outer = json::decode(s).unwrap();
+    let v: Outer = json::decode(s);
     assert_eq!(
         v,
         Outer { inner: vec![Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }] }
@@ -577,7 +575,7 @@ struct FloatStruct {
 #[test]
 fn test_decode_struct_with_nan() {
     let s = "{\"f\":null,\"a\":[null,123]}";
-    let obj: FloatStruct = json::decode(s).unwrap();
+    let obj: FloatStruct = json::decode(s);
     assert!(obj.f.is_nan());
     assert!(obj.a[0].is_nan());
     assert_eq!(obj.a[1], 123f64);
@@ -585,20 +583,20 @@ fn test_decode_struct_with_nan() {
 
 #[test]
 fn test_decode_option() {
-    let value: Option<string::String> = json::decode("null").unwrap();
+    let value: Option<string::String> = json::decode("null");
     assert_eq!(value, None);
 
-    let value: Option<string::String> = json::decode("\"jodhpurs\"").unwrap();
+    let value: Option<string::String> = json::decode("\"jodhpurs\"");
     assert_eq!(value, Some("jodhpurs".to_string()));
 }
 
 #[test]
 fn test_decode_enum() {
-    let value: Animal = json::decode("\"Dog\"").unwrap();
+    let value: Animal = json::decode("\"Dog\"");
     assert_eq!(value, Dog);
 
     let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}";
-    let value: Animal = json::decode(s).unwrap();
+    let value: Animal = json::decode(s);
     assert_eq!(value, Frog("Henry".to_string(), 349));
 }
 
@@ -606,7 +604,7 @@ fn test_decode_enum() {
 fn test_decode_map() {
     let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
               \"fields\":[\"Henry\", 349]}}";
-    let mut map: BTreeMap<string::String, Animal> = json::decode(s).unwrap();
+    let mut map: BTreeMap<string::String, Animal> = json::decode(s);
 
     assert_eq!(map.remove(&"a".to_string()), Some(Dog));
     assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349)));
@@ -630,59 +628,65 @@ enum DecodeEnum {
     A(f64),
     B(string::String),
 }
-fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected: DecoderError) {
-    let res: DecodeResult<T> = match from_str(to_parse) {
-        Err(e) => Err(ParseError(e)),
-        Ok(json) => Decodable::decode(&mut Decoder::new(json)),
-    };
-    match res {
-        Ok(_) => panic!("`{:?}` parsed & decoded ok, expecting error `{:?}`", to_parse, expected),
-        Err(ParseError(e)) => panic!("`{:?}` is not valid json: {:?}", to_parse, e),
-        Err(e) => {
-            assert_eq!(e, expected);
-        }
-    }
+fn check_err<T: Decodable<Decoder>>(to_parse: &str) {
+    let json = from_str(to_parse).unwrap();
+    let _: T = Decodable::decode(&mut Decoder::new(json));
 }
 #[test]
-fn test_decode_errors_struct() {
-    check_err::<DecodeStruct>("[]", ExpectedError("Object".to_string(), "[]".to_string()));
-    check_err::<DecodeStruct>(
-        "{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}",
-        ExpectedError("Number".to_string(), "true".to_string()),
-    );
-    check_err::<DecodeStruct>(
-        "{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}",
-        ExpectedError("Boolean".to_string(), "[]".to_string()),
-    );
-    check_err::<DecodeStruct>(
-        "{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}",
-        ExpectedError("String".to_string(), "{}".to_string()),
-    );
-    check_err::<DecodeStruct>(
-        "{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}",
-        ExpectedError("Array".to_string(), "null".to_string()),
-    );
-    check_err::<DecodeStruct>(
-        "{\"x\": 1, \"y\": true, \"z\": \"\"}",
-        MissingFieldError("w".to_string()),
-    );
+#[should_panic(expected = r#"ExpectedError("Object", "[]")"#)]
+fn test_decode_errors_struct1() {
+    check_err::<DecodeStruct>("[]");
 }
 #[test]
-fn test_decode_errors_enum() {
-    check_err::<DecodeEnum>("{}", MissingFieldError("variant".to_string()));
-    check_err::<DecodeEnum>(
-        "{\"variant\": 1}",
-        ExpectedError("String".to_string(), "1".to_string()),
-    );
-    check_err::<DecodeEnum>("{\"variant\": \"A\"}", MissingFieldError("fields".to_string()));
-    check_err::<DecodeEnum>(
-        "{\"variant\": \"A\", \"fields\": null}",
-        ExpectedError("Array".to_string(), "null".to_string()),
-    );
-    check_err::<DecodeEnum>(
-        "{\"variant\": \"C\", \"fields\": []}",
-        UnknownVariantError("C".to_string()),
-    );
+#[should_panic(expected = r#"ExpectedError("Number", "true")"#)]
+fn test_decode_errors_struct2() {
+    check_err::<DecodeStruct>(r#"{"x": true, "y": true, "z": "", "w": []}"#);
+}
+#[test]
+#[should_panic(expected = r#"ExpectedError("Boolean", "[]")"#)]
+fn test_decode_errors_struct3() {
+    check_err::<DecodeStruct>(r#"{"x": 1, "y": [], "z": "", "w": []}"#);
+}
+#[test]
+#[should_panic(expected = r#"ExpectedError("String", "{}")"#)]
+fn test_decode_errors_struct4() {
+    check_err::<DecodeStruct>(r#"{"x": 1, "y": true, "z": {}, "w": []}"#);
+}
+#[test]
+#[should_panic(expected = r#"ExpectedError("Array", "null")"#)]
+fn test_decode_errors_struct5() {
+    check_err::<DecodeStruct>(r#"{"x": 1, "y": true, "z": "", "w": null}"#);
+}
+#[test]
+#[should_panic(expected = r#"ExpectedError("Array", "null")"#)]
+fn test_decode_errors_struct6() {
+    check_err::<DecodeStruct>(r#"{"x": 1, "y": true, "z": ""}"#);
+}
+
+#[test]
+#[should_panic(expected = r#"MissingFieldError("variant")"#)]
+fn test_decode_errors_enum1() {
+    check_err::<DecodeEnum>(r#"{}"#);
+}
+#[test]
+#[should_panic(expected = r#"ExpectedError("String", "1")"#)]
+fn test_decode_errors_enum2() {
+    check_err::<DecodeEnum>(r#"{"variant": 1}"#);
+}
+#[test]
+#[should_panic(expected = r#"MissingFieldError("fields")"#)]
+fn test_decode_errors_enum3() {
+    check_err::<DecodeEnum>(r#"{"variant": "A"}"#);
+}
+#[test]
+#[should_panic(expected = r#"ExpectedError("Array", "null")"#)]
+fn test_decode_errors_enum4() {
+    check_err::<DecodeEnum>(r#"{"variant": "A", "fields": null}"#);
+}
+#[test]
+#[should_panic(expected = r#"UnknownVariantError("C")"#)]
+fn test_decode_errors_enum5() {
+    check_err::<DecodeEnum>(r#"{"variant": "C", "fields": []}"#);
 }
 
 #[test]
@@ -944,7 +948,7 @@ fn test_hashmap_with_enum_key() {
     map.insert(Enum::Foo, 0);
     let result = json::encode(&map).unwrap();
     assert_eq!(&result[..], r#"{"Foo":0}"#);
-    let decoded: HashMap<Enum, _> = json::decode(&result).unwrap();
+    let decoded: HashMap<Enum, _> = json::decode(&result);
     assert_eq!(map, decoded);
 }
 
@@ -957,10 +961,11 @@ fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() {
         Ok(o) => o,
     };
     let mut decoder = Decoder::new(json_obj);
-    let _hm: HashMap<usize, bool> = Decodable::decode(&mut decoder).unwrap();
+    let _hm: HashMap<usize, bool> = Decodable::decode(&mut decoder);
 }
 
 #[test]
+#[should_panic(expected = r#"ExpectedError("Number", "a")"#)]
 fn test_hashmap_with_numeric_key_will_error_with_string_keys() {
     use std::collections::HashMap;
     let json_str = "{\"a\":true}";
@@ -969,8 +974,7 @@ fn test_hashmap_with_numeric_key_will_error_with_string_keys() {
         Ok(o) => o,
     };
     let mut decoder = Decoder::new(json_obj);
-    let result: Result<HashMap<usize, bool>, DecoderError> = Decodable::decode(&mut decoder);
-    assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string())));
+    let _: HashMap<usize, bool> = Decodable::decode(&mut decoder);
 }
 
 fn assert_stream_equal(src: &str, expected: Vec<(JsonEvent, Vec<StackElement<'_>>)>) {
diff --git a/compiler/rustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/tests/opaque.rs
index 13b3676a56c..298eb115111 100644
--- a/compiler/rustc_serialize/tests/opaque.rs
+++ b/compiler/rustc_serialize/tests/opaque.rs
@@ -41,7 +41,7 @@ fn check_round_trip<T: Encodable<Encoder> + for<'a> Decodable<Decoder<'a>> + Par
     let mut decoder = Decoder::new(&data[..], 0);
 
     for value in values {
-        let decoded = Decodable::decode(&mut decoder).unwrap();
+        let decoded = Decodable::decode(&mut decoder);
         assert_eq!(value, decoded);
     }
 }
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 5390eed89fa..147c1f9e043 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -47,8 +47,8 @@ impl<E: Encoder> Encodable<E> for CrateNum {
 }
 
 impl<D: Decoder> Decodable<D> for CrateNum {
-    default fn decode(d: &mut D) -> Result<CrateNum, D::Error> {
-        Ok(CrateNum::from_u32(d.read_u32()?))
+    default fn decode(d: &mut D) -> CrateNum {
+        CrateNum::from_u32(d.read_u32())
     }
 }
 
@@ -209,7 +209,7 @@ impl<E: Encoder> Encodable<E> for DefIndex {
 }
 
 impl<D: Decoder> Decodable<D> for DefIndex {
-    default fn decode(_: &mut D) -> Result<DefIndex, D::Error> {
+    default fn decode(_: &mut D) -> DefIndex {
         panic!("cannot decode `DefIndex` with `{}`", std::any::type_name::<D>());
     }
 }
@@ -298,12 +298,10 @@ impl<E: Encoder> Encodable<E> for DefId {
 }
 
 impl<D: Decoder> Decodable<D> for DefId {
-    default fn decode(d: &mut D) -> Result<DefId, D::Error> {
-        d.read_struct(|d| {
-            Ok(DefId {
-                krate: d.read_struct_field("krate", Decodable::decode)?,
-                index: d.read_struct_field("index", Decodable::decode)?,
-            })
+    default fn decode(d: &mut D) -> DefId {
+        d.read_struct(|d| DefId {
+            krate: d.read_struct_field("krate", Decodable::decode),
+            index: d.read_struct_field("index", Decodable::decode),
         })
     }
 }
@@ -378,8 +376,8 @@ impl<E: Encoder> Encodable<E> for LocalDefId {
 }
 
 impl<D: Decoder> Decodable<D> for LocalDefId {
-    fn decode(d: &mut D) -> Result<LocalDefId, D::Error> {
-        DefId::decode(d).map(|d| d.expect_local())
+    fn decode(d: &mut D) -> LocalDefId {
+        DefId::decode(d).expect_local()
     }
 }
 
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 7b70c20d307..e0d6bd8cb7b 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1314,19 +1314,16 @@ pub fn decode_expn_id(
 // to track which `SyntaxContext`s we have already decoded.
 // The provided closure will be invoked to deserialize a `SyntaxContextData`
 // if we haven't already seen the id of the `SyntaxContext` we are deserializing.
-pub fn decode_syntax_context<
-    D: Decoder,
-    F: FnOnce(&mut D, u32) -> Result<SyntaxContextData, D::Error>,
->(
+pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContextData>(
     d: &mut D,
     context: &HygieneDecodeContext,
     decode_data: F,
-) -> Result<SyntaxContext, D::Error> {
-    let raw_id: u32 = Decodable::decode(d)?;
+) -> SyntaxContext {
+    let raw_id: u32 = Decodable::decode(d);
     if raw_id == 0 {
         debug!("decode_syntax_context: deserialized root");
         // The root is special
-        return Ok(SyntaxContext::root());
+        return SyntaxContext::root();
     }
 
     let outer_ctxts = &context.remapped_ctxts;
@@ -1334,7 +1331,7 @@ pub fn decode_syntax_context<
     // Ensure that the lock() temporary is dropped early
     {
         if let Some(ctxt) = outer_ctxts.lock().get(raw_id as usize).copied().flatten() {
-            return Ok(ctxt);
+            return ctxt;
         }
     }
 
@@ -1364,7 +1361,7 @@ pub fn decode_syntax_context<
 
     // Don't try to decode data while holding the lock, since we need to
     // be able to recursively decode a SyntaxContext
-    let mut ctxt_data = decode_data(d, raw_id)?;
+    let mut ctxt_data = decode_data(d, raw_id);
     // Reset `dollar_crate_name` so that it will be updated by `update_dollar_crate_names`
     // We don't care what the encoding crate set this to - we want to resolve it
     // from the perspective of the current compilation session
@@ -1380,7 +1377,7 @@ pub fn decode_syntax_context<
         assert_eq!(dummy.dollar_crate_name, kw::Empty);
     });
 
-    Ok(new_ctxt)
+    new_ctxt
 }
 
 fn for_all_ctxts_in<E, F: FnMut(u32, SyntaxContext, &SyntaxContextData) -> Result<(), E>>(
@@ -1422,13 +1419,13 @@ impl<E: Encoder> Encodable<E> for ExpnId {
 }
 
 impl<D: Decoder> Decodable<D> for LocalExpnId {
-    fn decode(d: &mut D) -> Result<Self, D::Error> {
-        ExpnId::decode(d).map(ExpnId::expect_local)
+    fn decode(d: &mut D) -> Self {
+        ExpnId::expect_local(ExpnId::decode(d))
     }
 }
 
 impl<D: Decoder> Decodable<D> for ExpnId {
-    default fn decode(_: &mut D) -> Result<Self, D::Error> {
+    default fn decode(_: &mut D) -> Self {
         panic!("cannot decode `ExpnId` with `{}`", std::any::type_name::<D>());
     }
 }
@@ -1451,7 +1448,7 @@ impl<E: Encoder> Encodable<E> for SyntaxContext {
 }
 
 impl<D: Decoder> Decodable<D> for SyntaxContext {
-    default fn decode(_: &mut D) -> Result<Self, D::Error> {
+    default fn decode(_: &mut D) -> Self {
         panic!("cannot decode `SyntaxContext` with `{}`", std::any::type_name::<D>());
     }
 }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 9602bc5d0b7..92360164a01 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -975,12 +975,12 @@ impl<E: Encoder> Encodable<E> for Span {
     }
 }
 impl<D: Decoder> Decodable<D> for Span {
-    default fn decode(s: &mut D) -> Result<Span, D::Error> {
+    default fn decode(s: &mut D) -> Span {
         s.read_struct(|d| {
-            let lo = d.read_struct_field("lo", Decodable::decode)?;
-            let hi = d.read_struct_field("hi", Decodable::decode)?;
+            let lo = d.read_struct_field("lo", Decodable::decode);
+            let hi = d.read_struct_field("hi", Decodable::decode);
 
-            Ok(Span::new(lo, hi, SyntaxContext::root(), None))
+            Span::new(lo, hi, SyntaxContext::root(), None)
         })
     }
 }
@@ -1448,30 +1448,30 @@ impl<S: Encoder> Encodable<S> for SourceFile {
 }
 
 impl<D: Decoder> Decodable<D> for SourceFile {
-    fn decode(d: &mut D) -> Result<SourceFile, D::Error> {
+    fn decode(d: &mut D) -> SourceFile {
         d.read_struct(|d| {
-            let name: FileName = d.read_struct_field("name", |d| Decodable::decode(d))?;
+            let name: FileName = d.read_struct_field("name", |d| Decodable::decode(d));
             let src_hash: SourceFileHash =
-                d.read_struct_field("src_hash", |d| Decodable::decode(d))?;
-            let start_pos: BytePos = d.read_struct_field("start_pos", |d| Decodable::decode(d))?;
-            let end_pos: BytePos = d.read_struct_field("end_pos", |d| Decodable::decode(d))?;
+                d.read_struct_field("src_hash", |d| Decodable::decode(d));
+            let start_pos: BytePos = d.read_struct_field("start_pos", |d| Decodable::decode(d));
+            let end_pos: BytePos = d.read_struct_field("end_pos", |d| Decodable::decode(d));
             let lines: Vec<BytePos> = d.read_struct_field("lines", |d| {
-                let num_lines: u32 = Decodable::decode(d)?;
+                let num_lines: u32 = Decodable::decode(d);
                 let mut lines = Vec::with_capacity(num_lines as usize);
 
                 if num_lines > 0 {
                     // Read the number of bytes used per diff.
-                    let bytes_per_diff: u8 = Decodable::decode(d)?;
+                    let bytes_per_diff: u8 = Decodable::decode(d);
 
                     // Read the first element.
-                    let mut line_start: BytePos = Decodable::decode(d)?;
+                    let mut line_start: BytePos = Decodable::decode(d);
                     lines.push(line_start);
 
                     for _ in 1..num_lines {
                         let diff = match bytes_per_diff {
-                            1 => d.read_u8()? as u32,
-                            2 => d.read_u16()? as u32,
-                            4 => d.read_u32()?,
+                            1 => d.read_u8() as u32,
+                            2 => d.read_u16() as u32,
+                            4 => d.read_u32(),
                             _ => unreachable!(),
                         };
 
@@ -1481,17 +1481,17 @@ impl<D: Decoder> Decodable<D> for SourceFile {
                     }
                 }
 
-                Ok(lines)
-            })?;
+                lines
+            });
             let multibyte_chars: Vec<MultiByteChar> =
-                d.read_struct_field("multibyte_chars", |d| Decodable::decode(d))?;
+                d.read_struct_field("multibyte_chars", |d| Decodable::decode(d));
             let non_narrow_chars: Vec<NonNarrowChar> =
-                d.read_struct_field("non_narrow_chars", |d| Decodable::decode(d))?;
-            let name_hash: u128 = d.read_struct_field("name_hash", |d| Decodable::decode(d))?;
+                d.read_struct_field("non_narrow_chars", |d| Decodable::decode(d));
+            let name_hash: u128 = d.read_struct_field("name_hash", |d| Decodable::decode(d));
             let normalized_pos: Vec<NormalizedPos> =
-                d.read_struct_field("normalized_pos", |d| Decodable::decode(d))?;
-            let cnum: CrateNum = d.read_struct_field("cnum", |d| Decodable::decode(d))?;
-            Ok(SourceFile {
+                d.read_struct_field("normalized_pos", |d| Decodable::decode(d));
+            let cnum: CrateNum = d.read_struct_field("cnum", |d| Decodable::decode(d));
+            SourceFile {
                 name,
                 start_pos,
                 end_pos,
@@ -1506,7 +1506,7 @@ impl<D: Decoder> Decodable<D> for SourceFile {
                 normalized_pos,
                 name_hash,
                 cnum,
-            })
+            }
         })
     }
 }
@@ -1949,8 +1949,8 @@ impl<S: rustc_serialize::Encoder> Encodable<S> for BytePos {
 }
 
 impl<D: rustc_serialize::Decoder> Decodable<D> for BytePos {
-    fn decode(d: &mut D) -> Result<BytePos, D::Error> {
-        Ok(BytePos(d.read_u32()?))
+    fn decode(d: &mut D) -> BytePos {
+        BytePos(d.read_u32())
     }
 }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9870c90f2ec..ac4729f717d 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1756,8 +1756,8 @@ impl<S: Encoder> Encodable<S> for Symbol {
 
 impl<D: Decoder> Decodable<D> for Symbol {
     #[inline]
-    fn decode(d: &mut D) -> Result<Symbol, D::Error> {
-        Ok(Symbol::intern(&d.read_str()?))
+    fn decode(d: &mut D) -> Symbol {
+        Symbol::intern(&d.read_str())
     }
 }
 
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index bf5fcfdcbf5..78bf28c843c 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -374,33 +374,51 @@ impl<T> Rc<T> {
         }
     }
 
-    /// Constructs a new `Rc<T>` using a weak reference to itself. Attempting
-    /// to upgrade the weak reference before this function returns will result
-    /// in a `None` value. However, the weak reference may be cloned freely and
-    /// stored for use at a later time.
+    /// Constructs a new `Rc<T>` using a closure `data_fn` that has access to a
+    /// weak reference to the constructing `Rc<T>`.
+    ///
+    /// Generally, a structure circularly referencing itself, either directly or
+    /// indirectly, should not hold a strong reference to prevent a memory leak.
+    /// In `data_fn`, initialization of `T` can make use of the weak reference
+    /// by cloning and storing it inside `T` for use at a later time.
+    ///
+    /// Since the new `Rc<T>` is not fully-constructed until `Rc<T>::new_cyclic`
+    /// returns, calling [`upgrade`] on the weak reference inside `data_fn` will
+    /// fail and result in a `None` value.
+    ///
+    /// # Panics
+    /// If `data_fn` panics, the panic is propagated to the caller, and the
+    /// temporary [`Weak<T>`] is dropped normally.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_new_cyclic)]
     /// #![allow(dead_code)]
     /// use std::rc::{Rc, Weak};
     ///
     /// struct Gadget {
-    ///     self_weak: Weak<Self>,
-    ///     // ... more fields
+    ///     me: Weak<Gadget>,
     /// }
+    ///
     /// impl Gadget {
-    ///     pub fn new() -> Rc<Self> {
-    ///         Rc::new_cyclic(|self_weak| {
-    ///             Gadget { self_weak: self_weak.clone(), /* ... */ }
-    ///         })
+    ///     /// Construct a reference counted Gadget.
+    ///     fn new() -> Rc<Self> {
+    ///         Rc::new_cyclic(|me| Gadget { me: me.clone() })
+    ///     }
+    ///
+    ///     /// Return a reference counted pointer to Self.
+    ///     fn me(&self) -> Rc<Self> {
+    ///         self.me.upgrade().unwrap()
     ///     }
     /// }
     /// ```
+    /// [`upgrade`]: Weak::upgrade
     #[cfg(not(no_global_oom_handling))]
-    #[unstable(feature = "arc_new_cyclic", issue = "75861")]
-    pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Rc<T> {
+    #[stable(feature = "arc_new_cyclic", since = "1.60.0")]
+    pub fn new_cyclic<F>(data_fn: F) -> Rc<T>
+    where
+        F: FnOnce(&Weak<T>) -> T,
+    {
         // Construct the inner in the "uninitialized" state with a single
         // weak reference.
         let uninit_ptr: NonNull<_> = Box::leak(box RcBox {
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index ab8a44b2147..64f21d087da 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -351,30 +351,51 @@ impl<T> Arc<T> {
         unsafe { Self::from_inner(Box::leak(x).into()) }
     }
 
-    /// Constructs a new `Arc<T>` using a weak reference to itself. Attempting
-    /// to upgrade the weak reference before this function returns will result
-    /// in a `None` value. However, the weak reference may be cloned freely and
-    /// stored for use at a later time.
+    /// Constructs a new `Arc<T>` using a closure `data_fn` that has access to
+    /// a weak reference to the constructing `Arc<T>`.
     ///
-    /// # Examples
+    /// Generally, a structure circularly referencing itself, either directly or
+    /// indirectly, should not hold a strong reference to prevent a memory leak.
+    /// In `data_fn`, initialization of `T` can make use of the weak reference
+    /// by cloning and storing it inside `T` for use at a later time.
+    ///
+    /// Since the new `Arc<T>` is not fully-constructed until
+    /// `Arc<T>::new_cyclic` returns, calling [`upgrade`] on the weak
+    /// reference inside `data_fn` will fail and result in a `None` value.
+    ///
+    /// # Panics
+    /// If `data_fn` panics, the panic is propagated to the caller, and the
+    /// temporary [`Weak<T>`] is dropped normally.
+    ///
+    /// # Example
     /// ```
-    /// #![feature(arc_new_cyclic)]
     /// #![allow(dead_code)]
-    ///
     /// use std::sync::{Arc, Weak};
     ///
-    /// struct Foo {
-    ///     me: Weak<Foo>,
+    /// struct Gadget {
+    ///     me: Weak<Gadget>,
     /// }
     ///
-    /// let foo = Arc::new_cyclic(|me| Foo {
-    ///     me: me.clone(),
-    /// });
+    /// impl Gadget {
+    ///     /// Construct a reference counted Gadget.
+    ///     fn new() -> Arc<Self> {
+    ///         Arc::new_cyclic(|me| Gadget { me: me.clone() })
+    ///     }
+    ///
+    ///     /// Return a reference counted pointer to Self.
+    ///     fn me(&self) -> Arc<Self> {
+    ///         self.me.upgrade().unwrap()
+    ///     }
+    /// }
     /// ```
+    /// [`upgrade`]: Weak::upgrade
     #[cfg(not(no_global_oom_handling))]
     #[inline]
-    #[unstable(feature = "arc_new_cyclic", issue = "75861")]
-    pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Arc<T> {
+    #[stable(feature = "arc_new_cyclic", since = "1.60.0")]
+    pub fn new_cyclic<F>(data_fn: F) -> Arc<T>
+    where
+        F: FnOnce(&Weak<T>) -> T,
+    {
         // Construct the inner in the "uninitialized" state with a single
         // weak reference.
         let uninit_ptr: NonNull<_> = Box::leak(box ArcInner {
diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs
index 255f6cb7933..7c664226fc2 100644
--- a/library/core/src/ops/bit.rs
+++ b/library/core/src/ops/bit.rs
@@ -68,6 +68,17 @@ macro_rules! not_impl {
 
 not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
+#[stable(feature = "not_never", since = "1.60.0")]
+#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+impl const Not for ! {
+    type Output = !;
+
+    #[inline]
+    fn not(self) -> ! {
+        match self {}
+    }
+}
+
 /// The bitwise AND operator `&`.
 ///
 /// Note that `Rhs` is `Self` by default, but this is not mandatory.
diff --git a/library/core/tests/ops.rs b/library/core/tests/ops.rs
index aa79dbac8f3..0c81cba35b3 100644
--- a/library/core/tests/ops.rs
+++ b/library/core/tests/ops.rs
@@ -232,3 +232,9 @@ fn deref_on_ref() {
     let y = deref(&mut x);
     assert_eq!(y, 4);
 }
+
+#[test]
+#[allow(unreachable_code)]
+fn test_not_never() {
+    if !return () {}
+}
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 5cab3e8be10..4fe69cefe12 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -588,7 +588,6 @@ impl<'a> Builder<'a> {
                 dist::RustcDev,
                 dist::Analysis,
                 dist::Src,
-                dist::PlainSourceTarball,
                 dist::Cargo,
                 dist::Rls,
                 dist::RustAnalyzer,
@@ -599,6 +598,11 @@ impl<'a> Builder<'a> {
                 dist::LlvmTools,
                 dist::RustDev,
                 dist::Extended,
+                // It seems that PlainSourceTarball somehow changes how some of the tools
+                // perceive their dependencies (see #93033) which would invaliate fingerprints
+                // and force us to rebuild tools after vendoring dependencies.
+                // To work around this, create the Tarball after building all the tools.
+                dist::PlainSourceTarball,
                 dist::BuildManifest,
                 dist::ReproducibleArtifacts,
             ),
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index b1ec072f3f8..28e95d81bb7 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -55,12 +55,6 @@ pub fn restore_library_path() {
     }
 }
 
-/// Run the command, printing what we are running.
-pub fn run_verbose(cmd: &mut Command) {
-    println!("running: {:?}", cmd);
-    run(cmd);
-}
-
 pub fn run(cmd: &mut Command) {
     if !try_run(cmd) {
         std::process::exit(1);
@@ -108,16 +102,6 @@ pub fn try_run_suppressed(cmd: &mut Command) -> bool {
     output.status.success()
 }
 
-pub fn gnu_target(target: &str) -> &str {
-    match target {
-        "i686-pc-windows-msvc" => "i686-pc-win32",
-        "x86_64-pc-windows-msvc" => "x86_64-pc-win32",
-        "i686-pc-windows-gnu" => "i686-w64-mingw32",
-        "x86_64-pc-windows-gnu" => "x86_64-w64-mingw32",
-        s => s,
-    }
-}
-
 pub fn make(host: &str) -> PathBuf {
     if host.contains("dragonfly")
         || host.contains("freebsd")
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 53f7108aca3..7898d2722cb 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -15,6 +15,7 @@
 - [Platform Support](platform-support.md)
     - [Template for target-specific documentation](platform-support/TEMPLATE.md)
     - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
+    - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
     - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
     - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index f4f659ffa27..d0ce5cb994b 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -220,7 +220,7 @@ target | std | host | notes
 `armv6-unknown-netbsd-eabihf` | ? |  |
 `armv6k-nintendo-3ds` | * |  | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
 `armv7-apple-ios` | ✓ |  | ARMv7 iOS, Cortex-a8
-`armv7-unknown-linux-uclibceabihf` | ✓ | ? | ARMv7 Linux uClibc
+[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux uClibc
 `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
 `armv7-unknown-netbsd-eabihf` | ✓ | ✓ |
 `armv7-wrs-vxworks-eabihf` | ? |  |
diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
index b3a4275c6ee..1f029406367 100644
--- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
+++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
@@ -18,7 +18,7 @@ This target is cross compiled, and requires a cross toolchain.  You can find sui
 
 Compiling rust for this target has been tested on `x86_64` linux hosts.  Other host types have not been tested, but may work, if you can find a suitable cross compilation toolchain for them.
 
-If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2020.08-1.tar.bz2), and unpack it into a directory.
+If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2021.11-1.tar.bz2), and unpack it into a directory.
 
 ### Configure rust
 
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 993503005d7..0c0787c6b2f 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -429,7 +429,7 @@ impl Item {
 
     /// Convenience wrapper around [`Self::from_def_id_and_parts`] which converts
     /// `hir_id` to a [`DefId`]
-    pub fn from_hir_id_and_parts(
+    crate fn from_hir_id_and_parts(
         hir_id: hir::HirId,
         name: Option<Symbol>,
         kind: ItemKind,
@@ -438,7 +438,7 @@ impl Item {
         Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx)
     }
 
-    pub fn from_def_id_and_parts(
+    crate fn from_def_id_and_parts(
         def_id: DefId,
         name: Option<Symbol>,
         kind: ItemKind,
@@ -456,7 +456,7 @@ impl Item {
         )
     }
 
-    pub fn from_def_id_and_attrs_and_parts(
+    crate fn from_def_id_and_attrs_and_parts(
         def_id: DefId,
         name: Option<Symbol>,
         kind: ItemKind,
@@ -984,26 +984,26 @@ crate fn collapse_doc_fragments(doc_strings: &[DocFragment]) -> String {
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 crate struct ItemLink {
     /// The original link written in the markdown
-    pub(crate) link: String,
+    crate link: String,
     /// The link text displayed in the HTML.
     ///
     /// This may not be the same as `link` if there was a disambiguator
     /// in an intra-doc link (e.g. \[`fn@f`\])
-    pub(crate) link_text: String,
-    pub(crate) did: DefId,
+    crate link_text: String,
+    crate did: DefId,
     /// The url fragment to append to the link
-    pub(crate) fragment: Option<UrlFragment>,
+    crate fragment: Option<UrlFragment>,
 }
 
 pub struct RenderedLink {
     /// The text the link was original written as.
     ///
     /// This could potentially include disambiguators and backticks.
-    pub(crate) original_text: String,
+    crate original_text: String,
     /// The text to display in the HTML
-    pub(crate) new_text: String,
+    crate new_text: String,
     /// The URL to put in the `href`
-    pub(crate) href: String,
+    crate href: String,
 }
 
 /// The attributes on an [`Item`], including attributes like `#[derive(...)]` and `#[inline]`,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 3b926e44403..d9f6a9d02ca 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -33,8 +33,8 @@ use crate::passes::{self, Condition::*};
 crate use rustc_session::config::{DebuggingOptions, Input, Options};
 
 crate struct ResolverCaches {
-    pub all_traits: Option<Vec<DefId>>,
-    pub all_trait_impls: Option<Vec<DefId>>,
+    crate all_traits: Option<Vec<DefId>>,
+    crate all_trait_impls: Option<Vec<DefId>>,
 }
 
 crate struct DocContext<'tcx> {
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 8badce8226f..c3edefc4698 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -175,7 +175,7 @@ crate struct StylePath {
 }
 
 impl StylePath {
-    pub fn basename(&self) -> Result<String, Error> {
+    crate fn basename(&self) -> Result<String, Error> {
         Ok(try_none!(try_none!(self.path.file_stem(), &self.path).to_str(), &self.path).to_string())
     }
 }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 836cf3cd56a..fc03a64fcd6 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -896,11 +896,11 @@ table,
 
 .search-container {
 	position: relative;
-	max-width: 960px;
+	display: flex;
+	height: 34px;
 }
-.search-container > div {
-	display: inline-flex;
-	width: calc(100% - 63px);
+.search-container > * {
+	height: 100%;
 }
 .search-results-title {
 	display: inline;
@@ -931,10 +931,8 @@ table,
 	background-position: calc(100% - 1px) 56%;
 	background-image: /* AUTOREPLACE: */url("down-arrow.svg");
 }
-.search-container > .top-button {
-	position: absolute;
-	right: 0;
-	top: 10px;
+.search-container {
+	margin-top: 4px;
 }
 .search-input {
 	/* Override Normalize.css: it has a rule that sets
@@ -947,23 +945,14 @@ table,
 	-moz-box-sizing: border-box !important;
 	box-sizing: border-box !important;
 	outline: none;
-	border: none;
-	border-radius: 1px;
-	margin-top: 5px;
-	padding: 10px 16px;
+	border: 1px solid;
+	border-radius: 2px;
+	padding: 5px 8px;
 	font-size: 1.0625rem;
 	transition: border-color 300ms ease;
-	transition: border-radius 300ms ease-in-out;
-	transition: box-shadow 300ms ease-in-out;
 	width: 100%;
 }
 
-.search-input:focus {
-	border-radius: 2px;
-	border: 0;
-	outline: 0;
-}
-
 .search-results {
 	display: none;
 	padding-bottom: 2em;
@@ -1199,7 +1188,6 @@ a.test-arrow:hover{
 .out-of-band > span.since {
 	position: initial;
 	font-size: 1.25rem;
-	margin-right: 5px;
 }
 
 h3.variant {
@@ -1437,8 +1425,8 @@ pre.rust {
 
 .theme-picker {
 	position: absolute;
-	left: -34px;
-	top: 9px;
+	left: -38px;
+	top: 4px;
 }
 
 .theme-picker button {
@@ -1446,34 +1434,27 @@ pre.rust {
 }
 
 #settings-menu, #help-button {
-	position: absolute;
-	top: 10px;
-}
-
-#settings-menu {
-	right: 0;
+	margin-left: 4px;
 	outline: none;
 }
 
+#theme-picker, #copy-path {
+	height: 34px;
+}
 #theme-picker, #settings-menu, #help-button, #copy-path {
-	padding: 4px;
-	/* Rare exception to specifying font sizes in rem. Since these are acting
-	   as icons, it's okay to specify their sizes in pixels. */
-	font-size: 16px;
-	width: 27px;
-	height: 29px;
+	padding: 5px;
+	width: 33px;
 	border: 1px solid;
-	border-radius: 3px;
+	border-radius: 2px;
 	cursor: pointer;
 }
 
 #help-button {
-	right: 30px;
 	font-family: "Fira Sans", Arial, sans-serif;
 	text-align: center;
 	/* Rare exception to specifying font sizes in rem. Since this is acting
 	   as an icon, it's okay to specify their sizes in pixels. */
-	font-size: 16px;
+	font-size: 20px;
 	padding-top: 2px;
 }
 
@@ -1910,10 +1891,6 @@ details.rustdoc-toggle[open] > summary.hideme::after {
 		display: none !important;
 	}
 
-	.theme-picker {
-		z-index: 1;
-	}
-
 	.notable-traits {
 		position: absolute;
 		left: -22px;
@@ -2000,10 +1977,6 @@ details.rustdoc-toggle[open] > summary.hideme::after {
 		width: 100%;
 	}
 
-	.search-container > div {
-		width: calc(100% - 32px);
-	}
-
 	/* Display an alternating layout on tablets and phones */
 	.search-results > a {
 		border-bottom: 1px solid #aaa9;
@@ -2048,30 +2021,11 @@ details.rustdoc-toggle[open] > summary.hideme::after {
 		width: 50%;
 	}
 
-	.search-container > div {
-		display: block;
-		width: calc(100% - 37px);
-	}
-
 	#crate-search {
 		border-radius: 4px;
 		border: 0;
 	}
 
-	#theme-picker, #settings-menu {
-		padding: 5px;
-		width: 31px;
-		height: 31px;
-	}
-
-	#theme-picker {
-		margin-top: -2px;
-	}
-
-	#settings-menu {
-		top: 7px;
-	}
-
 	.docblock {
 		margin-left: 12px;
 	}
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 69097b81b9f..b217d0e27f3 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -233,22 +233,14 @@ details.undocumented > summary::before {
 	filter: invert(100%);
 }
 
-#crate-search {
-	color: #c5c5c5;
+#crate-search, .search-input {
 	background-color: #141920;
-	box-shadow: 0 0 0 1px #424c57,0 0 0 2px transparent;
 	border-color: #424c57;
+	color: #c5c5c5;
 }
 
 .search-input {
 	color: #ffffff;
-	background-color: #141920;
-	box-shadow: 0 0 0 1px #424c57,0 0 0 2px transparent;
-	transition: box-shadow 150ms ease-in-out;
-}
-
-#crate-search+.search-input:focus {
-	box-shadow: 0 0 0 1px #148099,0 0 0 2px transparent;
 }
 
 .module-item .stab,
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 39165b2fc05..ead1e08386e 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -194,27 +194,20 @@ details.undocumented > summary::before {
 	filter: invert(100%);
 }
 
-#crate-search {
+#crate-search, .search-input {
 	color: #111;
 	background-color: #f0f0f0;
 	border-color: #000;
-	box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent;
 }
 
 .search-input {
-	color: #111;
-	background-color: #f0f0f0;
-	box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent;
+	border-color: #e0e0e0;
 }
 
 .search-input:focus {
 	border-color: #008dfd;
 }
 
-#crate-search + .search-input:focus {
-	box-shadow: 0 0 8px 4px #078dd8;
-}
-
 .module-item .stab,
 .import-item .stab {
 	color: #ddd;
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 448c9ac603c..cd77b80cd38 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -186,27 +186,16 @@ details.undocumented > summary::before {
 	color: #999;
 }
 
-#crate-search {
+#crate-search, .search-input {
 	color: #555;
 	background-color: white;
 	border-color: #e0e0e0;
-	box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent;
-}
-
-.search-input {
-	color: #555;
-	background-color: white;
-	box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent;
 }
 
 .search-input:focus {
 	border-color: #66afe9;
 }
 
-#crate-search + .search-input:focus {
-	box-shadow: 0 0 8px #078dd8;
-}
-
 .module-item .stab,
 .import-item .stab {
 	color: #000;
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index 1322b854b7f..3325515bef6 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -110,25 +110,23 @@
                 <nav class="sub"> {#- -#}
                     <div class="theme-picker hidden"> {#- -#}
                         <button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"> {#- -#}
-                            <img width="18" height="18" alt="Pick another theme!" {# -#}
+                            <img width="22" height="22" alt="Pick another theme!" {# -#}
                              src="{{static_root_path|safe}}brush{{page.resource_suffix}}.svg"> {#- -#}
                         </button> {#- -#}
                         <div id="theme-choices" role="menu"></div> {#- -#}
                     </div> {#- -#}
                     <form class="search-form"> {#- -#}
                         <div class="search-container"> {#- -#}
-                            <div>
-                                <input {# -#}
-                                    class="search-input" {# -#}
-                                    name="search" {# -#}
-                                    autocomplete="off" {# -#}
-                                    spellcheck="false" {# -#}
-                                    placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
-                                    type="search"> {#- -#}
-                            </div> {#- -#}
+                            <input {# -#}
+                                class="search-input" {# -#}
+                                name="search" {# -#}
+                                autocomplete="off" {# -#}
+                                spellcheck="false" {# -#}
+                                placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
+                                type="search"> {#- -#}
                             <button type="button" id="help-button" title="help">?</button> {#- -#}
                             <a id="settings-menu" href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
-                                <img width="18" height="18" alt="Change settings" {# -#}
+                                <img width="22" height="22" alt="Change settings" {# -#}
                                      src="{{static_root_path|safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
                             </a> {#- -#}
                         </div> {#- -#}
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
index 459b01a9960..1fa84e1c31f 100644
--- a/src/librustdoc/html/templates/print_item.html
+++ b/src/librustdoc/html/templates/print_item.html
@@ -16,7 +16,7 @@
     </h1> {#- -#}
     <span class="out-of-band"> {#- -#}
         {% if !stability_since_raw.is_empty() %}
-        {{- stability_since_raw|safe -}} · {# -#}
+        {{- stability_since_raw|safe }} · {# -#}
         {% endif %}
         {%- match src_href -%}
             {%- when Some with (href) -%}
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 7dbf00420de..e82ab122481 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -362,7 +362,7 @@ struct DiagnosticInfo<'a> {
 
 #[derive(Clone, Debug, Hash)]
 struct CachedLink {
-    pub res: (Res, Option<UrlFragment>),
+    res: (Res, Option<UrlFragment>),
 }
 
 struct LinkCollector<'a, 'tcx> {
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index 47fc666da9a..899c9e4c629 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -292,7 +292,7 @@ crate fn load_call_locations(
         for path in with_examples {
             let bytes = fs::read(&path).map_err(|e| format!("{} (for path {})", e, path))?;
             let mut decoder = Decoder::new(&bytes, 0);
-            let calls = AllCallLocations::decode(&mut decoder)?;
+            let calls = AllCallLocations::decode(&mut decoder);
 
             for (function, fn_calls) in calls.into_iter() {
                 all_calls.entry(function).or_default().extend(fn_calls.into_iter());
diff --git a/src/test/rustdoc/source-version-separator.rs b/src/test/rustdoc/source-version-separator.rs
index 45a555eaa15..8d23ca91801 100644
--- a/src/test/rustdoc/source-version-separator.rs
+++ b/src/test/rustdoc/source-version-separator.rs
@@ -1,10 +1,9 @@
 #![stable(feature = "bar", since = "1.0")]
 #![crate_name = "foo"]
-
 #![feature(staged_api)]
 
 // @has foo/trait.Bar.html
-// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0· source · '
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
 #[stable(feature = "bar", since = "1.0")]
 pub trait Bar {
     // @has - '//div[@id="tymethod.foo"]/*[@class="rightside"]' '3.0 · source'
@@ -15,7 +14,7 @@ pub trait Bar {
 // @has - '//div[@id="implementors-list"]//*[@class="rightside"]' '4.0 · source'
 
 // @has foo/struct.Foo.html
-// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0· source · '
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
 #[stable(feature = "baz", since = "1.0")]
 pub struct Foo;
 
diff --git a/src/test/ui-fulldeps/deriving-encodable-decodable-box.rs b/src/test/ui-fulldeps/deriving-encodable-decodable-box.rs
index fab2031d952..dd20eef0700 100644
--- a/src/test/ui-fulldeps/deriving-encodable-decodable-box.rs
+++ b/src/test/ui-fulldeps/deriving-encodable-decodable-box.rs
@@ -18,6 +18,6 @@ struct A {
 fn main() {
     let obj = A { foo: Box::new([true, false]) };
     let s = json::encode(&obj).unwrap();
-    let obj2: A = json::decode(&s).unwrap();
+    let obj2: A = json::decode(&s);
     assert_eq!(obj.foo, obj2.foo);
 }
diff --git a/src/test/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs b/src/test/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs
index 9dedf990f25..18aa974c31d 100644
--- a/src/test/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs
+++ b/src/test/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs
@@ -27,7 +27,7 @@ struct B {
 fn main() {
     let obj = B { foo: Cell::new(true), bar: RefCell::new(A { baz: 2 }) };
     let s = json::encode(&obj).unwrap();
-    let obj2: B = json::decode(&s).unwrap();
+    let obj2: B = json::decode(&s);
     assert_eq!(obj.foo.get(), obj2.foo.get());
     assert_eq!(obj.bar.borrow().baz, obj2.bar.borrow().baz);
 }
diff --git a/src/test/ui-fulldeps/issue-14021.rs b/src/test/ui-fulldeps/issue-14021.rs
index be88a593962..acd75170d68 100644
--- a/src/test/ui-fulldeps/issue-14021.rs
+++ b/src/test/ui-fulldeps/issue-14021.rs
@@ -20,7 +20,7 @@ pub fn main() {
 
     let json_object = json::from_str(&json_str);
     let mut decoder = json::Decoder::new(json_object.unwrap());
-    let mut decoded_obj: UnitLikeStruct = Decodable::decode(&mut decoder).unwrap();
+    let mut decoded_obj: UnitLikeStruct = Decodable::decode(&mut decoder);
 
     assert_eq!(obj, decoded_obj);
 }
diff --git a/src/test/ui-fulldeps/issue-4016.rs b/src/test/ui-fulldeps/issue-4016.rs
index 4fd192497a0..65dab8d7704 100644
--- a/src/test/ui-fulldeps/issue-4016.rs
+++ b/src/test/ui-fulldeps/issue-4016.rs
@@ -12,7 +12,7 @@ trait JD: Decodable<json::Decoder> {}
 fn exec<T: JD>() {
     let doc = json::from_str("").unwrap();
     let mut decoder = json::Decoder::new(doc);
-    let _v: T = Decodable::decode(&mut decoder).unwrap();
+    let _v: T = Decodable::decode(&mut decoder);
     panic!()
 }
 
diff --git a/src/test/ui-fulldeps/issue-4036.rs b/src/test/ui-fulldeps/issue-4036.rs
index 05a7a30140a..702bb2d6ef6 100644
--- a/src/test/ui-fulldeps/issue-4036.rs
+++ b/src/test/ui-fulldeps/issue-4036.rs
@@ -13,5 +13,5 @@ use rustc_serialize::{json, Decodable};
 pub fn main() {
     let json = json::from_str("[1]").unwrap();
     let mut decoder = json::Decoder::new(json);
-    let _x: Vec<isize> = Decodable::decode(&mut decoder).unwrap();
+    let _x: Vec<isize> = Decodable::decode(&mut decoder);
 }
diff --git a/src/test/ui/async-await/proper-span-for-type-error.fixed b/src/test/ui/async-await/proper-span-for-type-error.fixed
new file mode 100644
index 00000000000..1f1e1184dcc
--- /dev/null
+++ b/src/test/ui/async-await/proper-span-for-type-error.fixed
@@ -0,0 +1,11 @@
+// edition:2021
+// run-rustfix
+#![allow(dead_code)]
+
+async fn a() {}
+
+async fn foo() -> Result<(), i32> {
+    Ok(a().await) //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/proper-span-for-type-error.rs b/src/test/ui/async-await/proper-span-for-type-error.rs
new file mode 100644
index 00000000000..00ccde1bf99
--- /dev/null
+++ b/src/test/ui/async-await/proper-span-for-type-error.rs
@@ -0,0 +1,11 @@
+// edition:2021
+// run-rustfix
+#![allow(dead_code)]
+
+async fn a() {}
+
+async fn foo() -> Result<(), i32> {
+    a().await //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/proper-span-for-type-error.stderr b/src/test/ui/async-await/proper-span-for-type-error.stderr
new file mode 100644
index 00000000000..611dc0407bf
--- /dev/null
+++ b/src/test/ui/async-await/proper-span-for-type-error.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/proper-span-for-type-error.rs:8:5
+   |
+LL |     a().await
+   |     ^^^^^^^^^ expected enum `Result`, found `()`
+   |
+   = note:   expected enum `Result<(), i32>`
+           found unit type `()`
+help: try wrapping the expression in `Ok`
+   |
+LL |     Ok(a().await)
+   |     +++         +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs
index e229d22ebc7..190c7447dcc 100644
--- a/src/test/ui/reachable/expr_unary.rs
+++ b/src/test/ui/reachable/expr_unary.rs
@@ -5,8 +5,8 @@
 #![deny(unreachable_code)]
 
 fn foo() {
-    let x: ! = ! { return; }; //~ ERROR unreachable
-    //~| ERROR cannot apply unary operator `!` to type `!`
+    let x: ! = * { return; }; //~ ERROR unreachable
+    //~| ERROR type `!` cannot be dereferenced
 }
 
 fn main() { }
diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr
index 063d841c25e..0a763087c6f 100644
--- a/src/test/ui/reachable/expr_unary.stderr
+++ b/src/test/ui/reachable/expr_unary.stderr
@@ -1,13 +1,13 @@
-error[E0600]: cannot apply unary operator `!` to type `!`
+error[E0614]: type `!` cannot be dereferenced
   --> $DIR/expr_unary.rs:8:16
    |
-LL |     let x: ! = ! { return; };
-   |                ^^^^^^^^^^^^^ cannot apply unary operator `!`
+LL |     let x: ! = * { return; };
+   |                ^^^^^^^^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_unary.rs:8:16
    |
-LL |     let x: ! = ! { return; };
+LL |     let x: ! = * { return; };
    |                ^^^^------^^^
    |                |   |
    |                |   any code following this expression is unreachable
@@ -21,4 +21,4 @@ LL | #![deny(unreachable_code)]
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0600`.
+For more information about this error, try `rustc --explain E0614`.