about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md141
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0744.md19
-rw-r--r--compiler/rustc_hir/src/hir.rs8
-rw-r--r--compiler/rustc_interface/src/lib.rs2
-rw-r--r--compiler/rustc_interface/src/util.rs25
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs182
-rw-r--r--compiler/rustc_typeck/src/lib.rs1
-rw-r--r--library/alloc/src/collections/btree/map/tests.rs146
-rw-r--r--library/alloc/src/collections/btree/map/tests/ord_chaos.rs76
-rw-r--r--library/alloc/src/collections/btree/node/tests.rs5
-rw-r--r--library/alloc/src/collections/mod.rs6
-rw-r--r--library/alloc/src/raw_vec.rs4
-rw-r--r--library/core/src/alloc/layout.rs58
-rw-r--r--library/core/src/alloc/mod.rs13
-rw-r--r--library/core/src/array/mod.rs41
-rw-r--r--library/core/tests/ops.rs48
-rw-r--r--library/std/src/error.rs4
-rw-r--r--library/std/src/io/impls.rs14
-rw-r--r--library/std/src/io/mod.rs8
-rw-r--r--library/std/src/io/stdio.rs177
-rw-r--r--library/std/src/lib.rs3
-rw-r--r--library/std/src/panicking.rs12
-rw-r--r--library/std/src/thread/mod.rs6
-rw-r--r--library/test/src/bench.rs20
-rw-r--r--library/test/src/helpers/mod.rs1
-rw-r--r--library/test/src/helpers/sink.rs31
-rw-r--r--library/test/src/lib.rs21
-rw-r--r--src/doc/unstable-book/src/library-features/internal-output-capture.md (renamed from src/doc/unstable-book/src/library-features/libstd-io-internals.md)2
-rw-r--r--src/doc/unstable-book/src/library-features/set-stdio.md5
-rw-r--r--src/librustdoc/clean/auto_trait.rs10
-rw-r--r--src/librustdoc/clean/blanket_impl.rs8
-rw-r--r--src/librustdoc/clean/cfg.rs12
-rw-r--r--src/librustdoc/clean/mod.rs24
-rw-r--r--src/librustdoc/clean/simplify.rs4
-rw-r--r--src/librustdoc/clean/types.rs546
-rw-r--r--src/librustdoc/clean/utils.rs40
-rw-r--r--src/librustdoc/config.rs140
-rw-r--r--src/librustdoc/core.rs57
-rw-r--r--src/librustdoc/docfs.rs14
-rw-r--r--src/librustdoc/doctest.rs22
-rw-r--r--src/librustdoc/doctree.rs346
-rw-r--r--src/librustdoc/error.rs6
-rw-r--r--src/librustdoc/externalfiles.rs14
-rw-r--r--src/librustdoc/fold.rs6
-rw-r--r--src/librustdoc/formats/cache.rs38
-rw-r--r--src/librustdoc/formats/item_type.rs4
-rw-r--r--src/librustdoc/formats/mod.rs20
-rw-r--r--src/librustdoc/formats/renderer.rs4
-rw-r--r--src/librustdoc/html/escape.rs2
-rw-r--r--src/librustdoc/html/format.rs28
-rw-r--r--src/librustdoc/html/highlight.rs2
-rw-r--r--src/librustdoc/html/layout.rs40
-rw-r--r--src/librustdoc/html/markdown.rs84
-rw-r--r--src/librustdoc/html/mod.rs2
-rw-r--r--src/librustdoc/html/render/cache.rs6
-rw-r--r--src/librustdoc/html/render/mod.rs158
-rw-r--r--src/librustdoc/html/sources.rs2
-rw-r--r--src/librustdoc/html/static/main.js10
-rw-r--r--src/librustdoc/html/static_files.rs72
-rw-r--r--src/librustdoc/html/toc.rs12
-rw-r--r--src/librustdoc/json/mod.rs2
-rw-r--r--src/librustdoc/markdown.rs4
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs2
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs4
-rw-r--r--src/librustdoc/passes/collapse_docs.rs6
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs4
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs4
-rw-r--r--src/librustdoc/passes/doc_test_lints.rs8
-rw-r--r--src/librustdoc/passes/html_tags.rs4
-rw-r--r--src/librustdoc/passes/mod.rs60
-rw-r--r--src/librustdoc/passes/non_autolinks.rs4
-rw-r--r--src/librustdoc/passes/propagate_doc_cfg.rs4
-rw-r--r--src/librustdoc/passes/strip_hidden.rs4
-rw-r--r--src/librustdoc/passes/strip_priv_imports.rs4
-rw-r--r--src/librustdoc/passes/strip_private.rs4
-rw-r--r--src/librustdoc/passes/stripper.rs14
-rw-r--r--src/librustdoc/passes/unindent_comments.rs6
-rw-r--r--src/librustdoc/theme.rs12
-rw-r--r--src/librustdoc/visit_ast.rs8
-rw-r--r--src/librustdoc/visit_lib.rs8
-rw-r--r--src/test/rustdoc/doc-cfg-traits.rs124
-rw-r--r--src/test/ui/const-generics/const-param-shadowing.rs9
-rw-r--r--src/test/ui/const-generics/const-param-shadowing.stderr14
-rw-r--r--src/test/ui/const-generics/invalid-constant-in-args.rs3
-rw-r--r--src/test/ui/const-generics/invalid-constant-in-args.stderr2
-rw-r--r--src/test/ui/const-generics/invalid-enum.rs12
-rw-r--r--src/test/ui/const-generics/invalid-enum.stderr64
-rw-r--r--src/test/ui/const-generics/issues/issue-62878.full.stderr16
-rw-r--r--src/test/ui/const-generics/issues/issue-62878.rs3
-rw-r--r--src/test/ui/const-generics/issues/issue-76595.rs2
-rw-r--r--src/test/ui/const-generics/issues/issue-76595.stderr4
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs3
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr36
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro-fail.rs12
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro-fail.stderr56
-rw-r--r--src/test/ui/generics/generic-impl-more-params-with-defaults.stderr4
-rw-r--r--src/test/ui/generics/generic-type-more-params-with-defaults.stderr4
-rw-r--r--src/test/ui/panic-while-printing.rs22
-rw-r--r--src/test/ui/parser/issue-14303-fncall.stderr2
-rw-r--r--src/test/ui/parser/issue-14303-path.stderr2
-rw-r--r--src/test/ui/privacy/privacy-ns1.rs4
-rw-r--r--src/test/ui/privacy/privacy-ns1.stderr16
-rw-r--r--src/test/ui/privacy/privacy-ns2.rs6
-rw-r--r--src/test/ui/privacy/privacy-ns2.stderr42
-rw-r--r--src/test/ui/suggestions/suggest-move-types.stderr4
-rw-r--r--src/test/ui/threads-sendsync/task-stderr.rs26
-rw-r--r--src/test/ui/traits/trait-object-vs-lifetime.stderr2
107 files changed, 1863 insertions, 1609 deletions
diff --git a/RELEASES.md b/RELEASES.md
index c9ff4928763..9fd796fd775 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,143 @@
+Version 1.48.0 (2020-11-19)
+==========================
+
+Language
+--------
+
+- [The `unsafe` keyword is now syntactically permitted on modules.][75857] This
+  is still rejected *semantically*, but can now be parsed by procedural macros.
+
+Compiler
+--------
+- [Stabilised the `-C link-self-contained=<yes|no>` compiler flag.][76158] This tells
+  `rustc` whether to link its own C runtime and libraries or to rely on a external 
+  linker to find them. (Supported only on `windows-gnu`, `linux-musl`, and `wasi` platforms.)
+- [You can now use `-C target-feature=+crt-static` on `linux-gnu` targets.][77386]
+  Note: If you're using cargo you must explicitly pass the `--target` flag.
+- [Added tier 2\* support for `aarch64-unknown-linux-musl`.][76420]
+
+\* Refer to Rust's [platform support page][forge-platform-support] for more
+information on Rust's tiered platform support.
+
+Libraries
+---------
+- [`io::Write` is now implemented for `&ChildStdin` `&Sink`, `&Stdout`,
+  and `&Stderr`.][76275]
+- [All arrays of any length now implement `TryFrom<Vec<T>>`.][76310]
+- [The `matches!` macro now supports having a trailing comma.][74880]
+- [`Vec<A>` now implements `PartialEq<[B]>` where `A: PartialEq<B>`.][74194]
+- [The `RefCell::{replace, replace_with, clone}` methods now all use `#[track_caller]`.][77055]
+
+Stabilized APIs
+---------------
+- [`slice::as_ptr_range`]
+- [`slice::as_mut_ptr_range`]
+- [`VecDeque::make_contiguous`]
+- [`future::pending`]
+- [`future::ready`]
+
+The following previously stable methods are now `const fn`'s:
+
+- [`Option::is_some`]
+- [`Option::is_none`]
+- [`Option::as_ref`]
+- [`Result::is_ok`]
+- [`Result::is_err`]
+- [`Result::as_ref`]
+- [`Ordering::reverse`]
+- [`Ordering::then`]
+
+Cargo
+-----
+
+Rustdoc
+-------
+- [You can now link to items in `rustdoc` using the intra-doc link
+  syntax.][74430] E.g. ``/// Uses [`std::future`]`` will automatically generate
+  a link to `std::future`'s documentation. See ["Linking to items by
+  name"][intradoc-links] for more information.
+- [You can now specify `#[doc(alias = "<alias>")]` on items to add search aliases
+  when searching through `rustdoc`'s UI.][75740]
+
+Compatibility Notes
+-------------------
+- [Promotion of references to `'static` lifetime inside `const fn` now follows the
+  same rules as inside a `fn` body.][75502] In particular, `&foo()` will not be
+  promoted to `'static` lifetime any more inside `const fn`s.
+- [Associated type bindings on trait objects are now verified to meet the bounds
+  declared on the trait when checking that they implement the trait.][27675]
+- [When trait bounds on associated types or opaque types are ambiguous, the
+  compiler no longer makes an arbitrary choice on which bound to use.][54121]
+- [Fixed recursive nonterminals not being expanded in macros during
+  pretty-print/reparse check.][77153] This may cause errors if your macro wasn't
+  correctly handling recursive nonterminal tokens.
+- [`&mut` references to non zero-sized types are no longer promoted.][75585]
+- [`rustc` will now warn if you use attributes like `#[link_name]` or `#[cold]`
+  in places where they have no effect.][73461]
+- [Updated `_mm256_extract_epi8` and `_mm256_extract_epi16` signatures in
+  `arch::{x86, x86_64}` to return `i32` to match the vendor signatures.][73166]
+- [`mem::uninitialized` will now panic if any inner types inside a struct or enum
+  disallow zero-initialization.][71274]
+- [`#[target_feature]` will now error if used in a place where it has no effect.][78143]
+- [Foreign exceptions are now caught by `catch_unwind` and will cause an abort.][70212]
+  Note: This behaviour is not guaranteed and is still considered undefined behaviour,
+  see the [`catch_unwind`] documentation for further information.
+  
+
+
+Internal Only
+-------------
+These changes provide no direct user facing benefits, but represent significant
+improvements to the internals and overall performance of rustc and
+related tools.
+
+- [Building `rustc` from source now uses `ninja` by default over `make`.][74922]
+  You can continue building with `make` by setting `ninja=false` in
+  your `config.toml`.
+- [cg_llvm: `fewer_names` in `uncached_llvm_type`][76030]
+- [Made `ensure_sufficient_stack()` non-generic][76680]
+
+[78143]: https://github.com/rust-lang/rust/issues/78143
+[76680]: https://github.com/rust-lang/rust/pull/76680/
+[76030]: https://github.com/rust-lang/rust/pull/76030/
+[70212]: https://github.com/rust-lang/rust/pull/70212/
+[27675]: https://github.com/rust-lang/rust/issues/27675/
+[54121]: https://github.com/rust-lang/rust/issues/54121/  
+[71274]: https://github.com/rust-lang/rust/pull/71274/
+[77386]: https://github.com/rust-lang/rust/pull/77386/
+[77153]: https://github.com/rust-lang/rust/pull/77153/
+[77055]: https://github.com/rust-lang/rust/pull/77055/
+[76275]: https://github.com/rust-lang/rust/pull/76275/
+[76310]: https://github.com/rust-lang/rust/pull/76310/
+[76420]: https://github.com/rust-lang/rust/pull/76420/
+[76158]: https://github.com/rust-lang/rust/pull/76158/
+[75857]: https://github.com/rust-lang/rust/pull/75857/
+[75585]: https://github.com/rust-lang/rust/pull/75585/
+[75740]: https://github.com/rust-lang/rust/pull/75740/
+[75502]: https://github.com/rust-lang/rust/pull/75502/
+[74880]: https://github.com/rust-lang/rust/pull/74880/
+[74922]: https://github.com/rust-lang/rust/pull/74922/
+[74430]: https://github.com/rust-lang/rust/pull/74430/
+[74194]: https://github.com/rust-lang/rust/pull/74194/
+[73461]: https://github.com/rust-lang/rust/pull/73461/
+[73166]: https://github.com/rust-lang/rust/pull/73166/
+[intradoc-links]: https://doc.rust-lang.org/rustdoc/linking-to-items-by-name.html
+[`catch_unwind`]: https://doc.rust-lang.org/std/panic/fn.catch_unwind.html
+[`Option::is_some`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.is_some
+[`Option::is_none`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.is_none
+[`Option::as_ref`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.as_ref
+[`Result::is_ok`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_ok
+[`Result::is_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.is_err
+[`Result::as_ref`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.as_ref
+[`Ordering::reverse`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.reverse
+[`Ordering::then`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then
+[`slice::as_ptr_range`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr_range
+[`slice::as_mut_ptr_range`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_mut_ptr_range
+[`VecDeque::make_contiguous`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.make_contiguous
+[`future::pending`]: https://doc.rust-lang.org/std/future/fn.pending.html
+[`future::ready`]: https://doc.rust-lang.org/std/future/fn.ready.html
+
+
 Version 1.47.0 (2020-10-08)
 ==========================
 
@@ -90,6 +230,7 @@ Compatibility Notes
 
 Internal Only
 --------
+
 - [Improved default settings for bootstrapping in `x.py`.][73964] You can read details about this change in the ["Changes to `x.py` defaults"](https://blog.rust-lang.org/inside-rust/2020/08/30/changes-to-x-py-defaults.html) post on the Inside Rust blog.
 
 [1.47.0-cfg]: https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard
diff --git a/compiler/rustc_error_codes/src/error_codes/E0744.md b/compiler/rustc_error_codes/src/error_codes/E0744.md
index 14cff3613e0..45804ab266e 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0744.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0744.md
@@ -1,4 +1,4 @@
-A control-flow expression was used inside a const context.
+An unsupported expression was used inside a const context.
 
 Erroneous code example:
 
@@ -12,12 +12,15 @@ const _: i32 = {
 };
 ```
 
-At the moment, `if` and `match`, as well as the looping constructs `for`,
-`while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`.
+At the moment, `for` loops, `.await`, and the `Try` operator (`?`) are forbidden
+inside a `const`, `static`, or `const fn`.
 
-This will be allowed at some point in the future, but the implementation is not
-yet complete. See the tracking issue for [conditionals] or [loops] in a const
-context for the current status.
+This may be allowed at some point in the future, but the implementation is not
+yet complete. See the tracking issues for [`async`] and [`?`] in `const fn`, and
+(to support `for` loops in `const fn`) the tracking issues for [`impl const
+Trait for Ty`] and [`&mut T`] in `const fn`.
 
-[conditionals]: https://github.com/rust-lang/rust/issues/49146
-[loops]: https://github.com/rust-lang/rust/issues/52000
+[`async`]: https://github.com/rust-lang/rust/issues/69431
+[`?`]: https://github.com/rust-lang/rust/issues/74935
+[`impl const Trait for Ty`]: https://github.com/rust-lang/rust/issues/67792
+[`&mut T`]: https://github.com/rust-lang/rust/issues/57349
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 3c28b48795f..4497c8c0eaa 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -282,6 +282,14 @@ impl GenericArg<'_> {
             GenericArg::Const(_) => "constant",
         }
     }
+
+    pub fn short_descr(&self) -> &'static str {
+        match self {
+            GenericArg::Lifetime(_) => "lifetime",
+            GenericArg::Type(_) => "type",
+            GenericArg::Const(_) => "const",
+        }
+    }
 }
 
 #[derive(Debug, HashStable_Generic)]
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 88d2efe96d1..0935eb2bd71 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -1,6 +1,6 @@
 #![feature(bool_to_option)]
 #![feature(box_syntax)]
-#![feature(set_stdio)]
+#![feature(internal_output_capture)]
 #![feature(nll)]
 #![feature(generator_trait)]
 #![feature(generators)]
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index d9ec6d51cdf..20a7b47313e 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -25,7 +25,7 @@ use rustc_span::symbol::{sym, Symbol};
 use smallvec::SmallVec;
 use std::env;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
-use std::io::{self, Write};
+use std::io;
 use std::lazy::SyncOnceCell;
 use std::mem;
 use std::ops::DerefMut;
@@ -106,21 +106,6 @@ fn get_stack_size() -> Option<usize> {
     env::var_os("RUST_MIN_STACK").is_none().then_some(STACK_SIZE)
 }
 
-struct Sink(Arc<Mutex<Vec<u8>>>);
-impl Write for Sink {
-    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-        Write::write(&mut *self.0.lock().unwrap(), data)
-    }
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-impl io::LocalOutput for Sink {
-    fn clone_box(&self) -> Box<dyn io::LocalOutput> {
-        Box::new(Self(self.0.clone()))
-    }
-}
-
 /// Like a `thread::Builder::spawn` followed by a `join()`, but avoids the need
 /// for `'static` bounds.
 #[cfg(not(parallel_compiler))]
@@ -163,9 +148,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
 
     let main_handler = move || {
         rustc_span::with_session_globals(edition, || {
-            if let Some(stderr) = stderr {
-                io::set_panic(Some(box Sink(stderr.clone())));
-            }
+            io::set_output_capture(stderr.clone());
             f()
         })
     };
@@ -203,9 +186,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
             // on the new threads.
             let main_handler = move |thread: rayon::ThreadBuilder| {
                 rustc_span::SESSION_GLOBALS.set(session_globals, || {
-                    if let Some(stderr) = stderr {
-                        io::set_panic(Some(box Sink(stderr.clone())));
-                    }
+                    io::set_output_capture(stderr.clone());
                     thread.run()
                 })
             };
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index 301ede66006..0db5fda272a 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -23,6 +23,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         sess: &Session,
         arg: &GenericArg<'_>,
         kind: &'static str,
+        possible_ordering_error: bool,
         help: Option<&str>,
     ) {
         let mut err = struct_span_err!(
@@ -49,8 +50,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             GenericArg::Const(_) => ParamKindOrd::Const { unordered },
         };
 
+        if matches!(arg, GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. }))
+            && matches!(kind_ord, ParamKindOrd::Const { .. })
+        {
+            let suggestions = vec![
+                (arg.span().shrink_to_lo(), String::from("{ ")),
+                (arg.span().shrink_to_hi(), String::from(" }")),
+            ];
+            err.multipart_suggestion(
+                "if this generic argument was intended as a const parameter, \
+                try surrounding it with braces:",
+                suggestions,
+                Applicability::MaybeIncorrect,
+            );
+        }
+
         // This note is only true when generic parameters are strictly ordered by their kind.
-        if kind_ord.cmp(&arg_ord) != core::cmp::Ordering::Equal {
+        if possible_ordering_error && kind_ord.cmp(&arg_ord) != core::cmp::Ordering::Equal {
             let (first, last) =
                 if kind_ord < arg_ord { (kind, arg.descr()) } else { (arg.descr(), kind) };
             err.note(&format!("{} arguments must be provided before {} arguments", first, last));
@@ -148,8 +164,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             // Check whether this segment takes generic arguments and the user has provided any.
             let (generic_args, infer_args) = ctx.args_for_def_id(def_id);
 
-            let mut args =
-                generic_args.iter().flat_map(|generic_args| generic_args.args.iter()).peekable();
+            let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter());
+            let mut args = args_iter.clone().peekable();
 
             // If we encounter a type or const when we expect a lifetime, we infer the lifetimes.
             // If we later encounter a lifetime, we know that the arguments were provided in the
@@ -216,8 +232,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                                                     GenericParamDefKind::Const => {
                                                         ParamKindOrd::Const {
                                                             unordered: tcx
-                                                                .sess
-                                                                .features_untracked()
+                                                                .features()
                                                                 .const_generics,
                                                         }
                                                     }
@@ -237,6 +252,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                                         tcx.sess,
                                         arg,
                                         kind.descr(),
+                                        !args_iter.clone().is_sorted_by_key(|arg| match arg {
+                                            GenericArg::Lifetime(_) => ParamKindOrd::Lifetime,
+                                            GenericArg::Type(_) => ParamKindOrd::Type,
+                                            GenericArg::Const(_) => ParamKindOrd::Const {
+                                                unordered: tcx.features().const_generics,
+                                            },
+                                        }),
                                         Some(&format!(
                                             "reorder the arguments: {}: `<{}>`",
                                             param_types_present
@@ -288,7 +310,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             assert_eq!(kind, "lifetime");
                             let provided =
                                 force_infer_lt.expect("lifetimes ought to have been inferred");
-                            Self::generic_arg_mismatch_err(tcx.sess, provided, kind, None);
+                            Self::generic_arg_mismatch_err(tcx.sess, provided, kind, false, None);
                         }
 
                         break;
@@ -346,6 +368,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         // that lifetimes will proceed types. So it suffices to check the number of each generic
         // arguments in order to validate them with respect to the generic parameters.
         let param_counts = def.own_counts();
+        let named_type_param_count = param_counts.types - has_self as usize;
         let arg_counts = args.own_counts();
         let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
 
@@ -384,11 +407,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             // For kinds without defaults (e.g.., lifetimes), `required == permitted`.
             // For other kinds (i.e., types), `permitted` may be greater than `required`.
             if required <= provided && provided <= permitted {
-                return Ok(());
+                return true;
             }
 
             if silent {
-                return Err((0i32, None));
+                return false;
             }
 
             // Unfortunately lifetime and type parameter mismatches are typically styled
@@ -404,25 +427,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 (required, "")
             };
 
-            let (spans, label) = if required == permitted && provided > permitted {
+            let (spans, labels) = if provided > permitted {
                 // In the case when the user has provided too many arguments,
                 // we want to point to the unexpected arguments.
-                let spans: Vec<Span> = args.args[offset + permitted..offset + provided]
+                let (spans, labels): (Vec<Span>, Vec<String>) = args.args
+                    [offset + permitted..offset + provided]
                     .iter()
-                    .map(|arg| arg.span())
-                    .collect();
+                    .map(|arg| (arg.span(), format!("unexpected {} argument", arg.short_descr())))
+                    .unzip();
                 unexpected_spans.extend(spans.clone());
-                (spans, format!("unexpected {} argument", kind))
+                (spans, labels)
             } else {
                 (
                     vec![span],
-                    format!(
+                    vec![format!(
                         "expected {}{} {} argument{}",
                         quantifier,
                         bound,
                         kind,
                         pluralize!(bound),
-                    ),
+                    )],
                 )
             };
 
@@ -434,105 +458,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 ),
                 DiagnosticId::Error("E0107".into()),
             );
-            for span in spans {
+            for (span, label) in spans.into_iter().zip(labels) {
                 err.span_label(span, label.as_str());
             }
-
-            assert_ne!(bound, provided);
-            Err((bound as i32 - provided as i32, Some(err)))
+            err.emit();
+            false
         };
 
         let mut unexpected_spans = vec![];
 
-        let mut lifetime_count_correct = Ok(());
-        if !infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes {
-            lifetime_count_correct = check_kind_count(
-                "lifetime",
-                param_counts.lifetimes,
-                param_counts.lifetimes,
-                arg_counts.lifetimes,
-                0,
-                &mut unexpected_spans,
-                explicit_late_bound == ExplicitLateBound::Yes,
-            );
-        }
-
-        // FIXME(const_generics:defaults)
-        let mut const_count_correct = Ok(());
-        if !infer_args || arg_counts.consts > param_counts.consts {
-            const_count_correct = check_kind_count(
-                "const",
-                param_counts.consts,
-                param_counts.consts,
-                arg_counts.consts,
-                arg_counts.lifetimes + arg_counts.types,
-                &mut unexpected_spans,
-                false,
-            );
-        }
-
-        // Note that type errors are currently be emitted *after* const errors.
-        let mut type_count_correct = Ok(());
-        if !infer_args || arg_counts.types > param_counts.types - defaults.types - has_self as usize
-        {
-            type_count_correct = check_kind_count(
-                "type",
-                param_counts.types - defaults.types - has_self as usize,
-                param_counts.types - has_self as usize,
-                arg_counts.types,
-                arg_counts.lifetimes,
-                &mut unexpected_spans,
-                false,
-            );
-        }
-
-        // Emit a help message if it's possible that a type could be surrounded in braces
-        if let Err((c_mismatch, Some(ref mut _const_err))) = const_count_correct {
-            if let Err((_, Some(ref mut type_err))) = type_count_correct {
-                let possible_matches = args.args[arg_counts.lifetimes..]
-                    .iter()
-                    .filter(|arg| {
-                        matches!(
-                            arg,
-                            GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. })
-                        )
-                    })
-                    .take(c_mismatch.max(0) as usize);
-                for arg in possible_matches {
-                    let suggestions = vec![
-                        (arg.span().shrink_to_lo(), String::from("{ ")),
-                        (arg.span().shrink_to_hi(), String::from(" }")),
-                    ];
-                    type_err.multipart_suggestion(
-                        "If this generic argument was intended as a const parameter, \
-                        try surrounding it with braces:",
-                        suggestions,
-                        Applicability::MaybeIncorrect,
-                    );
-                }
-            }
-        }
+        let lifetime_count_correct = check_kind_count(
+            "lifetime",
+            if infer_lifetimes { 0 } else { param_counts.lifetimes },
+            param_counts.lifetimes,
+            arg_counts.lifetimes,
+            0,
+            &mut unexpected_spans,
+            explicit_late_bound == ExplicitLateBound::Yes,
+        );
 
-        let emit_correct =
-            |correct: Result<(), (_, Option<rustc_errors::DiagnosticBuilder<'_>>)>| match correct {
-                Ok(()) => Ok(()),
-                Err((_, None)) => Err(()),
-                Err((_, Some(mut err))) => {
-                    err.emit();
-                    Err(())
-                }
-            };
+        let kind_str = if param_counts.consts + arg_counts.consts == 0 {
+            "type"
+        } else if named_type_param_count + arg_counts.types == 0 {
+            "const"
+        } else {
+            "generic"
+        };
 
-        let arg_count_correct = emit_correct(lifetime_count_correct)
-            .and(emit_correct(const_count_correct))
-            .and(emit_correct(type_count_correct));
+        let arg_count_correct = check_kind_count(
+            kind_str,
+            if infer_args {
+                0
+            } else {
+                param_counts.consts + named_type_param_count - defaults.types
+            },
+            param_counts.consts + named_type_param_count,
+            arg_counts.consts + arg_counts.types,
+            arg_counts.lifetimes,
+            &mut unexpected_spans,
+            false,
+        );
 
         GenericArgCountResult {
             explicit_late_bound,
-            correct: arg_count_correct.map_err(|()| GenericArgCountMismatch {
-                reported: Some(ErrorReported),
-                invalid_args: unexpected_spans,
-            }),
+            correct: if lifetime_count_correct && arg_count_correct {
+                Ok(())
+            } else {
+                Err(GenericArgCountMismatch {
+                    reported: Some(ErrorReported),
+                    invalid_args: unexpected_spans,
+                })
+            },
         }
     }
 
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 30904091c1b..929c88455f0 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -61,6 +61,7 @@ This API is completely unstable and subject to change.
 #![feature(box_syntax)]
 #![feature(crate_visibility_modifier)]
 #![feature(in_band_lifetimes)]
+#![feature(is_sorted)]
 #![feature(nll)]
 #![feature(or_patterns)]
 #![feature(try_blocks)]
diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs
index 11dbb584abd..6e45d38dd9f 100644
--- a/library/alloc/src/collections/btree/map/tests.rs
+++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -14,6 +14,9 @@ use std::ops::RangeBounds;
 use std::panic::{catch_unwind, AssertUnwindSafe};
 use std::sync::atomic::{AtomicUsize, Ordering};
 
+mod ord_chaos;
+use ord_chaos::{Cyclic3, Governed, Governor};
+
 // Capacity of a tree with a single level,
 // i.e., a tree who's root is a leaf node at height 0.
 const NODE_CAPACITY: usize = node::CAPACITY;
@@ -28,7 +31,7 @@ const MIN_INSERTS_HEIGHT_1: usize = NODE_CAPACITY + 1;
 // It's not the minimum size: removing an element from such a tree does not always reduce height.
 const MIN_INSERTS_HEIGHT_2: usize = 89;
 
-// Gather all references from a mutable iterator and make sure Miri notices if
+// Gathers all references from a mutable iterator and makes sure Miri notices if
 // using them is dangerous.
 fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T>) {
     // Gather all those references.
@@ -43,28 +46,43 @@ fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T>
 }
 
 impl<K, V> BTreeMap<K, V> {
-    /// Panics if the map (or the code navigating it) is corrupted.
-    fn check(&self)
-    where
-        K: Copy + Debug + Ord,
-    {
+    // Panics if the map (or the code navigating it) is corrupted.
+    fn check_invariants(&self) {
         if let Some(root) = &self.root {
             let root_node = root.node_as_ref();
 
+            // Check the back pointers top-down, before we attempt to rely on
+            // more serious navigation code.
             assert!(root_node.ascend().is_err());
             root_node.assert_back_pointers();
 
+            // Check consistenty of `length` and some of the navigation.
             assert_eq!(self.length, root_node.calc_length());
+            assert_eq!(self.length, self.keys().count());
 
+            // Lastly, check the invariant causing the least harm.
             root_node.assert_min_len(if root_node.height() > 0 { 1 } else { 0 });
         } else {
+            // Check consistenty of `length` and some of the navigation.
             assert_eq!(self.length, 0);
+            assert_eq!(self.length, self.keys().count());
         }
+    }
 
-        self.assert_ascending();
+    // Panics if the map is corrupted or if the keys are not in strictly
+    // ascending order, in the current opinion of the `Ord` implementation.
+    // If the `Ord` implementation does not honor transitivity, this method
+    // does not guarantee that all the keys are unique, just that adjacent
+    // keys are unique.
+    fn check(&self)
+    where
+        K: Debug + Ord,
+    {
+        self.check_invariants();
+        self.assert_strictly_ascending();
     }
 
-    /// Returns the height of the root, if any.
+    // Returns the height of the root, if any.
     fn height(&self) -> Option<usize> {
         self.root.as_ref().map(node::Root::height)
     }
@@ -80,22 +98,18 @@ impl<K, V> BTreeMap<K, V> {
         }
     }
 
-    /// Asserts that the keys are in strictly ascending order.
-    fn assert_ascending(&self)
+    // Panics if the keys are not in strictly ascending order.
+    fn assert_strictly_ascending(&self)
     where
-        K: Copy + Debug + Ord,
+        K: Debug + Ord,
     {
-        let mut num_seen = 0;
         let mut keys = self.keys();
         if let Some(mut previous) = keys.next() {
-            num_seen = 1;
             for next in keys {
                 assert!(previous < next, "{:?} >= {:?}", previous, next);
                 previous = next;
-                num_seen += 1;
             }
         }
-        assert_eq!(num_seen, self.len());
     }
 }
 
@@ -111,7 +125,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>
     }
 }
 
-// Test our value of MIN_INSERTS_HEIGHT_2. It may change according to the
+// Tests our value of MIN_INSERTS_HEIGHT_2. It may change according to the
 // implementation of insertion, but it's best to be aware of when it does.
 #[test]
 fn test_levels() {
@@ -149,6 +163,25 @@ fn test_levels() {
     assert_eq!(map.len(), MIN_INSERTS_HEIGHT_2, "{}", map.dump_keys());
 }
 
+// Ensures the testing infrastructure usually notices order violations.
+#[test]
+#[should_panic]
+fn test_check_ord_chaos() {
+    let gov = Governor::new();
+    let map: BTreeMap<_, _> = (0..2).map(|i| (Governed(i, &gov), ())).collect();
+    gov.flip();
+    map.check();
+}
+
+// Ensures the testing infrastructure doesn't always mind order violations.
+#[test]
+fn test_check_invariants_ord_chaos() {
+    let gov = Governor::new();
+    let map: BTreeMap<_, _> = (0..2).map(|i| (Governed(i, &gov), ())).collect();
+    gov.flip();
+    map.check_invariants();
+}
+
 #[test]
 fn test_basic_large() {
     let mut map = BTreeMap::new();
@@ -334,7 +367,7 @@ fn test_iter_rev() {
     test(size, map.into_iter().rev());
 }
 
-/// Specifically tests iter_mut's ability to mutate the value of pairs in-line
+// Specifically tests iter_mut's ability to mutate the value of pairs in-line.
 fn do_test_iter_mut_mutation<T>(size: usize)
 where
     T: Copy + Debug + Ord + TryFrom<usize>,
@@ -439,6 +472,8 @@ fn test_iter_entering_root_twice() {
     *back.1 = 42;
     assert_eq!(front, (&0, &mut 24));
     assert_eq!(back, (&1, &mut 42));
+    assert_eq!(it.next(), None);
+    assert_eq!(it.next_back(), None);
     map.check();
 }
 
@@ -591,11 +626,12 @@ fn test_range_small() {
 
 #[test]
 fn test_range_height_1() {
-    // Tests tree with a root and 2 leaves. Depending on details we don't want or need
-    // to rely upon, the single key at the root will be 6 or 7.
+    // Tests tree with a root and 2 leaves. The single key in the root node is
+    // close to the middle among the keys.
 
-    let map: BTreeMap<_, _> = (1..=MIN_INSERTS_HEIGHT_1 as i32).map(|i| (i, i)).collect();
-    for &root in &[6, 7] {
+    let map: BTreeMap<_, _> = (0..MIN_INSERTS_HEIGHT_1 as i32).map(|i| (i, i)).collect();
+    let middle = MIN_INSERTS_HEIGHT_1 as i32 / 2;
+    for root in middle - 2..=middle + 2 {
         assert_eq!(range_keys(&map, (Excluded(root), Excluded(root + 1))), vec![]);
         assert_eq!(range_keys(&map, (Excluded(root), Included(root + 1))), vec![root + 1]);
         assert_eq!(range_keys(&map, (Included(root), Excluded(root + 1))), vec![root]);
@@ -728,6 +764,19 @@ fn test_range_backwards_4() {
 }
 
 #[test]
+#[should_panic]
+fn test_range_backwards_5() {
+    let mut map = BTreeMap::new();
+    map.insert(Cyclic3::B, ());
+    // Lacking static_assert, call `range` conditionally, to emphasise that
+    // we cause a different panic than `test_range_backwards_1` does.
+    // A more refined `should_panic` would be welcome.
+    if Cyclic3::C < Cyclic3::A {
+        map.range(Cyclic3::C..=Cyclic3::A);
+    }
+}
+
+#[test]
 fn test_range_1000() {
     // Miri is too slow
     let size = if cfg!(miri) { MIN_INSERTS_HEIGHT_2 as u32 } else { 1000 };
@@ -831,7 +880,7 @@ mod test_drain_filter {
     }
 
     #[test]
-    fn consuming_nothing() {
+    fn consumed_keeping_all() {
         let pairs = (0..3).map(|i| (i, i));
         let mut map: BTreeMap<_, _> = pairs.collect();
         assert!(map.drain_filter(|_, _| false).eq(iter::empty()));
@@ -839,10 +888,20 @@ mod test_drain_filter {
     }
 
     #[test]
-    fn consuming_all() {
+    fn consumed_removing_all() {
         let pairs = (0..3).map(|i| (i, i));
         let mut map: BTreeMap<_, _> = pairs.clone().collect();
         assert!(map.drain_filter(|_, _| true).eq(pairs));
+        assert!(map.is_empty());
+        map.check();
+    }
+
+    #[test]
+    fn dropped_removing_all() {
+        let pairs = (0..3).map(|i| (i, i));
+        let mut map: BTreeMap<_, _> = pairs.collect();
+        map.drain_filter(|_, _| true);
+        assert!(map.is_empty());
         map.check();
     }
 
@@ -1723,6 +1782,27 @@ fn test_append_drop_leak() {
     assert_eq!(DROPS.load(Ordering::SeqCst), 4); // Rust issue #47949 ate one little piggy
 }
 
+#[test]
+fn test_append_ord_chaos() {
+    let mut map1 = BTreeMap::new();
+    map1.insert(Cyclic3::A, ());
+    map1.insert(Cyclic3::B, ());
+    let mut map2 = BTreeMap::new();
+    map2.insert(Cyclic3::A, ());
+    map2.insert(Cyclic3::B, ());
+    map2.insert(Cyclic3::C, ()); // lands first, before A
+    map2.insert(Cyclic3::B, ()); // lands first, before C
+    map1.check();
+    map2.check(); // keys are not unique but still strictly ascending
+    assert_eq!(map1.len(), 2);
+    assert_eq!(map2.len(), 4);
+    map1.append(&mut map2);
+    assert_eq!(map1.len(), 5);
+    assert_eq!(map2.len(), 0);
+    map1.check();
+    map2.check();
+}
+
 fn rand_data(len: usize) -> Vec<(u32, u32)> {
     assert!(len * 2 <= 70029); // from that point on numbers repeat
     let mut rng = DeterministicRng::new();
@@ -1885,11 +1965,27 @@ fn test_insert_remove_intertwined() {
     let loops = if cfg!(miri) { 100 } else { 1_000_000 };
     let mut map = BTreeMap::new();
     let mut i = 1;
+    let offset = 165; // somewhat arbitrarily chosen to cover some code paths
     for _ in 0..loops {
-        i = (i + 421) & 0xFF;
+        i = (i + offset) & 0xFF;
         map.insert(i, i);
         map.remove(&(0xFF - i));
     }
-
     map.check();
 }
+
+#[test]
+fn test_insert_remove_intertwined_ord_chaos() {
+    let loops = if cfg!(miri) { 100 } else { 1_000_000 };
+    let gov = Governor::new();
+    let mut map = BTreeMap::new();
+    let mut i = 1;
+    let offset = 165; // more arbitrarily copied from above
+    for _ in 0..loops {
+        i = (i + offset) & 0xFF;
+        map.insert(Governed(i, &gov), ());
+        map.remove(&Governed(0xFF - i, &gov));
+        gov.flip();
+    }
+    map.check_invariants();
+}
diff --git a/library/alloc/src/collections/btree/map/tests/ord_chaos.rs b/library/alloc/src/collections/btree/map/tests/ord_chaos.rs
new file mode 100644
index 00000000000..91d1d6ea9ef
--- /dev/null
+++ b/library/alloc/src/collections/btree/map/tests/ord_chaos.rs
@@ -0,0 +1,76 @@
+use std::cell::Cell;
+use std::cmp::Ordering::{self, *};
+use std::ptr;
+
+#[derive(Debug)]
+pub enum Cyclic3 {
+    A,
+    B,
+    C,
+}
+use Cyclic3::*;
+
+impl PartialOrd for Cyclic3 {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Cyclic3 {
+    fn cmp(&self, other: &Self) -> Ordering {
+        match (self, other) {
+            (A, A) | (B, B) | (C, C) => Equal,
+            (A, B) | (B, C) | (C, A) => Less,
+            (A, C) | (B, A) | (C, B) => Greater,
+        }
+    }
+}
+
+impl PartialEq for Cyclic3 {
+    fn eq(&self, other: &Self) -> bool {
+        self.cmp(&other) == Equal
+    }
+}
+
+impl Eq for Cyclic3 {}
+
+#[derive(Debug)]
+pub struct Governor {
+    flipped: Cell<bool>,
+}
+
+impl Governor {
+    pub fn new() -> Self {
+        Governor { flipped: Cell::new(false) }
+    }
+
+    pub fn flip(&self) {
+        self.flipped.set(!self.flipped.get());
+    }
+}
+
+#[derive(Debug)]
+pub struct Governed<'a, T>(pub T, pub &'a Governor);
+
+impl<T: Ord> PartialOrd for Governed<'_, T> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl<T: Ord> Ord for Governed<'_, T> {
+    fn cmp(&self, other: &Self) -> Ordering {
+        assert!(ptr::eq(self.1, other.1));
+        let ord = self.0.cmp(&other.0);
+        if self.1.flipped.get() { ord.reverse() } else { ord }
+    }
+}
+
+impl<T: PartialEq> PartialEq for Governed<'_, T> {
+    fn eq(&self, other: &Self) -> bool {
+        assert!(ptr::eq(self.1, other.1));
+        self.0.eq(&other.0)
+    }
+}
+
+impl<T: Eq> Eq for Governed<'_, T> {}
diff --git a/library/alloc/src/collections/btree/node/tests.rs b/library/alloc/src/collections/btree/node/tests.rs
index ac61c1df8e2..b04b29320ac 100644
--- a/library/alloc/src/collections/btree/node/tests.rs
+++ b/library/alloc/src/collections/btree/node/tests.rs
@@ -5,7 +5,7 @@ use crate::string::String;
 use core::cmp::Ordering::*;
 
 impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal> {
-    /// Asserts that the back pointer in each reachable node points to its parent.
+    // Asserts that the back pointer in each reachable node points to its parent.
     pub fn assert_back_pointers(self) {
         if let ForceResult::Internal(node) = self.force() {
             for idx in 0..=node.len() {
@@ -17,6 +17,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>
         }
     }
 
+    // Renders a multi-line display of the keys in order and in tree hierarchy,
+    // picturing the tree growing sideways from its root on the left to its
+    // leaves on the right.
     pub fn dump_keys(self) -> String
     where
         K: Debug,
diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs
index 6b21e54f66a..8213e904fba 100644
--- a/library/alloc/src/collections/mod.rs
+++ b/library/alloc/src/collections/mod.rs
@@ -41,7 +41,7 @@ pub use linked_list::LinkedList;
 #[doc(no_inline)]
 pub use vec_deque::VecDeque;
 
-use crate::alloc::{Layout, LayoutErr};
+use crate::alloc::{Layout, LayoutError};
 use core::fmt::Display;
 
 /// The error type for `try_reserve` methods.
@@ -71,9 +71,9 @@ pub enum TryReserveError {
 }
 
 #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
-impl From<LayoutErr> for TryReserveError {
+impl From<LayoutError> for TryReserveError {
     #[inline]
-    fn from(_: LayoutErr) -> Self {
+    fn from(_: LayoutError) -> Self {
         TryReserveError::CapacityOverflow
     }
 }
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index a4240308bb3..522c5bcf5af 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -1,7 +1,7 @@
 #![unstable(feature = "raw_vec_internals", reason = "implementation detail", issue = "none")]
 #![doc(hidden)]
 
-use core::alloc::LayoutErr;
+use core::alloc::LayoutError;
 use core::cmp;
 use core::intrinsics;
 use core::mem::{self, ManuallyDrop, MaybeUninit};
@@ -472,7 +472,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
 // significant, because the number of different `A` types seen in practice is
 // much smaller than the number of `T` types.)
 fn finish_grow<A>(
-    new_layout: Result<Layout, LayoutErr>,
+    new_layout: Result<Layout, LayoutError>,
     current_memory: Option<(NonNull<u8>, Layout)>,
     alloc: &mut A,
 ) -> Result<NonNull<[u8]>, TryReserveError>
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index a3fbed2ec12..2258d9614d5 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -39,7 +39,7 @@ pub struct Layout {
 
 impl Layout {
     /// Constructs a `Layout` from a given `size` and `align`,
-    /// or returns `LayoutErr` if any of the following conditions
+    /// or returns `LayoutError` if any of the following conditions
     /// are not met:
     ///
     /// * `align` must not be zero,
@@ -52,9 +52,9 @@ impl Layout {
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[inline]
-    pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutErr> {
+    pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutError> {
         if !align.is_power_of_two() {
-            return Err(LayoutErr { private: () });
+            return Err(LayoutError { private: () });
         }
 
         // (power-of-two implies align != 0.)
@@ -72,7 +72,7 @@ impl Layout {
         // Above implies that checking for summation overflow is both
         // necessary and sufficient.
         if size > usize::MAX - (align - 1) {
-            return Err(LayoutErr { private: () });
+            return Err(LayoutError { private: () });
         }
 
         // SAFETY: the conditions for `from_size_align_unchecked` have been
@@ -200,7 +200,7 @@ impl Layout {
     /// `align` violates the conditions listed in [`Layout::from_size_align`].
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
     #[inline]
-    pub fn align_to(&self, align: usize) -> Result<Self, LayoutErr> {
+    pub fn align_to(&self, align: usize) -> Result<Self, LayoutError> {
         Layout::from_size_align(self.size(), cmp::max(self.align(), align))
     }
 
@@ -274,16 +274,16 @@ impl Layout {
     /// layout of the array and `offs` is the distance between the start
     /// of each element in the array.
     ///
-    /// On arithmetic overflow, returns `LayoutErr`.
+    /// On arithmetic overflow, returns `LayoutError`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[inline]
-    pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
+    pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
         // This cannot overflow. Quoting from the invariant of Layout:
         // > `size`, when rounded up to the nearest multiple of `align`,
         // > must not overflow (i.e., the rounded value must be less than
         // > `usize::MAX`)
         let padded_size = self.size() + self.padding_needed_for(self.align());
-        let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
+        let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError { private: () })?;
 
         // SAFETY: self.align is already known to be valid and alloc_size has been
         // padded already.
@@ -307,7 +307,7 @@ impl Layout {
     /// start of the `next` embedded within the concatenated record
     /// (assuming that the record itself starts at offset 0).
     ///
-    /// On arithmetic overflow, returns `LayoutErr`.
+    /// On arithmetic overflow, returns `LayoutError`.
     ///
     /// # Examples
     ///
@@ -315,8 +315,8 @@ impl Layout {
     /// the fields from its fields' layouts:
     ///
     /// ```rust
-    /// # use std::alloc::{Layout, LayoutErr};
-    /// pub fn repr_c(fields: &[Layout]) -> Result<(Layout, Vec<usize>), LayoutErr> {
+    /// # use std::alloc::{Layout, LayoutError};
+    /// pub fn repr_c(fields: &[Layout]) -> Result<(Layout, Vec<usize>), LayoutError> {
     ///     let mut offsets = Vec::new();
     ///     let mut layout = Layout::from_size_align(0, 1)?;
     ///     for &field in fields {
@@ -337,12 +337,12 @@ impl Layout {
     /// ```
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
     #[inline]
-    pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
+    pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
         let new_align = cmp::max(self.align(), next.align());
         let pad = self.padding_needed_for(next.align());
 
-        let offset = self.size().checked_add(pad).ok_or(LayoutErr { private: () })?;
-        let new_size = offset.checked_add(next.size()).ok_or(LayoutErr { private: () })?;
+        let offset = self.size().checked_add(pad).ok_or(LayoutError { private: () })?;
+        let new_size = offset.checked_add(next.size()).ok_or(LayoutError { private: () })?;
 
         let layout = Layout::from_size_align(new_size, new_align)?;
         Ok((layout, offset))
@@ -359,11 +359,11 @@ impl Layout {
     /// guaranteed that all elements in the array will be properly
     /// aligned.
     ///
-    /// On arithmetic overflow, returns `LayoutErr`.
+    /// On arithmetic overflow, returns `LayoutError`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[inline]
-    pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
-        let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
+    pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
+        let size = self.size().checked_mul(n).ok_or(LayoutError { private: () })?;
         Layout::from_size_align(size, self.align())
     }
 
@@ -372,38 +372,46 @@ impl Layout {
     /// padding is inserted, the alignment of `next` is irrelevant,
     /// and is not incorporated *at all* into the resulting layout.
     ///
-    /// On arithmetic overflow, returns `LayoutErr`.
+    /// On arithmetic overflow, returns `LayoutError`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[inline]
-    pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutErr> {
-        let new_size = self.size().checked_add(next.size()).ok_or(LayoutErr { private: () })?;
+    pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
+        let new_size = self.size().checked_add(next.size()).ok_or(LayoutError { private: () })?;
         Layout::from_size_align(new_size, self.align())
     }
 
     /// Creates a layout describing the record for a `[T; n]`.
     ///
-    /// On arithmetic overflow, returns `LayoutErr`.
+    /// On arithmetic overflow, returns `LayoutError`.
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
     #[inline]
-    pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
+    pub fn array<T>(n: usize) -> Result<Self, LayoutError> {
         let (layout, offset) = Layout::new::<T>().repeat(n)?;
         debug_assert_eq!(offset, mem::size_of::<T>());
         Ok(layout.pad_to_align())
     }
 }
 
+#[stable(feature = "alloc_layout", since = "1.28.0")]
+#[rustc_deprecated(
+    since = "1.51.0",
+    reason = "Name does not follow std convention, use LayoutError",
+    suggestion = "LayoutError"
+)]
+pub type LayoutErr = LayoutError;
+
 /// The parameters given to `Layout::from_size_align`
 /// or some other `Layout` constructor
 /// do not satisfy its documented constraints.
-#[stable(feature = "alloc_layout", since = "1.28.0")]
+#[stable(feature = "alloc_layout_error", since = "1.49.0")]
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub struct LayoutErr {
+pub struct LayoutError {
     private: (),
 }
 
 // (we need this for downstream impl of trait Error)
 #[stable(feature = "alloc_layout", since = "1.28.0")]
-impl fmt::Display for LayoutErr {
+impl fmt::Display for LayoutError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str("invalid parameters to Layout::from_size_align")
     }
diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs
index c61c19cc7d1..bc874e2e522 100644
--- a/library/core/src/alloc/mod.rs
+++ b/library/core/src/alloc/mod.rs
@@ -8,7 +8,18 @@ mod layout;
 #[stable(feature = "global_alloc", since = "1.28.0")]
 pub use self::global::GlobalAlloc;
 #[stable(feature = "alloc_layout", since = "1.28.0")]
-pub use self::layout::{Layout, LayoutErr};
+pub use self::layout::Layout;
+#[stable(feature = "alloc_layout", since = "1.28.0")]
+#[rustc_deprecated(
+    since = "1.51.0",
+    reason = "Name does not follow std convention, use LayoutError",
+    suggestion = "LayoutError"
+)]
+#[allow(deprecated, deprecated_in_future)]
+pub use self::layout::LayoutErr;
+
+#[stable(feature = "alloc_layout_error", since = "1.49.0")]
+pub use self::layout::LayoutError;
 
 use crate::fmt;
 use crate::ptr::{self, NonNull};
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 123a191dd2c..a7cb1023229 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -12,6 +12,7 @@ use crate::convert::{Infallible, TryFrom};
 use crate::fmt;
 use crate::hash::{self, Hash};
 use crate::marker::Unsize;
+use crate::ops::{Index, IndexMut};
 use crate::slice::{Iter, IterMut};
 
 mod iter;
@@ -208,6 +209,30 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] {
     }
 }
 
+#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
+impl<T, I, const N: usize> Index<I> for [T; N]
+where
+    [T]: Index<I>,
+{
+    type Output = <[T] as Index<I>>::Output;
+
+    #[inline]
+    fn index(&self, index: I) -> &Self::Output {
+        Index::index(self as &[T], index)
+    }
+}
+
+#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
+impl<T, I, const N: usize> IndexMut<I> for [T; N]
+where
+    [T]: IndexMut<I>,
+{
+    #[inline]
+    fn index_mut(&mut self, index: I) -> &mut Self::Output {
+        IndexMut::index_mut(self as &mut [T], index)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A, B, const N: usize> PartialEq<[B; N]> for [A; N]
 where
@@ -254,22 +279,22 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'b, A, B, const N: usize> PartialEq<&'b [B]> for [A; N]
+impl<A, B, const N: usize> PartialEq<&[B]> for [A; N]
 where
     A: PartialEq<B>,
 {
     #[inline]
-    fn eq(&self, other: &&'b [B]) -> bool {
+    fn eq(&self, other: &&[B]) -> bool {
         self[..] == other[..]
     }
     #[inline]
-    fn ne(&self, other: &&'b [B]) -> bool {
+    fn ne(&self, other: &&[B]) -> bool {
         self[..] != other[..]
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b [B]
+impl<A, B, const N: usize> PartialEq<[A; N]> for &[B]
 where
     B: PartialEq<A>,
 {
@@ -284,22 +309,22 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'b, A, B, const N: usize> PartialEq<&'b mut [B]> for [A; N]
+impl<A, B, const N: usize> PartialEq<&mut [B]> for [A; N]
 where
     A: PartialEq<B>,
 {
     #[inline]
-    fn eq(&self, other: &&'b mut [B]) -> bool {
+    fn eq(&self, other: &&mut [B]) -> bool {
         self[..] == other[..]
     }
     #[inline]
-    fn ne(&self, other: &&'b mut [B]) -> bool {
+    fn ne(&self, other: &&mut [B]) -> bool {
         self[..] != other[..]
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b mut [B]
+impl<A, B, const N: usize> PartialEq<[A; N]> for &mut [B]
 where
     B: PartialEq<A>,
 {
diff --git a/library/core/tests/ops.rs b/library/core/tests/ops.rs
index 8f0cd3be406..e9d595e65e2 100644
--- a/library/core/tests/ops.rs
+++ b/library/core/tests/ops.rs
@@ -1,4 +1,4 @@
-use core::ops::{Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo};
+use core::ops::{Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
 
 // Test the Range structs and syntax.
 
@@ -60,6 +60,12 @@ fn test_range_inclusive() {
 }
 
 #[test]
+fn test_range_to_inclusive() {
+    // Not much to test.
+    let _ = RangeToInclusive { end: 42 };
+}
+
+#[test]
 fn test_range_is_empty() {
     assert!(!(0.0..10.0).is_empty());
     assert!((-0.0..0.0).is_empty());
@@ -151,3 +157,43 @@ fn test_range_syntax_in_return_statement() {
     }
     // Not much to test.
 }
+
+#[test]
+fn range_structural_match() {
+    // test that all range types can be structurally matched upon
+
+    const RANGE: Range<usize> = 0..1000;
+    match RANGE {
+        RANGE => {}
+        _ => unreachable!(),
+    }
+
+    const RANGE_FROM: RangeFrom<usize> = 0..;
+    match RANGE_FROM {
+        RANGE_FROM => {}
+        _ => unreachable!(),
+    }
+
+    const RANGE_FULL: RangeFull = ..;
+    match RANGE_FULL {
+        RANGE_FULL => {}
+    }
+
+    const RANGE_INCLUSIVE: RangeInclusive<usize> = 0..=999;
+    match RANGE_INCLUSIVE {
+        RANGE_INCLUSIVE => {}
+        _ => unreachable!(),
+    }
+
+    const RANGE_TO: RangeTo<usize> = ..1000;
+    match RANGE_TO {
+        RANGE_TO => {}
+        _ => unreachable!(),
+    }
+
+    const RANGE_TO_INCLUSIVE: RangeToInclusive<usize> = ..=999;
+    match RANGE_TO_INCLUSIVE {
+        RANGE_TO_INCLUSIVE => {}
+        _ => unreachable!(),
+    }
+}
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index 5771ca758af..0044e59d697 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -19,7 +19,7 @@ mod tests;
 use core::array;
 use core::convert::Infallible;
 
-use crate::alloc::{AllocError, LayoutErr};
+use crate::alloc::{AllocError, LayoutError};
 use crate::any::TypeId;
 use crate::backtrace::Backtrace;
 use crate::borrow::Cow;
@@ -390,7 +390,7 @@ impl Error for ! {}
 impl Error for AllocError {}
 
 #[stable(feature = "alloc_layout", since = "1.28.0")]
-impl Error for LayoutErr {}
+impl Error for LayoutError {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Error for str::ParseBoolError {
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index 66426101d27..6b3c86cb0df 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -209,20 +209,6 @@ impl<B: BufRead + ?Sized> BufRead for Box<B> {
     }
 }
 
-// Used by panicking::default_hook
-#[cfg(test)]
-/// This impl is only used by printing logic, so any error returned is always
-/// of kind `Other`, and should be ignored.
-impl Write for dyn ::realstd::io::LocalOutput {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        (*self).write(buf).map_err(|_| ErrorKind::Other.into())
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        (*self).flush().map_err(|_| ErrorKind::Other.into())
-    }
-}
-
 // =============================================================================
 // In-memory buffer implementations
 
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 57413f9bc40..703c3755b63 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -271,20 +271,18 @@ pub use self::copy::copy;
 pub use self::cursor::Cursor;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::error::{Error, ErrorKind, Result};
+#[unstable(feature = "internal_output_capture", issue = "none")]
+#[doc(no_inline, hidden)]
+pub use self::stdio::set_output_capture;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::stdio::{stderr, stdin, stdout, Stderr, Stdin, Stdout};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::stdio::{StderrLock, StdinLock, StdoutLock};
 #[unstable(feature = "print_internals", issue = "none")]
 pub use self::stdio::{_eprint, _print};
-#[unstable(feature = "libstd_io_internals", issue = "42788")]
-#[doc(no_inline, hidden)]
-pub use self::stdio::{set_panic, set_print, LocalOutput};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::util::{empty, repeat, sink, Empty, Repeat, Sink};
 
-pub(crate) use self::stdio::clone_io;
-
 mod buffered;
 pub(crate) mod copy;
 mod cursor;
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 8fbce09dd63..6ea7704d422 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -5,44 +5,38 @@ mod tests;
 
 use crate::io::prelude::*;
 
-use crate::cell::RefCell;
+use crate::cell::{Cell, RefCell};
 use crate::fmt;
 use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter};
 use crate::lazy::SyncOnceCell;
 use crate::sync::atomic::{AtomicBool, Ordering};
-use crate::sync::{Mutex, MutexGuard};
+use crate::sync::{Arc, Mutex, MutexGuard};
 use crate::sys::stdio;
 use crate::sys_common;
 use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
-use crate::thread::LocalKey;
 
-thread_local! {
-    /// Used by the test crate to capture the output of the print! and println! macros.
-    static LOCAL_STDOUT: RefCell<Option<Box<dyn LocalOutput>>> = {
-        RefCell::new(None)
-    }
-}
+type LocalStream = Arc<Mutex<Vec<u8>>>;
 
 thread_local! {
-    /// Used by the test crate to capture the output of the eprint! and eprintln! macros, and panics.
-    static LOCAL_STDERR: RefCell<Option<Box<dyn LocalOutput>>> = {
-        RefCell::new(None)
+    /// Used by the test crate to capture the output of the print macros and panics.
+    static OUTPUT_CAPTURE: Cell<Option<LocalStream>> = {
+        Cell::new(None)
     }
 }
 
-/// Flag to indicate LOCAL_STDOUT and/or LOCAL_STDERR is used.
+/// Flag to indicate OUTPUT_CAPTURE is used.
 ///
-/// If both are None and were never set on any thread, this flag is set to
-/// false, and both LOCAL_STDOUT and LOCAL_STDOUT can be safely ignored on all
-/// threads, saving some time and memory registering an unused thread local.
+/// If it is None and was never set on any thread, this flag is set to false,
+/// and OUTPUT_CAPTURE can be safely ignored on all threads, saving some time
+/// and memory registering an unused thread local.
 ///
-/// Note about memory ordering: This contains information about whether two
-/// thread local variables might be in use. Although this is a global flag, the
+/// Note about memory ordering: This contains information about whether a
+/// thread local variable might be in use. Although this is a global flag, the
 /// memory ordering between threads does not matter: we only want this flag to
-/// have a consistent order between set_print/set_panic and print_to *within
+/// have a consistent order between set_output_capture and print_to *within
 /// the same thread*. Within the same thread, things always have a perfectly
 /// consistent order. So Ordering::Relaxed is fine.
-static LOCAL_STREAMS: AtomicBool = AtomicBool::new(false);
+static OUTPUT_CAPTURE_USED: AtomicBool = AtomicBool::new(false);
 
 /// A handle to a raw instance of the standard input stream of this process.
 ///
@@ -896,97 +890,24 @@ impl fmt::Debug for StderrLock<'_> {
     }
 }
 
-/// A writer than can be cloned to new threads.
-#[unstable(
-    feature = "set_stdio",
-    reason = "this trait may disappear completely or be replaced \
-                     with a more general mechanism",
-    issue = "none"
-)]
-#[doc(hidden)]
-pub trait LocalOutput: Write + Send {
-    fn clone_box(&self) -> Box<dyn LocalOutput>;
-}
-
-/// Resets the thread-local stderr handle to the specified writer
-///
-/// This will replace the current thread's stderr handle, returning the old
-/// handle. All future calls to `panic!` and friends will emit their output to
-/// this specified handle.
-///
-/// Note that this does not need to be called for all new threads; the default
-/// output handle is to the process's stderr stream.
-#[unstable(
-    feature = "set_stdio",
-    reason = "this function may disappear completely or be replaced \
-                     with a more general mechanism",
-    issue = "none"
-)]
-#[doc(hidden)]
-pub fn set_panic(sink: Option<Box<dyn LocalOutput>>) -> Option<Box<dyn LocalOutput>> {
-    use crate::mem;
-    if sink.is_none() && !LOCAL_STREAMS.load(Ordering::Relaxed) {
-        // LOCAL_STDERR is definitely None since LOCAL_STREAMS is false.
-        return None;
-    }
-    let s = LOCAL_STDERR.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(
-        |mut s| {
-            let _ = s.flush();
-            Some(s)
-        },
-    );
-    LOCAL_STREAMS.store(true, Ordering::Relaxed);
-    s
-}
-
-/// Resets the thread-local stdout handle to the specified writer
-///
-/// This will replace the current thread's stdout handle, returning the old
-/// handle. All future calls to `print!` and friends will emit their output to
-/// this specified handle.
-///
-/// Note that this does not need to be called for all new threads; the default
-/// output handle is to the process's stdout stream.
+/// Sets the thread-local output capture buffer and returns the old one.
 #[unstable(
-    feature = "set_stdio",
-    reason = "this function may disappear completely or be replaced \
-                     with a more general mechanism",
+    feature = "internal_output_capture",
+    reason = "this function is meant for use in the test crate \
+        and may disappear in the future",
     issue = "none"
 )]
 #[doc(hidden)]
-pub fn set_print(sink: Option<Box<dyn LocalOutput>>) -> Option<Box<dyn LocalOutput>> {
-    use crate::mem;
-    if sink.is_none() && !LOCAL_STREAMS.load(Ordering::Relaxed) {
-        // LOCAL_STDOUT is definitely None since LOCAL_STREAMS is false.
+pub fn set_output_capture(sink: Option<LocalStream>) -> Option<LocalStream> {
+    if sink.is_none() && !OUTPUT_CAPTURE_USED.load(Ordering::Relaxed) {
+        // OUTPUT_CAPTURE is definitely None since OUTPUT_CAPTURE_USED is false.
         return None;
     }
-    let s = LOCAL_STDOUT.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(
-        |mut s| {
-            let _ = s.flush();
-            Some(s)
-        },
-    );
-    LOCAL_STREAMS.store(true, Ordering::Relaxed);
-    s
-}
-
-pub(crate) fn clone_io() -> (Option<Box<dyn LocalOutput>>, Option<Box<dyn LocalOutput>>) {
-    // Don't waste time when LOCAL_{STDOUT,STDERR} are definitely None.
-    if !LOCAL_STREAMS.load(Ordering::Relaxed) {
-        return (None, None);
-    }
-
-    LOCAL_STDOUT.with(|stdout| {
-        LOCAL_STDERR.with(|stderr| {
-            (
-                stdout.borrow().as_ref().map(|o| o.clone_box()),
-                stderr.borrow().as_ref().map(|o| o.clone_box()),
-            )
-        })
-    })
+    OUTPUT_CAPTURE_USED.store(true, Ordering::Relaxed);
+    OUTPUT_CAPTURE.with(move |slot| slot.replace(sink))
 }
 
-/// Write `args` to output stream `local_s` if possible, `global_s`
+/// Write `args` to the capture buffer if enabled and possible, or `global_s`
 /// otherwise. `label` identifies the stream in a panic message.
 ///
 /// This function is used to print error messages, so it takes extra
@@ -996,36 +917,26 @@ pub(crate) fn clone_io() -> (Option<Box<dyn LocalOutput>>, Option<Box<dyn LocalO
 /// thread, it will just fall back to the global stream.
 ///
 /// However, if the actual I/O causes an error, this function does panic.
-fn print_to<T>(
-    args: fmt::Arguments<'_>,
-    local_s: &'static LocalKey<RefCell<Option<Box<dyn LocalOutput>>>>,
-    global_s: fn() -> T,
-    label: &str,
-) where
+fn print_to<T>(args: fmt::Arguments<'_>, global_s: fn() -> T, label: &str)
+where
     T: Write,
 {
-    let result = LOCAL_STREAMS
-        .load(Ordering::Relaxed)
-        .then(|| {
-            local_s
-                .try_with(|s| {
-                    // Note that we completely remove a local sink to write to in case
-                    // our printing recursively panics/prints, so the recursive
-                    // panic/print goes to the global sink instead of our local sink.
-                    let prev = s.borrow_mut().take();
-                    if let Some(mut w) = prev {
-                        let result = w.write_fmt(args);
-                        *s.borrow_mut() = Some(w);
-                        return result;
-                    }
-                    global_s().write_fmt(args)
-                })
-                .ok()
-        })
-        .flatten()
-        .unwrap_or_else(|| global_s().write_fmt(args));
-
-    if let Err(e) = result {
+    if OUTPUT_CAPTURE_USED.load(Ordering::Relaxed)
+        && OUTPUT_CAPTURE.try_with(|s| {
+            // Note that we completely remove a local sink to write to in case
+            // our printing recursively panics/prints, so the recursive
+            // panic/print goes to the global sink instead of our local sink.
+            s.take().map(|w| {
+                let _ = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
+                s.set(Some(w));
+            })
+        }) == Ok(Some(()))
+    {
+        // Succesfully wrote to capture buffer.
+        return;
+    }
+
+    if let Err(e) = global_s().write_fmt(args) {
         panic!("failed printing to {}: {}", label, e);
     }
 }
@@ -1038,7 +949,7 @@ fn print_to<T>(
 #[doc(hidden)]
 #[cfg(not(test))]
 pub fn _print(args: fmt::Arguments<'_>) {
-    print_to(args, &LOCAL_STDOUT, stdout, "stdout");
+    print_to(args, stdout, "stdout");
 }
 
 #[unstable(
@@ -1049,7 +960,7 @@ pub fn _print(args: fmt::Arguments<'_>) {
 #[doc(hidden)]
 #[cfg(not(test))]
 pub fn _eprint(args: fmt::Arguments<'_>) {
-    print_to(args, &LOCAL_STDERR, stderr, "stderr");
+    print_to(args, stderr, "stderr");
 }
 
 #[cfg(test)]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index ffc9cf3f2eb..ac11fcf7329 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -207,7 +207,7 @@
 // std may use features in a platform-specific way
 #![allow(unused_features)]
 #![cfg_attr(not(bootstrap), feature(rustc_allow_const_fn_unstable))]
-#![cfg_attr(test, feature(print_internals, set_stdio, update_panic_count))]
+#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count))]
 #![cfg_attr(
     all(target_vendor = "fortanix", target_env = "sgx"),
     feature(slice_index_methods, coerce_unsized, sgx_platform)
@@ -298,6 +298,7 @@
 #![feature(raw)]
 #![feature(raw_ref_macros)]
 #![feature(ready_macro)]
+#![feature(refcell_take)]
 #![feature(rustc_attrs)]
 #![feature(rustc_private)]
 #![feature(shrink_to)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index fbbc61f4e60..8ba3feccb6b 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -24,11 +24,11 @@ use crate::sys_common::{thread_info, util};
 use crate::thread;
 
 #[cfg(not(test))]
-use crate::io::set_panic;
+use crate::io::set_output_capture;
 // make sure to use the stderr output configured
 // by libtest in the real copy of std
 #[cfg(test)]
-use realstd::io::set_panic;
+use realstd::io::set_output_capture;
 
 // Binary interface to the panic runtime that the standard library depends on.
 //
@@ -218,11 +218,9 @@ fn default_hook(info: &PanicInfo<'_>) {
         }
     };
 
-    if let Some(mut local) = set_panic(None) {
-        // NB. In `cfg(test)` this uses the forwarding impl
-        // for `dyn ::realstd::io::LocalOutput`.
-        write(&mut local);
-        set_panic(Some(local));
+    if let Some(local) = set_output_capture(None) {
+        write(&mut *local.lock().unwrap_or_else(|e| e.into_inner()));
+        set_output_capture(Some(local));
     } else if let Some(mut out) = panic_output() {
         write(&mut out);
     }
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index fefaa77a2a1..5d65f960fcd 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -456,15 +456,15 @@ impl Builder {
         let my_packet: Arc<UnsafeCell<Option<Result<T>>>> = Arc::new(UnsafeCell::new(None));
         let their_packet = my_packet.clone();
 
-        let (stdout, stderr) = crate::io::clone_io();
+        let output_capture = crate::io::set_output_capture(None);
+        crate::io::set_output_capture(output_capture.clone());
 
         let main = move || {
             if let Some(name) = their_thread.cname() {
                 imp::Thread::set_name(name);
             }
 
-            crate::io::set_print(stdout);
-            crate::io::set_panic(stderr);
+            crate::io::set_output_capture(output_capture);
 
             // SAFETY: the stack guard passed is the one for the current thread.
             // This means the current thread's stack and the new thread's stack
diff --git a/library/test/src/bench.rs b/library/test/src/bench.rs
index 10546de1764..d4b37284ea7 100644
--- a/library/test/src/bench.rs
+++ b/library/test/src/bench.rs
@@ -2,8 +2,7 @@
 pub use std::hint::black_box;
 
 use super::{
-    event::CompletedTest, helpers::sink::Sink, options::BenchMode, test_result::TestResult,
-    types::TestDesc, Sender,
+    event::CompletedTest, options::BenchMode, test_result::TestResult, types::TestDesc, Sender,
 };
 
 use crate::stats;
@@ -185,21 +184,14 @@ where
     let mut bs = Bencher { mode: BenchMode::Auto, summary: None, bytes: 0 };
 
     let data = Arc::new(Mutex::new(Vec::new()));
-    let oldio = if !nocapture {
-        Some((
-            io::set_print(Some(Sink::new_boxed(&data))),
-            io::set_panic(Some(Sink::new_boxed(&data))),
-        ))
-    } else {
-        None
-    };
+
+    if !nocapture {
+        io::set_output_capture(Some(data.clone()));
+    }
 
     let result = catch_unwind(AssertUnwindSafe(|| bs.bench(f)));
 
-    if let Some((printio, panicio)) = oldio {
-        io::set_print(printio);
-        io::set_panic(panicio);
-    }
+    io::set_output_capture(None);
 
     let test_result = match result {
         //bs.bench(f) {
diff --git a/library/test/src/helpers/mod.rs b/library/test/src/helpers/mod.rs
index eb416b10150..b7f00c4c86c 100644
--- a/library/test/src/helpers/mod.rs
+++ b/library/test/src/helpers/mod.rs
@@ -5,4 +5,3 @@ pub mod concurrency;
 pub mod exit_code;
 pub mod isatty;
 pub mod metrics;
-pub mod sink;
diff --git a/library/test/src/helpers/sink.rs b/library/test/src/helpers/sink.rs
deleted file mode 100644
index dfbf0a3b72f..00000000000
--- a/library/test/src/helpers/sink.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-//! Module providing a helper structure to capture output in subprocesses.
-
-use std::{
-    io,
-    io::prelude::Write,
-    sync::{Arc, Mutex},
-};
-
-#[derive(Clone)]
-pub struct Sink(Arc<Mutex<Vec<u8>>>);
-
-impl Sink {
-    pub fn new_boxed(data: &Arc<Mutex<Vec<u8>>>) -> Box<Self> {
-        Box::new(Self(data.clone()))
-    }
-}
-
-impl io::LocalOutput for Sink {
-    fn clone_box(&self) -> Box<dyn io::LocalOutput> {
-        Box::new(self.clone())
-    }
-}
-
-impl Write for Sink {
-    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-        Write::write(&mut *self.0.lock().unwrap(), data)
-    }
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 9c5bb8957b5..816b4d51188 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -25,7 +25,7 @@
 #![feature(nll)]
 #![feature(bool_to_option)]
 #![feature(available_concurrency)]
-#![feature(set_stdio)]
+#![feature(internal_output_capture)]
 #![feature(panic_unwind)]
 #![feature(staged_api)]
 #![feature(termination_trait_lib)]
@@ -89,7 +89,6 @@ mod tests;
 use event::{CompletedTest, TestEvent};
 use helpers::concurrency::get_concurrency;
 use helpers::exit_code::get_exit_code;
-use helpers::sink::Sink;
 use options::{Concurrent, RunStrategy};
 use test_result::*;
 use time::TestExecTime;
@@ -531,14 +530,9 @@ fn run_test_in_process(
     // Buffer for capturing standard I/O
     let data = Arc::new(Mutex::new(Vec::new()));
 
-    let oldio = if !nocapture {
-        Some((
-            io::set_print(Some(Sink::new_boxed(&data))),
-            io::set_panic(Some(Sink::new_boxed(&data))),
-        ))
-    } else {
-        None
-    };
+    if !nocapture {
+        io::set_output_capture(Some(data.clone()));
+    }
 
     let start = report_time.then(Instant::now);
     let result = catch_unwind(AssertUnwindSafe(testfn));
@@ -547,16 +541,13 @@ fn run_test_in_process(
         TestExecTime(duration)
     });
 
-    if let Some((printio, panicio)) = oldio {
-        io::set_print(printio);
-        io::set_panic(panicio);
-    }
+    io::set_output_capture(None);
 
     let test_result = match result {
         Ok(()) => calc_result(&desc, Ok(()), &time_opts, &exec_time),
         Err(e) => calc_result(&desc, Err(e.as_ref()), &time_opts, &exec_time),
     };
-    let stdout = data.lock().unwrap().to_vec();
+    let stdout = data.lock().unwrap_or_else(|e| e.into_inner()).to_vec();
     let message = CompletedTest::new(desc, test_result, exec_time, stdout);
     monitor_ch.send(message).unwrap();
 }
diff --git a/src/doc/unstable-book/src/library-features/libstd-io-internals.md b/src/doc/unstable-book/src/library-features/internal-output-capture.md
index 8bcc2769db7..7e1241fce98 100644
--- a/src/doc/unstable-book/src/library-features/libstd-io-internals.md
+++ b/src/doc/unstable-book/src/library-features/internal-output-capture.md
@@ -1,4 +1,4 @@
-# `libstd_io_internals`
+# `internal_output_capture`
 
 This feature is internal to the Rust compiler and is not intended for general use.
 
diff --git a/src/doc/unstable-book/src/library-features/set-stdio.md b/src/doc/unstable-book/src/library-features/set-stdio.md
deleted file mode 100644
index 7dbdcdaa1a2..00000000000
--- a/src/doc/unstable-book/src/library-features/set-stdio.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# `set_stdio`
-
-This feature is internal to the Rust compiler and is not intended for general use.
-
-------------------------
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index a07d6b73f06..ff996b2a925 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -20,13 +20,13 @@ struct RegionDeps<'tcx> {
     smaller: FxHashSet<RegionTarget<'tcx>>,
 }
 
-pub struct AutoTraitFinder<'a, 'tcx> {
-    pub cx: &'a core::DocContext<'tcx>,
-    pub f: auto_trait::AutoTraitFinder<'tcx>,
+crate struct AutoTraitFinder<'a, 'tcx> {
+    crate cx: &'a core::DocContext<'tcx>,
+    crate f: auto_trait::AutoTraitFinder<'tcx>,
 }
 
 impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
-    pub fn new(cx: &'a core::DocContext<'tcx>) -> Self {
+    crate fn new(cx: &'a core::DocContext<'tcx>) -> Self {
         let f = auto_trait::AutoTraitFinder::new(cx.tcx);
 
         AutoTraitFinder { cx, f }
@@ -34,7 +34,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
 
     // FIXME(eddyb) figure out a better way to pass information about
     // parametrization of `ty` than `param_env_def_id`.
-    pub fn get_auto_trait_impls(&self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
+    crate fn get_auto_trait_impls(&self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
         let param_env = self.cx.tcx.param_env(param_env_def_id);
 
         debug!("get_auto_trait_impls({:?})", ty);
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index f15142f4983..5721927d0ec 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -9,18 +9,18 @@ use rustc_span::DUMMY_SP;
 
 use super::*;
 
-pub struct BlanketImplFinder<'a, 'tcx> {
-    pub cx: &'a core::DocContext<'tcx>,
+crate struct BlanketImplFinder<'a, 'tcx> {
+    crate cx: &'a core::DocContext<'tcx>,
 }
 
 impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
-    pub fn new(cx: &'a core::DocContext<'tcx>) -> Self {
+    crate fn new(cx: &'a core::DocContext<'tcx>) -> Self {
         BlanketImplFinder { cx }
     }
 
     // FIXME(eddyb) figure out a better way to pass information about
     // parametrization of `ty` than `param_env_def_id`.
-    pub fn get_blanket_impls(&self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
+    crate fn get_blanket_impls(&self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
         let param_env = self.cx.tcx.param_env(param_env_def_id);
 
         debug!("get_blanket_impls({:?})", ty);
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index b659f3eab43..2f169d1d3f3 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -20,7 +20,7 @@ use crate::html::escape::Escape;
 mod tests;
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub enum Cfg {
+crate enum Cfg {
     /// Accepts all configurations.
     True,
     /// Denies all configurations.
@@ -36,9 +36,9 @@ pub enum Cfg {
 }
 
 #[derive(PartialEq, Debug)]
-pub struct InvalidCfgError {
-    pub msg: &'static str,
-    pub span: Span,
+crate struct InvalidCfgError {
+    crate msg: &'static str,
+    crate span: Span,
 }
 
 impl Cfg {
@@ -59,7 +59,7 @@ impl Cfg {
     ///
     /// If the content is not properly formatted, it will return an error indicating what and where
     /// the error is.
-    pub fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
+    crate fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
         let name = match cfg.ident() {
             Some(ident) => ident.name,
             None => {
@@ -102,7 +102,7 @@ impl Cfg {
     ///
     /// Equivalent to `attr::cfg_matches`.
     // FIXME: Actually make use of `features`.
-    pub fn matches(&self, parse_sess: &ParseSess, features: Option<&Features>) -> bool {
+    crate fn matches(&self, parse_sess: &ParseSess, features: Option<&Features>) -> bool {
         match *self {
             Cfg::False => false,
             Cfg::True => true,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 56ce0bae8bb..daca4f8a933 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -3,11 +3,11 @@
 
 mod auto_trait;
 mod blanket_impl;
-pub mod cfg;
-pub mod inline;
+crate mod cfg;
+crate mod inline;
 mod simplify;
-pub mod types;
-pub mod utils;
+crate mod types;
+crate mod utils;
 
 use rustc_ast as ast;
 use rustc_attr as attr;
@@ -39,18 +39,18 @@ use crate::doctree;
 
 use utils::*;
 
-pub use utils::{get_auto_trait_and_blanket_impls, krate, register_res};
+crate use utils::{get_auto_trait_and_blanket_impls, krate, register_res};
 
-pub use self::types::FnRetTy::*;
-pub use self::types::ItemKind::*;
-pub use self::types::SelfTy::*;
-pub use self::types::Type::*;
-pub use self::types::Visibility::{Inherited, Public};
-pub use self::types::*;
+crate use self::types::FnRetTy::*;
+crate use self::types::ItemKind::*;
+crate use self::types::SelfTy::*;
+crate use self::types::Type::*;
+crate use self::types::Visibility::{Inherited, Public};
+crate use self::types::*;
 
 const FN_OUTPUT_NAME: &str = "Output";
 
-pub trait Clean<T> {
+crate trait Clean<T> {
     fn clean(&self, cx: &DocContext<'_>) -> T;
 }
 
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 990189f6ea0..121c9d2bc4c 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -21,7 +21,7 @@ use crate::clean::GenericArgs as PP;
 use crate::clean::WherePredicate as WP;
 use crate::core::DocContext;
 
-pub fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
+crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     // First, partition the where clause into its separate components
     let mut params: BTreeMap<_, Vec<_>> = BTreeMap::new();
     let mut lifetimes = Vec::new();
@@ -74,7 +74,7 @@ pub fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     clauses
 }
 
-pub fn merge_bounds(
+crate fn merge_bounds(
     cx: &clean::DocContext<'_>,
     bounds: &mut Vec<clean::GenericBound>,
     trait_did: DefId,
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 3060cf79cd5..9dd8415341e 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -45,47 +45,47 @@ use self::ItemKind::*;
 use self::SelfTy::*;
 use self::Type::*;
 
-thread_local!(pub static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> = Default::default());
+thread_local!(crate static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> = Default::default());
 
 #[derive(Clone, Debug)]
-pub struct Crate {
-    pub name: String,
-    pub version: Option<String>,
-    pub src: FileName,
-    pub module: Option<Item>,
-    pub externs: Vec<(CrateNum, ExternalCrate)>,
-    pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
+crate struct Crate {
+    crate name: String,
+    crate version: Option<String>,
+    crate src: FileName,
+    crate module: Option<Item>,
+    crate externs: Vec<(CrateNum, ExternalCrate)>,
+    crate primitives: Vec<(DefId, PrimitiveType, Attributes)>,
     // These are later on moved into `CACHEKEY`, leaving the map empty.
     // Only here so that they can be filtered through the rustdoc passes.
-    pub external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>,
-    pub masked_crates: FxHashSet<CrateNum>,
-    pub collapsed: bool,
+    crate external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>,
+    crate masked_crates: FxHashSet<CrateNum>,
+    crate collapsed: bool,
 }
 
 #[derive(Clone, Debug)]
-pub struct ExternalCrate {
-    pub name: String,
-    pub src: FileName,
-    pub attrs: Attributes,
-    pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
-    pub keywords: Vec<(DefId, String, Attributes)>,
+crate struct ExternalCrate {
+    crate name: String,
+    crate src: FileName,
+    crate attrs: Attributes,
+    crate primitives: Vec<(DefId, PrimitiveType, Attributes)>,
+    crate keywords: Vec<(DefId, String, Attributes)>,
 }
 
 /// Anything with a source location and set of attributes and, optionally, a
 /// name. That is, anything that can be documented. This doesn't correspond
 /// directly to the AST's concept of an item; it's a strict superset.
 #[derive(Clone)]
-pub struct Item {
+crate struct Item {
     /// Stringified span
-    pub source: Span,
+    crate source: Span,
     /// Not everything has a name. E.g., impls
-    pub name: Option<String>,
-    pub attrs: Attributes,
-    pub kind: ItemKind,
-    pub visibility: Visibility,
-    pub def_id: DefId,
-    pub stability: Option<Stability>,
-    pub deprecation: Option<Deprecation>,
+    crate name: Option<String>,
+    crate attrs: Attributes,
+    crate visibility: Visibility,
+    crate kind: ItemKind,
+    crate def_id: DefId,
+    crate stability: Option<Stability>,
+    crate deprecation: Option<Deprecation>,
 }
 
 impl fmt::Debug for Item {
@@ -108,80 +108,80 @@ impl fmt::Debug for Item {
 impl Item {
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
-    pub fn doc_value(&self) -> Option<&str> {
+    crate fn doc_value(&self) -> Option<&str> {
         self.attrs.doc_value()
     }
 
     /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
     /// with newlines.
-    pub fn collapsed_doc_value(&self) -> Option<String> {
+    crate fn collapsed_doc_value(&self) -> Option<String> {
         self.attrs.collapsed_doc_value()
     }
 
-    pub fn links(&self) -> Vec<RenderedLink> {
+    crate fn links(&self) -> Vec<RenderedLink> {
         self.attrs.links(&self.def_id.krate)
     }
 
-    pub fn is_crate(&self) -> bool {
+    crate fn is_crate(&self) -> bool {
         match self.kind {
             StrippedItem(box ModuleItem(Module { is_crate: true, .. }))
             | ModuleItem(Module { is_crate: true, .. }) => true,
             _ => false,
         }
     }
-    pub fn is_mod(&self) -> bool {
+    crate fn is_mod(&self) -> bool {
         self.type_() == ItemType::Module
     }
-    pub fn is_trait(&self) -> bool {
+    crate fn is_trait(&self) -> bool {
         self.type_() == ItemType::Trait
     }
-    pub fn is_struct(&self) -> bool {
+    crate fn is_struct(&self) -> bool {
         self.type_() == ItemType::Struct
     }
-    pub fn is_enum(&self) -> bool {
+    crate fn is_enum(&self) -> bool {
         self.type_() == ItemType::Enum
     }
-    pub fn is_variant(&self) -> bool {
+    crate fn is_variant(&self) -> bool {
         self.type_() == ItemType::Variant
     }
-    pub fn is_associated_type(&self) -> bool {
+    crate fn is_associated_type(&self) -> bool {
         self.type_() == ItemType::AssocType
     }
-    pub fn is_associated_const(&self) -> bool {
+    crate fn is_associated_const(&self) -> bool {
         self.type_() == ItemType::AssocConst
     }
-    pub fn is_method(&self) -> bool {
+    crate fn is_method(&self) -> bool {
         self.type_() == ItemType::Method
     }
-    pub fn is_ty_method(&self) -> bool {
+    crate fn is_ty_method(&self) -> bool {
         self.type_() == ItemType::TyMethod
     }
-    pub fn is_typedef(&self) -> bool {
+    crate fn is_typedef(&self) -> bool {
         self.type_() == ItemType::Typedef
     }
-    pub fn is_primitive(&self) -> bool {
+    crate fn is_primitive(&self) -> bool {
         self.type_() == ItemType::Primitive
     }
-    pub fn is_union(&self) -> bool {
+    crate fn is_union(&self) -> bool {
         self.type_() == ItemType::Union
     }
-    pub fn is_import(&self) -> bool {
+    crate fn is_import(&self) -> bool {
         self.type_() == ItemType::Import
     }
-    pub fn is_extern_crate(&self) -> bool {
+    crate fn is_extern_crate(&self) -> bool {
         self.type_() == ItemType::ExternCrate
     }
-    pub fn is_keyword(&self) -> bool {
+    crate fn is_keyword(&self) -> bool {
         self.type_() == ItemType::Keyword
     }
-    pub fn is_stripped(&self) -> bool {
+    crate fn is_stripped(&self) -> bool {
         match self.kind {
             StrippedItem(..) => true,
             ImportItem(ref i) => !i.should_be_displayed,
             _ => false,
         }
     }
-    pub fn has_stripped_fields(&self) -> Option<bool> {
+    crate fn has_stripped_fields(&self) -> Option<bool> {
         match self.kind {
             StructItem(ref _struct) => Some(_struct.fields_stripped),
             UnionItem(ref union) => Some(union.fields_stripped),
@@ -192,7 +192,7 @@ impl Item {
         }
     }
 
-    pub fn stability_class(&self) -> Option<String> {
+    crate fn stability_class(&self) -> Option<String> {
         self.stability.as_ref().and_then(|ref s| {
             let mut classes = Vec::with_capacity(2);
 
@@ -209,23 +209,23 @@ impl Item {
         })
     }
 
-    pub fn stable_since(&self) -> Option<SymbolStr> {
+    crate fn stable_since(&self) -> Option<SymbolStr> {
         match self.stability?.level {
             StabilityLevel::Stable { since, .. } => Some(since.as_str()),
             StabilityLevel::Unstable { .. } => None,
         }
     }
 
-    pub fn is_non_exhaustive(&self) -> bool {
+    crate fn is_non_exhaustive(&self) -> bool {
         self.attrs.other_attrs.iter().any(|a| a.has_name(sym::non_exhaustive))
     }
 
     /// Returns a documentation-level item type from the item.
-    pub fn type_(&self) -> ItemType {
+    crate fn type_(&self) -> ItemType {
         ItemType::from(self)
     }
 
-    pub fn is_default(&self) -> bool {
+    crate fn is_default(&self) -> bool {
         match self.kind {
             ItemKind::MethodItem(ref meth) => {
                 if let Some(defaultness) = meth.defaultness {
@@ -239,7 +239,7 @@ impl Item {
     }
 
     /// See comments on next_def_id
-    pub fn is_fake(&self) -> bool {
+    crate fn is_fake(&self) -> bool {
         MAX_DEF_ID.with(|m| {
             m.borrow().get(&self.def_id.krate).map(|id| self.def_id >= *id).unwrap_or(false)
         })
@@ -247,7 +247,7 @@ impl Item {
 }
 
 #[derive(Clone, Debug)]
-pub enum ItemKind {
+crate enum ItemKind {
     ExternCrateItem(String, Option<String>),
     ImportItem(Import),
     StructItem(Struct),
@@ -286,14 +286,14 @@ pub enum ItemKind {
 }
 
 impl ItemKind {
-    pub fn is_type_alias(&self) -> bool {
+    crate fn is_type_alias(&self) -> bool {
         match *self {
             ItemKind::TypedefItem(_, _) | ItemKind::AssocTypeItem(_, _) => true,
             _ => false,
         }
     }
 
-    pub fn as_assoc_kind(&self) -> Option<AssocKind> {
+    crate fn as_assoc_kind(&self) -> Option<AssocKind> {
         match *self {
             ItemKind::AssocConstItem(..) => Some(AssocKind::Const),
             ItemKind::AssocTypeItem(..) => Some(AssocKind::Type),
@@ -304,12 +304,12 @@ impl ItemKind {
 }
 
 #[derive(Clone, Debug)]
-pub struct Module {
-    pub items: Vec<Item>,
-    pub is_crate: bool,
+crate struct Module {
+    crate items: Vec<Item>,
+    crate is_crate: bool,
 }
 
-pub struct ListAttributesIter<'a> {
+crate struct ListAttributesIter<'a> {
     attrs: slice::Iter<'a, ast::Attribute>,
     current_list: vec::IntoIter<ast::NestedMetaItem>,
     name: Symbol,
@@ -343,7 +343,7 @@ impl<'a> Iterator for ListAttributesIter<'a> {
     }
 }
 
-pub trait AttributesExt {
+crate trait AttributesExt {
     /// Finds an attribute as List and returns the list of attributes nested inside.
     fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
 }
@@ -354,7 +354,7 @@ impl AttributesExt for [ast::Attribute] {
     }
 }
 
-pub trait NestedAttributesExt {
+crate trait NestedAttributesExt {
     /// Returns `true` if the attribute list contains a specific `Word`
     fn has_word(self, word: Symbol) -> bool;
 }
@@ -374,20 +374,20 @@ impl<I: IntoIterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I {
 /// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
 /// kept separate because of issue #42760.
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct DocFragment {
-    pub line: usize,
-    pub span: rustc_span::Span,
+crate struct DocFragment {
+    crate line: usize,
+    crate span: rustc_span::Span,
     /// The module this doc-comment came from.
     ///
     /// This allows distinguishing between the original documentation and a pub re-export.
     /// If it is `None`, the item was not re-exported.
-    pub parent_module: Option<DefId>,
-    pub doc: String,
-    pub kind: DocFragmentKind,
+    crate parent_module: Option<DefId>,
+    crate doc: String,
+    crate kind: DocFragmentKind,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum DocFragmentKind {
+crate enum DocFragmentKind {
     /// A doc fragment created from a `///` or `//!` doc comment.
     SugaredDoc,
     /// A doc fragment created from a "raw" `#[doc=""]` attribute.
@@ -413,21 +413,21 @@ impl<'a> FromIterator<&'a DocFragment> for String {
 }
 
 #[derive(Clone, Debug, Default)]
-pub struct Attributes {
-    pub doc_strings: Vec<DocFragment>,
-    pub other_attrs: Vec<ast::Attribute>,
-    pub cfg: Option<Arc<Cfg>>,
-    pub span: Option<rustc_span::Span>,
+crate struct Attributes {
+    crate doc_strings: Vec<DocFragment>,
+    crate other_attrs: Vec<ast::Attribute>,
+    crate cfg: Option<Arc<Cfg>>,
+    crate span: Option<rustc_span::Span>,
     /// map from Rust paths to resolved defs and potential URL fragments
-    pub links: Vec<ItemLink>,
-    pub inner_docs: bool,
+    crate links: Vec<ItemLink>,
+    crate inner_docs: bool,
 }
 
 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
 /// A link that has not yet been rendered.
 ///
 /// This link will be turned into a rendered link by [`Attributes::links`]
-pub struct ItemLink {
+crate struct ItemLink {
     /// The original link written in the markdown
     pub(crate) link: String,
     /// The link text displayed in the HTML.
@@ -453,7 +453,7 @@ pub struct RenderedLink {
 
 impl Attributes {
     /// Extracts the content from an attribute `#[doc(cfg(content))]`.
-    pub fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
+    crate fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
         use rustc_ast::NestedMetaItem::MetaItem;
 
         if let ast::MetaItemKind::List(ref nmis) = mi.kind {
@@ -478,7 +478,7 @@ impl Attributes {
     /// Reads a `MetaItem` from within an attribute, looks for whether it is a
     /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from
     /// its expansion.
-    pub fn extract_include(mi: &ast::MetaItem) -> Option<(String, String)> {
+    crate fn extract_include(mi: &ast::MetaItem) -> Option<(String, String)> {
         mi.meta_item_list().and_then(|list| {
             for meta in list {
                 if meta.has_name(sym::include) {
@@ -514,7 +514,7 @@ impl Attributes {
         })
     }
 
-    pub fn has_doc_flag(&self, flag: Symbol) -> bool {
+    crate fn has_doc_flag(&self, flag: Symbol) -> bool {
         for attr in &self.other_attrs {
             if !attr.has_name(sym::doc) {
                 continue;
@@ -530,7 +530,7 @@ impl Attributes {
         false
     }
 
-    pub fn from_ast(
+    crate fn from_ast(
         diagnostic: &::rustc_errors::Handler,
         attrs: &[ast::Attribute],
         additional_attrs: Option<(&[ast::Attribute], DefId)>,
@@ -634,20 +634,20 @@ impl Attributes {
 
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
-    pub fn doc_value(&self) -> Option<&str> {
+    crate fn doc_value(&self) -> Option<&str> {
         self.doc_strings.first().map(|s| s.doc.as_str())
     }
 
     /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
     /// with newlines.
-    pub fn collapsed_doc_value(&self) -> Option<String> {
+    crate fn collapsed_doc_value(&self) -> Option<String> {
         if !self.doc_strings.is_empty() { Some(self.doc_strings.iter().collect()) } else { None }
     }
 
     /// Gets links as a vector
     ///
     /// Cache must be populated before call
-    pub fn links(&self, krate: &CrateNum) -> Vec<RenderedLink> {
+    crate fn links(&self, krate: &CrateNum) -> Vec<RenderedLink> {
         use crate::html::format::href;
         use crate::html::render::CURRENT_DEPTH;
 
@@ -711,7 +711,7 @@ impl Attributes {
             .collect()
     }
 
-    pub fn get_doc_aliases(&self) -> FxHashSet<String> {
+    crate fn get_doc_aliases(&self) -> FxHashSet<String> {
         self.other_attrs
             .lists(sym::doc)
             .filter(|a| a.has_name(sym::alias))
@@ -756,13 +756,13 @@ impl AttributesExt for Attributes {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum GenericBound {
+crate enum GenericBound {
     TraitBound(PolyTrait, hir::TraitBoundModifier),
     Outlives(Lifetime),
 }
 
 impl GenericBound {
-    pub fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
+    crate fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
         let did = cx.tcx.require_lang_item(LangItem::Sized, None);
         let empty = cx.tcx.intern_substs(&[]);
         let path = external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
@@ -776,7 +776,7 @@ impl GenericBound {
         )
     }
 
-    pub fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
+    crate fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
         use rustc_hir::TraitBoundModifier as TBM;
         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
             if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
@@ -786,14 +786,14 @@ impl GenericBound {
         false
     }
 
-    pub fn get_poly_trait(&self) -> Option<PolyTrait> {
+    crate fn get_poly_trait(&self) -> Option<PolyTrait> {
         if let GenericBound::TraitBound(ref p, _) = *self {
             return Some(p.clone());
         }
         None
     }
 
-    pub fn get_trait_type(&self) -> Option<Type> {
+    crate fn get_trait_type(&self) -> Option<Type> {
         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
             Some(trait_.clone())
         } else {
@@ -803,33 +803,33 @@ impl GenericBound {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct Lifetime(pub String);
+crate struct Lifetime(pub String);
 
 impl Lifetime {
-    pub fn get_ref<'a>(&'a self) -> &'a str {
+    crate fn get_ref<'a>(&'a self) -> &'a str {
         let Lifetime(ref s) = *self;
         let s: &'a str = s;
         s
     }
 
-    pub fn statik() -> Lifetime {
+    crate fn statik() -> Lifetime {
         Lifetime("'static".to_string())
     }
 
-    pub fn elided() -> Lifetime {
+    crate fn elided() -> Lifetime {
         Lifetime("'_".to_string())
     }
 }
 
 #[derive(Clone, Debug)]
-pub enum WherePredicate {
+crate enum WherePredicate {
     BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
     RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
     EqPredicate { lhs: Type, rhs: Type },
 }
 
 impl WherePredicate {
-    pub fn get_bounds(&self) -> Option<&[GenericBound]> {
+    crate fn get_bounds(&self) -> Option<&[GenericBound]> {
         match *self {
             WherePredicate::BoundPredicate { ref bounds, .. } => Some(bounds),
             WherePredicate::RegionPredicate { ref bounds, .. } => Some(bounds),
@@ -839,7 +839,7 @@ impl WherePredicate {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum GenericParamDefKind {
+crate enum GenericParamDefKind {
     Lifetime,
     Type {
         did: DefId,
@@ -854,7 +854,7 @@ pub enum GenericParamDefKind {
 }
 
 impl GenericParamDefKind {
-    pub fn is_type(&self) -> bool {
+    crate fn is_type(&self) -> bool {
         match *self {
             GenericParamDefKind::Type { .. } => true,
             _ => false,
@@ -864,7 +864,7 @@ impl GenericParamDefKind {
     // FIXME(eddyb) this either returns the default of a type parameter, or the
     // type of a `const` parameter. It seems that the intention is to *visit*
     // any embedded types, but `get_type` seems to be the wrong name for that.
-    pub fn get_type(&self) -> Option<Type> {
+    crate fn get_type(&self) -> Option<Type> {
         match self {
             GenericParamDefKind::Type { default, .. } => default.clone(),
             GenericParamDefKind::Const { ty, .. } => Some(ty.clone()),
@@ -874,28 +874,28 @@ impl GenericParamDefKind {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct GenericParamDef {
-    pub name: String,
-    pub kind: GenericParamDefKind,
+crate struct GenericParamDef {
+    crate name: String,
+    crate kind: GenericParamDefKind,
 }
 
 impl GenericParamDef {
-    pub fn is_synthetic_type_param(&self) -> bool {
+    crate fn is_synthetic_type_param(&self) -> bool {
         match self.kind {
             GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => false,
             GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(),
         }
     }
 
-    pub fn is_type(&self) -> bool {
+    crate fn is_type(&self) -> bool {
         self.kind.is_type()
     }
 
-    pub fn get_type(&self) -> Option<Type> {
+    crate fn get_type(&self) -> Option<Type> {
         self.kind.get_type()
     }
 
-    pub fn get_bounds(&self) -> Option<&[GenericBound]> {
+    crate fn get_bounds(&self) -> Option<&[GenericBound]> {
         match self.kind {
             GenericParamDefKind::Type { ref bounds, .. } => Some(bounds),
             _ => None,
@@ -905,49 +905,49 @@ impl GenericParamDef {
 
 // maybe use a Generic enum and use Vec<Generic>?
 #[derive(Clone, Debug, Default)]
-pub struct Generics {
-    pub params: Vec<GenericParamDef>,
-    pub where_predicates: Vec<WherePredicate>,
+crate struct Generics {
+    crate params: Vec<GenericParamDef>,
+    crate where_predicates: Vec<WherePredicate>,
 }
 
 #[derive(Clone, Debug)]
-pub struct Method {
-    pub generics: Generics,
-    pub decl: FnDecl,
-    pub header: hir::FnHeader,
-    pub defaultness: Option<hir::Defaultness>,
-    pub all_types: Vec<(Type, TypeKind)>,
-    pub ret_types: Vec<(Type, TypeKind)>,
+crate struct Method {
+    crate generics: Generics,
+    crate decl: FnDecl,
+    crate header: hir::FnHeader,
+    crate defaultness: Option<hir::Defaultness>,
+    crate all_types: Vec<(Type, TypeKind)>,
+    crate ret_types: Vec<(Type, TypeKind)>,
 }
 
 #[derive(Clone, Debug)]
-pub struct TyMethod {
-    pub header: hir::FnHeader,
-    pub decl: FnDecl,
-    pub generics: Generics,
-    pub all_types: Vec<(Type, TypeKind)>,
-    pub ret_types: Vec<(Type, TypeKind)>,
+crate struct TyMethod {
+    crate header: hir::FnHeader,
+    crate decl: FnDecl,
+    crate generics: Generics,
+    crate all_types: Vec<(Type, TypeKind)>,
+    crate ret_types: Vec<(Type, TypeKind)>,
 }
 
 #[derive(Clone, Debug)]
-pub struct Function {
-    pub decl: FnDecl,
-    pub generics: Generics,
-    pub header: hir::FnHeader,
-    pub all_types: Vec<(Type, TypeKind)>,
-    pub ret_types: Vec<(Type, TypeKind)>,
+crate struct Function {
+    crate decl: FnDecl,
+    crate generics: Generics,
+    crate header: hir::FnHeader,
+    crate all_types: Vec<(Type, TypeKind)>,
+    crate ret_types: Vec<(Type, TypeKind)>,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct FnDecl {
-    pub inputs: Arguments,
-    pub output: FnRetTy,
-    pub c_variadic: bool,
-    pub attrs: Attributes,
+crate struct FnDecl {
+    crate inputs: Arguments,
+    crate output: FnRetTy,
+    crate c_variadic: bool,
+    crate attrs: Attributes,
 }
 
 impl FnDecl {
-    pub fn self_type(&self) -> Option<SelfTy> {
+    crate fn self_type(&self) -> Option<SelfTy> {
         self.inputs.values.get(0).and_then(|v| v.to_self())
     }
 
@@ -960,7 +960,7 @@ impl FnDecl {
     ///
     /// This function will panic if the return type does not match the expected sugaring for async
     /// functions.
-    pub fn sugared_async_return_type(&self) -> FnRetTy {
+    crate fn sugared_async_return_type(&self) -> FnRetTy {
         match &self.output {
             FnRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] {
                 GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
@@ -975,25 +975,25 @@ impl FnDecl {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct Arguments {
-    pub values: Vec<Argument>,
+crate struct Arguments {
+    crate values: Vec<Argument>,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct Argument {
-    pub type_: Type,
-    pub name: String,
+crate struct Argument {
+    crate type_: Type,
+    crate name: String,
 }
 
 #[derive(Clone, PartialEq, Debug)]
-pub enum SelfTy {
+crate enum SelfTy {
     SelfValue,
     SelfBorrowed(Option<Lifetime>, Mutability),
     SelfExplicit(Type),
 }
 
 impl Argument {
-    pub fn to_self(&self) -> Option<SelfTy> {
+    crate fn to_self(&self) -> Option<SelfTy> {
         if self.name != "self" {
             return None;
         }
@@ -1010,7 +1010,7 @@ impl Argument {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum FnRetTy {
+crate enum FnRetTy {
     Return(Type),
     DefaultReturn,
 }
@@ -1025,34 +1025,34 @@ impl GetDefId for FnRetTy {
 }
 
 #[derive(Clone, Debug)]
-pub struct Trait {
-    pub auto: bool,
-    pub unsafety: hir::Unsafety,
-    pub items: Vec<Item>,
-    pub generics: Generics,
-    pub bounds: Vec<GenericBound>,
-    pub is_spotlight: bool,
-    pub is_auto: bool,
+crate struct Trait {
+    crate auto: bool,
+    crate unsafety: hir::Unsafety,
+    crate items: Vec<Item>,
+    crate generics: Generics,
+    crate bounds: Vec<GenericBound>,
+    crate is_spotlight: bool,
+    crate is_auto: bool,
 }
 
 #[derive(Clone, Debug)]
-pub struct TraitAlias {
-    pub generics: Generics,
-    pub bounds: Vec<GenericBound>,
+crate struct TraitAlias {
+    crate generics: Generics,
+    crate bounds: Vec<GenericBound>,
 }
 
 /// A trait reference, which may have higher ranked lifetimes.
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct PolyTrait {
-    pub trait_: Type,
-    pub generic_params: Vec<GenericParamDef>,
+crate struct PolyTrait {
+    crate trait_: Type,
+    crate generic_params: Vec<GenericParamDef>,
 }
 
 /// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
 /// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
 /// importantly, it does not preserve mutability or boxes.
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum Type {
+crate enum Type {
     /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
     ResolvedPath {
         path: Path,
@@ -1095,7 +1095,7 @@ pub enum Type {
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
-pub enum PrimitiveType {
+crate enum PrimitiveType {
     Isize,
     I8,
     I16,
@@ -1124,7 +1124,7 @@ pub enum PrimitiveType {
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
-pub enum TypeKind {
+crate enum TypeKind {
     Enum,
     Function,
     Module,
@@ -1141,7 +1141,7 @@ pub enum TypeKind {
     TraitAlias,
 }
 
-pub trait GetDefId {
+crate trait GetDefId {
     fn def_id(&self) -> Option<DefId>;
 }
 
@@ -1152,7 +1152,7 @@ impl<T: GetDefId> GetDefId for Option<T> {
 }
 
 impl Type {
-    pub fn primitive_type(&self) -> Option<PrimitiveType> {
+    crate fn primitive_type(&self) -> Option<PrimitiveType> {
         match *self {
             Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p),
             Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice),
@@ -1172,21 +1172,21 @@ impl Type {
         }
     }
 
-    pub fn is_generic(&self) -> bool {
+    crate fn is_generic(&self) -> bool {
         match *self {
             ResolvedPath { is_generic, .. } => is_generic,
             _ => false,
         }
     }
 
-    pub fn is_self_type(&self) -> bool {
+    crate fn is_self_type(&self) -> bool {
         match *self {
             Generic(ref name) => name == "Self",
             _ => false,
         }
     }
 
-    pub fn generics(&self) -> Option<Vec<Type>> {
+    crate fn generics(&self) -> Option<Vec<Type>> {
         match *self {
             ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
                 if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
@@ -1206,7 +1206,7 @@ impl Type {
         }
     }
 
-    pub fn bindings(&self) -> Option<&[TypeBinding]> {
+    crate fn bindings(&self) -> Option<&[TypeBinding]> {
         match *self {
             ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
                 if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
@@ -1219,14 +1219,14 @@ impl Type {
         }
     }
 
-    pub fn is_full_generic(&self) -> bool {
+    crate fn is_full_generic(&self) -> bool {
         match *self {
             Type::Generic(_) => true,
             _ => false,
         }
     }
 
-    pub fn projection(&self) -> Option<(&Type, DefId, &str)> {
+    crate fn projection(&self) -> Option<(&Type, DefId, &str)> {
         let (self_, trait_, name) = match self {
             QPath { ref self_type, ref trait_, ref name } => (self_type, trait_, name),
             _ => return None,
@@ -1267,7 +1267,7 @@ impl GetDefId for Type {
 }
 
 impl PrimitiveType {
-    pub fn from_hir(prim: hir::PrimTy) -> PrimitiveType {
+    crate fn from_hir(prim: hir::PrimTy) -> PrimitiveType {
         match prim {
             hir::PrimTy::Int(IntTy::Isize) => PrimitiveType::Isize,
             hir::PrimTy::Int(IntTy::I8) => PrimitiveType::I8,
@@ -1289,7 +1289,7 @@ impl PrimitiveType {
         }
     }
 
-    pub fn from_symbol(s: Symbol) -> Option<PrimitiveType> {
+    crate fn from_symbol(s: Symbol) -> Option<PrimitiveType> {
         match s {
             sym::isize => Some(PrimitiveType::Isize),
             sym::i8 => Some(PrimitiveType::I8),
@@ -1320,7 +1320,7 @@ impl PrimitiveType {
         }
     }
 
-    pub fn as_str(&self) -> &'static str {
+    crate fn as_str(&self) -> &'static str {
         use self::PrimitiveType::*;
         match *self {
             Isize => "isize",
@@ -1351,11 +1351,11 @@ impl PrimitiveType {
         }
     }
 
-    pub fn impls(&self, tcx: TyCtxt<'_>) -> &'static SmallVec<[DefId; 4]> {
+    crate fn impls(&self, tcx: TyCtxt<'_>) -> &'static SmallVec<[DefId; 4]> {
         Self::all_impls(tcx).get(self).expect("missing impl for primitive type")
     }
 
-    pub fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap<PrimitiveType, SmallVec<[DefId; 4]>> {
+    crate fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap<PrimitiveType, SmallVec<[DefId; 4]>> {
         static CELL: OnceCell<FxHashMap<PrimitiveType, SmallVec<[DefId; 4]>>> = OnceCell::new();
 
         CELL.get_or_init(move || {
@@ -1431,7 +1431,7 @@ impl PrimitiveType {
         })
     }
 
-    pub fn to_url_str(&self) -> &'static str {
+    crate fn to_url_str(&self) -> &'static str {
         self.as_str()
     }
 }
@@ -1485,7 +1485,7 @@ impl From<hir::PrimTy> for PrimitiveType {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub enum Visibility {
+crate enum Visibility {
     Public,
     Inherited,
     Crate,
@@ -1493,63 +1493,63 @@ pub enum Visibility {
 }
 
 #[derive(Clone, Debug)]
-pub struct Struct {
-    pub struct_type: doctree::StructType,
-    pub generics: Generics,
-    pub fields: Vec<Item>,
-    pub fields_stripped: bool,
+crate struct Struct {
+    crate struct_type: doctree::StructType,
+    crate generics: Generics,
+    crate fields: Vec<Item>,
+    crate fields_stripped: bool,
 }
 
 #[derive(Clone, Debug)]
-pub struct Union {
-    pub struct_type: doctree::StructType,
-    pub generics: Generics,
-    pub fields: Vec<Item>,
-    pub fields_stripped: bool,
+crate struct Union {
+    crate struct_type: doctree::StructType,
+    crate generics: Generics,
+    crate fields: Vec<Item>,
+    crate fields_stripped: bool,
 }
 
 /// This is a more limited form of the standard Struct, different in that
 /// it lacks the things most items have (name, id, parameterization). Found
 /// only as a variant in an enum.
 #[derive(Clone, Debug)]
-pub struct VariantStruct {
-    pub struct_type: doctree::StructType,
-    pub fields: Vec<Item>,
-    pub fields_stripped: bool,
+crate struct VariantStruct {
+    crate struct_type: doctree::StructType,
+    crate fields: Vec<Item>,
+    crate fields_stripped: bool,
 }
 
 #[derive(Clone, Debug)]
-pub struct Enum {
-    pub variants: IndexVec<VariantIdx, Item>,
-    pub generics: Generics,
-    pub variants_stripped: bool,
+crate struct Enum {
+    crate variants: IndexVec<VariantIdx, Item>,
+    crate generics: Generics,
+    crate variants_stripped: bool,
 }
 
 #[derive(Clone, Debug)]
-pub struct Variant {
-    pub kind: VariantKind,
+crate struct Variant {
+    crate kind: VariantKind,
 }
 
 #[derive(Clone, Debug)]
-pub enum VariantKind {
+crate enum VariantKind {
     CLike,
     Tuple(Vec<Type>),
     Struct(VariantStruct),
 }
 
 #[derive(Clone, Debug)]
-pub struct Span {
-    pub filename: FileName,
-    pub cnum: CrateNum,
-    pub loline: usize,
-    pub locol: usize,
-    pub hiline: usize,
-    pub hicol: usize,
-    pub original: rustc_span::Span,
+crate struct Span {
+    crate filename: FileName,
+    crate cnum: CrateNum,
+    crate loline: usize,
+    crate locol: usize,
+    crate hiline: usize,
+    crate hicol: usize,
+    crate original: rustc_span::Span,
 }
 
 impl Span {
-    pub fn empty() -> Span {
+    crate fn empty() -> Span {
         Span {
             filename: FileName::Anon(0),
             cnum: LOCAL_CRATE,
@@ -1561,49 +1561,49 @@ impl Span {
         }
     }
 
-    pub fn span(&self) -> rustc_span::Span {
+    crate fn span(&self) -> rustc_span::Span {
         self.original
     }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct Path {
-    pub global: bool,
-    pub res: Res,
-    pub segments: Vec<PathSegment>,
+crate struct Path {
+    crate global: bool,
+    crate res: Res,
+    crate segments: Vec<PathSegment>,
 }
 
 impl Path {
-    pub fn last_name(&self) -> &str {
+    crate fn last_name(&self) -> &str {
         self.segments.last().expect("segments were empty").name.as_str()
     }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum GenericArg {
+crate enum GenericArg {
     Lifetime(Lifetime),
     Type(Type),
     Const(Constant),
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum GenericArgs {
+crate enum GenericArgs {
     AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> },
     Parenthesized { inputs: Vec<Type>, output: Option<Type> },
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct PathSegment {
-    pub name: String,
-    pub args: GenericArgs,
+crate struct PathSegment {
+    crate name: String,
+    crate args: GenericArgs,
 }
 
 #[derive(Clone, Debug)]
-pub struct Typedef {
-    pub type_: Type,
-    pub generics: Generics,
+crate struct Typedef {
+    crate type_: Type,
+    crate generics: Generics,
     // Type of target item.
-    pub item_type: Option<Type>,
+    crate item_type: Option<Type>,
 }
 
 impl GetDefId for Typedef {
@@ -1613,75 +1613,75 @@ impl GetDefId for Typedef {
 }
 
 #[derive(Clone, Debug)]
-pub struct OpaqueTy {
-    pub bounds: Vec<GenericBound>,
-    pub generics: Generics,
+crate struct OpaqueTy {
+    crate bounds: Vec<GenericBound>,
+    crate generics: Generics,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct BareFunctionDecl {
-    pub unsafety: hir::Unsafety,
-    pub generic_params: Vec<GenericParamDef>,
-    pub decl: FnDecl,
-    pub abi: Abi,
+crate struct BareFunctionDecl {
+    crate unsafety: hir::Unsafety,
+    crate generic_params: Vec<GenericParamDef>,
+    crate decl: FnDecl,
+    crate abi: Abi,
 }
 
 #[derive(Clone, Debug)]
-pub struct Static {
-    pub type_: Type,
-    pub mutability: Mutability,
+crate struct Static {
+    crate type_: Type,
+    crate mutability: Mutability,
     /// It's useful to have the value of a static documented, but I have no
     /// desire to represent expressions (that'd basically be all of the AST,
     /// which is huge!). So, have a string.
-    pub expr: String,
+    crate expr: String,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
-pub struct Constant {
-    pub type_: Type,
-    pub expr: String,
-    pub value: Option<String>,
-    pub is_literal: bool,
+crate struct Constant {
+    crate type_: Type,
+    crate expr: String,
+    crate value: Option<String>,
+    crate is_literal: bool,
 }
 
 #[derive(Clone, PartialEq, Debug)]
-pub enum ImplPolarity {
+crate enum ImplPolarity {
     Positive,
     Negative,
 }
 
 #[derive(Clone, Debug)]
-pub struct Impl {
-    pub unsafety: hir::Unsafety,
-    pub generics: Generics,
-    pub provided_trait_methods: FxHashSet<String>,
-    pub trait_: Option<Type>,
-    pub for_: Type,
-    pub items: Vec<Item>,
-    pub polarity: Option<ImplPolarity>,
-    pub synthetic: bool,
-    pub blanket_impl: Option<Type>,
+crate struct Impl {
+    crate unsafety: hir::Unsafety,
+    crate generics: Generics,
+    crate provided_trait_methods: FxHashSet<String>,
+    crate trait_: Option<Type>,
+    crate for_: Type,
+    crate items: Vec<Item>,
+    crate polarity: Option<ImplPolarity>,
+    crate synthetic: bool,
+    crate blanket_impl: Option<Type>,
 }
 
 #[derive(Clone, Debug)]
-pub struct Import {
-    pub kind: ImportKind,
-    pub source: ImportSource,
-    pub should_be_displayed: bool,
+crate struct Import {
+    crate kind: ImportKind,
+    crate source: ImportSource,
+    crate should_be_displayed: bool,
 }
 
 impl Import {
-    pub fn new_simple(name: String, source: ImportSource, should_be_displayed: bool) -> Self {
+    crate fn new_simple(name: String, source: ImportSource, should_be_displayed: bool) -> Self {
         Self { kind: ImportKind::Simple(name), source, should_be_displayed }
     }
 
-    pub fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self {
+    crate fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self {
         Self { kind: ImportKind::Glob, source, should_be_displayed }
     }
 }
 
 #[derive(Clone, Debug)]
-pub enum ImportKind {
+crate enum ImportKind {
     // use source as str;
     Simple(String),
     // use source::*;
@@ -1689,46 +1689,46 @@ pub enum ImportKind {
 }
 
 #[derive(Clone, Debug)]
-pub struct ImportSource {
-    pub path: Path,
-    pub did: Option<DefId>,
+crate struct ImportSource {
+    crate path: Path,
+    crate did: Option<DefId>,
 }
 
 #[derive(Clone, Debug)]
-pub struct Macro {
-    pub source: String,
-    pub imported_from: Option<String>,
+crate struct Macro {
+    crate source: String,
+    crate imported_from: Option<String>,
 }
 
 #[derive(Clone, Debug)]
-pub struct ProcMacro {
-    pub kind: MacroKind,
-    pub helpers: Vec<String>,
+crate struct ProcMacro {
+    crate kind: MacroKind,
+    crate helpers: Vec<String>,
 }
 
 #[derive(Clone, Debug)]
-pub struct Deprecation {
-    pub since: Option<String>,
-    pub note: Option<String>,
-    pub is_since_rustc_version: bool,
+crate struct Deprecation {
+    crate since: Option<String>,
+    crate note: Option<String>,
+    crate is_since_rustc_version: bool,
 }
 
 /// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
 /// `A: Send + Sync` in `Foo<A: Send + Sync>`).
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct TypeBinding {
-    pub name: String,
-    pub kind: TypeBindingKind,
+crate struct TypeBinding {
+    crate name: String,
+    crate kind: TypeBindingKind,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum TypeBindingKind {
+crate enum TypeBindingKind {
     Equality { ty: Type },
     Constraint { bounds: Vec<GenericBound> },
 }
 
 impl TypeBinding {
-    pub fn ty(&self) -> &Type {
+    crate fn ty(&self) -> &Type {
         match self.kind {
             TypeBindingKind::Equality { ref ty } => ty,
             _ => panic!("expected equality type binding for parenthesized generic args"),
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index e5fb656cbb9..22917fbceb4 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -20,7 +20,7 @@ use rustc_middle::ty::{self, DefIdTree, Ty};
 use rustc_span::symbol::{kw, sym, Symbol};
 use std::mem;
 
-pub fn krate(mut cx: &mut DocContext<'_>) -> Crate {
+crate fn krate(mut cx: &mut DocContext<'_>) -> Crate {
     use crate::visit_lib::LibEmbargoVisitor;
 
     let krate = cx.tcx.hir().krate();
@@ -102,11 +102,11 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate {
 }
 
 // extract the stability index for a node from tcx, if possible
-pub fn get_stability(cx: &DocContext<'_>, def_id: DefId) -> Option<Stability> {
+crate fn get_stability(cx: &DocContext<'_>, def_id: DefId) -> Option<Stability> {
     cx.tcx.lookup_stability(def_id).cloned()
 }
 
-pub fn get_deprecation(cx: &DocContext<'_>, def_id: DefId) -> Option<Deprecation> {
+crate fn get_deprecation(cx: &DocContext<'_>, def_id: DefId) -> Option<Deprecation> {
     cx.tcx.lookup_deprecation(def_id).clean(cx)
 }
 
@@ -183,7 +183,7 @@ pub(super) fn external_path(
 /// i.e. `[T, U]` when you have the following bounds: `T: Display, U: Option<T>` will return
 /// `[Display, Option]` (we just returns the list of the types, we don't care about the
 /// wrapped types in here).
-pub fn get_real_types(
+crate fn get_real_types(
     generics: &Generics,
     arg: &Type,
     cx: &DocContext<'_>,
@@ -261,7 +261,7 @@ pub fn get_real_types(
 ///
 /// i.e. `fn foo<A: Display, B: Option<A>>(x: u32, y: B)` will return
 /// `[u32, Display, Option]`.
-pub fn get_all_types(
+crate fn get_all_types(
     generics: &Generics,
     decl: &FnDecl,
     cx: &DocContext<'_>,
@@ -296,7 +296,7 @@ pub fn get_all_types(
     (all_types.into_iter().collect(), ret_types)
 }
 
-pub fn strip_type(ty: Type) -> Type {
+crate fn strip_type(ty: Type) -> Type {
     match ty {
         Type::ResolvedPath { path, param_names, did, is_generic } => {
             Type::ResolvedPath { path: strip_path(&path), param_names, did, is_generic }
@@ -319,7 +319,7 @@ pub fn strip_type(ty: Type) -> Type {
     }
 }
 
-pub fn strip_path(path: &Path) -> Path {
+crate fn strip_path(path: &Path) -> Path {
     let segments = path
         .segments
         .iter()
@@ -332,7 +332,7 @@ pub fn strip_path(path: &Path) -> Path {
     Path { global: path.global, res: path.res, segments }
 }
 
-pub fn qpath_to_string(p: &hir::QPath<'_>) -> String {
+crate fn qpath_to_string(p: &hir::QPath<'_>) -> String {
     let segments = match *p {
         hir::QPath::Resolved(_, ref path) => &path.segments,
         hir::QPath::TypeRelative(_, ref segment) => return segment.ident.to_string(),
@@ -351,7 +351,7 @@ pub fn qpath_to_string(p: &hir::QPath<'_>) -> String {
     s
 }
 
-pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec<Item>) {
+crate fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec<Item>) {
     let tcx = cx.tcx;
 
     for item in items {
@@ -378,7 +378,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V
     }
 }
 
-pub trait ToSource {
+crate trait ToSource {
     fn to_src(&self, cx: &DocContext<'_>) -> String;
 }
 
@@ -394,7 +394,7 @@ impl ToSource for rustc_span::Span {
     }
 }
 
-pub fn name_from_pat(p: &hir::Pat<'_>) -> String {
+crate fn name_from_pat(p: &hir::Pat<'_>) -> String {
     use rustc_hir::*;
     debug!("trying to get a name from pattern: {:?}", p);
 
@@ -440,7 +440,7 @@ pub fn name_from_pat(p: &hir::Pat<'_>) -> String {
     }
 }
 
-pub fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
+crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
     match n.val {
         ty::ConstKind::Unevaluated(def, _, promoted) => {
             let mut s = if let Some(def) = def.as_local() {
@@ -470,7 +470,7 @@ pub fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
     }
 }
 
-pub fn print_evaluated_const(cx: &DocContext<'_>, def_id: DefId) -> Option<String> {
+crate fn print_evaluated_const(cx: &DocContext<'_>, def_id: DefId) -> Option<String> {
     cx.tcx.const_eval_poly(def_id).ok().and_then(|val| {
         let ty = cx.tcx.type_of(def_id);
         match (val, ty.kind()) {
@@ -518,7 +518,7 @@ fn print_const_with_custom_print_scalar(cx: &DocContext<'_>, ct: &'tcx ty::Const
     }
 }
 
-pub fn is_literal_expr(cx: &DocContext<'_>, hir_id: hir::HirId) -> bool {
+crate fn is_literal_expr(cx: &DocContext<'_>, hir_id: hir::HirId) -> bool {
     if let hir::Node::Expr(expr) = cx.tcx.hir().get(hir_id) {
         if let hir::ExprKind::Lit(_) = &expr.kind {
             return true;
@@ -534,7 +534,7 @@ pub fn is_literal_expr(cx: &DocContext<'_>, hir_id: hir::HirId) -> bool {
     false
 }
 
-pub fn print_const_expr(cx: &DocContext<'_>, body: hir::BodyId) -> String {
+crate fn print_const_expr(cx: &DocContext<'_>, body: hir::BodyId) -> String {
     let value = &cx.tcx.hir().body(body).value;
 
     let snippet = if !value.span.from_expansion() {
@@ -547,7 +547,7 @@ pub fn print_const_expr(cx: &DocContext<'_>, body: hir::BodyId) -> String {
 }
 
 /// Given a type Path, resolve it to a Type using the TyCtxt
-pub fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type {
+crate fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type {
     debug!("resolve_type({:?},{:?})", path, id);
 
     let is_generic = match path.res {
@@ -565,7 +565,7 @@ pub fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type {
     ResolvedPath { path, param_names: None, did, is_generic }
 }
 
-pub fn get_auto_trait_and_blanket_impls(
+crate fn get_auto_trait_and_blanket_impls(
     cx: &DocContext<'tcx>,
     ty: Ty<'tcx>,
     param_env_def_id: DefId,
@@ -576,7 +576,7 @@ pub fn get_auto_trait_and_blanket_impls(
         .chain(BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id))
 }
 
-pub fn register_res(cx: &DocContext<'_>, res: Res) -> DefId {
+crate fn register_res(cx: &DocContext<'_>, res: Res) -> DefId {
     debug!("register_res({:?})", res);
 
     let (did, kind) = match res {
@@ -616,14 +616,14 @@ pub fn register_res(cx: &DocContext<'_>, res: Res) -> DefId {
     did
 }
 
-pub fn resolve_use_source(cx: &DocContext<'_>, path: Path) -> ImportSource {
+crate fn resolve_use_source(cx: &DocContext<'_>, path: Path) -> ImportSource {
     ImportSource {
         did: if path.res.opt_def_id().is_none() { None } else { Some(register_res(cx, path.res)) },
         path,
     }
 }
 
-pub fn enter_impl_trait<F, R>(cx: &DocContext<'_>, f: F) -> R
+crate fn enter_impl_trait<F, R>(cx: &DocContext<'_>, f: F) -> R
 where
     F: FnOnce() -> R,
 {
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index f0fc0dc6514..e60970af0d3 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -30,13 +30,13 @@ use crate::passes::{self, Condition, DefaultPassOption};
 use crate::theme;
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum OutputFormat {
+crate enum OutputFormat {
     Json,
     Html,
 }
 
 impl OutputFormat {
-    pub fn is_json(&self) -> bool {
+    crate fn is_json(&self) -> bool {
         match self {
             OutputFormat::Json => true,
             _ => false,
@@ -58,96 +58,96 @@ impl TryFrom<&str> for OutputFormat {
 
 /// Configuration options for rustdoc.
 #[derive(Clone)]
-pub struct Options {
+crate struct Options {
     // Basic options / Options passed directly to rustc
     /// The crate root or Markdown file to load.
-    pub input: PathBuf,
+    crate input: PathBuf,
     /// The name of the crate being documented.
-    pub crate_name: Option<String>,
+    crate crate_name: Option<String>,
     /// Whether or not this is a proc-macro crate
-    pub proc_macro_crate: bool,
+    crate proc_macro_crate: bool,
     /// How to format errors and warnings.
-    pub error_format: ErrorOutputType,
+    crate error_format: ErrorOutputType,
     /// Library search paths to hand to the compiler.
-    pub libs: Vec<SearchPath>,
+    crate libs: Vec<SearchPath>,
     /// Library search paths strings to hand to the compiler.
-    pub lib_strs: Vec<String>,
+    crate lib_strs: Vec<String>,
     /// The list of external crates to link against.
-    pub externs: Externs,
+    crate externs: Externs,
     /// The list of external crates strings to link against.
-    pub extern_strs: Vec<String>,
+    crate extern_strs: Vec<String>,
     /// List of `cfg` flags to hand to the compiler. Always includes `rustdoc`.
-    pub cfgs: Vec<String>,
+    crate cfgs: Vec<String>,
     /// Codegen options to hand to the compiler.
-    pub codegen_options: CodegenOptions,
+    crate codegen_options: CodegenOptions,
     /// Codegen options strings to hand to the compiler.
-    pub codegen_options_strs: Vec<String>,
+    crate codegen_options_strs: Vec<String>,
     /// Debugging (`-Z`) options to pass to the compiler.
-    pub debugging_opts: DebuggingOptions,
+    crate debugging_opts: DebuggingOptions,
     /// Debugging (`-Z`) options strings to pass to the compiler.
-    pub debugging_opts_strs: Vec<String>,
+    crate debugging_opts_strs: Vec<String>,
     /// The target used to compile the crate against.
-    pub target: TargetTriple,
+    crate target: TargetTriple,
     /// Edition used when reading the crate. Defaults to "2015". Also used by default when
     /// compiling doctests from the crate.
-    pub edition: Edition,
+    crate edition: Edition,
     /// The path to the sysroot. Used during the compilation process.
-    pub maybe_sysroot: Option<PathBuf>,
+    crate maybe_sysroot: Option<PathBuf>,
     /// Lint information passed over the command-line.
-    pub lint_opts: Vec<(String, Level)>,
+    crate lint_opts: Vec<(String, Level)>,
     /// Whether to ask rustc to describe the lints it knows. Practically speaking, this will not be
     /// used, since we abort if we have no input file, but it's included for completeness.
-    pub describe_lints: bool,
+    crate describe_lints: bool,
     /// What level to cap lints at.
-    pub lint_cap: Option<Level>,
+    crate lint_cap: Option<Level>,
 
     // Options specific to running doctests
     /// Whether we should run doctests instead of generating docs.
-    pub should_test: bool,
+    crate should_test: bool,
     /// List of arguments to pass to the test harness, if running tests.
-    pub test_args: Vec<String>,
+    crate test_args: Vec<String>,
     /// Optional path to persist the doctest executables to, defaults to a
     /// temporary directory if not set.
-    pub persist_doctests: Option<PathBuf>,
+    crate persist_doctests: Option<PathBuf>,
     /// Runtool to run doctests with
-    pub runtool: Option<String>,
+    crate runtool: Option<String>,
     /// Arguments to pass to the runtool
-    pub runtool_args: Vec<String>,
+    crate runtool_args: Vec<String>,
     /// Whether to allow ignoring doctests on a per-target basis
     /// For example, using ignore-foo to ignore running the doctest on any target that
     /// contains "foo" as a substring
-    pub enable_per_target_ignores: bool,
+    crate enable_per_target_ignores: bool,
 
     /// The path to a rustc-like binary to build tests with. If not set, we
     /// default to loading from $sysroot/bin/rustc.
-    pub test_builder: Option<PathBuf>,
+    crate test_builder: Option<PathBuf>,
 
     // Options that affect the documentation process
     /// The selected default set of passes to use.
     ///
     /// Be aware: This option can come both from the CLI and from crate attributes!
-    pub default_passes: DefaultPassOption,
+    crate default_passes: DefaultPassOption,
     /// Any passes manually selected by the user.
     ///
     /// Be aware: This option can come both from the CLI and from crate attributes!
-    pub manual_passes: Vec<String>,
+    crate manual_passes: Vec<String>,
     /// Whether to display warnings during doc generation or while gathering doctests. By default,
     /// all non-rustdoc-specific lints are allowed when generating docs.
-    pub display_warnings: bool,
+    crate display_warnings: bool,
     /// Whether to run the `calculate-doc-coverage` pass, which counts the number of public items
     /// with and without documentation.
-    pub show_coverage: bool,
+    crate show_coverage: bool,
 
     // Options that alter generated documentation pages
     /// Crate version to note on the sidebar of generated docs.
-    pub crate_version: Option<String>,
+    crate crate_version: Option<String>,
     /// Collected options specific to outputting final pages.
-    pub render_options: RenderOptions,
+    crate render_options: RenderOptions,
     /// Output format rendering (used only for "show-coverage" option for the moment)
-    pub output_format: Option<OutputFormat>,
+    crate output_format: Option<OutputFormat>,
     /// If this option is set to `true`, rustdoc will only run checks and not generate
     /// documentation.
-    pub run_check: bool,
+    crate run_check: bool,
 }
 
 impl fmt::Debug for Options {
@@ -195,89 +195,89 @@ impl fmt::Debug for Options {
 
 /// Configuration options for the HTML page-creation process.
 #[derive(Clone, Debug)]
-pub struct RenderOptions {
+crate struct RenderOptions {
     /// Output directory to generate docs into. Defaults to `doc`.
-    pub output: PathBuf,
+    crate output: PathBuf,
     /// External files to insert into generated pages.
-    pub external_html: ExternalHtml,
+    crate external_html: ExternalHtml,
     /// A pre-populated `IdMap` with the default headings and any headings added by Markdown files
     /// processed by `external_html`.
-    pub id_map: IdMap,
+    crate id_map: IdMap,
     /// If present, playground URL to use in the "Run" button added to code samples.
     ///
     /// Be aware: This option can come both from the CLI and from crate attributes!
-    pub playground_url: Option<String>,
+    crate playground_url: Option<String>,
     /// Whether to sort modules alphabetically on a module page instead of using declaration order.
     /// `true` by default.
     //
     // FIXME(misdreavus): the flag name is `--sort-modules-by-appearance` but the meaning is
     // inverted once read.
-    pub sort_modules_alphabetically: bool,
+    crate sort_modules_alphabetically: bool,
     /// List of themes to extend the docs with. Original argument name is included to assist in
     /// displaying errors if it fails a theme check.
-    pub themes: Vec<StylePath>,
+    crate themes: Vec<StylePath>,
     /// If present, CSS file that contains rules to add to the default CSS.
-    pub extension_css: Option<PathBuf>,
+    crate extension_css: Option<PathBuf>,
     /// A map of crate names to the URL to use instead of querying the crate's `html_root_url`.
-    pub extern_html_root_urls: BTreeMap<String, String>,
+    crate extern_html_root_urls: BTreeMap<String, String>,
     /// A map of the default settings (values are as for DOM storage API). Keys should lack the
     /// `rustdoc-` prefix.
-    pub default_settings: HashMap<String, String>,
+    crate default_settings: HashMap<String, String>,
     /// If present, suffix added to CSS/JavaScript files when referencing them in generated pages.
-    pub resource_suffix: String,
+    crate resource_suffix: String,
     /// Whether to run the static CSS/JavaScript through a minifier when outputting them. `true` by
     /// default.
     //
     // FIXME(misdreavus): the flag name is `--disable-minification` but the meaning is inverted
     // once read.
-    pub enable_minification: bool,
+    crate enable_minification: bool,
     /// Whether to create an index page in the root of the output directory. If this is true but
     /// `enable_index_page` is None, generate a static listing of crates instead.
-    pub enable_index_page: bool,
+    crate enable_index_page: bool,
     /// A file to use as the index page at the root of the output directory. Overrides
     /// `enable_index_page` to be true if set.
-    pub index_page: Option<PathBuf>,
+    crate index_page: Option<PathBuf>,
     /// An optional path to use as the location of static files. If not set, uses combinations of
     /// `../` to reach the documentation root.
-    pub static_root_path: Option<String>,
+    crate static_root_path: Option<String>,
 
     // Options specific to reading standalone Markdown files
     /// Whether to generate a table of contents on the output file when reading a standalone
     /// Markdown file.
-    pub markdown_no_toc: bool,
+    crate markdown_no_toc: bool,
     /// Additional CSS files to link in pages generated from standalone Markdown files.
-    pub markdown_css: Vec<String>,
+    crate markdown_css: Vec<String>,
     /// If present, playground URL to use in the "Run" button added to code samples generated from
     /// standalone Markdown files. If not present, `playground_url` is used.
-    pub markdown_playground_url: Option<String>,
+    crate markdown_playground_url: Option<String>,
     /// If false, the `select` element to have search filtering by crates on rendered docs
     /// won't be generated.
-    pub generate_search_filter: bool,
+    crate generate_search_filter: bool,
     /// Document items that have lower than `pub` visibility.
-    pub document_private: bool,
+    crate document_private: bool,
     /// Document items that have `doc(hidden)`.
-    pub document_hidden: bool,
-    pub unstable_features: rustc_feature::UnstableFeatures,
+    crate document_hidden: bool,
+    crate unstable_features: rustc_feature::UnstableFeatures,
 }
 
 /// Temporary storage for data obtained during `RustdocVisitor::clean()`.
 /// Later on moved into `CACHE_KEY`.
 #[derive(Default, Clone)]
-pub struct RenderInfo {
-    pub inlined: FxHashSet<DefId>,
-    pub external_paths: crate::core::ExternalPaths,
-    pub exact_paths: FxHashMap<DefId, Vec<String>>,
-    pub access_levels: AccessLevels<DefId>,
-    pub deref_trait_did: Option<DefId>,
-    pub deref_mut_trait_did: Option<DefId>,
-    pub owned_box_did: Option<DefId>,
-    pub output_format: Option<OutputFormat>,
+crate struct RenderInfo {
+    crate inlined: FxHashSet<DefId>,
+    crate external_paths: crate::core::ExternalPaths,
+    crate exact_paths: FxHashMap<DefId, Vec<String>>,
+    crate access_levels: AccessLevels<DefId>,
+    crate deref_trait_did: Option<DefId>,
+    crate deref_mut_trait_did: Option<DefId>,
+    crate owned_box_did: Option<DefId>,
+    crate output_format: Option<OutputFormat>,
 }
 
 impl Options {
     /// Parses the given command-line for options. If an error message or other early-return has
     /// been printed, returns `Err` with the exit code.
-    pub fn from_matches(matches: &getopts::Matches) -> Result<Options, i32> {
+    crate fn from_matches(matches: &getopts::Matches) -> Result<Options, i32> {
         // Check for unstable options.
         nightly_options::check_nightly_options(&matches, &opts());
 
@@ -656,7 +656,7 @@ impl Options {
     }
 
     /// Returns `true` if the file given as `self.input` is a Markdown file.
-    pub fn markdown_input(&self) -> bool {
+    crate fn markdown_input(&self) -> bool {
         self.input.extension().map_or(false, |e| e == "md" || e == "markdown")
     }
 }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 14a2def1383..413f5bdf521 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -36,52 +36,51 @@ use crate::config::{Options as RustdocOptions, RenderOptions};
 use crate::config::{OutputFormat, RenderInfo};
 use crate::passes::{self, Condition::*, ConditionalPass};
 
-pub use rustc_session::config::{CodegenOptions, DebuggingOptions, Input, Options};
-pub use rustc_session::search_paths::SearchPath;
+crate use rustc_session::config::{DebuggingOptions, Input, Options};
 
-pub type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
+crate type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
 
-pub struct DocContext<'tcx> {
-    pub tcx: TyCtxt<'tcx>,
-    pub resolver: Rc<RefCell<interface::BoxedResolver>>,
+crate struct DocContext<'tcx> {
+    crate tcx: TyCtxt<'tcx>,
+    crate resolver: Rc<RefCell<interface::BoxedResolver>>,
     /// Later on moved into `CACHE_KEY`
-    pub renderinfo: RefCell<RenderInfo>,
+    crate renderinfo: RefCell<RenderInfo>,
     /// Later on moved through `clean::Crate` into `CACHE_KEY`
-    pub external_traits: Rc<RefCell<FxHashMap<DefId, clean::Trait>>>,
+    crate external_traits: Rc<RefCell<FxHashMap<DefId, clean::Trait>>>,
     /// Used while populating `external_traits` to ensure we don't process the same trait twice at
     /// the same time.
-    pub active_extern_traits: RefCell<FxHashSet<DefId>>,
+    crate active_extern_traits: RefCell<FxHashSet<DefId>>,
     // The current set of type and lifetime substitutions,
     // for expanding type aliases at the HIR level:
     /// Table `DefId` of type parameter -> substituted type
-    pub ty_substs: RefCell<FxHashMap<DefId, clean::Type>>,
+    crate ty_substs: RefCell<FxHashMap<DefId, clean::Type>>,
     /// Table `DefId` of lifetime parameter -> substituted lifetime
-    pub lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>,
+    crate lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>,
     /// Table `DefId` of const parameter -> substituted const
-    pub ct_substs: RefCell<FxHashMap<DefId, clean::Constant>>,
+    crate ct_substs: RefCell<FxHashMap<DefId, clean::Constant>>,
     /// Table synthetic type parameter for `impl Trait` in argument position -> bounds
-    pub impl_trait_bounds: RefCell<FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>>,
-    pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
-    pub all_fake_def_ids: RefCell<FxHashSet<DefId>>,
+    crate impl_trait_bounds: RefCell<FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>>,
+    crate fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
+    crate all_fake_def_ids: RefCell<FxHashSet<DefId>>,
     /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`.
     // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set.
-    pub generated_synthetics: RefCell<FxHashSet<(Ty<'tcx>, DefId)>>,
-    pub auto_traits: Vec<DefId>,
+    crate generated_synthetics: RefCell<FxHashSet<(Ty<'tcx>, DefId)>>,
+    crate auto_traits: Vec<DefId>,
     /// The options given to rustdoc that could be relevant to a pass.
-    pub render_options: RenderOptions,
+    crate render_options: RenderOptions,
     /// The traits in scope for a given module.
     ///
     /// See `collect_intra_doc_links::traits_implemented_by` for more details.
     /// `map<module, set<trait>>`
-    pub module_trait_cache: RefCell<FxHashMap<DefId, FxHashSet<DefId>>>,
+    crate module_trait_cache: RefCell<FxHashMap<DefId, FxHashSet<DefId>>>,
 }
 
 impl<'tcx> DocContext<'tcx> {
-    pub fn sess(&self) -> &Session {
+    crate fn sess(&self) -> &Session {
         &self.tcx.sess
     }
 
-    pub fn enter_resolver<F, R>(&self, f: F) -> R
+    crate fn enter_resolver<F, R>(&self, f: F) -> R
     where
         F: FnOnce(&mut resolve::Resolver<'_>) -> R,
     {
@@ -90,7 +89,7 @@ impl<'tcx> DocContext<'tcx> {
 
     /// Call the closure with the given parameters set as
     /// the substitutions for a type alias' RHS.
-    pub fn enter_alias<F, R>(
+    crate fn enter_alias<F, R>(
         &self,
         ty_substs: FxHashMap<DefId, clean::Type>,
         lt_substs: FxHashMap<DefId, clean::Lifetime>,
@@ -120,7 +119,7 @@ impl<'tcx> DocContext<'tcx> {
     // Instead, we construct 'fake' def ids, which start immediately after the last DefId.
     // In the Debug impl for clean::Item, we explicitly check for fake
     // def ids, as we'll end up with a panic if we use the DefId Debug impl for fake DefIds
-    pub fn next_def_id(&self, crate_num: CrateNum) -> DefId {
+    crate fn next_def_id(&self, crate_num: CrateNum) -> DefId {
         let start_def_id = {
             let num_def_ids = if crate_num == LOCAL_CRATE {
                 self.tcx.hir().definitions().def_path_table().num_def_ids()
@@ -150,7 +149,7 @@ impl<'tcx> DocContext<'tcx> {
 
     /// Like `hir().local_def_id_to_hir_id()`, but skips calling it on fake DefIds.
     /// (This avoids a slice-index-out-of-bounds panic.)
-    pub fn as_local_hir_id(&self, def_id: DefId) -> Option<HirId> {
+    crate fn as_local_hir_id(&self, def_id: DefId) -> Option<HirId> {
         if self.all_fake_def_ids.borrow().contains(&def_id) {
             None
         } else {
@@ -158,7 +157,7 @@ impl<'tcx> DocContext<'tcx> {
         }
     }
 
-    pub fn stability(&self, id: HirId) -> Option<attr::Stability> {
+    crate fn stability(&self, id: HirId) -> Option<attr::Stability> {
         self.tcx
             .hir()
             .opt_local_def_id(id)
@@ -166,7 +165,7 @@ impl<'tcx> DocContext<'tcx> {
             .cloned()
     }
 
-    pub fn deprecation(&self, id: HirId) -> Option<attr::Deprecation> {
+    crate fn deprecation(&self, id: HirId) -> Option<attr::Deprecation> {
         self.tcx
             .hir()
             .opt_local_def_id(id)
@@ -178,7 +177,7 @@ impl<'tcx> DocContext<'tcx> {
 ///
 /// If the given `error_format` is `ErrorOutputType::Json` and no `SourceMap` is given, a new one
 /// will be created for the handler.
-pub fn new_handler(
+crate fn new_handler(
     error_format: ErrorOutputType,
     source_map: Option<Lrc<source_map::SourceMap>>,
     debugging_opts: &DebuggingOptions,
@@ -280,7 +279,7 @@ where
     (lint_opts, lint_caps)
 }
 
-pub fn run_core(
+crate fn run_core(
     options: RustdocOptions,
 ) -> (clean::Crate, RenderInfo, RenderOptions, Lrc<Session>) {
     // Parse, resolve, and typecheck the given crate.
@@ -725,7 +724,7 @@ impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> {
 /// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter
 /// for `impl Trait` in argument position.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub enum ImplTraitParam {
+crate enum ImplTraitParam {
     DefId(DefId),
     ParamIndex(u32),
 }
diff --git a/src/librustdoc/docfs.rs b/src/librustdoc/docfs.rs
index 8b52ce710a4..9b740acfcdf 100644
--- a/src/librustdoc/docfs.rs
+++ b/src/librustdoc/docfs.rs
@@ -24,38 +24,38 @@ macro_rules! try_err {
     };
 }
 
-pub trait PathError {
+crate trait PathError {
     fn new<S, P: AsRef<Path>>(e: S, path: P) -> Self
     where
         S: ToString + Sized;
 }
 
-pub struct DocFS {
+crate struct DocFS {
     sync_only: bool,
     errors: Option<Sender<String>>,
 }
 
 impl DocFS {
-    pub fn new(errors: Sender<String>) -> DocFS {
+    crate fn new(errors: Sender<String>) -> DocFS {
         DocFS { sync_only: false, errors: Some(errors) }
     }
 
-    pub fn set_sync_only(&mut self, sync_only: bool) {
+    crate fn set_sync_only(&mut self, sync_only: bool) {
         self.sync_only = sync_only;
     }
 
-    pub fn close(&mut self) {
+    crate fn close(&mut self) {
         self.errors = None;
     }
 
-    pub fn create_dir_all<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
+    crate fn create_dir_all<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
         // For now, dir creation isn't a huge time consideration, do it
         // synchronously, which avoids needing ordering between write() actions
         // and directory creation.
         fs::create_dir_all(path)
     }
 
-    pub fn write<P, C, E>(&self, path: P, contents: C) -> Result<(), E>
+    crate fn write<P, C, E>(&self, path: P, contents: C) -> Result<(), E>
     where
         P: AsRef<Path>,
         C: AsRef<[u8]>,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 5e40e6b151d..c79b2395d23 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -31,17 +31,17 @@ use crate::html::markdown::{self, ErrorCodes, Ignore, LangString};
 use crate::passes::span_of_attrs;
 
 #[derive(Clone, Default)]
-pub struct TestOptions {
+crate struct TestOptions {
     /// Whether to disable the default `extern crate my_crate;` when creating doctests.
-    pub no_crate_inject: bool,
+    crate no_crate_inject: bool,
     /// Whether to emit compilation warnings when compiling doctests. Setting this will suppress
     /// the default `#![allow(unused)]`.
-    pub display_warnings: bool,
+    crate display_warnings: bool,
     /// Additional crate-level attributes to add to doctests.
-    pub attrs: Vec<String>,
+    crate attrs: Vec<String>,
 }
 
-pub fn run(options: Options) -> Result<(), ErrorReported> {
+crate fn run(options: Options) -> Result<(), ErrorReported> {
     let input = config::Input::File(options.input.clone());
 
     let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name;
@@ -363,7 +363,7 @@ fn run_test(
 
 /// Transforms a test into code that can be compiled into a Rust binary, and returns the number of
 /// lines before the test code begins.
-pub fn make_test(
+crate fn make_test(
     s: &str,
     cratename: Option<&str>,
     dont_insert_main: bool,
@@ -605,7 +605,7 @@ fn partition_source(s: &str) -> (String, String, String) {
     (before, after, crates)
 }
 
-pub trait Tester {
+crate trait Tester {
     fn add_test(&mut self, test: String, config: LangString, line: usize);
     fn get_line(&self) -> usize {
         0
@@ -613,8 +613,8 @@ pub trait Tester {
     fn register_header(&mut self, _name: &str, _level: u32) {}
 }
 
-pub struct Collector {
-    pub tests: Vec<testing::TestDescAndFn>,
+crate struct Collector {
+    crate tests: Vec<testing::TestDescAndFn>,
 
     // The name of the test displayed to the user, separated by `::`.
     //
@@ -650,7 +650,7 @@ pub struct Collector {
 }
 
 impl Collector {
-    pub fn new(
+    crate fn new(
         cratename: String,
         options: Options,
         use_headers: bool,
@@ -682,7 +682,7 @@ impl Collector {
         format!("{} - {}(line {})", filename, item_path, line)
     }
 
-    pub fn set_position(&mut self, position: Span) {
+    crate fn set_position(&mut self, position: Span) {
         self.position = position;
     }
 
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index ee217d99d2c..a80ac1e72fc 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -1,6 +1,6 @@
 //! This module is used to store stuff from Rust's AST in a more convenient
 //! manner (and with prettier names) before cleaning.
-pub use self::StructType::*;
+crate use self::StructType::*;
 
 use rustc_ast as ast;
 use rustc_span::hygiene::MacroKind;
@@ -10,35 +10,35 @@ use rustc_hir as hir;
 use rustc_hir::def_id::CrateNum;
 use rustc_hir::HirId;
 
-pub struct Module<'hir> {
-    pub name: Option<Symbol>,
-    pub attrs: &'hir [ast::Attribute],
-    pub where_outer: Span,
-    pub where_inner: Span,
-    pub extern_crates: Vec<ExternCrate<'hir>>,
-    pub imports: Vec<Import<'hir>>,
-    pub structs: Vec<Struct<'hir>>,
-    pub unions: Vec<Union<'hir>>,
-    pub enums: Vec<Enum<'hir>>,
-    pub fns: Vec<Function<'hir>>,
-    pub mods: Vec<Module<'hir>>,
-    pub id: hir::HirId,
-    pub typedefs: Vec<Typedef<'hir>>,
-    pub opaque_tys: Vec<OpaqueTy<'hir>>,
-    pub statics: Vec<Static<'hir>>,
-    pub constants: Vec<Constant<'hir>>,
-    pub traits: Vec<Trait<'hir>>,
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub impls: Vec<Impl<'hir>>,
-    pub foreigns: Vec<ForeignItem<'hir>>,
-    pub macros: Vec<Macro<'hir>>,
-    pub proc_macros: Vec<ProcMacro<'hir>>,
-    pub trait_aliases: Vec<TraitAlias<'hir>>,
-    pub is_crate: bool,
+crate struct Module<'hir> {
+    crate name: Option<Symbol>,
+    crate attrs: &'hir [ast::Attribute],
+    crate where_outer: Span,
+    crate where_inner: Span,
+    crate extern_crates: Vec<ExternCrate<'hir>>,
+    crate imports: Vec<Import<'hir>>,
+    crate structs: Vec<Struct<'hir>>,
+    crate unions: Vec<Union<'hir>>,
+    crate enums: Vec<Enum<'hir>>,
+    crate fns: Vec<Function<'hir>>,
+    crate mods: Vec<Module<'hir>>,
+    crate id: hir::HirId,
+    crate typedefs: Vec<Typedef<'hir>>,
+    crate opaque_tys: Vec<OpaqueTy<'hir>>,
+    crate statics: Vec<Static<'hir>>,
+    crate constants: Vec<Constant<'hir>>,
+    crate traits: Vec<Trait<'hir>>,
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate impls: Vec<Impl<'hir>>,
+    crate foreigns: Vec<ForeignItem<'hir>>,
+    crate macros: Vec<Macro<'hir>>,
+    crate proc_macros: Vec<ProcMacro<'hir>>,
+    crate trait_aliases: Vec<TraitAlias<'hir>>,
+    crate is_crate: bool,
 }
 
 impl Module<'hir> {
-    pub fn new(
+    crate fn new(
         name: Option<Symbol>,
         attrs: &'hir [ast::Attribute],
         vis: &'hir hir::Visibility<'hir>,
@@ -73,7 +73,7 @@ impl Module<'hir> {
 }
 
 #[derive(Debug, Clone, Copy)]
-pub enum StructType {
+crate enum StructType {
     /// A braced struct
     Plain,
     /// A tuple struct
@@ -82,190 +82,190 @@ pub enum StructType {
     Unit,
 }
 
-pub struct Struct<'hir> {
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub id: hir::HirId,
-    pub struct_type: StructType,
-    pub name: Symbol,
-    pub generics: &'hir hir::Generics<'hir>,
-    pub attrs: &'hir [ast::Attribute],
-    pub fields: &'hir [hir::StructField<'hir>],
-    pub span: Span,
+crate struct Struct<'hir> {
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate id: hir::HirId,
+    crate struct_type: StructType,
+    crate name: Symbol,
+    crate generics: &'hir hir::Generics<'hir>,
+    crate attrs: &'hir [ast::Attribute],
+    crate fields: &'hir [hir::StructField<'hir>],
+    crate span: Span,
 }
 
-pub struct Union<'hir> {
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub id: hir::HirId,
-    pub struct_type: StructType,
-    pub name: Symbol,
-    pub generics: &'hir hir::Generics<'hir>,
-    pub attrs: &'hir [ast::Attribute],
-    pub fields: &'hir [hir::StructField<'hir>],
-    pub span: Span,
+crate struct Union<'hir> {
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate id: hir::HirId,
+    crate struct_type: StructType,
+    crate name: Symbol,
+    crate generics: &'hir hir::Generics<'hir>,
+    crate attrs: &'hir [ast::Attribute],
+    crate fields: &'hir [hir::StructField<'hir>],
+    crate span: Span,
 }
 
-pub struct Enum<'hir> {
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub variants: Vec<Variant<'hir>>,
-    pub generics: &'hir hir::Generics<'hir>,
-    pub attrs: &'hir [ast::Attribute],
-    pub id: hir::HirId,
-    pub span: Span,
-    pub name: Symbol,
+crate struct Enum<'hir> {
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate variants: Vec<Variant<'hir>>,
+    crate generics: &'hir hir::Generics<'hir>,
+    crate attrs: &'hir [ast::Attribute],
+    crate id: hir::HirId,
+    crate span: Span,
+    crate name: Symbol,
 }
 
-pub struct Variant<'hir> {
-    pub name: Symbol,
-    pub id: hir::HirId,
-    pub attrs: &'hir [ast::Attribute],
-    pub def: &'hir hir::VariantData<'hir>,
-    pub span: Span,
+crate struct Variant<'hir> {
+    crate name: Symbol,
+    crate id: hir::HirId,
+    crate attrs: &'hir [ast::Attribute],
+    crate def: &'hir hir::VariantData<'hir>,
+    crate span: Span,
 }
 
-pub struct Function<'hir> {
-    pub decl: &'hir hir::FnDecl<'hir>,
-    pub attrs: &'hir [ast::Attribute],
-    pub id: hir::HirId,
-    pub name: Symbol,
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub header: hir::FnHeader,
-    pub span: Span,
-    pub generics: &'hir hir::Generics<'hir>,
-    pub body: hir::BodyId,
+crate struct Function<'hir> {
+    crate decl: &'hir hir::FnDecl<'hir>,
+    crate attrs: &'hir [ast::Attribute],
+    crate id: hir::HirId,
+    crate name: Symbol,
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate header: hir::FnHeader,
+    crate span: Span,
+    crate generics: &'hir hir::Generics<'hir>,
+    crate body: hir::BodyId,
 }
 
-pub struct Typedef<'hir> {
-    pub ty: &'hir hir::Ty<'hir>,
-    pub gen: &'hir hir::Generics<'hir>,
-    pub name: Symbol,
-    pub id: hir::HirId,
-    pub attrs: &'hir [ast::Attribute],
-    pub span: Span,
-    pub vis: &'hir hir::Visibility<'hir>,
+crate struct Typedef<'hir> {
+    crate ty: &'hir hir::Ty<'hir>,
+    crate gen: &'hir hir::Generics<'hir>,
+    crate name: Symbol,
+    crate id: hir::HirId,
+    crate attrs: &'hir [ast::Attribute],
+    crate span: Span,
+    crate vis: &'hir hir::Visibility<'hir>,
 }
 
-pub struct OpaqueTy<'hir> {
-    pub opaque_ty: &'hir hir::OpaqueTy<'hir>,
-    pub name: Symbol,
-    pub id: hir::HirId,
-    pub attrs: &'hir [ast::Attribute],
-    pub span: Span,
-    pub vis: &'hir hir::Visibility<'hir>,
+crate struct OpaqueTy<'hir> {
+    crate opaque_ty: &'hir hir::OpaqueTy<'hir>,
+    crate name: Symbol,
+    crate id: hir::HirId,
+    crate attrs: &'hir [ast::Attribute],
+    crate span: Span,
+    crate vis: &'hir hir::Visibility<'hir>,
 }
 
 #[derive(Debug)]
-pub struct Static<'hir> {
-    pub type_: &'hir hir::Ty<'hir>,
-    pub mutability: hir::Mutability,
-    pub expr: hir::BodyId,
-    pub name: Symbol,
-    pub attrs: &'hir [ast::Attribute],
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub id: hir::HirId,
-    pub span: Span,
+crate struct Static<'hir> {
+    crate type_: &'hir hir::Ty<'hir>,
+    crate mutability: hir::Mutability,
+    crate expr: hir::BodyId,
+    crate name: Symbol,
+    crate attrs: &'hir [ast::Attribute],
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate id: hir::HirId,
+    crate span: Span,
 }
 
-pub struct Constant<'hir> {
-    pub type_: &'hir hir::Ty<'hir>,
-    pub expr: hir::BodyId,
-    pub name: Symbol,
-    pub attrs: &'hir [ast::Attribute],
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub id: hir::HirId,
-    pub span: Span,
+crate struct Constant<'hir> {
+    crate type_: &'hir hir::Ty<'hir>,
+    crate expr: hir::BodyId,
+    crate name: Symbol,
+    crate attrs: &'hir [ast::Attribute],
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate id: hir::HirId,
+    crate span: Span,
 }
 
-pub struct Trait<'hir> {
-    pub is_auto: hir::IsAuto,
-    pub unsafety: hir::Unsafety,
-    pub name: Symbol,
-    pub items: Vec<&'hir hir::TraitItem<'hir>>,
-    pub generics: &'hir hir::Generics<'hir>,
-    pub bounds: &'hir [hir::GenericBound<'hir>],
-    pub attrs: &'hir [ast::Attribute],
-    pub id: hir::HirId,
-    pub span: Span,
-    pub vis: &'hir hir::Visibility<'hir>,
+crate struct Trait<'hir> {
+    crate is_auto: hir::IsAuto,
+    crate unsafety: hir::Unsafety,
+    crate name: Symbol,
+    crate items: Vec<&'hir hir::TraitItem<'hir>>,
+    crate generics: &'hir hir::Generics<'hir>,
+    crate bounds: &'hir [hir::GenericBound<'hir>],
+    crate attrs: &'hir [ast::Attribute],
+    crate id: hir::HirId,
+    crate span: Span,
+    crate vis: &'hir hir::Visibility<'hir>,
 }
 
-pub struct TraitAlias<'hir> {
-    pub name: Symbol,
-    pub generics: &'hir hir::Generics<'hir>,
-    pub bounds: &'hir [hir::GenericBound<'hir>],
-    pub attrs: &'hir [ast::Attribute],
-    pub id: hir::HirId,
-    pub span: Span,
-    pub vis: &'hir hir::Visibility<'hir>,
+crate struct TraitAlias<'hir> {
+    crate name: Symbol,
+    crate generics: &'hir hir::Generics<'hir>,
+    crate bounds: &'hir [hir::GenericBound<'hir>],
+    crate attrs: &'hir [ast::Attribute],
+    crate id: hir::HirId,
+    crate span: Span,
+    crate vis: &'hir hir::Visibility<'hir>,
 }
 
 #[derive(Debug)]
-pub struct Impl<'hir> {
-    pub unsafety: hir::Unsafety,
-    pub polarity: hir::ImplPolarity,
-    pub defaultness: hir::Defaultness,
-    pub constness: hir::Constness,
-    pub generics: &'hir hir::Generics<'hir>,
-    pub trait_: &'hir Option<hir::TraitRef<'hir>>,
-    pub for_: &'hir hir::Ty<'hir>,
-    pub items: Vec<&'hir hir::ImplItem<'hir>>,
-    pub attrs: &'hir [ast::Attribute],
-    pub span: Span,
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub id: hir::HirId,
+crate struct Impl<'hir> {
+    crate unsafety: hir::Unsafety,
+    crate polarity: hir::ImplPolarity,
+    crate defaultness: hir::Defaultness,
+    crate constness: hir::Constness,
+    crate generics: &'hir hir::Generics<'hir>,
+    crate trait_: &'hir Option<hir::TraitRef<'hir>>,
+    crate for_: &'hir hir::Ty<'hir>,
+    crate items: Vec<&'hir hir::ImplItem<'hir>>,
+    crate attrs: &'hir [ast::Attribute],
+    crate span: Span,
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate id: hir::HirId,
 }
 
-pub struct ForeignItem<'hir> {
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub id: hir::HirId,
-    pub name: Symbol,
-    pub kind: &'hir hir::ForeignItemKind<'hir>,
-    pub attrs: &'hir [ast::Attribute],
-    pub span: Span,
+crate struct ForeignItem<'hir> {
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate id: hir::HirId,
+    crate name: Symbol,
+    crate kind: &'hir hir::ForeignItemKind<'hir>,
+    crate attrs: &'hir [ast::Attribute],
+    crate span: Span,
 }
 
 // For Macro we store the DefId instead of the NodeId, since we also create
 // these imported macro_rules (which only have a DUMMY_NODE_ID).
-pub struct Macro<'hir> {
-    pub name: Symbol,
-    pub hid: hir::HirId,
-    pub def_id: hir::def_id::DefId,
-    pub attrs: &'hir [ast::Attribute],
-    pub span: Span,
-    pub matchers: Vec<Span>,
-    pub imported_from: Option<Symbol>,
+crate struct Macro<'hir> {
+    crate name: Symbol,
+    crate hid: hir::HirId,
+    crate def_id: hir::def_id::DefId,
+    crate attrs: &'hir [ast::Attribute],
+    crate span: Span,
+    crate matchers: Vec<Span>,
+    crate imported_from: Option<Symbol>,
 }
 
-pub struct ExternCrate<'hir> {
-    pub name: Symbol,
-    pub hir_id: HirId,
-    pub cnum: CrateNum,
-    pub path: Option<String>,
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub attrs: &'hir [ast::Attribute],
-    pub span: Span,
+crate struct ExternCrate<'hir> {
+    crate name: Symbol,
+    crate hir_id: HirId,
+    crate cnum: CrateNum,
+    crate path: Option<String>,
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate attrs: &'hir [ast::Attribute],
+    crate span: Span,
 }
 
 #[derive(Debug)]
-pub struct Import<'hir> {
-    pub name: Symbol,
-    pub id: hir::HirId,
-    pub vis: &'hir hir::Visibility<'hir>,
-    pub attrs: &'hir [ast::Attribute],
-    pub path: &'hir hir::Path<'hir>,
-    pub glob: bool,
-    pub span: Span,
+crate struct Import<'hir> {
+    crate name: Symbol,
+    crate id: hir::HirId,
+    crate vis: &'hir hir::Visibility<'hir>,
+    crate attrs: &'hir [ast::Attribute],
+    crate path: &'hir hir::Path<'hir>,
+    crate glob: bool,
+    crate span: Span,
 }
 
-pub struct ProcMacro<'hir> {
-    pub name: Symbol,
-    pub id: hir::HirId,
-    pub kind: MacroKind,
-    pub helpers: Vec<Symbol>,
-    pub attrs: &'hir [ast::Attribute],
-    pub span: Span,
+crate struct ProcMacro<'hir> {
+    crate name: Symbol,
+    crate id: hir::HirId,
+    crate kind: MacroKind,
+    crate helpers: Vec<Symbol>,
+    crate attrs: &'hir [ast::Attribute],
+    crate span: Span,
 }
 
-pub fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType {
+crate fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType {
     match *vdata {
         hir::VariantData::Struct(..) => Plain,
         hir::VariantData::Tuple(..) => Tuple,
diff --git a/src/librustdoc/error.rs b/src/librustdoc/error.rs
index 77063ab4639..82d0002b98b 100644
--- a/src/librustdoc/error.rs
+++ b/src/librustdoc/error.rs
@@ -5,9 +5,9 @@ use std::path::{Path, PathBuf};
 use crate::docfs::PathError;
 
 #[derive(Debug)]
-pub struct Error {
-    pub file: PathBuf,
-    pub error: String,
+crate struct Error {
+    crate file: PathBuf,
+    crate error: String,
 }
 
 impl error::Error for Error {}
diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs
index 900821dbf4a..6c86baa36ac 100644
--- a/src/librustdoc/externalfiles.rs
+++ b/src/librustdoc/externalfiles.rs
@@ -5,20 +5,20 @@ use std::path::Path;
 use std::str;
 
 #[derive(Clone, Debug)]
-pub struct ExternalHtml {
+crate struct ExternalHtml {
     /// Content that will be included inline in the <head> section of a
     /// rendered Markdown file or generated documentation
-    pub in_header: String,
+    crate in_header: String,
     /// Content that will be included inline between <body> and the content of
     /// a rendered Markdown file or generated documentation
-    pub before_content: String,
+    crate before_content: String,
     /// Content that will be included inline between the content and </body> of
     /// a rendered Markdown file or generated documentation
-    pub after_content: String,
+    crate after_content: String,
 }
 
 impl ExternalHtml {
-    pub fn load(
+    crate fn load(
         in_header: &[String],
         before_content: &[String],
         after_content: &[String],
@@ -50,12 +50,12 @@ impl ExternalHtml {
     }
 }
 
-pub enum LoadStringError {
+crate enum LoadStringError {
     ReadFail,
     BadUtf8,
 }
 
-pub fn load_string<P: AsRef<Path>>(
+crate fn load_string<P: AsRef<Path>>(
     file_path: P,
     diag: &rustc_errors::Handler,
 ) -> Result<String, LoadStringError> {
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 694051aa54f..a72860ef0a8 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -1,9 +1,9 @@
 use crate::clean::*;
 
-pub struct StripItem(pub Item);
+crate struct StripItem(pub Item);
 
 impl StripItem {
-    pub fn strip(self) -> Option<Item> {
+    crate fn strip(self) -> Option<Item> {
         match self.0 {
             Item { kind: StrippedItem(..), .. } => Some(self.0),
             mut i => {
@@ -14,7 +14,7 @@ impl StripItem {
     }
 }
 
-pub trait DocFolder: Sized {
+crate trait DocFolder: Sized {
     fn fold_item(&mut self, item: Item) -> Option<Item> {
         self.fold_item_recur(item)
     }
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 277571b11f5..917c1a95fdb 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -30,25 +30,25 @@ thread_local!(crate static CACHE_KEY: RefCell<Arc<Cache>> = Default::default());
 /// to `Send` so it may be stored in a `Arc` instance and shared among the various
 /// rendering threads.
 #[derive(Default)]
-pub struct Cache {
+crate struct Cache {
     /// Maps a type ID to all known implementations for that type. This is only
     /// recognized for intra-crate `ResolvedPath` types, and is used to print
     /// out extra documentation on the page of an enum/struct.
     ///
     /// The values of the map are a list of implementations and documentation
     /// found on that implementation.
-    pub impls: FxHashMap<DefId, Vec<Impl>>,
+    crate impls: FxHashMap<DefId, Vec<Impl>>,
 
     /// Maintains a mapping of local crate `DefId`s to the fully qualified name
     /// and "short type description" of that node. This is used when generating
     /// URLs when a type is being linked to. External paths are not located in
     /// this map because the `External` type itself has all the information
     /// necessary.
-    pub paths: FxHashMap<DefId, (Vec<String>, ItemType)>,
+    crate paths: FxHashMap<DefId, (Vec<String>, ItemType)>,
 
     /// Similar to `paths`, but only holds external paths. This is only used for
     /// generating explicit hyperlinks to other crates.
-    pub external_paths: FxHashMap<DefId, (Vec<String>, ItemType)>,
+    crate external_paths: FxHashMap<DefId, (Vec<String>, ItemType)>,
 
     /// Maps local `DefId`s of exported types to fully qualified paths.
     /// Unlike 'paths', this mapping ignores any renames that occur
@@ -60,36 +60,36 @@ pub struct Cache {
     /// to the path used if the corresponding type is inlined. By
     /// doing this, we can detect duplicate impls on a trait page, and only display
     /// the impl for the inlined type.
-    pub exact_paths: FxHashMap<DefId, Vec<String>>,
+    crate exact_paths: FxHashMap<DefId, Vec<String>>,
 
     /// This map contains information about all known traits of this crate.
     /// Implementations of a crate should inherit the documentation of the
     /// parent trait if no extra documentation is specified, and default methods
     /// should show up in documentation about trait implementations.
-    pub traits: FxHashMap<DefId, clean::Trait>,
+    crate traits: FxHashMap<DefId, clean::Trait>,
 
     /// When rendering traits, it's often useful to be able to list all
     /// implementors of the trait, and this mapping is exactly, that: a mapping
     /// of trait ids to the list of known implementors of the trait
-    pub implementors: FxHashMap<DefId, Vec<Impl>>,
+    crate implementors: FxHashMap<DefId, Vec<Impl>>,
 
     /// Cache of where external crate documentation can be found.
-    pub extern_locations: FxHashMap<CrateNum, (String, PathBuf, ExternalLocation)>,
+    crate extern_locations: FxHashMap<CrateNum, (String, PathBuf, ExternalLocation)>,
 
     /// Cache of where documentation for primitives can be found.
-    pub primitive_locations: FxHashMap<clean::PrimitiveType, DefId>,
+    crate primitive_locations: FxHashMap<clean::PrimitiveType, DefId>,
 
     // Note that external items for which `doc(hidden)` applies to are shown as
     // non-reachable while local items aren't. This is because we're reusing
     // the access levels from the privacy check pass.
-    pub access_levels: AccessLevels<DefId>,
+    crate access_levels: AccessLevels<DefId>,
 
     /// The version of the crate being documented, if given from the `--crate-version` flag.
-    pub crate_version: Option<String>,
+    crate crate_version: Option<String>,
 
     /// Whether to document private items.
     /// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions.
-    pub document_private: bool,
+    crate document_private: bool,
 
     // Private fields only used when initially crawling a crate to build a cache
     stack: Vec<String>,
@@ -98,17 +98,17 @@ pub struct Cache {
     stripped_mod: bool,
     masked_crates: FxHashSet<CrateNum>,
 
-    pub search_index: Vec<IndexItem>,
-    pub deref_trait_did: Option<DefId>,
-    pub deref_mut_trait_did: Option<DefId>,
-    pub owned_box_did: Option<DefId>,
+    crate search_index: Vec<IndexItem>,
+    crate deref_trait_did: Option<DefId>,
+    crate deref_mut_trait_did: Option<DefId>,
+    crate owned_box_did: Option<DefId>,
 
     // In rare case where a structure is defined in one module but implemented
     // in another, if the implementing module is parsed before defining module,
     // then the fully qualified name of the structure isn't presented in `paths`
     // yet when its implementation methods are being indexed. Caches such methods
     // and their parent id here and indexes them at the end of crate parsing.
-    pub orphan_impl_items: Vec<(DefId, clean::Item)>,
+    crate orphan_impl_items: Vec<(DefId, clean::Item)>,
 
     // Similarly to `orphan_impl_items`, sometimes trait impls are picked up
     // even though the trait itself is not exported. This can happen if a trait
@@ -121,11 +121,11 @@ pub struct Cache {
 
     /// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias,
     /// we need the alias element to have an array of items.
-    pub aliases: BTreeMap<String, Vec<usize>>,
+    crate aliases: BTreeMap<String, Vec<usize>>,
 }
 
 impl Cache {
-    pub fn from_krate(
+    crate fn from_krate(
         render_info: RenderInfo,
         document_private: bool,
         extern_html_root_urls: &BTreeMap<String, String>,
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index a0f4502f750..af512e37460 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -20,7 +20,7 @@ use crate::clean;
 /// a heading, edit the listing in `html/render.rs`, function `sidebar_module`. This uses an
 /// ordering based on a helper function inside `item_module`, in the same file.
 #[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord)]
-pub enum ItemType {
+crate enum ItemType {
     Module = 0,
     ExternCrate = 1,
     Import = 2,
@@ -124,7 +124,7 @@ impl From<clean::TypeKind> for ItemType {
 }
 
 impl ItemType {
-    pub fn as_str(&self) -> &'static str {
+    crate fn as_str(&self) -> &'static str {
         match *self {
             ItemType::Module => "mod",
             ItemType::ExternCrate => "externcrate",
diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs
index b893d6c64ec..55fd4948f45 100644
--- a/src/librustdoc/formats/mod.rs
+++ b/src/librustdoc/formats/mod.rs
@@ -1,8 +1,8 @@
-pub mod cache;
-pub mod item_type;
-pub mod renderer;
+crate mod cache;
+crate mod item_type;
+crate mod renderer;
 
-pub use renderer::{run_format, FormatRenderer};
+crate use renderer::{run_format, FormatRenderer};
 
 use rustc_span::def_id::DefId;
 
@@ -11,7 +11,7 @@ use crate::clean::types::GetDefId;
 
 /// Specifies whether rendering directly implemented trait items or ones from a certain Deref
 /// impl.
-pub enum AssocItemRender<'a> {
+crate enum AssocItemRender<'a> {
     All,
     DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool },
 }
@@ -19,26 +19,26 @@ pub enum AssocItemRender<'a> {
 /// For different handling of associated items from the Deref target of a type rather than the type
 /// itself.
 #[derive(Copy, Clone, PartialEq)]
-pub enum RenderMode {
+crate enum RenderMode {
     Normal,
     ForDeref { mut_: bool },
 }
 
 /// Metadata about implementations for a type or trait.
 #[derive(Clone, Debug)]
-pub struct Impl {
-    pub impl_item: clean::Item,
+crate struct Impl {
+    crate impl_item: clean::Item,
 }
 
 impl Impl {
-    pub fn inner_impl(&self) -> &clean::Impl {
+    crate fn inner_impl(&self) -> &clean::Impl {
         match self.impl_item.kind {
             clean::ImplItem(ref impl_) => impl_,
             _ => panic!("non-impl item found in impl"),
         }
     }
 
-    pub fn trait_did(&self) -> Option<DefId> {
+    crate fn trait_did(&self) -> Option<DefId> {
         self.inner_impl().trait_.def_id()
     }
 }
diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs
index 273e2819257..d0fdc69cc19 100644
--- a/src/librustdoc/formats/renderer.rs
+++ b/src/librustdoc/formats/renderer.rs
@@ -10,7 +10,7 @@ use crate::formats::cache::{Cache, CACHE_KEY};
 /// Allows for different backends to rustdoc to be used with the `run_format()` function. Each
 /// backend renderer has hooks for initialization, documenting an item, entering and exiting a
 /// module, and cleanup/finalizing output.
-pub trait FormatRenderer: Clone {
+crate trait FormatRenderer: Clone {
     /// Sets up any state required for the renderer. When this is called the cache has already been
     /// populated.
     fn init(
@@ -43,7 +43,7 @@ pub trait FormatRenderer: Clone {
 }
 
 /// Main method for rendering a crate.
-pub fn run_format<T: FormatRenderer>(
+crate fn run_format<T: FormatRenderer>(
     krate: clean::Crate,
     options: RenderOptions,
     render_info: RenderInfo,
diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs
index 03660c32654..60c19551983 100644
--- a/src/librustdoc/html/escape.rs
+++ b/src/librustdoc/html/escape.rs
@@ -7,7 +7,7 @@ use std::fmt;
 
 /// Wrapper struct which will emit the HTML-escaped version of the contained
 /// string when passed to a format string.
-pub struct Escape<'a>(pub &'a str);
+crate struct Escape<'a>(pub &'a str);
 
 impl<'a> fmt::Display for Escape<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index d18282d6e67..d2722ed1cd2 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -21,7 +21,7 @@ use crate::html::escape::Escape;
 use crate::html::render::cache::ExternalLocation;
 use crate::html::render::CURRENT_DEPTH;
 
-pub trait Print {
+crate trait Print {
     fn print(self, buffer: &mut Buffer);
 }
 
@@ -47,7 +47,7 @@ impl Print for &'_ str {
 }
 
 #[derive(Debug, Clone)]
-pub struct Buffer {
+crate struct Buffer {
     for_html: bool,
     buffer: String,
 }
@@ -115,28 +115,28 @@ impl Buffer {
 }
 
 /// Wrapper struct for properly emitting a function or method declaration.
-pub struct Function<'a> {
+crate struct Function<'a> {
     /// The declaration to emit.
-    pub decl: &'a clean::FnDecl,
+    crate decl: &'a clean::FnDecl,
     /// The length of the function header and name. In other words, the number of characters in the
     /// function declaration up to but not including the parentheses.
     ///
     /// Used to determine line-wrapping.
-    pub header_len: usize,
+    crate header_len: usize,
     /// The number of spaces to indent each successive line with, if line-wrapping is necessary.
-    pub indent: usize,
+    crate indent: usize,
     /// Whether the function is async or not.
-    pub asyncness: hir::IsAsync,
+    crate asyncness: hir::IsAsync,
 }
 
 /// Wrapper struct for emitting a where-clause from Generics.
-pub struct WhereClause<'a> {
+crate struct WhereClause<'a> {
     /// The Generics from which to emit a where-clause.
-    pub gens: &'a clean::Generics,
+    crate gens: &'a clean::Generics,
     /// The number of spaces to indent each line with.
-    pub indent: usize,
+    crate indent: usize,
     /// Whether the where-clause needs to add a comma and newline after the last bound.
-    pub end_newline: bool,
+    crate end_newline: bool,
 }
 
 fn comma_sep<T: fmt::Display>(items: impl Iterator<Item = T>) -> impl fmt::Display {
@@ -480,7 +480,7 @@ impl clean::Path {
     }
 }
 
-pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
+crate fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
     let cache = cache();
     if !did.is_local() && !cache.access_levels.is_public(did) && !cache.document_private {
         return None;
@@ -618,7 +618,7 @@ fn tybounds(param_names: &Option<Vec<clean::GenericBound>>) -> impl fmt::Display
     })
 }
 
-pub fn anchor(did: DefId, text: &str) -> impl fmt::Display + '_ {
+crate fn anchor(did: DefId, text: &str) -> impl fmt::Display + '_ {
     display_fn(move |f| {
         if let Some((url, short_ty, fqp)) = href(did) {
             write!(
@@ -910,7 +910,7 @@ impl clean::Impl {
 }
 
 // The difference from above is that trait is not hyperlinked.
-pub fn fmt_impl_for_trait_page(i: &clean::Impl, f: &mut Buffer, use_absolute: bool) {
+crate fn fmt_impl_for_trait_page(i: &clean::Impl, f: &mut Buffer, use_absolute: bool) {
     f.from_display(i.print_inner(false, use_absolute))
 }
 
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 4769edc50ff..22233731411 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -15,7 +15,7 @@ use rustc_span::symbol::Ident;
 use rustc_span::with_default_session_globals;
 
 /// Highlights `src`, returning the HTML output.
-pub fn render_with_highlighting(
+crate fn render_with_highlighting(
     src: String,
     class: Option<&str>,
     playground_button: Option<&str>,
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index db73af7ec16..e8039942f4f 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -7,33 +7,33 @@ use crate::html::format::{Buffer, Print};
 use crate::html::render::{ensure_trailing_slash, StylePath};
 
 #[derive(Clone)]
-pub struct Layout {
-    pub logo: String,
-    pub favicon: String,
-    pub external_html: ExternalHtml,
-    pub default_settings: HashMap<String, String>,
-    pub krate: String,
+crate struct Layout {
+    crate logo: String,
+    crate favicon: String,
+    crate external_html: ExternalHtml,
+    crate default_settings: HashMap<String, String>,
+    crate krate: String,
     /// The given user css file which allow to customize the generated
     /// documentation theme.
-    pub css_file_extension: Option<PathBuf>,
+    crate css_file_extension: Option<PathBuf>,
     /// If false, the `select` element to have search filtering by crates on rendered docs
     /// won't be generated.
-    pub generate_search_filter: bool,
+    crate generate_search_filter: bool,
 }
 
-pub struct Page<'a> {
-    pub title: &'a str,
-    pub css_class: &'a str,
-    pub root_path: &'a str,
-    pub static_root_path: Option<&'a str>,
-    pub description: &'a str,
-    pub keywords: &'a str,
-    pub resource_suffix: &'a str,
-    pub extra_scripts: &'a [&'a str],
-    pub static_extra_scripts: &'a [&'a str],
+crate struct Page<'a> {
+    crate title: &'a str,
+    crate css_class: &'a str,
+    crate root_path: &'a str,
+    crate static_root_path: Option<&'a str>,
+    crate description: &'a str,
+    crate keywords: &'a str,
+    crate resource_suffix: &'a str,
+    crate extra_scripts: &'a [&'a str],
+    crate static_extra_scripts: &'a [&'a str],
 }
 
-pub fn render<T: Print, S: Print>(
+crate fn render<T: Print, S: Print>(
     layout: &Layout,
     page: &Page<'_>,
     sidebar: S,
@@ -228,7 +228,7 @@ pub fn render<T: Print, S: Print>(
     )
 }
 
-pub fn redirect(url: &str) -> String {
+crate fn redirect(url: &str) -> String {
     // <script> triggers a redirect before refresh, so this is fine.
     format!(
         r##"<!DOCTYPE html>
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index ca8b811681c..cdb9aea5ad6 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -62,23 +62,23 @@ pub struct Markdown<'a>(
     pub &'a Option<Playground>,
 );
 /// A tuple struct like `Markdown` that renders the markdown with a table of contents.
-pub struct MarkdownWithToc<'a>(
-    pub &'a str,
-    pub &'a mut IdMap,
-    pub ErrorCodes,
-    pub Edition,
-    pub &'a Option<Playground>,
+crate struct MarkdownWithToc<'a>(
+    crate &'a str,
+    crate &'a mut IdMap,
+    crate ErrorCodes,
+    crate Edition,
+    crate &'a Option<Playground>,
 );
 /// A tuple struct like `Markdown` that renders the markdown escaping HTML tags.
-pub struct MarkdownHtml<'a>(
-    pub &'a str,
-    pub &'a mut IdMap,
-    pub ErrorCodes,
-    pub Edition,
-    pub &'a Option<Playground>,
+crate struct MarkdownHtml<'a>(
+    crate &'a str,
+    crate &'a mut IdMap,
+    crate ErrorCodes,
+    crate Edition,
+    crate &'a Option<Playground>,
 );
 /// A tuple struct like `Markdown` that renders only the first paragraph.
-pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [RenderedLink]);
+crate struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [RenderedLink]);
 
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum ErrorCodes {
@@ -87,14 +87,14 @@ pub enum ErrorCodes {
 }
 
 impl ErrorCodes {
-    pub fn from(b: bool) -> Self {
+    crate fn from(b: bool) -> Self {
         match b {
             true => ErrorCodes::Yes,
             false => ErrorCodes::No,
         }
     }
 
-    pub fn as_bool(self) -> bool {
+    crate fn as_bool(self) -> bool {
         match self {
             ErrorCodes::Yes => true,
             ErrorCodes::No => false,
@@ -643,7 +643,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
     }
 }
 
-pub fn find_testable_code<T: doctest::Tester>(
+crate fn find_testable_code<T: doctest::Tester>(
     doc: &str,
     tests: &mut T,
     error_codes: ErrorCodes,
@@ -709,7 +709,7 @@ pub fn find_testable_code<T: doctest::Tester>(
     }
 }
 
-pub struct ExtraInfo<'a, 'b> {
+crate struct ExtraInfo<'a, 'b> {
     hir_id: Option<HirId>,
     item_did: Option<DefId>,
     sp: Span,
@@ -717,11 +717,11 @@ pub struct ExtraInfo<'a, 'b> {
 }
 
 impl<'a, 'b> ExtraInfo<'a, 'b> {
-    pub fn new(tcx: &'a TyCtxt<'b>, hir_id: HirId, sp: Span) -> ExtraInfo<'a, 'b> {
+    crate fn new(tcx: &'a TyCtxt<'b>, hir_id: HirId, sp: Span) -> ExtraInfo<'a, 'b> {
         ExtraInfo { hir_id: Some(hir_id), item_did: None, sp, tcx }
     }
 
-    pub fn new_did(tcx: &'a TyCtxt<'b>, did: DefId, sp: Span) -> ExtraInfo<'a, 'b> {
+    crate fn new_did(tcx: &'a TyCtxt<'b>, did: DefId, sp: Span) -> ExtraInfo<'a, 'b> {
         ExtraInfo { hir_id: None, item_did: Some(did), sp, tcx }
     }
 
@@ -753,21 +753,21 @@ impl<'a, 'b> ExtraInfo<'a, 'b> {
 }
 
 #[derive(Eq, PartialEq, Clone, Debug)]
-pub struct LangString {
+crate struct LangString {
     original: String,
-    pub should_panic: bool,
-    pub no_run: bool,
-    pub ignore: Ignore,
-    pub rust: bool,
-    pub test_harness: bool,
-    pub compile_fail: bool,
-    pub error_codes: Vec<String>,
-    pub allow_fail: bool,
-    pub edition: Option<Edition>,
+    crate should_panic: bool,
+    crate no_run: bool,
+    crate ignore: Ignore,
+    crate rust: bool,
+    crate test_harness: bool,
+    crate compile_fail: bool,
+    crate error_codes: Vec<String>,
+    crate allow_fail: bool,
+    crate edition: Option<Edition>,
 }
 
 #[derive(Eq, PartialEq, Clone, Debug)]
-pub enum Ignore {
+crate enum Ignore {
     All,
     None,
     Some(Vec<String>),
@@ -955,7 +955,7 @@ impl Markdown<'_> {
 }
 
 impl MarkdownWithToc<'_> {
-    pub fn into_string(self) -> String {
+    crate fn into_string(self) -> String {
         let MarkdownWithToc(md, mut ids, codes, edition, playground) = self;
 
         let p = Parser::new_ext(md, opts());
@@ -976,7 +976,7 @@ impl MarkdownWithToc<'_> {
 }
 
 impl MarkdownHtml<'_> {
-    pub fn into_string(self) -> String {
+    crate fn into_string(self) -> String {
         let MarkdownHtml(md, mut ids, codes, edition, playground) = self;
 
         // This is actually common enough to special-case
@@ -1003,7 +1003,7 @@ impl MarkdownHtml<'_> {
 }
 
 impl MarkdownSummaryLine<'_> {
-    pub fn into_string(self) -> String {
+    crate fn into_string(self) -> String {
         let MarkdownSummaryLine(md, links) = self;
         // This is actually common enough to special-case
         if md.is_empty() {
@@ -1039,7 +1039,7 @@ impl MarkdownSummaryLine<'_> {
 /// - Headings, links, and formatting are stripped.
 /// - Inline code is rendered as-is, surrounded by backticks.
 /// - HTML and code blocks are ignored.
-pub fn plain_text_summary(md: &str) -> String {
+crate fn plain_text_summary(md: &str) -> String {
     if md.is_empty() {
         return String::new();
     }
@@ -1064,7 +1064,7 @@ pub fn plain_text_summary(md: &str) -> String {
     s
 }
 
-pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
+crate fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
     if md.is_empty() {
         return vec![];
     }
@@ -1120,11 +1120,11 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
 crate struct RustCodeBlock {
     /// The range in the markdown that the code block occupies. Note that this includes the fences
     /// for fenced code blocks.
-    pub range: Range<usize>,
+    crate range: Range<usize>,
     /// The range in the markdown that the code within the code block occupies.
-    pub code: Range<usize>,
-    pub is_fenced: bool,
-    pub syntax: Option<String>,
+    crate code: Range<usize>,
+    crate is_fenced: bool,
+    crate syntax: Option<String>,
 }
 
 /// Returns a range of bytes for each code block in the markdown that is tagged as `rust` or
@@ -1247,17 +1247,17 @@ impl IdMap {
         IdMap { map: init_id_map() }
     }
 
-    pub fn populate<I: IntoIterator<Item = String>>(&mut self, ids: I) {
+    crate fn populate<I: IntoIterator<Item = String>>(&mut self, ids: I) {
         for id in ids {
             let _ = self.derive(id);
         }
     }
 
-    pub fn reset(&mut self) {
+    crate fn reset(&mut self) {
         self.map = init_id_map();
     }
 
-    pub fn derive(&mut self, candidate: String) -> String {
+    crate fn derive(&mut self, candidate: String) -> String {
         let id = match self.map.get_mut(&candidate) {
             None => candidate,
             Some(a) => {
diff --git a/src/librustdoc/html/mod.rs b/src/librustdoc/html/mod.rs
index 367538d440e..403a9303c3f 100644
--- a/src/librustdoc/html/mod.rs
+++ b/src/librustdoc/html/mod.rs
@@ -3,7 +3,7 @@ crate mod format;
 crate mod highlight;
 crate mod layout;
 pub mod markdown;
-pub mod render;
+crate mod render;
 crate mod sources;
 crate mod static_files;
 crate mod toc;
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index 0541bf118e1..cef9b8952dd 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -13,7 +13,7 @@ use crate::html::render::{plain_text_summary, shorten};
 use crate::html::render::{Generic, IndexItem, IndexItemFunctionType, RenderType, TypeWithKind};
 
 /// Indicates where an external crate can be found.
-pub enum ExternalLocation {
+crate enum ExternalLocation {
     /// Remote URL root of the external crate
     Remote(String),
     /// This external crate can be found in the local doc/ folder
@@ -24,7 +24,7 @@ pub enum ExternalLocation {
 
 /// Attempts to find where an external crate is located, given that we're
 /// rendering in to the specified source destination.
-pub fn extern_location(
+crate fn extern_location(
     e: &clean::ExternalCrate,
     extern_url: Option<&str>,
     dst: &Path,
@@ -62,7 +62,7 @@ pub fn extern_location(
 }
 
 /// Builds the search index from the collected metadata
-pub fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
+crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
     let mut defid_to_pathid = FxHashMap::default();
     let mut crate_items = Vec::with_capacity(cache.search_index.len());
     let mut crate_paths = vec![];
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index eebb07f0476..78822e678d4 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -25,7 +25,7 @@
 //! These threads are not parallelized (they haven't been a bottleneck yet), and
 //! both occur before the crate is rendered.
 
-pub mod cache;
+crate mod cache;
 
 #[cfg(test)]
 mod tests;
@@ -82,7 +82,7 @@ use crate::html::{highlight, layout, static_files};
 use cache::{build_index, ExternalLocation};
 
 /// A pair of name and its optional document.
-pub type NameDoc = (String, Option<String>);
+crate type NameDoc = (String, Option<String>);
 
 crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
     crate::html::format::display_fn(move |f| {
@@ -101,60 +101,60 @@ crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
 crate struct Context {
     /// Current hierarchy of components leading down to what's currently being
     /// rendered
-    pub current: Vec<String>,
+    crate current: Vec<String>,
     /// The current destination folder of where HTML artifacts should be placed.
     /// This changes as the context descends into the module hierarchy.
-    pub dst: PathBuf,
+    crate dst: PathBuf,
     /// A flag, which when `true`, will render pages which redirect to the
     /// real location of an item. This is used to allow external links to
     /// publicly reused items to redirect to the right location.
-    pub render_redirect_pages: bool,
+    crate render_redirect_pages: bool,
     /// The map used to ensure all generated 'id=' attributes are unique.
     id_map: Rc<RefCell<IdMap>>,
-    pub shared: Arc<SharedContext>,
+    crate shared: Arc<SharedContext>,
     all: Rc<RefCell<AllTypes>>,
     /// Storage for the errors produced while generating documentation so they
     /// can be printed together at the end.
-    pub errors: Rc<Receiver<String>>,
+    crate errors: Rc<Receiver<String>>,
 }
 
 crate struct SharedContext {
     /// The path to the crate root source minus the file name.
     /// Used for simplifying paths to the highlighted source code files.
-    pub src_root: PathBuf,
+    crate src_root: PathBuf,
     /// This describes the layout of each page, and is not modified after
     /// creation of the context (contains info like the favicon and added html).
-    pub layout: layout::Layout,
+    crate layout: layout::Layout,
     /// This flag indicates whether `[src]` links should be generated or not. If
     /// the source files are present in the html rendering, then this will be
     /// `true`.
-    pub include_sources: bool,
+    crate include_sources: bool,
     /// The local file sources we've emitted and their respective url-paths.
-    pub local_sources: FxHashMap<PathBuf, String>,
+    crate local_sources: FxHashMap<PathBuf, String>,
     /// Whether the collapsed pass ran
-    pub collapsed: bool,
+    crate collapsed: bool,
     /// The base-URL of the issue tracker for when an item has been tagged with
     /// an issue number.
-    pub issue_tracker_base_url: Option<String>,
+    crate issue_tracker_base_url: Option<String>,
     /// The directories that have already been created in this doc run. Used to reduce the number
     /// of spurious `create_dir_all` calls.
-    pub created_dirs: RefCell<FxHashSet<PathBuf>>,
+    crate created_dirs: RefCell<FxHashSet<PathBuf>>,
     /// This flag indicates whether listings of modules (in the side bar and documentation itself)
     /// should be ordered alphabetically or in order of appearance (in the source code).
-    pub sort_modules_alphabetically: bool,
+    crate sort_modules_alphabetically: bool,
     /// Additional CSS files to be added to the generated docs.
-    pub style_files: Vec<StylePath>,
+    crate style_files: Vec<StylePath>,
     /// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes
     /// "light-v2.css").
-    pub resource_suffix: String,
+    crate resource_suffix: String,
     /// Optional path string to be used to load static files on output pages. If not set, uses
     /// combinations of `../` to reach the documentation root.
-    pub static_root_path: Option<String>,
+    crate static_root_path: Option<String>,
     /// The fs handle we are working with.
-    pub fs: DocFS,
+    crate fs: DocFS,
     /// The default edition used to parse doctests.
-    pub edition: Edition,
-    pub codes: ErrorCodes,
+    crate edition: Edition,
+    crate codes: ErrorCodes,
     playground: Option<markdown::Playground>,
 }
 
@@ -186,7 +186,7 @@ impl SharedContext {
 
     /// Based on whether the `collapse-docs` pass was run, return either the `doc_value` or the
     /// `collapsed_doc_value` of the given item.
-    pub fn maybe_collapsed_doc_value<'a>(&self, item: &'a clean::Item) -> Option<Cow<'a, str>> {
+    crate fn maybe_collapsed_doc_value<'a>(&self, item: &'a clean::Item) -> Option<Cow<'a, str>> {
         if self.collapsed {
             item.collapsed_doc_value().map(|s| s.into())
         } else {
@@ -201,14 +201,14 @@ impl SharedContext {
 /// Struct representing one entry in the JS search index. These are all emitted
 /// by hand to a large JS file at the end of cache-creation.
 #[derive(Debug)]
-pub struct IndexItem {
-    pub ty: ItemType,
-    pub name: String,
-    pub path: String,
-    pub desc: String,
-    pub parent: Option<DefId>,
-    pub parent_idx: Option<usize>,
-    pub search_type: Option<IndexItemFunctionType>,
+crate struct IndexItem {
+    crate ty: ItemType,
+    crate name: String,
+    crate path: String,
+    crate desc: String,
+    crate parent: Option<DefId>,
+    crate parent_idx: Option<usize>,
+    crate search_type: Option<IndexItemFunctionType>,
 }
 
 impl Serialize for IndexItem {
@@ -282,7 +282,7 @@ impl Serialize for Generic {
 
 /// Full type of functions/methods in the search index.
 #[derive(Debug)]
-pub struct IndexItemFunctionType {
+crate struct IndexItemFunctionType {
     inputs: Vec<TypeWithKind>,
     output: Option<Vec<TypeWithKind>>,
 }
@@ -340,16 +340,16 @@ impl Serialize for TypeWithKind {
 }
 
 #[derive(Debug, Clone)]
-pub struct StylePath {
+crate struct StylePath {
     /// The path to the theme
-    pub path: PathBuf,
+    crate path: PathBuf,
     /// What the `disabled` attribute should be set to in the HTML tag
-    pub disabled: bool,
+    crate disabled: bool,
 }
 
-thread_local!(pub static CURRENT_DEPTH: Cell<usize> = Cell::new(0));
+thread_local!(crate static CURRENT_DEPTH: Cell<usize> = Cell::new(0));
 
-pub fn initial_ids() -> Vec<String> {
+crate fn initial_ids() -> Vec<String> {
     [
         "main",
         "search",
@@ -1701,7 +1701,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache)
 
     // Write `src` tag
     //
-    // When this item is part of a `pub use` in a downstream crate, the
+    // When this item is part of a `crate use` in a downstream crate, the
     // [src] link in the downstream documentation will actually come back to
     // this page, and this link will be auto-clicked. The `id` attribute is
     // used to find the link to auto-click.
@@ -1994,7 +1994,7 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) {
 }
 
 /// Compare two strings treating multi-digit numbers as single units (i.e. natural sort order).
-pub fn compare_names(mut lhs: &str, mut rhs: &str) -> Ordering {
+crate fn compare_names(mut lhs: &str, mut rhs: &str) -> Ordering {
     /// Takes a non-numeric and a numeric part from the given &str.
     fn take_parts<'a>(s: &mut &'a str) -> (&'a str, &'a str) {
         let i = s.find(|c: char| c.is_ascii_digit());
@@ -2081,14 +2081,14 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
     // This call is to remove re-export duplicates in cases such as:
     //
     // ```
-    // pub mod foo {
-    //     pub mod bar {
-    //         pub trait Double { fn foo(); }
+    // crate mod foo {
+    //     crate mod bar {
+    //         crate trait Double { fn foo(); }
     //     }
     // }
     //
-    // pub use foo::bar::*;
-    // pub use foo::*;
+    // crate use foo::bar::*;
+    // crate use foo::*;
     // ```
     //
     // `Double` will appear twice in the generated docs.
@@ -2251,6 +2251,22 @@ fn stability_tags(item: &clean::Item, parent: &clean::Item) -> String {
     tags
 }
 
+fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<String> {
+    let cfg = match (&item.attrs.cfg, parent.and_then(|p| p.attrs.cfg.as_ref())) {
+        (Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
+        (cfg, _) => cfg.as_deref().cloned(),
+    };
+
+    debug!(
+        "Portability {:?} - {:?} = {:?}",
+        item.attrs.cfg,
+        parent.and_then(|p| p.attrs.cfg.as_ref()),
+        cfg
+    );
+
+    Some(format!("<div class=\"stab portability\">{}</div>", cfg?.render_long_html()))
+}
+
 /// Render the stability and/or deprecation warning that is displayed at the top of the item's
 /// documentation.
 fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item>) -> Vec<String> {
@@ -2328,19 +2344,8 @@ fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
         stability.push(format!("<div class=\"stab unstable\">{}</div>", message));
     }
 
-    let cfg = match (&item.attrs.cfg, parent.and_then(|p| p.attrs.cfg.as_ref())) {
-        (Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
-        (cfg, _) => cfg.as_deref().cloned(),
-    };
-
-    debug!(
-        "Portability {:?} - {:?} = {:?}",
-        item.attrs.cfg,
-        parent.and_then(|p| p.attrs.cfg.as_ref()),
-        cfg
-    );
-    if let Some(cfg) = cfg {
-        stability.push(format!("<div class=\"stab portability\">{}</div>", cfg.render_long_html()));
+    if let Some(portability) = portability(item, parent) {
+        stability.push(portability);
     }
 
     stability
@@ -2431,6 +2436,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
 fn render_implementor(
     cx: &Context,
     implementor: &Impl,
+    parent: &clean::Item,
     w: &mut Buffer,
     implementor_dups: &FxHashMap<&str, (DefId, bool)>,
     aliases: &[String],
@@ -2450,7 +2456,7 @@ fn render_implementor(
         w,
         cx,
         implementor,
-        None,
+        parent,
         AssocItemLink::Anchor(None),
         RenderMode::Normal,
         implementor.impl_item.stable_since().as_deref(),
@@ -2480,7 +2486,7 @@ fn render_impls(
                 &mut buffer,
                 cx,
                 i,
-                Some(containing_item),
+                containing_item,
                 assoc_link,
                 RenderMode::Normal,
                 containing_item.stable_since().as_deref(),
@@ -2727,7 +2733,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                     w,
                     cx,
                     &implementor,
-                    None,
+                    it,
                     assoc_link,
                     RenderMode::Normal,
                     implementor.impl_item.stable_since().as_deref(),
@@ -2749,7 +2755,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
             "<div class=\"item-list\" id=\"implementors-list\">",
         );
         for implementor in concrete {
-            render_implementor(cx, implementor, w, &implementor_dups, &[], cache);
+            render_implementor(cx, implementor, it, w, &implementor_dups, &[], cache);
         }
         write_loading_content(w, "</div>");
 
@@ -2764,6 +2770,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                 render_implementor(
                     cx,
                     implementor,
+                    it,
                     w,
                     &implementor_dups,
                     &collect_paths_for_type(implementor.inner_impl().for_.clone()),
@@ -3430,7 +3437,7 @@ fn render_assoc_items(
                 w,
                 cx,
                 i,
-                Some(containing_item),
+                containing_item,
                 AssocItemLink::Anchor(None),
                 render_mode,
                 containing_item.stable_since().as_deref(),
@@ -3622,7 +3629,7 @@ fn render_impl(
     w: &mut Buffer,
     cx: &Context,
     i: &Impl,
-    parent: Option<&clean::Item>,
+    parent: &clean::Item,
     link: AssocItemLink<'_>,
     render_mode: RenderMode,
     outer_version: Option<&str>,
@@ -3635,6 +3642,9 @@ fn render_impl(
     aliases: &[String],
     cache: &Cache,
 ) {
+    let traits = &cache.traits;
+    let trait_ = i.trait_did().map(|did| &traits[&did]);
+
     if render_mode == RenderMode::Normal {
         let id = cx.derive_id(match i.inner_impl().trait_ {
             Some(ref t) => {
@@ -3687,6 +3697,13 @@ fn render_impl(
             );
         }
         write!(w, "</h3>");
+
+        if trait_.is_some() {
+            if let Some(portability) = portability(&i.impl_item, Some(parent)) {
+                write!(w, "<div class=\"stability\">{}</div>", portability);
+            }
+        }
+
         if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
             let mut ids = cx.id_map.borrow_mut();
             write!(
@@ -3709,7 +3726,7 @@ fn render_impl(
         w: &mut Buffer,
         cx: &Context,
         item: &clean::Item,
-        parent: Option<&clean::Item>,
+        parent: &clean::Item,
         link: AssocItemLink<'_>,
         render_mode: RenderMode,
         is_default_item: bool,
@@ -3794,7 +3811,7 @@ fn render_impl(
                     if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
                         // We need the stability of the item from the trait
                         // because impls can't have a stability.
-                        document_stability(w, cx, it, is_hidden, parent);
+                        document_stability(w, cx, it, is_hidden, Some(parent));
                         if item.doc_value().is_some() {
                             document_full(w, item, cx, "", is_hidden);
                         } else if show_def_docs {
@@ -3804,13 +3821,13 @@ fn render_impl(
                         }
                     }
                 } else {
-                    document_stability(w, cx, item, is_hidden, parent);
+                    document_stability(w, cx, item, is_hidden, Some(parent));
                     if show_def_docs {
                         document_full(w, item, cx, "", is_hidden);
                     }
                 }
             } else {
-                document_stability(w, cx, item, is_hidden, parent);
+                document_stability(w, cx, item, is_hidden, Some(parent));
                 if show_def_docs {
                     document_short(w, item, link, "", is_hidden);
                 }
@@ -3818,16 +3835,13 @@ fn render_impl(
         }
     }
 
-    let traits = &cache.traits;
-    let trait_ = i.trait_did().map(|did| &traits[&did]);
-
     write!(w, "<div class=\"impl-items\">");
     for trait_item in &i.inner_impl().items {
         doc_impl_item(
             w,
             cx,
             trait_item,
-            parent,
+            if trait_.is_some() { &i.impl_item } else { parent },
             link,
             render_mode,
             false,
@@ -3843,7 +3857,7 @@ fn render_impl(
         cx: &Context,
         t: &clean::Trait,
         i: &clean::Impl,
-        parent: Option<&clean::Item>,
+        parent: &clean::Item,
         render_mode: RenderMode,
         outer_version: Option<&str>,
         show_def_docs: bool,
@@ -3884,7 +3898,7 @@ fn render_impl(
                 cx,
                 t,
                 &i.inner_impl(),
-                parent,
+                &i.impl_item,
                 render_mode,
                 outer_version,
                 show_def_docs,
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index b487b399521..0f82649409f 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -137,7 +137,7 @@ impl<'a> SourceCollector<'a> {
 /// static HTML tree. Each component in the cleaned path will be passed as an
 /// argument to `f`. The very last component of the path (ie the file name) will
 /// be passed to `f` if `keep_filename` is true, and ignored otherwise.
-pub fn clean_path<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F)
+crate fn clean_path<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F)
 where
     F: FnMut(&OsStr),
 {
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index cbf15cd0b6e..b8377dc1569 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2439,12 +2439,13 @@ function defocusSearchBar() {
 
         var func = function(e) {
             var next = e.nextElementSibling;
+            if (next && hasClass(next, "stability")) {
+              next = next.nextElementSibling;
+            }
             if (!next) {
                 return;
             }
-            if (hasClass(next, "docblock") === true ||
-                (hasClass(next, "stability") === true &&
-                 hasClass(next.nextElementSibling, "docblock") === true)) {
+            if (hasClass(next, "docblock")) {
                 var newToggle = toggle.cloneNode(true);
                 insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
                 if (hideMethodDocs === true && hasClass(e, "method") === true) {
@@ -2455,6 +2456,9 @@ function defocusSearchBar() {
 
         var funcImpl = function(e) {
             var next = e.nextElementSibling;
+            if (next && hasClass(next, "stability")) {
+                next = next.nextElementSibling;
+            }
             if (next && hasClass(next, "docblock")) {
                 next = next.nextElementSibling;
             }
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index 213c7f3aab8..132ac42c422 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -8,111 +8,111 @@
 //! directly written to a `Write` handle.
 
 /// The file contents of the main `rustdoc.css` file, responsible for the core layout of the page.
-pub static RUSTDOC_CSS: &str = include_str!("static/rustdoc.css");
+crate static RUSTDOC_CSS: &str = include_str!("static/rustdoc.css");
 
 /// The file contents of `settings.css`, responsible for the items on the settings page.
-pub static SETTINGS_CSS: &str = include_str!("static/settings.css");
+crate static SETTINGS_CSS: &str = include_str!("static/settings.css");
 
 /// The file contents of the `noscript.css` file, used in case JS isn't supported or is disabled.
-pub static NOSCRIPT_CSS: &str = include_str!("static/noscript.css");
+crate static NOSCRIPT_CSS: &str = include_str!("static/noscript.css");
 
 /// The file contents of `normalize.css`, included to even out standard elements between browser
 /// implementations.
-pub static NORMALIZE_CSS: &str = include_str!("static/normalize.css");
+crate static NORMALIZE_CSS: &str = include_str!("static/normalize.css");
 
 /// The file contents of `main.js`, which contains the core JavaScript used on documentation pages,
 /// including search behavior and docblock folding, among others.
-pub static MAIN_JS: &str = include_str!("static/main.js");
+crate static MAIN_JS: &str = include_str!("static/main.js");
 
 /// The file contents of `settings.js`, which contains the JavaScript used to handle the settings
 /// page.
-pub static SETTINGS_JS: &str = include_str!("static/settings.js");
+crate static SETTINGS_JS: &str = include_str!("static/settings.js");
 
 /// The file contents of `storage.js`, which contains functionality related to browser Local
 /// Storage, used to store documentation settings.
-pub static STORAGE_JS: &str = include_str!("static/storage.js");
+crate static STORAGE_JS: &str = include_str!("static/storage.js");
 
 /// The file contents of `brush.svg`, the icon used for the theme-switch button.
-pub static BRUSH_SVG: &[u8] = include_bytes!("static/brush.svg");
+crate static BRUSH_SVG: &[u8] = include_bytes!("static/brush.svg");
 
 /// The file contents of `wheel.svg`, the icon used for the settings button.
-pub static WHEEL_SVG: &[u8] = include_bytes!("static/wheel.svg");
+crate static WHEEL_SVG: &[u8] = include_bytes!("static/wheel.svg");
 
 /// The file contents of `down-arrow.svg`, the icon used for the crate choice combobox.
-pub static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/down-arrow.svg");
+crate static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/down-arrow.svg");
 
 /// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation
 /// output.
-pub static COPYRIGHT: &[u8] = include_bytes!("static/COPYRIGHT.txt");
+crate static COPYRIGHT: &[u8] = include_bytes!("static/COPYRIGHT.txt");
 
 /// The contents of `LICENSE-APACHE.txt`, the text of the Apache License, version 2.0.
-pub static LICENSE_APACHE: &[u8] = include_bytes!("static/LICENSE-APACHE.txt");
+crate static LICENSE_APACHE: &[u8] = include_bytes!("static/LICENSE-APACHE.txt");
 
 /// The contents of `LICENSE-MIT.txt`, the text of the MIT License.
-pub static LICENSE_MIT: &[u8] = include_bytes!("static/LICENSE-MIT.txt");
+crate static LICENSE_MIT: &[u8] = include_bytes!("static/LICENSE-MIT.txt");
 
 /// The contents of `rust-logo.png`, the default icon of the documentation.
-pub static RUST_LOGO: &[u8] = include_bytes!("static/rust-logo.png");
+crate static RUST_LOGO: &[u8] = include_bytes!("static/rust-logo.png");
 /// The default documentation favicons (SVG and PNG fallbacks)
-pub static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/favicon.svg");
-pub static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/favicon-16x16.png");
-pub static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/favicon-32x32.png");
+crate static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/favicon.svg");
+crate static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/favicon-16x16.png");
+crate static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/favicon-32x32.png");
 
 /// The built-in themes given to every documentation site.
-pub mod themes {
+crate mod themes {
     /// The "light" theme, selected by default when no setting is available. Used as the basis for
     /// the `--check-theme` functionality.
-    pub static LIGHT: &str = include_str!("static/themes/light.css");
+    crate static LIGHT: &str = include_str!("static/themes/light.css");
 
     /// The "dark" theme.
-    pub static DARK: &str = include_str!("static/themes/dark.css");
+    crate static DARK: &str = include_str!("static/themes/dark.css");
 
     /// The "ayu" theme.
-    pub static AYU: &str = include_str!("static/themes/ayu.css");
+    crate static AYU: &str = include_str!("static/themes/ayu.css");
 }
 
 /// Files related to the Fira Sans font.
-pub mod fira_sans {
+crate mod fira_sans {
     /// The file `FiraSans-Regular.woff`, the Regular variant of the Fira Sans font.
-    pub static REGULAR: &[u8] = include_bytes!("static/FiraSans-Regular.woff");
+    crate static REGULAR: &[u8] = include_bytes!("static/FiraSans-Regular.woff");
 
     /// The file `FiraSans-Medium.woff`, the Medium variant of the Fira Sans font.
-    pub static MEDIUM: &[u8] = include_bytes!("static/FiraSans-Medium.woff");
+    crate static MEDIUM: &[u8] = include_bytes!("static/FiraSans-Medium.woff");
 
     /// The file `FiraSans-LICENSE.txt`, the license text for the Fira Sans font.
-    pub static LICENSE: &[u8] = include_bytes!("static/FiraSans-LICENSE.txt");
+    crate static LICENSE: &[u8] = include_bytes!("static/FiraSans-LICENSE.txt");
 }
 
 /// Files related to the Source Serif Pro font.
-pub mod source_serif_pro {
+crate mod source_serif_pro {
     /// The file `SourceSerifPro-Regular.ttf.woff`, the Regular variant of the Source Serif Pro
     /// font.
-    pub static REGULAR: &[u8] = include_bytes!("static/SourceSerifPro-Regular.ttf.woff");
+    crate static REGULAR: &[u8] = include_bytes!("static/SourceSerifPro-Regular.ttf.woff");
 
     /// The file `SourceSerifPro-Bold.ttf.woff`, the Bold variant of the Source Serif Pro font.
-    pub static BOLD: &[u8] = include_bytes!("static/SourceSerifPro-Bold.ttf.woff");
+    crate static BOLD: &[u8] = include_bytes!("static/SourceSerifPro-Bold.ttf.woff");
 
     /// The file `SourceSerifPro-It.ttf.woff`, the Italic variant of the Source Serif Pro font.
-    pub static ITALIC: &[u8] = include_bytes!("static/SourceSerifPro-It.ttf.woff");
+    crate static ITALIC: &[u8] = include_bytes!("static/SourceSerifPro-It.ttf.woff");
 
     /// The file `SourceSerifPro-LICENSE.txt`, the license text for the Source Serif Pro font.
-    pub static LICENSE: &[u8] = include_bytes!("static/SourceSerifPro-LICENSE.md");
+    crate static LICENSE: &[u8] = include_bytes!("static/SourceSerifPro-LICENSE.md");
 }
 
 /// Files related to the Source Code Pro font.
-pub mod source_code_pro {
+crate mod source_code_pro {
     /// The file `SourceCodePro-Regular.woff`, the Regular variant of the Source Code Pro font.
-    pub static REGULAR: &[u8] = include_bytes!("static/SourceCodePro-Regular.woff");
+    crate static REGULAR: &[u8] = include_bytes!("static/SourceCodePro-Regular.woff");
 
     /// The file `SourceCodePro-Semibold.woff`, the Semibold variant of the Source Code Pro font.
-    pub static SEMIBOLD: &[u8] = include_bytes!("static/SourceCodePro-Semibold.woff");
+    crate static SEMIBOLD: &[u8] = include_bytes!("static/SourceCodePro-Semibold.woff");
 
     /// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font.
-    pub static LICENSE: &[u8] = include_bytes!("static/SourceCodePro-LICENSE.txt");
+    crate static LICENSE: &[u8] = include_bytes!("static/SourceCodePro-LICENSE.txt");
 }
 
 /// Files related to the sidebar in rustdoc sources.
-pub mod sidebar {
+crate mod sidebar {
     /// File script to handle sidebar.
-    pub static SOURCE_SCRIPT: &str = include_str!("static/source-script.js");
+    crate static SOURCE_SCRIPT: &str = include_str!("static/source-script.js");
 }
diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs
index 721988e29a6..b39a4e179cd 100644
--- a/src/librustdoc/html/toc.rs
+++ b/src/librustdoc/html/toc.rs
@@ -2,7 +2,7 @@
 
 /// A (recursive) table of contents
 #[derive(Debug, PartialEq)]
-pub struct Toc {
+crate struct Toc {
     /// The levels are strictly decreasing, i.e.
     ///
     /// `entries[0].level >= entries[1].level >= ...`
@@ -26,7 +26,7 @@ impl Toc {
 }
 
 #[derive(Debug, PartialEq)]
-pub struct TocEntry {
+crate struct TocEntry {
     level: u32,
     sec_number: String,
     name: String,
@@ -36,7 +36,7 @@ pub struct TocEntry {
 
 /// Progressive construction of a table of contents.
 #[derive(PartialEq)]
-pub struct TocBuilder {
+crate struct TocBuilder {
     top_level: Toc,
     /// The current hierarchy of parent headings, the levels are
     /// strictly increasing (i.e., `chain[0].level < chain[1].level <
@@ -50,12 +50,12 @@ pub struct TocBuilder {
 }
 
 impl TocBuilder {
-    pub fn new() -> TocBuilder {
+    crate fn new() -> TocBuilder {
         TocBuilder { top_level: Toc { entries: Vec::new() }, chain: Vec::new() }
     }
 
     /// Converts into a true `Toc` struct.
-    pub fn into_toc(mut self) -> Toc {
+    crate fn into_toc(mut self) -> Toc {
         // we know all levels are >= 1.
         self.fold_until(0);
         self.top_level
@@ -115,7 +115,7 @@ impl TocBuilder {
     /// Push a level `level` heading into the appropriate place in the
     /// hierarchy, returning a string containing the section number in
     /// `<num>.<num>.<num>` format.
-    pub fn push(&mut self, level: u32, name: String, id: String) -> &str {
+    crate fn push(&mut self, level: u32, name: String, id: String) -> &str {
         assert!(level >= 1);
 
         // collapse all previous sections into their parents until we
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 14f87ec2aa9..5eb1f7b1f77 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -7,7 +7,7 @@ use crate::formats::FormatRenderer;
 use rustc_span::edition::Edition;
 
 #[derive(Clone)]
-pub struct JsonRenderer {}
+crate struct JsonRenderer {}
 
 impl FormatRenderer for JsonRenderer {
     fn init(
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 33bd57223b8..963f2cf71f3 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -32,7 +32,7 @@ fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) {
 
 /// Render `input` (e.g., "foo.md") into an HTML file in `output`
 /// (e.g., output = "bar" => "bar/foo.html").
-pub fn render<P: AsRef<Path>>(
+crate fn render<P: AsRef<Path>>(
     input: P,
     options: RenderOptions,
     edition: Edition,
@@ -114,7 +114,7 @@ pub fn render<P: AsRef<Path>>(
 }
 
 /// Runs any tests/code examples in the markdown file `input`.
-pub fn test(mut options: Options) -> Result<(), String> {
+crate fn test(mut options: Options) -> Result<(), String> {
     let input_str = read_to_string(&options.input)
         .map_err(|err| format!("{}: {}", options.input.display(), err))?;
     let mut opts = TestOptions::default();
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index ef68bae1078..aca218e5381 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -14,7 +14,7 @@ use serde::Serialize;
 use std::collections::BTreeMap;
 use std::ops;
 
-pub const CALCULATE_DOC_COVERAGE: Pass = Pass {
+crate const CALCULATE_DOC_COVERAGE: Pass = Pass {
     name: "calculate-doc-coverage",
     run: calculate_doc_coverage,
     description: "counts the number of items with and without documentation",
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index beb1f13ca6f..a48fa738e3b 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -11,13 +11,13 @@ use crate::fold::DocFolder;
 use crate::html::markdown::{self, RustCodeBlock};
 use crate::passes::{span_of_attrs, Pass};
 
-pub const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass {
+crate const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass {
     name: "check-code-block-syntax",
     run: check_code_block_syntax,
     description: "validates syntax inside Rust code blocks",
 };
 
-pub fn check_code_block_syntax(krate: clean::Crate, cx: &DocContext<'_>) -> clean::Crate {
+crate fn check_code_block_syntax(krate: clean::Crate, cx: &DocContext<'_>) -> clean::Crate {
     SyntaxChecker { cx }.fold_crate(krate)
 }
 
diff --git a/src/librustdoc/passes/collapse_docs.rs b/src/librustdoc/passes/collapse_docs.rs
index c2f7f97a673..1f9f5c58e5a 100644
--- a/src/librustdoc/passes/collapse_docs.rs
+++ b/src/librustdoc/passes/collapse_docs.rs
@@ -6,13 +6,13 @@ use crate::passes::Pass;
 
 use std::mem::take;
 
-pub const COLLAPSE_DOCS: Pass = Pass {
+crate const COLLAPSE_DOCS: Pass = Pass {
     name: "collapse-docs",
     run: collapse_docs,
     description: "concatenates all document attributes into one document attribute",
 };
 
-pub fn collapse_docs(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
+crate fn collapse_docs(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
     let mut krate = Collapser.fold_crate(krate);
     krate.collapsed = true;
     krate
@@ -66,7 +66,7 @@ fn collapse(doc_strings: &mut Vec<DocFragment>) {
 }
 
 impl clean::Attributes {
-    pub fn collapse_doc_comments(&mut self) {
+    crate fn collapse_doc_comments(&mut self) {
         collapse(&mut self.doc_strings);
     }
 }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index fd0dd339abd..895414b1d7e 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -39,13 +39,13 @@ use crate::passes::Pass;
 
 use super::span_of_attrs;
 
-pub const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
+crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
     name: "collect-intra-doc-links",
     run: collect_intra_doc_links,
     description: "reads a crate's documentation to resolve intra-doc-links",
 };
 
-pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate {
+crate fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate {
     LinkCollector::new(cx).fold_crate(krate)
 }
 
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 81de0730247..2946db1f462 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -7,13 +7,13 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_span::symbol::sym;
 
-pub const COLLECT_TRAIT_IMPLS: Pass = Pass {
+crate const COLLECT_TRAIT_IMPLS: Pass = Pass {
     name: "collect-trait-impls",
     run: collect_trait_impls,
     description: "retrieves trait impls for items in the crate",
 };
 
-pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
+crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
     let mut synth = SyntheticImplCollector::new(cx);
     let mut krate = synth.fold_crate(krate);
 
diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs
index 094f85f2ccb..60fe8080f56 100644
--- a/src/librustdoc/passes/doc_test_lints.rs
+++ b/src/librustdoc/passes/doc_test_lints.rs
@@ -12,7 +12,7 @@ use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString};
 use rustc_middle::lint::LintSource;
 use rustc_session::lint;
 
-pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
+crate const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
     name: "check-private-items-doc-tests",
     run: check_private_items_doc_tests,
     description: "check private items doc tests",
@@ -28,7 +28,7 @@ impl<'a, 'tcx> PrivateItemDocTestLinter<'a, 'tcx> {
     }
 }
 
-pub fn check_private_items_doc_tests(krate: Crate, cx: &DocContext<'_>) -> Crate {
+crate fn check_private_items_doc_tests(krate: Crate, cx: &DocContext<'_>) -> Crate {
     let mut coll = PrivateItemDocTestLinter::new(cx);
 
     coll.fold_crate(krate)
@@ -57,7 +57,7 @@ impl crate::doctest::Tester for Tests {
     }
 }
 
-pub fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
+crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
     if matches!(item.kind,
         clean::StructFieldItem(_)
         | clean::VariantItem(_)
@@ -79,7 +79,7 @@ pub fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool
     level != lint::Level::Allow || matches!(source, LintSource::Default)
 }
 
-pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
+crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
     let hir_id = match cx.as_local_hir_id(item.def_id) {
         Some(hir_id) => hir_id,
         None => {
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index 26b64b4905e..01efd07cbcd 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -9,7 +9,7 @@ use rustc_session::lint;
 use std::iter::Peekable;
 use std::str::CharIndices;
 
-pub const CHECK_INVALID_HTML_TAGS: Pass = Pass {
+crate const CHECK_INVALID_HTML_TAGS: Pass = Pass {
     name: "check-invalid-html-tags",
     run: check_invalid_html_tags,
     description: "detects invalid HTML tags in doc comments",
@@ -25,7 +25,7 @@ impl<'a, 'tcx> InvalidHtmlTagsLinter<'a, 'tcx> {
     }
 }
 
-pub fn check_invalid_html_tags(krate: Crate, cx: &DocContext<'_>) -> Crate {
+crate fn check_invalid_html_tags(krate: Crate, cx: &DocContext<'_>) -> Crate {
     if !cx.tcx.sess.is_nightly_build() {
         krate
     } else {
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 047a73835c8..51818d7faf0 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -9,67 +9,67 @@ use crate::clean::{self, DocFragmentKind};
 use crate::core::DocContext;
 
 mod stripper;
-pub use stripper::*;
+crate use stripper::*;
 
 mod non_autolinks;
-pub use self::non_autolinks::CHECK_NON_AUTOLINKS;
+crate use self::non_autolinks::CHECK_NON_AUTOLINKS;
 
 mod collapse_docs;
-pub use self::collapse_docs::COLLAPSE_DOCS;
+crate use self::collapse_docs::COLLAPSE_DOCS;
 
 mod strip_hidden;
-pub use self::strip_hidden::STRIP_HIDDEN;
+crate use self::strip_hidden::STRIP_HIDDEN;
 
 mod strip_private;
-pub use self::strip_private::STRIP_PRIVATE;
+crate use self::strip_private::STRIP_PRIVATE;
 
 mod strip_priv_imports;
-pub use self::strip_priv_imports::STRIP_PRIV_IMPORTS;
+crate use self::strip_priv_imports::STRIP_PRIV_IMPORTS;
 
 mod unindent_comments;
-pub use self::unindent_comments::UNINDENT_COMMENTS;
+crate use self::unindent_comments::UNINDENT_COMMENTS;
 
 mod propagate_doc_cfg;
-pub use self::propagate_doc_cfg::PROPAGATE_DOC_CFG;
+crate use self::propagate_doc_cfg::PROPAGATE_DOC_CFG;
 
 mod collect_intra_doc_links;
-pub use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS;
+crate use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS;
 
 mod doc_test_lints;
-pub use self::doc_test_lints::CHECK_PRIVATE_ITEMS_DOC_TESTS;
+crate use self::doc_test_lints::CHECK_PRIVATE_ITEMS_DOC_TESTS;
 
 mod collect_trait_impls;
-pub use self::collect_trait_impls::COLLECT_TRAIT_IMPLS;
+crate use self::collect_trait_impls::COLLECT_TRAIT_IMPLS;
 
 mod check_code_block_syntax;
-pub use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX;
+crate use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX;
 
 mod calculate_doc_coverage;
-pub use self::calculate_doc_coverage::CALCULATE_DOC_COVERAGE;
+crate use self::calculate_doc_coverage::CALCULATE_DOC_COVERAGE;
 
 mod html_tags;
-pub use self::html_tags::CHECK_INVALID_HTML_TAGS;
+crate use self::html_tags::CHECK_INVALID_HTML_TAGS;
 
 /// A single pass over the cleaned documentation.
 ///
 /// Runs in the compiler context, so it has access to types and traits and the like.
 #[derive(Copy, Clone)]
-pub struct Pass {
-    pub name: &'static str,
-    pub run: fn(clean::Crate, &DocContext<'_>) -> clean::Crate,
-    pub description: &'static str,
+crate struct Pass {
+    crate name: &'static str,
+    crate run: fn(clean::Crate, &DocContext<'_>) -> clean::Crate,
+    crate description: &'static str,
 }
 
 /// In a list of passes, a pass that may or may not need to be run depending on options.
 #[derive(Copy, Clone)]
-pub struct ConditionalPass {
-    pub pass: Pass,
-    pub condition: Condition,
+crate struct ConditionalPass {
+    crate pass: Pass,
+    crate condition: Condition,
 }
 
 /// How to decide whether to run a conditional pass.
 #[derive(Copy, Clone)]
-pub enum Condition {
+crate enum Condition {
     Always,
     /// When `--document-private-items` is passed.
     WhenDocumentPrivate,
@@ -80,7 +80,7 @@ pub enum Condition {
 }
 
 /// The full list of passes.
-pub const PASSES: &[Pass] = &[
+crate const PASSES: &[Pass] = &[
     CHECK_PRIVATE_ITEMS_DOC_TESTS,
     STRIP_HIDDEN,
     UNINDENT_COMMENTS,
@@ -97,7 +97,7 @@ pub const PASSES: &[Pass] = &[
 ];
 
 /// The list of passes run by default.
-pub const DEFAULT_PASSES: &[ConditionalPass] = &[
+crate const DEFAULT_PASSES: &[ConditionalPass] = &[
     ConditionalPass::always(COLLECT_TRAIT_IMPLS),
     ConditionalPass::always(COLLAPSE_DOCS),
     ConditionalPass::always(UNINDENT_COMMENTS),
@@ -113,7 +113,7 @@ pub const DEFAULT_PASSES: &[ConditionalPass] = &[
 ];
 
 /// The list of default passes run when `--doc-coverage` is passed to rustdoc.
-pub const COVERAGE_PASSES: &[ConditionalPass] = &[
+crate const COVERAGE_PASSES: &[ConditionalPass] = &[
     ConditionalPass::always(COLLECT_TRAIT_IMPLS),
     ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden),
     ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate),
@@ -121,11 +121,11 @@ pub const COVERAGE_PASSES: &[ConditionalPass] = &[
 ];
 
 impl ConditionalPass {
-    pub const fn always(pass: Pass) -> Self {
+    crate const fn always(pass: Pass) -> Self {
         Self::new(pass, Always)
     }
 
-    pub const fn new(pass: Pass, condition: Condition) -> Self {
+    crate const fn new(pass: Pass, condition: Condition) -> Self {
         ConditionalPass { pass, condition }
     }
 }
@@ -133,14 +133,14 @@ impl ConditionalPass {
 /// A shorthand way to refer to which set of passes to use, based on the presence of
 /// `--no-defaults` and `--show-coverage`.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub enum DefaultPassOption {
+crate enum DefaultPassOption {
     Default,
     Coverage,
     None,
 }
 
 /// Returns the given default set of passes.
-pub fn defaults(default_set: DefaultPassOption) -> &'static [ConditionalPass] {
+crate fn defaults(default_set: DefaultPassOption) -> &'static [ConditionalPass] {
     match default_set {
         DefaultPassOption::Default => DEFAULT_PASSES,
         DefaultPassOption::Coverage => COVERAGE_PASSES,
@@ -149,7 +149,7 @@ pub fn defaults(default_set: DefaultPassOption) -> &'static [ConditionalPass] {
 }
 
 /// If the given name matches a known pass, returns its information.
-pub fn find_pass(pass_name: &str) -> Option<Pass> {
+crate fn find_pass(pass_name: &str) -> Option<Pass> {
     PASSES.iter().find(|p| p.name == pass_name).copied()
 }
 
diff --git a/src/librustdoc/passes/non_autolinks.rs b/src/librustdoc/passes/non_autolinks.rs
index 964773dc055..c9c49968b93 100644
--- a/src/librustdoc/passes/non_autolinks.rs
+++ b/src/librustdoc/passes/non_autolinks.rs
@@ -9,7 +9,7 @@ use regex::Regex;
 use rustc_errors::Applicability;
 use rustc_session::lint;
 
-pub const CHECK_NON_AUTOLINKS: Pass = Pass {
+crate const CHECK_NON_AUTOLINKS: Pass = Pass {
     name: "check-non-autolinks",
     run: check_non_autolinks,
     description: "detects URLS that could be written using angle brackets",
@@ -52,7 +52,7 @@ impl<'a, 'tcx> NonAutolinksLinter<'a, 'tcx> {
     }
 }
 
-pub fn check_non_autolinks(krate: Crate, cx: &DocContext<'_>) -> Crate {
+crate fn check_non_autolinks(krate: Crate, cx: &DocContext<'_>) -> Crate {
     if !cx.tcx.sess.is_nightly_build() {
         krate
     } else {
diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs
index 64b0c45ba65..fbfc693c534 100644
--- a/src/librustdoc/passes/propagate_doc_cfg.rs
+++ b/src/librustdoc/passes/propagate_doc_cfg.rs
@@ -6,13 +6,13 @@ use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::passes::Pass;
 
-pub const PROPAGATE_DOC_CFG: Pass = Pass {
+crate const PROPAGATE_DOC_CFG: Pass = Pass {
     name: "propagate-doc-cfg",
     run: propagate_doc_cfg,
     description: "propagates `#[doc(cfg(...))]` to child items",
 };
 
-pub fn propagate_doc_cfg(cr: Crate, _: &DocContext<'_>) -> Crate {
+crate fn propagate_doc_cfg(cr: Crate, _: &DocContext<'_>) -> Crate {
     CfgPropagator { parent_cfg: None }.fold_crate(cr)
 }
 
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index 4b9e150eb1e..6da753ea6e6 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -8,14 +8,14 @@ use crate::core::DocContext;
 use crate::fold::{DocFolder, StripItem};
 use crate::passes::{ImplStripper, Pass};
 
-pub const STRIP_HIDDEN: Pass = Pass {
+crate const STRIP_HIDDEN: Pass = Pass {
     name: "strip-hidden",
     run: strip_hidden,
     description: "strips all doc(hidden) items from the output",
 };
 
 /// Strip items marked `#[doc(hidden)]`
-pub fn strip_hidden(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
+crate fn strip_hidden(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
     let mut retained = DefIdSet::default();
 
     // strip all #[doc(hidden)] items
diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs
index 35b26fb8ab0..6eeaabacbc1 100644
--- a/src/librustdoc/passes/strip_priv_imports.rs
+++ b/src/librustdoc/passes/strip_priv_imports.rs
@@ -3,12 +3,12 @@ use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::passes::{ImportStripper, Pass};
 
-pub const STRIP_PRIV_IMPORTS: Pass = Pass {
+crate const STRIP_PRIV_IMPORTS: Pass = Pass {
     name: "strip-priv-imports",
     run: strip_priv_imports,
     description: "strips all private import statements (`use`, `extern crate`) from a crate",
 };
 
-pub fn strip_priv_imports(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
+crate fn strip_priv_imports(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
     ImportStripper.fold_crate(krate)
 }
diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs
index 9173d8e9605..e812bcd87fe 100644
--- a/src/librustdoc/passes/strip_private.rs
+++ b/src/librustdoc/passes/strip_private.rs
@@ -5,7 +5,7 @@ use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::passes::{ImplStripper, ImportStripper, Pass, Stripper};
 
-pub const STRIP_PRIVATE: Pass = Pass {
+crate const STRIP_PRIVATE: Pass = Pass {
     name: "strip-private",
     run: strip_private,
     description: "strips all private items from a crate which cannot be seen externally, \
@@ -14,7 +14,7 @@ pub const STRIP_PRIVATE: Pass = Pass {
 
 /// Strip private items from the point of view of a crate or externally from a
 /// crate, specified by the `xcrate` flag.
-pub fn strip_private(mut krate: clean::Crate, cx: &DocContext<'_>) -> clean::Crate {
+crate fn strip_private(mut krate: clean::Crate, cx: &DocContext<'_>) -> clean::Crate {
     // This stripper collects all *retained* nodes.
     let mut retained = DefIdSet::default();
     let access_levels = cx.renderinfo.borrow().access_levels.clone();
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 4250c2b48fc..3a10142adcf 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -5,10 +5,10 @@ use std::mem;
 use crate::clean::{self, GetDefId, Item};
 use crate::fold::{DocFolder, StripItem};
 
-pub struct Stripper<'a> {
-    pub retained: &'a mut DefIdSet,
-    pub access_levels: &'a AccessLevels<DefId>,
-    pub update_retained: bool,
+crate struct Stripper<'a> {
+    crate retained: &'a mut DefIdSet,
+    crate access_levels: &'a AccessLevels<DefId>,
+    crate update_retained: bool,
 }
 
 impl<'a> DocFolder for Stripper<'a> {
@@ -117,8 +117,8 @@ impl<'a> DocFolder for Stripper<'a> {
 }
 
 /// This stripper discards all impls which reference stripped items
-pub struct ImplStripper<'a> {
-    pub retained: &'a DefIdSet,
+crate struct ImplStripper<'a> {
+    crate retained: &'a DefIdSet,
 }
 
 impl<'a> DocFolder for ImplStripper<'a> {
@@ -158,7 +158,7 @@ impl<'a> DocFolder for ImplStripper<'a> {
 }
 
 /// This stripper discards all private import statements (`use`, `extern crate`)
-pub struct ImportStripper;
+crate struct ImportStripper;
 
 impl DocFolder for ImportStripper {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs
index 51c380f438c..eb2f066bbde 100644
--- a/src/librustdoc/passes/unindent_comments.rs
+++ b/src/librustdoc/passes/unindent_comments.rs
@@ -8,13 +8,13 @@ use crate::passes::Pass;
 #[cfg(test)]
 mod tests;
 
-pub const UNINDENT_COMMENTS: Pass = Pass {
+crate const UNINDENT_COMMENTS: Pass = Pass {
     name: "unindent-comments",
     run: unindent_comments,
     description: "removes excess indentation on comments in order for markdown to like it",
 };
 
-pub fn unindent_comments(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
+crate fn unindent_comments(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
     CommentCleaner.fold_crate(krate)
 }
 
@@ -28,7 +28,7 @@ impl fold::DocFolder for CommentCleaner {
 }
 
 impl clean::Attributes {
-    pub fn unindent_doc_comments(&mut self) {
+    crate fn unindent_doc_comments(&mut self) {
         unindent_fragments(&mut self.doc_strings);
     }
 }
diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs
index c8eb271c807..3bcf64f91c9 100644
--- a/src/librustdoc/theme.rs
+++ b/src/librustdoc/theme.rs
@@ -9,9 +9,9 @@ use rustc_errors::Handler;
 mod tests;
 
 #[derive(Debug, Clone, Eq)]
-pub struct CssPath {
-    pub name: String,
-    pub children: FxHashSet<CssPath>,
+crate struct CssPath {
+    crate name: String,
+    crate children: FxHashSet<CssPath>,
 }
 
 // This PartialEq implementation IS NOT COMMUTATIVE!!!
@@ -212,7 +212,7 @@ fn inner(v: &[u8], events: &[Events], pos: &mut usize) -> FxHashSet<CssPath> {
     paths.iter().cloned().collect()
 }
 
-pub fn load_css_paths(v: &[u8]) -> CssPath {
+crate fn load_css_paths(v: &[u8]) -> CssPath {
     let events = load_css_events(v);
     let mut pos = 0;
 
@@ -221,7 +221,7 @@ pub fn load_css_paths(v: &[u8]) -> CssPath {
     parent
 }
 
-pub fn get_differences(against: &CssPath, other: &CssPath, v: &mut Vec<String>) {
+crate fn get_differences(against: &CssPath, other: &CssPath, v: &mut Vec<String>) {
     if against.name == other.name {
         for child in &against.children {
             let mut found = false;
@@ -248,7 +248,7 @@ pub fn get_differences(against: &CssPath, other: &CssPath, v: &mut Vec<String>)
     }
 }
 
-pub fn test_theme_against<P: AsRef<Path>>(
+crate fn test_theme_against<P: AsRef<Path>>(
     f: &P,
     against: &CssPath,
     diag: &Handler,
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index cbfd2199d9f..509cc47caf8 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -34,7 +34,7 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec<String> {
 // Also, is there some reason that this doesn't use the 'visit'
 // framework from syntax?.
 
-pub struct RustdocVisitor<'a, 'tcx> {
+crate struct RustdocVisitor<'a, 'tcx> {
     cx: &'a mut core::DocContext<'tcx>,
     view_item_stack: FxHashSet<hir::HirId>,
     inlining: bool,
@@ -44,7 +44,7 @@ pub struct RustdocVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
-    pub fn new(cx: &'a mut core::DocContext<'tcx>) -> RustdocVisitor<'a, 'tcx> {
+    crate fn new(cx: &'a mut core::DocContext<'tcx>) -> RustdocVisitor<'a, 'tcx> {
         // If the root is re-exported, terminate all recursion.
         let mut stack = FxHashSet::default();
         stack.insert(hir::CRATE_HIR_ID);
@@ -62,7 +62,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         self.exact_paths.entry(did).or_insert_with(|| def_id_to_path(tcx, did));
     }
 
-    pub fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> {
+    crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> {
         let mut module = self.visit_mod_contents(
             krate.item.span,
             krate.item.attrs,
@@ -251,7 +251,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         om
     }
 
-    /// Tries to resolve the target of a `pub use` statement and inlines the
+    /// Tries to resolve the target of a `crate use` statement and inlines the
     /// target if it is defined locally and would not be documented otherwise,
     /// or when it is specifically requested with `please_inline`.
     /// (the latter is the case when the import is marked `doc(inline)`)
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index ea2f5f8abc7..0bf22562eae 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -11,7 +11,7 @@ use crate::clean::{AttributesExt, NestedAttributesExt};
 
 /// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
 /// specific rustdoc annotations into account (i.e., `doc(hidden)`)
-pub struct LibEmbargoVisitor<'a, 'tcx> {
+crate struct LibEmbargoVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     // Accessibility levels for reachable nodes
     access_levels: &'a mut AccessLevels<DefId>,
@@ -22,7 +22,7 @@ pub struct LibEmbargoVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
-    pub fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
+    crate fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
         LibEmbargoVisitor {
             tcx: cx.tcx,
             access_levels: &mut cx.renderinfo.get_mut().access_levels,
@@ -31,7 +31,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
         }
     }
 
-    pub fn visit_lib(&mut self, cnum: CrateNum) {
+    crate fn visit_lib(&mut self, cnum: CrateNum) {
         let did = DefId { krate: cnum, index: CRATE_DEF_INDEX };
         self.update(did, Some(AccessLevel::Public));
         self.visit_mod(did);
@@ -51,7 +51,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
         }
     }
 
-    pub fn visit_mod(&mut self, def_id: DefId) {
+    crate fn visit_mod(&mut self, def_id: DefId) {
         if !self.visited_mods.insert(def_id) {
             return;
         }
diff --git a/src/test/rustdoc/doc-cfg-traits.rs b/src/test/rustdoc/doc-cfg-traits.rs
new file mode 100644
index 00000000000..13407b2c791
--- /dev/null
+++ b/src/test/rustdoc/doc-cfg-traits.rs
@@ -0,0 +1,124 @@
+#![crate_name = "myrmecophagous"]
+#![feature(doc_cfg, associated_type_defaults)]
+
+// @has 'myrmecophagous/index.html'
+// @count   - '//*[@class="stab portability"]' 2
+// @matches - '//*[@class="stab portability"]' '^jurisconsult$'
+// @matches - '//*[@class="stab portability"]' '^quarter$'
+
+pub trait Lea {}
+
+// @has 'myrmecophagous/trait.Vortoscope.html'
+// @count   - '//*[@class="stab portability"]' 6
+// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
+// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
+// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
+// @matches - '//*[@class="stab portability"]' 'crate feature lea'
+// @matches - '//*[@class="stab portability"]' 'crate feature unit'
+// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
+pub trait Vortoscope {
+    type Batology = ();
+
+    #[doc(cfg(feature = "zibib"))]
+    type Zibib = ();
+
+    const YAHRZEIT: () = ();
+
+    #[doc(cfg(feature = "poriform"))]
+    const PORIFORM: () = ();
+
+    fn javanais() {}
+
+    #[doc(cfg(feature = "ethopoeia"))]
+    fn ethopoeia() {}
+}
+
+#[doc(cfg(feature = "lea"))]
+impl<T: Lea> Vortoscope for T {}
+
+#[doc(cfg(feature = "unit"))]
+impl Vortoscope for () {}
+
+// @has 'myrmecophagous/trait.Jurisconsult.html'
+// @count   - '//*[@class="stab portability"]' 7
+// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
+// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
+// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
+// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
+// @matches - '//*[@class="stab portability"]' 'crate feature lea'
+// @matches - '//*[@class="stab portability"]' 'crate feature unit'
+// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
+#[doc(cfg(feature = "jurisconsult"))]
+pub trait Jurisconsult {
+    type Urbanist = ();
+
+    #[doc(cfg(feature = "lithomancy"))]
+    type Lithomancy = ();
+
+    const UNIFILAR: () = ();
+
+    #[doc(cfg(feature = "boodle"))]
+    const BOODLE: () = ();
+
+    fn mersion() {}
+
+    #[doc(cfg(feature = "mistetch"))]
+    fn mistetch() {}
+}
+
+#[doc(cfg(feature = "lea"))]
+impl<T: Lea> Jurisconsult for T {}
+
+#[doc(cfg(feature = "unit"))]
+impl Jurisconsult for () {}
+
+// @has 'myrmecophagous/struct.Ultimogeniture.html'
+// @count   - '//*[@class="stab portability"]' 8
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
+// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
+// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
+// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
+// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
+// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature copy'
+#[derive(Clone)]
+pub struct Ultimogeniture;
+
+impl Vortoscope for Ultimogeniture {}
+
+#[doc(cfg(feature = "jurisconsult"))]
+impl Jurisconsult for Ultimogeniture {}
+
+#[doc(cfg(feature = "copy"))]
+impl Copy for Ultimogeniture {}
+
+// @has 'myrmecophagous/struct.Quarter.html'
+// @count   - '//*[@class="stab portability"]' 9
+// @matches - '//*[@class="stab portability"]' 'crate feature quarter'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature zibib'
+// @matches - '//*[@class="stab portability"]' 'crate feature poriform'
+// @matches - '//*[@class="stab portability"]' 'crate feature ethopoeia'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature jurisconsult'
+// @matches - '//*[@class="stab portability"]' 'crate feature lithomancy'
+// @matches - '//*[@class="stab portability"]' 'crate feature boodle'
+// @matches - '//*[@class="stab portability"]' 'crate feature mistetch'
+//
+// @matches - '//*[@class="stab portability"]' 'crate feature copy'
+#[doc(cfg(feature = "quarter"))]
+#[derive(Clone)]
+pub struct Quarter;
+
+#[doc(cfg(feature = "quarter"))]
+impl Vortoscope for Quarter {}
+
+#[doc(cfg(all(feature = "jurisconsult", feature = "quarter")))]
+impl Jurisconsult for Quarter {}
+
+#[doc(cfg(all(feature = "copy", feature = "quarter")))]
+impl Copy for Quarter {}
diff --git a/src/test/ui/const-generics/const-param-shadowing.rs b/src/test/ui/const-generics/const-param-shadowing.rs
new file mode 100644
index 00000000000..8440e47968e
--- /dev/null
+++ b/src/test/ui/const-generics/const-param-shadowing.rs
@@ -0,0 +1,9 @@
+#![feature(min_const_generics)]
+
+type N = u32;
+struct Foo<const M: usize>;
+fn test<const N: usize>() -> Foo<N> { //~ ERROR type provided when
+    Foo
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const-param-shadowing.stderr b/src/test/ui/const-generics/const-param-shadowing.stderr
new file mode 100644
index 00000000000..df170278026
--- /dev/null
+++ b/src/test/ui/const-generics/const-param-shadowing.stderr
@@ -0,0 +1,14 @@
+error[E0747]: type provided when a constant was expected
+  --> $DIR/const-param-shadowing.rs:5:34
+   |
+LL | fn test<const N: usize>() -> Foo<N> {
+   |                                  ^
+   |
+help: if this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL | fn test<const N: usize>() -> Foo<{ N }> {
+   |                                  ^   ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/const-generics/invalid-constant-in-args.rs b/src/test/ui/const-generics/invalid-constant-in-args.rs
index 40df237ee72..38ad510e5d7 100644
--- a/src/test/ui/const-generics/invalid-constant-in-args.rs
+++ b/src/test/ui/const-generics/invalid-constant-in-args.rs
@@ -1,3 +1,4 @@
 fn main() {
-    let _: Vec<&str, "a"> = Vec::new(); //~ ERROR wrong number of const arguments
+    let _: Vec<&str, "a"> = Vec::new();
+    //~^ ERROR wrong number of generic arguments
 }
diff --git a/src/test/ui/const-generics/invalid-constant-in-args.stderr b/src/test/ui/const-generics/invalid-constant-in-args.stderr
index b9f874ff18b..5111815e002 100644
--- a/src/test/ui/const-generics/invalid-constant-in-args.stderr
+++ b/src/test/ui/const-generics/invalid-constant-in-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: wrong number of const arguments: expected 0, found 1
+error[E0107]: wrong number of generic arguments: expected 1, found 2
   --> $DIR/invalid-constant-in-args.rs:2:22
    |
 LL |     let _: Vec<&str, "a"> = Vec::new();
diff --git a/src/test/ui/const-generics/invalid-enum.rs b/src/test/ui/const-generics/invalid-enum.rs
index ceb188a0d3d..4ca10ed8b71 100644
--- a/src/test/ui/const-generics/invalid-enum.rs
+++ b/src/test/ui/const-generics/invalid-enum.rs
@@ -20,20 +20,16 @@ impl<const CF: CompileFlag, T> Example<CF, T> {
 pub fn main() {
   test_1::<CompileFlag::A>();
   //~^ ERROR: expected type, found variant
-  //~| ERROR: wrong number of const arguments
-  //~| ERROR: wrong number of type arguments
+  //~| ERROR: type provided when a constant was expected
 
   test_2::<_, CompileFlag::A>(0);
   //~^ ERROR: expected type, found variant
-  //~| ERROR: wrong number of const arguments
-  //~| ERROR: wrong number of type arguments
+  //~| ERROR: type provided when a constant was expected
 
   let _: Example<CompileFlag::A, _> = Example { x: 0 };
   //~^ ERROR: expected type, found variant
-  //~| ERROR: wrong number of const arguments
-  //~| ERROR: wrong number of type arguments
+  //~| ERROR: type provided when a constant was expected
 
   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
-  //~^ ERROR: wrong number of const arguments
-  //~| ERROR: wrong number of type arguments
+  //~^ ERROR: type provided when a constant was expected
 }
diff --git a/src/test/ui/const-generics/invalid-enum.stderr b/src/test/ui/const-generics/invalid-enum.stderr
index 965abbc9cb7..7822fc072e3 100644
--- a/src/test/ui/const-generics/invalid-enum.stderr
+++ b/src/test/ui/const-generics/invalid-enum.stderr
@@ -8,7 +8,7 @@ LL |   test_1::<CompileFlag::A>();
    |            help: try using the variant's enum: `CompileFlag`
 
 error[E0573]: expected type, found variant `CompileFlag::A`
-  --> $DIR/invalid-enum.rs:26:15
+  --> $DIR/invalid-enum.rs:25:15
    |
 LL |   test_2::<_, CompileFlag::A>(0);
    |               ^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |   test_2::<_, CompileFlag::A>(0);
    |               help: try using the variant's enum: `CompileFlag`
 
 error[E0573]: expected type, found variant `CompileFlag::A`
-  --> $DIR/invalid-enum.rs:31:18
+  --> $DIR/invalid-enum.rs:29:18
    |
 LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
    |                  ^^^^^^^^^^^^^^
@@ -25,75 +25,51 @@ LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
    |                  not a type
    |                  help: try using the variant's enum: `CompileFlag`
 
-error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/invalid-enum.rs:31:10
+error[E0747]: type provided when a constant was expected
+  --> $DIR/invalid-enum.rs:29:18
    |
 LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
-
-error[E0107]: wrong number of type arguments: expected at most 1, found 2
-  --> $DIR/invalid-enum.rs:31:10
-   |
-LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
+   |                  ^^^^^^^^^^^^^^
    |
-help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+help: if this generic argument was intended as a const parameter, try surrounding it with braces:
    |
 LL |   let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
    |                  ^                ^
 
-error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/invalid-enum.rs:36:10
+error[E0747]: type provided when a constant was expected
+  --> $DIR/invalid-enum.rs:33:18
    |
 LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
-
-error[E0107]: wrong number of type arguments: expected at most 1, found 2
-  --> $DIR/invalid-enum.rs:36:10
-   |
-LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
+   |                  ^^^^^^^^^^^^^^^^^^^
    |
-help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+help: if this generic argument was intended as a const parameter, try surrounding it with braces:
    |
 LL |   let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
    |                  ^                     ^
 
-error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/invalid-enum.rs:21:3
-   |
-LL |   test_1::<CompileFlag::A>();
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
+error[E0747]: type provided when a constant was expected
   --> $DIR/invalid-enum.rs:21:12
    |
 LL |   test_1::<CompileFlag::A>();
-   |            ^^^^^^^^^^^^^^ unexpected type argument
+   |            ^^^^^^^^^^^^^^
    |
-help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+help: if this generic argument was intended as a const parameter, try surrounding it with braces:
    |
 LL |   test_1::<{ CompileFlag::A }>();
    |            ^                ^
 
-error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/invalid-enum.rs:26:3
+error[E0747]: type provided when a constant was expected
+  --> $DIR/invalid-enum.rs:25:15
    |
 LL |   test_2::<_, CompileFlag::A>(0);
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
-
-error[E0107]: wrong number of type arguments: expected 1, found 2
-  --> $DIR/invalid-enum.rs:26:15
-   |
-LL |   test_2::<_, CompileFlag::A>(0);
-   |               ^^^^^^^^^^^^^^ unexpected type argument
+   |               ^^^^^^^^^^^^^^
    |
-help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+help: if this generic argument was intended as a const parameter, try surrounding it with braces:
    |
 LL |   test_2::<_, { CompileFlag::A }>(0);
    |               ^                ^
 
-error: aborting due to 11 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0107, E0573.
-For more information about an error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0573, E0747.
+For more information about an error, try `rustc --explain E0573`.
diff --git a/src/test/ui/const-generics/issues/issue-62878.full.stderr b/src/test/ui/const-generics/issues/issue-62878.full.stderr
index c8b9db89410..fc70be40497 100644
--- a/src/test/ui/const-generics/issues/issue-62878.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-62878.full.stderr
@@ -4,17 +4,11 @@ error[E0770]: the type of const parameters must not depend on other generic para
 LL | fn foo<const N: usize, const A: [u8; N]>() {}
    |                                      ^ the type must not depend on the parameter `N`
 
-error[E0107]: wrong number of const arguments: expected 2, found 1
-  --> $DIR/issue-62878.rs:11:5
-   |
-LL |     foo::<_, {[1]}>();
-   |     ^^^^^^^^^^^^^^^ expected 2 const arguments
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
+error[E0747]: type provided when a constant was expected
   --> $DIR/issue-62878.rs:11:11
    |
 LL |     foo::<_, {[1]}>();
-   |           ^ unexpected type argument
+   |           ^
 
 error[E0308]: mismatched types
   --> $DIR/issue-62878.rs:11:15
@@ -22,7 +16,7 @@ error[E0308]: mismatched types
 LL |     foo::<_, {[1]}>();
    |               ^^^ expected `usize`, found array `[{integer}; 1]`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0107, E0308, E0770.
-For more information about an error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0308, E0747, E0770.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/issues/issue-62878.rs b/src/test/ui/const-generics/issues/issue-62878.rs
index 0487dda2fe8..c087711e5f9 100644
--- a/src/test/ui/const-generics/issues/issue-62878.rs
+++ b/src/test/ui/const-generics/issues/issue-62878.rs
@@ -9,7 +9,6 @@ fn foo<const N: usize, const A: [u8; N]>() {}
 
 fn main() {
     foo::<_, {[1]}>();
-    //[full]~^ ERROR wrong number of const arguments
-    //[full]~| ERROR wrong number of type arguments
+    //[full]~^ ERROR type provided when a constant was expected
     //[full]~| ERROR mismatched types
 }
diff --git a/src/test/ui/const-generics/issues/issue-76595.rs b/src/test/ui/const-generics/issues/issue-76595.rs
index 9fdbbff66e9..04c01901517 100644
--- a/src/test/ui/const-generics/issues/issue-76595.rs
+++ b/src/test/ui/const-generics/issues/issue-76595.rs
@@ -13,5 +13,5 @@ fn test<T, const P: usize>() where Bool<{core::mem::size_of::<T>() > 4}>: True {
 
 fn main() {
     test::<2>();
-    //~^ ERROR wrong number of type
+    //~^ ERROR wrong number of generic arguments
 }
diff --git a/src/test/ui/const-generics/issues/issue-76595.stderr b/src/test/ui/const-generics/issues/issue-76595.stderr
index f258d297718..1e37f9dcb19 100644
--- a/src/test/ui/const-generics/issues/issue-76595.stderr
+++ b/src/test/ui/const-generics/issues/issue-76595.stderr
@@ -1,8 +1,8 @@
-error[E0107]: wrong number of type arguments: expected 1, found 0
+error[E0107]: wrong number of generic arguments: expected 2, found 1
   --> $DIR/issue-76595.rs:15:5
    |
 LL |     test::<2>();
-   |     ^^^^^^^^^ expected 1 type argument
+   |     ^^^^^^^^^ expected 2 generic arguments
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs
index aea3def5aeb..b96d5c561ff 100644
--- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs
@@ -13,8 +13,7 @@ fn b() {
     foo::<BAR + BAR>();
     //~^ ERROR expected trait, found constant `BAR`
     //~| ERROR expected trait, found constant `BAR`
-    //~| ERROR wrong number of const arguments: expected 1, found 0
-    //~| ERROR wrong number of type arguments: expected 0, found 1
+    //~| ERROR type provided when a constant was expected
     //~| WARN trait objects without an explicit `dyn` are deprecated
 }
 fn c() {
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
index 47e9dc034ef..6adcf6a3e36 100644
--- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
@@ -10,7 +10,7 @@ LL |     foo::<{ BAR + 3 }>();
    |           ^         ^
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/const-expression-suggest-missing-braces.rs:21:11
+  --> $DIR/const-expression-suggest-missing-braces.rs:20:11
    |
 LL |     foo::<3 + 3>();
    |           ^^^^^
@@ -21,7 +21,7 @@ LL |     foo::<{ 3 + 3 }>();
    |           ^       ^
 
 error: expected one of `,` or `>`, found `-`
-  --> $DIR/const-expression-suggest-missing-braces.rs:24:15
+  --> $DIR/const-expression-suggest-missing-braces.rs:23:15
    |
 LL |     foo::<BAR - 3>();
    |               ^ expected one of `,` or `>`
@@ -32,7 +32,7 @@ LL |     foo::<{ BAR - 3 }>();
    |           ^         ^
 
 error: expected one of `,` or `>`, found `-`
-  --> $DIR/const-expression-suggest-missing-braces.rs:27:15
+  --> $DIR/const-expression-suggest-missing-braces.rs:26:15
    |
 LL |     foo::<BAR - BAR>();
    |               ^ expected one of `,` or `>`
@@ -43,7 +43,7 @@ LL |     foo::<{ BAR - BAR }>();
    |           ^           ^
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/const-expression-suggest-missing-braces.rs:30:11
+  --> $DIR/const-expression-suggest-missing-braces.rs:29:11
    |
 LL |     foo::<100 - BAR>();
    |           ^^^^^^^^^
@@ -54,7 +54,7 @@ LL |     foo::<{ 100 - BAR }>();
    |           ^           ^
 
 error: expected one of `,` or `>`, found `(`
-  --> $DIR/const-expression-suggest-missing-braces.rs:33:19
+  --> $DIR/const-expression-suggest-missing-braces.rs:32:19
    |
 LL |     foo::<bar<i32>()>();
    |                   ^ expected one of `,` or `>`
@@ -65,7 +65,7 @@ LL |     foo::<{ bar<i32>() }>();
    |           ^            ^
 
 error: expected one of `,` or `>`, found `(`
-  --> $DIR/const-expression-suggest-missing-braces.rs:36:21
+  --> $DIR/const-expression-suggest-missing-braces.rs:35:21
    |
 LL |     foo::<bar::<i32>()>();
    |                     ^ expected one of `,` or `>`
@@ -76,7 +76,7 @@ LL |     foo::<{ bar::<i32>() }>();
    |           ^              ^
 
 error: expected one of `,` or `>`, found `(`
-  --> $DIR/const-expression-suggest-missing-braces.rs:39:21
+  --> $DIR/const-expression-suggest-missing-braces.rs:38:21
    |
 LL |     foo::<bar::<i32>() + BAR>();
    |                     ^ expected one of `,` or `>`
@@ -87,7 +87,7 @@ LL |     foo::<{ bar::<i32>() + BAR }>();
    |           ^                    ^
 
 error: expected one of `,` or `>`, found `(`
-  --> $DIR/const-expression-suggest-missing-braces.rs:42:21
+  --> $DIR/const-expression-suggest-missing-braces.rs:41:21
    |
 LL |     foo::<bar::<i32>() - BAR>();
    |                     ^ expected one of `,` or `>`
@@ -98,7 +98,7 @@ LL |     foo::<{ bar::<i32>() - BAR }>();
    |           ^                    ^
 
 error: expected one of `,` or `>`, found `-`
-  --> $DIR/const-expression-suggest-missing-braces.rs:45:15
+  --> $DIR/const-expression-suggest-missing-braces.rs:44:15
    |
 LL |     foo::<BAR - bar::<i32>()>();
    |               ^ expected one of `,` or `>`
@@ -109,7 +109,7 @@ LL |     foo::<{ BAR - bar::<i32>() }>();
    |           ^                    ^
 
 error: expected one of `,` or `>`, found `-`
-  --> $DIR/const-expression-suggest-missing-braces.rs:48:15
+  --> $DIR/const-expression-suggest-missing-braces.rs:47:15
    |
 LL |     foo::<BAR - bar::<i32>()>();
    |               ^ expected one of `,` or `>`
@@ -139,19 +139,13 @@ LL |     foo::<BAR + BAR>();
    |
    = note: `#[warn(bare_trait_objects)]` on by default
 
-error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/const-expression-suggest-missing-braces.rs:13:5
-   |
-LL |     foo::<BAR + BAR>();
-   |     ^^^^^^^^^^^^^^^^ expected 1 const argument
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
+error[E0747]: type provided when a constant was expected
   --> $DIR/const-expression-suggest-missing-braces.rs:13:11
    |
 LL |     foo::<BAR + BAR>();
-   |           ^^^^^^^^^ unexpected type argument
+   |           ^^^^^^^^^
 
-error: aborting due to 15 previous errors; 1 warning emitted
+error: aborting due to 14 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0107, E0404.
-For more information about an error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0404, E0747.
+For more information about an error, try `rustc --explain E0404`.
diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.rs b/src/test/ui/const-generics/min_const_generics/macro-fail.rs
index 7f16f2f33de..1bd0c46f55e 100644
--- a/src/test/ui/const-generics/min_const_generics/macro-fail.rs
+++ b/src/test/ui/const-generics/min_const_generics/macro-fail.rs
@@ -14,11 +14,9 @@ trait Marker<const N: usize> {}
 impl<const N: usize> Marker<N> for Example<N> {}
 
 fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
-  //~^ ERROR wrong number of const
-  //~| ERROR wrong number of type
+  //~^ ERROR: type provided when a constant was expected
   Example::<gimme_a_const!(marker)>
-  //~^ ERROR wrong number of const
-  //~| ERROR wrong number of type
+  //~^ ERROR: type provided when a constant was expected
 }
 
 fn from_marker(_: impl Marker<{
@@ -38,11 +36,9 @@ fn main() {
   }>;
 
   let _fail = Example::<external_macro!()>;
-  //~^ ERROR wrong number of const
-  //~| ERROR wrong number of type
+  //~^ ERROR: type provided when a constant was expected
 
   let _fail = Example::<gimme_a_const!()>;
-  //~^ ERROR wrong number of const
-  //~| ERROR wrong number of type
+  //~^ ERROR: type provided when a constant was expected
   //~| ERROR unexpected end of macro invocation
 }
diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.stderr b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
index fe7a4a5c382..a5dedf6fe20 100644
--- a/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
+++ b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
@@ -1,5 +1,5 @@
 error: expected type, found `{`
-  --> $DIR/macro-fail.rs:33:27
+  --> $DIR/macro-fail.rs:31:27
    |
 LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
    |                                 ----------------------
@@ -13,7 +13,7 @@ LL |       ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected type, found `{`
-  --> $DIR/macro-fail.rs:33:27
+  --> $DIR/macro-fail.rs:31:27
    |
 LL |   Example::<gimme_a_const!(marker)>
    |             ----------------------
@@ -46,7 +46,7 @@ LL |     let _fail = Example::<external_macro!()>;
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-fail.rs:44:25
+  --> $DIR/macro-fail.rs:41:25
    |
 LL |     macro_rules! gimme_a_const {
    |     -------------------------- when calling this macro
@@ -54,54 +54,30 @@ LL |     macro_rules! gimme_a_const {
 LL |   let _fail = Example::<gimme_a_const!()>;
    |                         ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
 
-error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/macro-fail.rs:16:26
-   |
-LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
+error[E0747]: type provided when a constant was expected
   --> $DIR/macro-fail.rs:16:33
    |
 LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^ unexpected type argument
-
-error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/macro-fail.rs:19:3
-   |
-LL |   Example::<gimme_a_const!(marker)>
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/macro-fail.rs:19:13
+error[E0747]: type provided when a constant was expected
+  --> $DIR/macro-fail.rs:18:13
    |
 LL |   Example::<gimme_a_const!(marker)>
-   |             ^^^^^^^^^^^^^^^^^^^^^^ unexpected type argument
+   |             ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/macro-fail.rs:40:15
+error[E0747]: type provided when a constant was expected
+  --> $DIR/macro-fail.rs:38:25
    |
 LL |   let _fail = Example::<external_macro!()>;
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/macro-fail.rs:40:25
-   |
-LL |   let _fail = Example::<external_macro!()>;
-   |                         ^^^^^^^^^^^^^^^^^ unexpected type argument
-
-error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/macro-fail.rs:44:15
-   |
-LL |   let _fail = Example::<gimme_a_const!()>;
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+   |                         ^^^^^^^^^^^^^^^^^
 
-error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/macro-fail.rs:44:25
+error[E0747]: type provided when a constant was expected
+  --> $DIR/macro-fail.rs:41:25
    |
 LL |   let _fail = Example::<gimme_a_const!()>;
-   |                         ^^^^^^^^^^^^^^^^ unexpected type argument
+   |                         ^^^^^^^^^^^^^^^^
 
-error: aborting due to 12 previous errors
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/generics/generic-impl-more-params-with-defaults.stderr b/src/test/ui/generics/generic-impl-more-params-with-defaults.stderr
index 66950d450a1..380e9209e6c 100644
--- a/src/test/ui/generics/generic-impl-more-params-with-defaults.stderr
+++ b/src/test/ui/generics/generic-impl-more-params-with-defaults.stderr
@@ -1,8 +1,8 @@
 error[E0107]: wrong number of type arguments: expected at most 2, found 3
-  --> $DIR/generic-impl-more-params-with-defaults.rs:13:5
+  --> $DIR/generic-impl-more-params-with-defaults.rs:13:24
    |
 LL |     Vec::<isize, Heap, bool>::new();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 2 type arguments
+   |                        ^^^^ unexpected type argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generics/generic-type-more-params-with-defaults.stderr b/src/test/ui/generics/generic-type-more-params-with-defaults.stderr
index 5031930b1bb..cc296b5105a 100644
--- a/src/test/ui/generics/generic-type-more-params-with-defaults.stderr
+++ b/src/test/ui/generics/generic-type-more-params-with-defaults.stderr
@@ -1,8 +1,8 @@
 error[E0107]: wrong number of type arguments: expected at most 2, found 3
-  --> $DIR/generic-type-more-params-with-defaults.rs:9:12
+  --> $DIR/generic-type-more-params-with-defaults.rs:9:29
    |
 LL |     let _: Vec<isize, Heap, bool>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^ expected at most 2 type arguments
+   |                             ^^^^ unexpected type argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/panic-while-printing.rs b/src/test/ui/panic-while-printing.rs
index 21fc12759f8..96b35e45535 100644
--- a/src/test/ui/panic-while-printing.rs
+++ b/src/test/ui/panic-while-printing.rs
@@ -1,11 +1,12 @@
 // run-pass
 // ignore-emscripten no subprocess support
 
-#![feature(set_stdio)]
+#![feature(internal_output_capture)]
 
 use std::fmt;
 use std::fmt::{Display, Formatter};
-use std::io::{self, set_panic, LocalOutput, Write};
+use std::io::set_output_capture;
+use std::sync::{Arc, Mutex};
 
 pub struct A;
 
@@ -15,23 +16,8 @@ impl Display for A {
     }
 }
 
-struct Sink;
-impl Write for Sink {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        Ok(buf.len())
-    }
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-impl LocalOutput for Sink {
-    fn clone_box(&self) -> Box<dyn LocalOutput> {
-        Box::new(Sink)
-    }
-}
-
 fn main() {
-    set_panic(Some(Box::new(Sink)));
+    set_output_capture(Some(Arc::new(Mutex::new(Vec::new()))));
     assert!(std::panic::catch_unwind(|| {
         eprintln!("{}", A);
     })
diff --git a/src/test/ui/parser/issue-14303-fncall.stderr b/src/test/ui/parser/issue-14303-fncall.stderr
index 10954223713..cdda0d001c7 100644
--- a/src/test/ui/parser/issue-14303-fncall.stderr
+++ b/src/test/ui/parser/issue-14303-fncall.stderr
@@ -3,8 +3,6 @@ error[E0747]: type provided when a lifetime was expected
    |
 LL |         .collect::<Vec<S<_, 'a>>>();
    |                          ^
-   |
-   = note: lifetime arguments must be provided before type arguments
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-path.stderr b/src/test/ui/parser/issue-14303-path.stderr
index c1ad2332b5b..841e63ecbe9 100644
--- a/src/test/ui/parser/issue-14303-path.stderr
+++ b/src/test/ui/parser/issue-14303-path.stderr
@@ -3,8 +3,6 @@ error[E0747]: type provided when a lifetime was expected
    |
 LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {}
    |                                     ^
-   |
-   = note: lifetime arguments must be provided before type arguments
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/privacy/privacy-ns1.rs b/src/test/ui/privacy/privacy-ns1.rs
index c7084bfd980..1af5b857e9d 100644
--- a/src/test/ui/privacy/privacy-ns1.rs
+++ b/src/test/ui/privacy/privacy-ns1.rs
@@ -32,8 +32,8 @@ pub mod foo2 {
 fn test_glob2() {
     use foo2::*;
 
-    let _x: Box<Bar>;  //~ ERROR wrong number of const arguments: expected 0, found 1
-    //~^ ERROR wrong number of type arguments: expected at least 1, found 0
+    let _x: Box<Bar>;
+    //~^ ERROR constant provided when a type was expected
 }
 
 // neither public
diff --git a/src/test/ui/privacy/privacy-ns1.stderr b/src/test/ui/privacy/privacy-ns1.stderr
index ccbb5d5c90f..714f28941f1 100644
--- a/src/test/ui/privacy/privacy-ns1.stderr
+++ b/src/test/ui/privacy/privacy-ns1.stderr
@@ -52,19 +52,13 @@ help: consider importing this trait
 LL | use foo1::Bar;
    |
 
-error[E0107]: wrong number of const arguments: expected 0, found 1
+error[E0747]: constant provided when a type was expected
   --> $DIR/privacy-ns1.rs:35:17
    |
 LL |     let _x: Box<Bar>;
-   |                 ^^^ unexpected const argument
-
-error[E0107]: wrong number of type arguments: expected at least 1, found 0
-  --> $DIR/privacy-ns1.rs:35:13
-   |
-LL |     let _x: Box<Bar>;
-   |             ^^^^^^^^ expected at least 1 type argument
+   |                 ^^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0107, E0412, E0423, E0425.
-For more information about an error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0412, E0423, E0425, E0747.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/privacy/privacy-ns2.rs b/src/test/ui/privacy/privacy-ns2.rs
index b770c8f8f86..47035ef3af5 100644
--- a/src/test/ui/privacy/privacy-ns2.rs
+++ b/src/test/ui/privacy/privacy-ns2.rs
@@ -38,16 +38,14 @@ pub mod foo2 {
 fn test_single2() {
     use foo2::Bar;
 
-    let _x : Box<Bar>; //~ ERROR wrong number of const arguments: expected 0, found 1
-    //~^ ERROR wrong number of type arguments: expected at least 1, found 0
+    let _x : Box<Bar>; //~ ERROR constant provided when a type was expected
     let _x : Bar(); //~ ERROR expected type, found function `Bar`
 }
 
 fn test_list2() {
     use foo2::{Bar,Baz};
 
-    let _x: Box<Bar>; //~ ERROR wrong number of const arguments: expected 0, found 1
-    //~^ ERROR wrong number of type arguments: expected at least 1, found 0
+    let _x: Box<Bar>; //~ ERROR constant provided when a type was expected
 }
 
 // neither public
diff --git a/src/test/ui/privacy/privacy-ns2.stderr b/src/test/ui/privacy/privacy-ns2.stderr
index dbb269c0ba6..c7ad8ec5036 100644
--- a/src/test/ui/privacy/privacy-ns2.stderr
+++ b/src/test/ui/privacy/privacy-ns2.stderr
@@ -28,7 +28,7 @@ LL | use foo2::Bar;
    |
 
 error[E0573]: expected type, found function `Bar`
-  --> $DIR/privacy-ns2.rs:43:14
+  --> $DIR/privacy-ns2.rs:42:14
    |
 LL |     let _x : Bar();
    |              ^^^^^ not a type
@@ -43,66 +43,54 @@ LL | use foo1::Bar;
    |
 
 error[E0603]: trait `Bar` is private
-  --> $DIR/privacy-ns2.rs:63:15
+  --> $DIR/privacy-ns2.rs:61:15
    |
 LL |     use foo3::Bar;
    |               ^^^ private trait
    |
 note: the trait `Bar` is defined here
-  --> $DIR/privacy-ns2.rs:55:5
+  --> $DIR/privacy-ns2.rs:53:5
    |
 LL |     trait Bar {
    |     ^^^^^^^^^
 
 error[E0603]: trait `Bar` is private
-  --> $DIR/privacy-ns2.rs:67:15
+  --> $DIR/privacy-ns2.rs:65:15
    |
 LL |     use foo3::Bar;
    |               ^^^ private trait
    |
 note: the trait `Bar` is defined here
-  --> $DIR/privacy-ns2.rs:55:5
+  --> $DIR/privacy-ns2.rs:53:5
    |
 LL |     trait Bar {
    |     ^^^^^^^^^
 
 error[E0603]: trait `Bar` is private
-  --> $DIR/privacy-ns2.rs:74:16
+  --> $DIR/privacy-ns2.rs:72:16
    |
 LL |     use foo3::{Bar,Baz};
    |                ^^^ private trait
    |
 note: the trait `Bar` is defined here
-  --> $DIR/privacy-ns2.rs:55:5
+  --> $DIR/privacy-ns2.rs:53:5
    |
 LL |     trait Bar {
    |     ^^^^^^^^^
 
-error[E0107]: wrong number of const arguments: expected 0, found 1
+error[E0747]: constant provided when a type was expected
   --> $DIR/privacy-ns2.rs:41:18
    |
 LL |     let _x : Box<Bar>;
-   |                  ^^^ unexpected const argument
+   |                  ^^^
 
-error[E0107]: wrong number of type arguments: expected at least 1, found 0
-  --> $DIR/privacy-ns2.rs:41:14
-   |
-LL |     let _x : Box<Bar>;
-   |              ^^^^^^^^ expected at least 1 type argument
-
-error[E0107]: wrong number of const arguments: expected 0, found 1
-  --> $DIR/privacy-ns2.rs:49:17
-   |
-LL |     let _x: Box<Bar>;
-   |                 ^^^ unexpected const argument
-
-error[E0107]: wrong number of type arguments: expected at least 1, found 0
-  --> $DIR/privacy-ns2.rs:49:13
+error[E0747]: constant provided when a type was expected
+  --> $DIR/privacy-ns2.rs:48:17
    |
 LL |     let _x: Box<Bar>;
-   |             ^^^^^^^^ expected at least 1 type argument
+   |                 ^^^
 
-error: aborting due to 10 previous errors
+error: aborting due to 8 previous errors
 
-Some errors have detailed explanations: E0107, E0423, E0573, E0603.
-For more information about an error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0423, E0573, E0603, E0747.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr
index 3c2226574ee..df064f22f35 100644
--- a/src/test/ui/suggestions/suggest-move-types.stderr
+++ b/src/test/ui/suggestions/suggest-move-types.stderr
@@ -107,16 +107,12 @@ error[E0747]: type provided when a lifetime was expected
    |
 LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
    |                                           ^
-   |
-   = note: lifetime arguments must be provided before type arguments
 
 error[E0747]: type provided when a lifetime was expected
   --> $DIR/suggest-move-types.rs:48:71
    |
 LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
    |                                                                       ^
-   |
-   = note: lifetime arguments must be provided before type arguments
 
 error[E0747]: lifetime provided when a type was expected
   --> $DIR/suggest-move-types.rs:65:56
diff --git a/src/test/ui/threads-sendsync/task-stderr.rs b/src/test/ui/threads-sendsync/task-stderr.rs
index bc4bedac196..78145e337da 100644
--- a/src/test/ui/threads-sendsync/task-stderr.rs
+++ b/src/test/ui/threads-sendsync/task-stderr.rs
@@ -1,33 +1,21 @@
 // run-pass
 // ignore-emscripten no threads support
 
-#![feature(box_syntax, set_stdio)]
+#![feature(internal_output_capture)]
 
-use std::io::prelude::*;
 use std::io;
 use std::str;
 use std::sync::{Arc, Mutex};
 use std::thread;
 
-struct Sink(Arc<Mutex<Vec<u8>>>);
-impl Write for Sink {
-    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-        Write::write(&mut *self.0.lock().unwrap(), data)
-    }
-    fn flush(&mut self) -> io::Result<()> { Ok(()) }
-}
-impl io::LocalOutput for Sink {
-    fn clone_box(&self) -> Box<dyn io::LocalOutput> {
-        Box::new(Sink(self.0.clone()))
-    }
-}
-
 fn main() {
     let data = Arc::new(Mutex::new(Vec::new()));
-    let sink = Sink(data.clone());
-    let res = thread::Builder::new().spawn(move|| -> () {
-        io::set_panic(Some(Box::new(sink)));
-        panic!("Hello, world!")
+    let res = thread::Builder::new().spawn({
+        let data = data.clone();
+        move || {
+            io::set_output_capture(Some(data));
+            panic!("Hello, world!")
+        }
     }).unwrap().join();
     assert!(res.is_err());
 
diff --git a/src/test/ui/traits/trait-object-vs-lifetime.stderr b/src/test/ui/traits/trait-object-vs-lifetime.stderr
index ff3fc2a197c..8958547e827 100644
--- a/src/test/ui/traits/trait-object-vs-lifetime.stderr
+++ b/src/test/ui/traits/trait-object-vs-lifetime.stderr
@@ -27,8 +27,6 @@ error[E0747]: type provided when a lifetime was expected
    |
 LL |     let _: S<dyn 'static +, 'static>;
    |              ^^^^^^^^^^^^^
-   |
-   = note: lifetime arguments must be provided before type arguments
 
 error: aborting due to 5 previous errors