about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs2
-rw-r--r--compiler/rustc_ast/src/lib.rs1
-rw-r--r--compiler/rustc_ast/src/token.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs10
-rw-r--r--compiler/rustc_ast_pretty/src/lib.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs57
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs16
-rw-r--r--compiler/rustc_borrowck/src/borrow_set.rs12
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs50
-rw-r--r--compiler/rustc_borrowck/src/constraints/graph.rs32
-rw-r--r--compiler/rustc_borrowck/src/constraints/mod.rs14
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs10
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/find_use.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs12
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs22
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/var_name.rs14
-rw-r--r--compiler/rustc_borrowck/src/facts.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs1
-rw-r--r--compiler/rustc_borrowck/src/location.rs2
-rw-r--r--compiler/rustc_borrowck/src/member_constraints.rs22
-rw-r--r--compiler/rustc_borrowck/src/nll.rs4
-rw-r--r--compiler/rustc_borrowck/src/place_ext.rs2
-rw-r--r--compiler/rustc_borrowck/src/places_conflict.rs4
-rw-r--r--compiler/rustc_borrowck/src/region_infer/graphviz.rs4
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs32
-rw-r--r--compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/values.rs82
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs28
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs14
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs29
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs2
-rw-r--r--compiler/rustc_borrowck/src/used_muts.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_accessible.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/derive.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/type_.rs30
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/mod.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs2
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs12
-rw-r--r--compiler/rustc_errors/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/base.rs2
-rw-r--r--compiler/rustc_expand/src/config.rs6
-rw-r--r--compiler/rustc_expand/src/expand.rs2
-rw-r--r--compiler/rustc_expand/src/lib.rs5
-rw-r--r--compiler/rustc_expand/src/mbe.rs12
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs10
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs6
-rw-r--r--compiler/rustc_expand/src/mbe/metavar_expr.rs6
-rw-r--r--compiler/rustc_expand/src/module.rs6
-rw-r--r--compiler/rustc_expand/src/tests.rs10
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/builtin.rs2
-rw-r--r--compiler/rustc_lint/src/late.rs2
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/types.rs9
-rw-r--r--compiler/rustc_metadata/src/creader.rs16
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs2
-rw-r--r--compiler/rustc_metadata/src/foreign_modules.rs2
-rw-r--r--compiler/rustc_metadata/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/locator.rs22
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs64
-rw-r--r--compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs18
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs7
-rw-r--r--compiler/rustc_middle/src/dep_graph/mod.rs2
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/block.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/cfg.rs22
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_operand.rs8
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs24
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_temp.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/category.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/stmt.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs23
-rw-r--r--compiler/rustc_mir_build/src/build/matches/util.rs11
-rw-r--r--compiler/rustc_mir_build/src/build/misc.rs14
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs42
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs4
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_build/src/lints.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/block.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs14
-rw-r--r--compiler/rustc_mir_build/src/thir/mod.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs26
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs30
-rw-r--r--compiler/rustc_mir_build/src/thir/util.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs4
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs1
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs1
-rw-r--r--compiler/rustc_monomorphize/src/util.rs2
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs2
-rw-r--r--compiler/rustc_parse/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs8
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs10
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs4
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs4
-rw-r--r--compiler/rustc_passes/src/lib.rs1
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs2
-rw-r--r--compiler/rustc_query_impl/src/lib.rs1
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs2
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs16
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs2
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs40
-rw-r--r--compiler/rustc_resolve/src/ident.rs16
-rw-r--r--compiler/rustc_resolve/src/imports.rs10
-rw-r--r--compiler/rustc_resolve/src/late.rs18
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs36
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs18
-rw-r--r--compiler/rustc_resolve/src/lib.rs1
-rw-r--r--compiler/rustc_resolve/src/macros.rs19
-rw-r--r--compiler/rustc_session/src/config.rs6
-rw-r--r--compiler/rustc_session/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/options.rs120
-rw-r--r--compiler/rustc_span/src/hygiene.rs8
-rw-r--r--compiler/rustc_span/src/lib.rs1
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs1
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs2
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs32
-rw-r--r--compiler/rustc_traits/src/chalk/mod.rs8
-rw-r--r--compiler/rustc_traits/src/dropck_outlives.rs4
-rw-r--r--compiler/rustc_traits/src/evaluate_obligation.rs2
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs2
-rw-r--r--compiler/rustc_traits/src/lib.rs1
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs2
-rw-r--r--compiler/rustc_traits/src/normalize_projection_ty.rs2
-rw-r--r--compiler/rustc_traits/src/type_op.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs2
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs2
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs6
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs9
-rw-r--r--compiler/rustc_typeck/src/check/dropck.rs4
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs4
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs7
-rw-r--r--compiler/rustc_typeck/src/check/method/mod.rs2
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs2
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs2
-rw-r--r--compiler/rustc_typeck/src/collect.rs6
-rw-r--r--compiler/rustc_typeck/src/lib.rs1
-rw-r--r--compiler/rustc_typeck/src/mem_categorization.rs37
-rw-r--r--compiler/rustc_typeck/src/outlives/mod.rs2
-rw-r--r--compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs16
-rw-r--r--src/librustdoc/clean/auto_trait.rs8
-rw-r--r--src/librustdoc/clean/blanket_impl.rs6
-rw-r--r--src/librustdoc/clean/cfg.rs14
-rw-r--r--src/librustdoc/clean/inline.rs18
-rw-r--r--src/librustdoc/clean/mod.rs14
-rw-r--r--src/librustdoc/clean/simplify.rs4
-rw-r--r--src/librustdoc/clean/types.rs584
-rw-r--r--src/librustdoc/clean/utils.rs40
-rw-r--r--src/librustdoc/config.rs144
-rw-r--r--src/librustdoc/core.rs76
-rw-r--r--src/librustdoc/docfs.rs14
-rw-r--r--src/librustdoc/doctest.rs26
-rw-r--r--src/librustdoc/error.rs6
-rw-r--r--src/librustdoc/externalfiles.rs14
-rw-r--r--src/librustdoc/fold.rs4
-rw-r--r--src/librustdoc/formats/cache.rs38
-rw-r--r--src/librustdoc/formats/item_type.rs4
-rw-r--r--src/librustdoc/formats/mod.rs22
-rw-r--r--src/librustdoc/formats/renderer.rs4
-rw-r--r--src/librustdoc/html/escape.rs2
-rw-r--r--src/librustdoc/html/format.rs102
-rw-r--r--src/librustdoc/html/highlight.rs12
-rw-r--r--src/librustdoc/html/layout.rs44
-rw-r--r--src/librustdoc/html/markdown.rs89
-rw-r--r--src/librustdoc/html/mod.rs16
-rw-r--r--src/librustdoc/html/render/context.rs38
-rw-r--r--src/librustdoc/html/render/mod.rs44
-rw-r--r--src/librustdoc/html/render/print_item.rs12
-rw-r--r--src/librustdoc/html/render/search_index.rs8
-rw-r--r--src/librustdoc/html/render/span_map.rs8
-rw-r--r--src/librustdoc/html/sources.rs10
-rw-r--r--src/librustdoc/html/static_files.rs93
-rw-r--r--src/librustdoc/html/toc.rs14
-rw-r--r--src/librustdoc/html/url_parts_builder.rs16
-rw-r--r--src/librustdoc/json/conversions.rs22
-rw-r--r--src/librustdoc/json/mod.rs2
-rw-r--r--src/librustdoc/lib.rs3
-rw-r--r--src/librustdoc/lint.rs4
-rw-r--r--src/librustdoc/markdown.rs4
-rw-r--r--src/librustdoc/passes/bare_urls.rs4
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs2
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs7
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs8
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs19
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links/early.rs2
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs4
-rw-r--r--src/librustdoc/passes/html_tags.rs4
-rw-r--r--src/librustdoc/passes/mod.rs58
-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.rs16
-rw-r--r--src/librustdoc/scrape_examples.rs38
-rw-r--r--src/librustdoc/theme.rs12
-rw-r--r--src/librustdoc/visit.rs2
-rw-r--r--src/librustdoc/visit_ast.rs26
-rw-r--r--src/librustdoc/visit_lib.rs8
-rw-r--r--src/test/rustdoc/visibility.rs4
-rw-r--r--src/test/ui/lint/dead-code/issue-85255.rs5
-rw-r--r--src/test/ui/lint/dead-code/issue-85255.stderr24
-rw-r--r--src/test/ui/lint/unnecessary-extern-crate.rs4
-rw-r--r--src/test/ui/lint/unreachable_pub-pub_crate.rs72
-rw-r--r--src/test/ui/lint/unreachable_pub-pub_crate.stderr148
-rw-r--r--src/test/ui/lint/unreachable_pub.rs10
-rw-r--r--src/test/ui/lint/unreachable_pub.stderr58
-rw-r--r--src/test/ui/macros/macro-pub-matcher.rs19
-rw-r--r--src/test/ui/privacy/issue-46209-private-enum-variant-reexport.rs4
-rw-r--r--src/test/ui/privacy/issue-46209-private-enum-variant-reexport.stderr16
-rw-r--r--src/test/ui/privacy/restricted/auxiliary/pub_restricted.rs6
-rw-r--r--src/test/ui/privacy/restricted/private-in-public.rs4
-rw-r--r--src/test/ui/privacy/restricted/private-in-public.stderr8
-rw-r--r--src/test/ui/privacy/restricted/test.stderr10
-rw-r--r--src/test/ui/resolve/crate-in-paths.rs4
-rw-r--r--src/test/ui/resolve/crate-in-paths.stderr2
-rw-r--r--src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed6
-rw-r--r--src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs6
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed12
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs12
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-paths.fixed8
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-paths.rs8
-rw-r--r--src/tools/rustfmt/tests/source/fn-simple.rs2
-rw-r--r--src/tools/rustfmt/tests/source/pub-restricted.rs13
-rw-r--r--src/tools/rustfmt/tests/target/fn-simple.rs2
-rw-r--r--src/tools/rustfmt/tests/target/pub-restricted.rs13
271 files changed, 1902 insertions, 2052 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index b7091ea1864..988918b0505 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -340,7 +340,7 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
     NestedMetaItem::MetaItem(mk_word_item(ident))
 }
 
-crate fn mk_attr_id() -> AttrId {
+pub(crate) fn mk_attr_id() -> AttrId {
     use std::sync::atomic::AtomicU32;
     use std::sync::atomic::Ordering;
 
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 12467169192..2015d635e56 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(box_patterns)]
 #![feature(const_default_impls)]
 #![feature(const_trait_impl)]
-#![feature(crate_visibility_modifier)]
 #![feature(if_let_guard)]
 #![feature(label_break_value)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 35eca23a116..1522d12cbf9 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -134,7 +134,7 @@ impl LitKind {
         }
     }
 
-    crate fn may_have_suffix(self) -> bool {
+    pub(crate) fn may_have_suffix(self) -> bool {
         matches!(self, Integer | Float | Err)
     }
 }
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index ae3e3675962..6c055645ef3 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -17,7 +17,11 @@ use std::collections::hash_map::Entry;
 use std::fmt::Write;
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
-    crate fn lower_inline_asm(&mut self, sp: Span, asm: &InlineAsm) -> &'hir hir::InlineAsm<'hir> {
+    pub(crate) fn lower_inline_asm(
+        &mut self,
+        sp: Span,
+        asm: &InlineAsm,
+    ) -> &'hir hir::InlineAsm<'hir> {
         // Rustdoc needs to support asm! from foreign architectures: don't try
         // lowering the register constraints in this case.
         let asm_arch = if self.sess.opts.actually_rustdoc { None } else { self.sess.asm_arch };
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index cf97b270ed8..a01ab32c282 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -848,7 +848,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     /// Construct `ExprKind::Err` for the given `span`.
-    crate fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
+    pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
         self.expr(span, hir::ExprKind::Err, AttrVec::new())
     }
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index c143266f6c1..3dd6b4e52db 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -30,7 +30,6 @@
 //! get confused if the spans from leaf AST nodes occur in multiple places
 //! in the HIR, especially for multiple identifiers.
 
-#![feature(crate_visibility_modifier)]
 #![feature(box_patterns)]
 #![feature(let_chains)]
 #![feature(let_else)]
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2c331767b89..e27bc7a0f47 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -12,11 +12,11 @@ use rustc_span::symbol::Ident;
 use rustc_span::{source_map::Spanned, Span};
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
-    crate fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> {
+    pub(crate) fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> {
         self.arena.alloc(self.lower_pat_mut(pattern))
     }
 
-    crate fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
+    pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
         ensure_sufficient_stack(|| {
             // loop here to avoid recursion
             let node = loop {
@@ -290,7 +290,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     }
 
     /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
-    crate fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) {
+    pub(crate) fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) {
         self.diagnostic()
             .struct_span_err(sp, &format!("`..` can only be used once per {} pattern", ctx))
             .span_label(sp, &format!("can only be used once per {} pattern", ctx))
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 3c9399c1fdf..7fc8aac5116 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -15,7 +15,7 @@ use smallvec::smallvec;
 use tracing::debug;
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
-    crate fn lower_qpath(
+    pub(crate) fn lower_qpath(
         &mut self,
         id: NodeId,
         qself: &Option<QSelf>,
@@ -142,7 +142,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         );
     }
 
-    crate fn lower_path_extra(
+    pub(crate) fn lower_path_extra(
         &mut self,
         res: Res,
         p: &Path,
@@ -163,7 +163,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         })
     }
 
-    crate fn lower_path(
+    pub(crate) fn lower_path(
         &mut self,
         id: NodeId,
         p: &Path,
@@ -174,7 +174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.lower_path_extra(res, p, param_mode)
     }
 
-    crate fn lower_path_segment(
+    pub(crate) fn lower_path_segment(
         &mut self,
         path_span: Span,
         segment: &PathSegment,
@@ -381,7 +381,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     }
 
     /// An associated type binding `Output = $ty`.
-    crate fn output_ty_binding(
+    pub(crate) fn output_ty_binding(
         &mut self,
         span: Span,
         ty: &'hir hir::Ty<'hir>,
diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index 95beccbb728..79178830bf9 100644
--- a/compiler/rustc_ast_pretty/src/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
@@ -1,5 +1,4 @@
 #![feature(associated_type_bounds)]
-#![feature(crate_visibility_modifier)]
 #![feature(box_patterns)]
 #![feature(with_negative_coherence)]
 #![recursion_limit = "256"]
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index ed0177a5b4d..7357ddf2134 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -95,7 +95,7 @@ pub struct State<'a> {
     ann: &'a (dyn PpAnn + 'a),
 }
 
-crate const INDENT_UNIT: isize = 4;
+pub(crate) const INDENT_UNIT: isize = 4;
 
 /// Requires you to pass an input filename and reader so that
 /// it can scan the input text for comments to copy forward.
@@ -955,8 +955,13 @@ impl<'a> State<'a> {
         State { s: pp::Printer::new(), comments: None, ann: &NoAnn }
     }
 
-    crate fn commasep_cmnt<T, F, G>(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G)
-    where
+    pub(crate) fn commasep_cmnt<T, F, G>(
+        &mut self,
+        b: Breaks,
+        elts: &[T],
+        mut op: F,
+        mut get_span: G,
+    ) where
         F: FnMut(&mut State<'_>, &T),
         G: FnMut(&T) -> rustc_span::Span,
     {
@@ -976,7 +981,7 @@ impl<'a> State<'a> {
         self.end();
     }
 
-    crate fn commasep_exprs(&mut self, b: Breaks, exprs: &[P<ast::Expr>]) {
+    pub(crate) fn commasep_exprs(&mut self, b: Breaks, exprs: &[P<ast::Expr>]) {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span)
     }
 
@@ -1109,7 +1114,7 @@ impl<'a> State<'a> {
         self.print_trait_ref(&t.trait_ref)
     }
 
-    crate fn print_stmt(&mut self, st: &ast::Stmt) {
+    pub(crate) fn print_stmt(&mut self, st: &ast::Stmt) {
         self.maybe_print_comment(st.span.lo());
         match st.kind {
             ast::StmtKind::Local(ref loc) => {
@@ -1164,19 +1169,19 @@ impl<'a> State<'a> {
         self.maybe_print_trailing_comment(st.span, None)
     }
 
-    crate fn print_block(&mut self, blk: &ast::Block) {
+    pub(crate) fn print_block(&mut self, blk: &ast::Block) {
         self.print_block_with_attrs(blk, &[])
     }
 
-    crate fn print_block_unclosed_indent(&mut self, blk: &ast::Block) {
+    pub(crate) fn print_block_unclosed_indent(&mut self, blk: &ast::Block) {
         self.print_block_maybe_unclosed(blk, &[], false)
     }
 
-    crate fn print_block_with_attrs(&mut self, blk: &ast::Block, attrs: &[ast::Attribute]) {
+    pub(crate) fn print_block_with_attrs(&mut self, blk: &ast::Block, attrs: &[ast::Attribute]) {
         self.print_block_maybe_unclosed(blk, attrs, true)
     }
 
-    crate fn print_block_maybe_unclosed(
+    pub(crate) fn print_block_maybe_unclosed(
         &mut self,
         blk: &ast::Block,
         attrs: &[ast::Attribute],
@@ -1210,7 +1215,7 @@ impl<'a> State<'a> {
     }
 
     /// Print a `let pat = expr` expression.
-    crate fn print_let(&mut self, pat: &ast::Pat, expr: &ast::Expr) {
+    pub(crate) fn print_let(&mut self, pat: &ast::Pat, expr: &ast::Expr) {
         self.word("let ");
         self.print_pat(pat);
         self.space();
@@ -1219,7 +1224,7 @@ impl<'a> State<'a> {
         self.print_expr_cond_paren(expr, Self::cond_needs_par(expr) || npals())
     }
 
-    crate fn print_mac(&mut self, m: &ast::MacCall) {
+    pub(crate) fn print_mac(&mut self, m: &ast::MacCall) {
         self.print_mac_common(
             Some(MacHeader::Path(&m.path)),
             true,
@@ -1360,7 +1365,7 @@ impl<'a> State<'a> {
         self.pclose();
     }
 
-    crate fn print_local_decl(&mut self, loc: &ast::Local) {
+    pub(crate) fn print_local_decl(&mut self, loc: &ast::Local) {
         self.print_pat(&loc.pat);
         if let Some(ref ty) = loc.ty {
             self.word_space(":");
@@ -1368,7 +1373,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_name(&mut self, name: Symbol) {
+    pub(crate) fn print_name(&mut self, name: Symbol) {
         self.word(name.to_string());
         self.ann.post(self, AnnNode::Name(&name))
     }
@@ -1392,7 +1397,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_pat(&mut self, pat: &ast::Pat) {
+    pub(crate) fn print_pat(&mut self, pat: &ast::Pat) {
         self.maybe_print_comment(pat.span.lo());
         self.ann.pre(self, AnnNode::Pat(pat));
         /* Pat isn't normalized, but the beauty of it
@@ -1551,7 +1556,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_asyncness(&mut self, asyncness: ast::Async) {
+    pub(crate) fn print_asyncness(&mut self, asyncness: ast::Async) {
         if asyncness.is_async() {
             self.word_nbsp("async");
         }
@@ -1584,11 +1589,11 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_lifetime(&mut self, lifetime: ast::Lifetime) {
+    pub(crate) fn print_lifetime(&mut self, lifetime: ast::Lifetime) {
         self.print_name(lifetime.ident.name)
     }
 
-    crate fn print_lifetime_bounds(
+    pub(crate) fn print_lifetime_bounds(
         &mut self,
         lifetime: ast::Lifetime,
         bounds: &ast::GenericBounds,
@@ -1608,7 +1613,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_generic_params(&mut self, generic_params: &[ast::GenericParam]) {
+    pub(crate) fn print_generic_params(&mut self, generic_params: &[ast::GenericParam]) {
         if generic_params.is_empty() {
             return;
         }
@@ -1662,12 +1667,12 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_mt(&mut self, mt: &ast::MutTy, print_const: bool) {
+    pub(crate) fn print_mt(&mut self, mt: &ast::MutTy, print_const: bool) {
         self.print_mutability(mt.mutbl, print_const);
         self.print_type(&mt.ty)
     }
 
-    crate fn print_param(&mut self, input: &ast::Param, is_closure: bool) {
+    pub(crate) fn print_param(&mut self, input: &ast::Param, is_closure: bool) {
         self.ibox(INDENT_UNIT);
 
         self.print_outer_attributes_inline(&input.attrs);
@@ -1695,7 +1700,7 @@ impl<'a> State<'a> {
         self.end();
     }
 
-    crate fn print_fn_ret_ty(&mut self, fn_ret_ty: &ast::FnRetTy) {
+    pub(crate) fn print_fn_ret_ty(&mut self, fn_ret_ty: &ast::FnRetTy) {
         if let ast::FnRetTy::Ty(ty) = fn_ret_ty {
             self.space_if_not_bol();
             self.ibox(INDENT_UNIT);
@@ -1706,7 +1711,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_ty_fn(
+    pub(crate) fn print_ty_fn(
         &mut self,
         ext: ast::Extern,
         unsafety: ast::Unsafe,
@@ -1730,7 +1735,7 @@ impl<'a> State<'a> {
         self.end();
     }
 
-    crate fn print_fn_header_info(&mut self, header: ast::FnHeader) {
+    pub(crate) fn print_fn_header_info(&mut self, header: ast::FnHeader) {
         self.print_constness(header.constness);
         self.print_asyncness(header.asyncness);
         self.print_unsafety(header.unsafety);
@@ -1750,21 +1755,21 @@ impl<'a> State<'a> {
         self.word("fn")
     }
 
-    crate fn print_unsafety(&mut self, s: ast::Unsafe) {
+    pub(crate) fn print_unsafety(&mut self, s: ast::Unsafe) {
         match s {
             ast::Unsafe::No => {}
             ast::Unsafe::Yes(_) => self.word_nbsp("unsafe"),
         }
     }
 
-    crate fn print_constness(&mut self, s: ast::Const) {
+    pub(crate) fn print_constness(&mut self, s: ast::Const) {
         match s {
             ast::Const::No => {}
             ast::Const::Yes(_) => self.word_nbsp("const"),
         }
     }
 
-    crate fn print_is_auto(&mut self, s: ast::IsAuto) {
+    pub(crate) fn print_is_auto(&mut self, s: ast::IsAuto) {
         match s {
             ast::IsAuto::Yes => self.word_nbsp("auto"),
             ast::IsAuto::No => {}
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 23c5a92e352..0de5e2099fd 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -19,7 +19,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_foreign_item(&mut self, item: &ast::ForeignItem) {
+    pub(crate) fn print_foreign_item(&mut self, item: &ast::ForeignItem) {
         let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item;
         self.ann.pre(self, AnnNode::SubItem(id));
         self.hardbreak_if_not_bol();
@@ -128,7 +128,7 @@ impl<'a> State<'a> {
     }
 
     /// Pretty-prints an item.
-    crate fn print_item(&mut self, item: &ast::Item) {
+    pub(crate) fn print_item(&mut self, item: &ast::Item) {
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(item.span.lo());
         self.print_outer_attributes(&item.attrs);
@@ -400,7 +400,7 @@ impl<'a> State<'a> {
         self.bclose(span, empty)
     }
 
-    crate fn print_visibility(&mut self, vis: &ast::Visibility) {
+    pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) {
         match vis.kind {
             ast::VisibilityKind::Public => self.word_nbsp("pub"),
             ast::VisibilityKind::Crate(sugar) => match sugar {
@@ -484,7 +484,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_variant(&mut self, v: &ast::Variant) {
+    pub(crate) fn print_variant(&mut self, v: &ast::Variant) {
         self.head("");
         self.print_visibility(&v.vis);
         let generics = ast::Generics::default();
@@ -496,7 +496,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_assoc_item(&mut self, item: &ast::AssocItem) {
+    pub(crate) fn print_assoc_item(&mut self, item: &ast::AssocItem) {
         let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item;
         self.ann.pre(self, AnnNode::SubItem(id));
         self.hardbreak_if_not_bol();
@@ -562,7 +562,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_fn(
+    pub(crate) fn print_fn(
         &mut self,
         decl: &ast::FnDecl,
         header: ast::FnHeader,
@@ -579,7 +579,7 @@ impl<'a> State<'a> {
         self.print_where_clause(&generics.where_clause)
     }
 
-    crate fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) {
+    pub(crate) fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) {
         let (open, close) = if is_closure { ("|", "|") } else { ("(", ")") };
         self.word(open);
         self.commasep(Inconsistent, &decl.inputs, |s, param| s.print_param(param, is_closure));
@@ -591,7 +591,7 @@ impl<'a> State<'a> {
         self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates);
     }
 
-    crate fn print_where_clause_parts(
+    pub(crate) fn print_where_clause_parts(
         &mut self,
         has_where_token: bool,
         predicates: &[ast::WherePredicate],
diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs
index 7c921b85058..c7d0e336133 100644
--- a/compiler/rustc_borrowck/src/borrow_set.rs
+++ b/compiler/rustc_borrowck/src/borrow_set.rs
@@ -29,7 +29,7 @@ pub struct BorrowSet<'tcx> {
     /// Map from local to all the borrows on that local.
     pub local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
 
-    crate locals_state_at_exit: LocalsStateAtExit,
+    pub(crate) locals_state_at_exit: LocalsStateAtExit,
 }
 
 impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
@@ -148,23 +148,23 @@ impl<'tcx> BorrowSet<'tcx> {
         }
     }
 
-    crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] {
+    pub(crate) fn activations_at_location(&self, location: Location) -> &[BorrowIndex] {
         self.activation_map.get(&location).map_or(&[], |activations| &activations[..])
     }
 
-    crate fn len(&self) -> usize {
+    pub(crate) fn len(&self) -> usize {
         self.location_map.len()
     }
 
-    crate fn indices(&self) -> impl Iterator<Item = BorrowIndex> {
+    pub(crate) fn indices(&self) -> impl Iterator<Item = BorrowIndex> {
         BorrowIndex::from_usize(0)..BorrowIndex::from_usize(self.len())
     }
 
-    crate fn iter_enumerated(&self) -> impl Iterator<Item = (BorrowIndex, &BorrowData<'tcx>)> {
+    pub(crate) fn iter_enumerated(&self) -> impl Iterator<Item = (BorrowIndex, &BorrowData<'tcx>)> {
         self.indices().zip(self.location_map.values())
     }
 
-    crate fn get_index_of(&self, location: &Location) -> Option<BorrowIndex> {
+    pub(crate) fn get_index_of(&self, location: &Location) -> Option<BorrowIndex> {
         self.location_map.get_index_of(location).map(BorrowIndex::from)
     }
 }
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index 70f7f1e493e..a1233d62cb0 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -3,7 +3,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
 
 impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
-    crate fn cannot_move_when_borrowed(
+    pub(crate) fn cannot_move_when_borrowed(
         &self,
         span: Span,
         desc: &str,
@@ -11,7 +11,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,)
     }
 
-    crate fn cannot_use_when_mutably_borrowed(
+    pub(crate) fn cannot_use_when_mutably_borrowed(
         &self,
         span: Span,
         desc: &str,
@@ -31,7 +31,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_act_on_uninitialized_variable(
+    pub(crate) fn cannot_act_on_uninitialized_variable(
         &self,
         span: Span,
         verb: &str,
@@ -47,7 +47,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         )
     }
 
-    crate fn cannot_mutably_borrow_multiply(
+    pub(crate) fn cannot_mutably_borrow_multiply(
         &self,
         new_loan_span: Span,
         desc: &str,
@@ -97,7 +97,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_uniquely_borrow_by_two_closures(
+    pub(crate) fn cannot_uniquely_borrow_by_two_closures(
         &self,
         new_loan_span: Span,
         desc: &str,
@@ -126,7 +126,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_uniquely_borrow_by_one_closure(
+    pub(crate) fn cannot_uniquely_borrow_by_one_closure(
         &self,
         new_loan_span: Span,
         container_name: &str,
@@ -157,7 +157,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_reborrow_already_uniquely_borrowed(
+    pub(crate) fn cannot_reborrow_already_uniquely_borrowed(
         &self,
         new_loan_span: Span,
         container_name: &str,
@@ -193,7 +193,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_reborrow_already_borrowed(
+    pub(crate) fn cannot_reborrow_already_borrowed(
         &self,
         span: Span,
         desc_new: &str,
@@ -242,7 +242,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_assign_to_borrowed(
+    pub(crate) fn cannot_assign_to_borrowed(
         &self,
         span: Span,
         borrow_span: Span,
@@ -261,7 +261,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_reassign_immutable(
+    pub(crate) fn cannot_reassign_immutable(
         &self,
         span: Span,
         desc: &str,
@@ -271,7 +271,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc)
     }
 
-    crate fn cannot_assign(
+    pub(crate) fn cannot_assign(
         &self,
         span: Span,
         desc: &str,
@@ -279,7 +279,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         struct_span_err!(self, span, E0594, "cannot assign to {}", desc)
     }
 
-    crate fn cannot_move_out_of(
+    pub(crate) fn cannot_move_out_of(
         &self,
         move_from_span: Span,
         move_from_desc: &str,
@@ -290,7 +290,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
     /// Signal an error due to an attempt to move out of the interior
     /// of an array or slice. `is_index` is None when error origin
     /// didn't capture whether there was an indexing operation or not.
-    crate fn cannot_move_out_of_interior_noncopy(
+    pub(crate) fn cannot_move_out_of_interior_noncopy(
         &self,
         move_from_span: Span,
         ty: Ty<'_>,
@@ -313,7 +313,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_move_out_of_interior_of_drop(
+    pub(crate) fn cannot_move_out_of_interior_of_drop(
         &self,
         move_from_span: Span,
         container_ty: Ty<'_>,
@@ -329,7 +329,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_act_on_moved_value(
+    pub(crate) fn cannot_act_on_moved_value(
         &self,
         use_span: Span,
         verb: &str,
@@ -349,7 +349,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         )
     }
 
-    crate fn cannot_borrow_path_as_mutable_because(
+    pub(crate) fn cannot_borrow_path_as_mutable_because(
         &self,
         span: Span,
         path: &str,
@@ -358,7 +358,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,)
     }
 
-    crate fn cannot_mutate_in_immutable_section(
+    pub(crate) fn cannot_mutate_in_immutable_section(
         &self,
         mutate_span: Span,
         immutable_span: Span,
@@ -380,7 +380,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_borrow_across_generator_yield(
+    pub(crate) fn cannot_borrow_across_generator_yield(
         &self,
         span: Span,
         yield_span: Span,
@@ -395,7 +395,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_borrow_across_destructor(
+    pub(crate) fn cannot_borrow_across_destructor(
         &self,
         borrow_span: Span,
     ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
@@ -407,7 +407,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         )
     }
 
-    crate fn path_does_not_live_long_enough(
+    pub(crate) fn path_does_not_live_long_enough(
         &self,
         span: Span,
         path: &str,
@@ -415,7 +415,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         struct_span_err!(self, span, E0597, "{} does not live long enough", path,)
     }
 
-    crate fn cannot_return_reference_to_local(
+    pub(crate) fn cannot_return_reference_to_local(
         &self,
         span: Span,
         return_kind: &str,
@@ -440,7 +440,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn cannot_capture_in_long_lived_closure(
+    pub(crate) fn cannot_capture_in_long_lived_closure(
         &self,
         closure_span: Span,
         closure_kind: &str,
@@ -462,14 +462,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    crate fn thread_local_value_does_not_live_long_enough(
+    pub(crate) fn thread_local_value_does_not_live_long_enough(
         &self,
         span: Span,
     ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
         struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",)
     }
 
-    crate fn temporary_value_borrowed_for_too_long(
+    pub(crate) fn temporary_value_borrowed_for_too_long(
         &self,
         span: Span,
     ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
@@ -486,7 +486,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
     }
 }
 
-crate fn borrowed_data_escapes_closure<'tcx>(
+pub(crate) fn borrowed_data_escapes_closure<'tcx>(
     tcx: TyCtxt<'tcx>,
     escape_span: Span,
     escapes_from: &str,
diff --git a/compiler/rustc_borrowck/src/constraints/graph.rs b/compiler/rustc_borrowck/src/constraints/graph.rs
index c19a39c393f..609fbc2bc15 100644
--- a/compiler/rustc_borrowck/src/constraints/graph.rs
+++ b/compiler/rustc_borrowck/src/constraints/graph.rs
@@ -13,19 +13,19 @@ use crate::{
 /// The construct graph organizes the constraints by their end-points.
 /// It can be used to view a `R1: R2` constraint as either an edge `R1
 /// -> R2` or `R2 -> R1` depending on the direction type `D`.
-crate struct ConstraintGraph<D: ConstraintGraphDirecton> {
+pub(crate) struct ConstraintGraph<D: ConstraintGraphDirecton> {
     _direction: D,
     first_constraints: IndexVec<RegionVid, Option<OutlivesConstraintIndex>>,
     next_constraints: IndexVec<OutlivesConstraintIndex, Option<OutlivesConstraintIndex>>,
 }
 
-crate type NormalConstraintGraph = ConstraintGraph<Normal>;
+pub(crate) type NormalConstraintGraph = ConstraintGraph<Normal>;
 
-crate type ReverseConstraintGraph = ConstraintGraph<Reverse>;
+pub(crate) type ReverseConstraintGraph = ConstraintGraph<Reverse>;
 
 /// Marker trait that controls whether a `R1: R2` constraint
 /// represents an edge `R1 -> R2` or `R2 -> R1`.
-crate trait ConstraintGraphDirecton: Copy + 'static {
+pub(crate) trait ConstraintGraphDirecton: Copy + 'static {
     fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid;
     fn end_region(c: &OutlivesConstraint<'_>) -> RegionVid;
     fn is_normal() -> bool;
@@ -36,7 +36,7 @@ crate trait ConstraintGraphDirecton: Copy + 'static {
 /// inference. This is because we compute the value of R1 by union'ing
 /// all the things that it relies on.
 #[derive(Copy, Clone, Debug)]
-crate struct Normal;
+pub(crate) struct Normal;
 
 impl ConstraintGraphDirecton for Normal {
     fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid {
@@ -57,7 +57,7 @@ impl ConstraintGraphDirecton for Normal {
 /// we wish to iterate from a region (e.g., R2) to all the regions
 /// that will outlive it (e.g., R1).
 #[derive(Copy, Clone, Debug)]
-crate struct Reverse;
+pub(crate) struct Reverse;
 
 impl ConstraintGraphDirecton for Reverse {
     fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid {
@@ -78,7 +78,11 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     /// R2` is treated as an edge `R1 -> R2`. We use this graph to
     /// construct SCCs for region inference but also for error
     /// reporting.
-    crate fn new(direction: D, set: &OutlivesConstraintSet<'_>, num_region_vars: usize) -> Self {
+    pub(crate) fn new(
+        direction: D,
+        set: &OutlivesConstraintSet<'_>,
+        num_region_vars: usize,
+    ) -> Self {
         let mut first_constraints = IndexVec::from_elem_n(None, num_region_vars);
         let mut next_constraints = IndexVec::from_elem(None, &set.outlives);
 
@@ -96,7 +100,7 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     /// Given the constraint set from which this graph was built
     /// creates a region graph so that you can iterate over *regions*
     /// and not constraints.
-    crate fn region_graph<'rg, 'tcx>(
+    pub(crate) fn region_graph<'rg, 'tcx>(
         &'rg self,
         set: &'rg OutlivesConstraintSet<'tcx>,
         static_region: RegionVid,
@@ -105,7 +109,7 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     }
 
     /// Given a region `R`, iterate over all constraints `R: R1`.
-    crate fn outgoing_edges<'a, 'tcx>(
+    pub(crate) fn outgoing_edges<'a, 'tcx>(
         &'a self,
         region_sup: RegionVid,
         constraints: &'a OutlivesConstraintSet<'tcx>,
@@ -129,7 +133,7 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     }
 }
 
-crate struct Edges<'s, 'tcx, D: ConstraintGraphDirecton> {
+pub(crate) struct Edges<'s, 'tcx, D: ConstraintGraphDirecton> {
     graph: &'s ConstraintGraph<D>,
     constraints: &'s OutlivesConstraintSet<'tcx>,
     pointer: Option<OutlivesConstraintIndex>,
@@ -169,7 +173,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> {
 /// This struct brings together a constraint set and a (normal, not
 /// reverse) constraint graph. It implements the graph traits and is
 /// usd for doing the SCC computation.
-crate struct RegionGraph<'s, 'tcx, D: ConstraintGraphDirecton> {
+pub(crate) struct RegionGraph<'s, 'tcx, D: ConstraintGraphDirecton> {
     set: &'s OutlivesConstraintSet<'tcx>,
     constraint_graph: &'s ConstraintGraph<D>,
     static_region: RegionVid,
@@ -180,7 +184,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> RegionGraph<'s, 'tcx, D> {
     /// R2` is treated as an edge `R1 -> R2`. We use this graph to
     /// construct SCCs for region inference but also for error
     /// reporting.
-    crate fn new(
+    pub(crate) fn new(
         set: &'s OutlivesConstraintSet<'tcx>,
         constraint_graph: &'s ConstraintGraph<D>,
         static_region: RegionVid,
@@ -190,14 +194,14 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> RegionGraph<'s, 'tcx, D> {
 
     /// Given a region `R`, iterate over all regions `R1` such that
     /// there exists a constraint `R: R1`.
-    crate fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'s, 'tcx, D> {
+    pub(crate) fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'s, 'tcx, D> {
         Successors {
             edges: self.constraint_graph.outgoing_edges(region_sup, self.set, self.static_region),
         }
     }
 }
 
-crate struct Successors<'s, 'tcx, D: ConstraintGraphDirecton> {
+pub(crate) struct Successors<'s, 'tcx, D: ConstraintGraphDirecton> {
     edges: Edges<'s, 'tcx, D>,
 }
 
diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs
index 14f0e5f620a..6d5466c0c41 100644
--- a/compiler/rustc_borrowck/src/constraints/mod.rs
+++ b/compiler/rustc_borrowck/src/constraints/mod.rs
@@ -8,19 +8,19 @@ use std::ops::Index;
 
 use crate::type_check::Locations;
 
-crate mod graph;
+pub(crate) mod graph;
 
 /// A set of NLL region constraints. These include "outlives"
 /// constraints of the form `R1: R2`. Each constraint is identified by
 /// a unique `OutlivesConstraintIndex` and you can index into the set
 /// (`constraint_set[i]`) to access the constraint details.
 #[derive(Clone, Default)]
-crate struct OutlivesConstraintSet<'tcx> {
+pub(crate) struct OutlivesConstraintSet<'tcx> {
     outlives: IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>>,
 }
 
 impl<'tcx> OutlivesConstraintSet<'tcx> {
-    crate fn push(&mut self, constraint: OutlivesConstraint<'tcx>) {
+    pub(crate) fn push(&mut self, constraint: OutlivesConstraint<'tcx>) {
         debug!(
             "OutlivesConstraintSet::push({:?}: {:?} @ {:?}",
             constraint.sup, constraint.sub, constraint.locations
@@ -38,20 +38,20 @@ impl<'tcx> OutlivesConstraintSet<'tcx> {
     /// N.B., this graph contains a "frozen" view of the current
     /// constraints. Any new constraints added to the `OutlivesConstraintSet`
     /// after the graph is built will not be present in the graph.
-    crate fn graph(&self, num_region_vars: usize) -> graph::NormalConstraintGraph {
+    pub(crate) fn graph(&self, num_region_vars: usize) -> graph::NormalConstraintGraph {
         graph::ConstraintGraph::new(graph::Normal, self, num_region_vars)
     }
 
     /// Like `graph`, but constraints a reverse graph where `R1: R2`
     /// represents an edge `R2 -> R1`.
-    crate fn reverse_graph(&self, num_region_vars: usize) -> graph::ReverseConstraintGraph {
+    pub(crate) fn reverse_graph(&self, num_region_vars: usize) -> graph::ReverseConstraintGraph {
         graph::ConstraintGraph::new(graph::Reverse, self, num_region_vars)
     }
 
     /// Computes cycles (SCCs) in the graph of regions. In particular,
     /// find all regions R1, R2 such that R1: R2 and R2: R1 and group
     /// them into an SCC, and find the relationships between SCCs.
-    crate fn compute_sccs(
+    pub(crate) fn compute_sccs(
         &self,
         constraint_graph: &graph::NormalConstraintGraph,
         static_region: RegionVid,
@@ -60,7 +60,7 @@ impl<'tcx> OutlivesConstraintSet<'tcx> {
         Sccs::new(region_graph)
     }
 
-    crate fn outlives(&self) -> &IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>> {
+    pub(crate) fn outlives(&self) -> &IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>> {
         &self.outlives
     }
 }
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 5252b0b50c3..97d5a8d158e 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -233,7 +233,7 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
 }
 
 impl<'a, 'tcx> Borrows<'a, 'tcx> {
-    crate fn new(
+    pub(crate) fn new(
         tcx: TyCtxt<'tcx>,
         body: &'a Body<'tcx>,
         nonlexical_regioncx: &'a RegionInferenceContext<'tcx>,
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 8601fbe27f3..07f182102f3 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -22,7 +22,7 @@ use crate::region_infer::values::RegionElement;
 use crate::MirBorrowckCtxt;
 
 #[derive(Clone)]
-crate struct UniverseInfo<'tcx>(UniverseInfoInner<'tcx>);
+pub(crate) struct UniverseInfo<'tcx>(UniverseInfoInner<'tcx>);
 
 /// What operation a universe was created for.
 #[derive(Clone)]
@@ -36,15 +36,15 @@ enum UniverseInfoInner<'tcx> {
 }
 
 impl<'tcx> UniverseInfo<'tcx> {
-    crate fn other() -> UniverseInfo<'tcx> {
+    pub(crate) fn other() -> UniverseInfo<'tcx> {
         UniverseInfo(UniverseInfoInner::Other)
     }
 
-    crate fn relate(expected: Ty<'tcx>, found: Ty<'tcx>) -> UniverseInfo<'tcx> {
+    pub(crate) fn relate(expected: Ty<'tcx>, found: Ty<'tcx>) -> UniverseInfo<'tcx> {
         UniverseInfo(UniverseInfoInner::RelateTys { expected, found })
     }
 
-    crate fn report_error(
+    pub(crate) fn report_error(
         &self,
         mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
         placeholder: ty::PlaceholderRegion,
@@ -76,7 +76,7 @@ impl<'tcx> UniverseInfo<'tcx> {
     }
 }
 
-crate trait ToUniverseInfo<'tcx> {
+pub(crate) trait ToUniverseInfo<'tcx> {
     fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx>;
 }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs
index 22e7cd9e52c..06fca4db0cf 100644
--- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs
@@ -11,7 +11,7 @@ use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
 use rustc_middle::mir::{Body, Local, Location};
 use rustc_middle::ty::{RegionVid, TyCtxt};
 
-crate fn find<'tcx>(
+pub(crate) fn find<'tcx>(
     body: &Body<'tcx>,
     regioncx: &Rc<RegionInferenceContext<'tcx>>,
     tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 05d29503180..9581bb65236 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -35,12 +35,12 @@ mod move_errors;
 mod mutability_errors;
 mod region_errors;
 
-crate use bound_region_errors::{ToUniverseInfo, UniverseInfo};
-crate use mutability_errors::AccessKind;
-crate use outlives_suggestion::OutlivesSuggestionBuilder;
-crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
-crate use region_name::{RegionName, RegionNameSource};
-crate use rustc_const_eval::util::CallKind;
+pub(crate) use bound_region_errors::{ToUniverseInfo, UniverseInfo};
+pub(crate) use mutability_errors::AccessKind;
+pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder;
+pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
+pub(crate) use region_name::{RegionName, RegionNameSource};
+pub(crate) use rustc_const_eval::util::CallKind;
 use rustc_middle::mir::tcx::PlaceTy;
 
 pub(super) struct IncludingDowncast(pub(super) bool);
diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
index ab9c206a46f..1688d1259fa 100644
--- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
@@ -149,7 +149,7 @@ impl OutlivesSuggestionBuilder {
     }
 
     /// Add the outlives constraint `fr: outlived_fr` to the set of constraints we need to suggest.
-    crate fn collect_constraint(&mut self, fr: RegionVid, outlived_fr: RegionVid) {
+    pub(crate) fn collect_constraint(&mut self, fr: RegionVid, outlived_fr: RegionVid) {
         debug!("Collected {:?}: {:?}", fr, outlived_fr);
 
         // Add to set of constraints for final help note.
@@ -158,7 +158,7 @@ impl OutlivesSuggestionBuilder {
 
     /// Emit an intermediate note on the given `Diagnostic` if the involved regions are
     /// suggestable.
-    crate fn intermediate_suggestion(
+    pub(crate) fn intermediate_suggestion(
         &mut self,
         mbcx: &MirBorrowckCtxt<'_, '_>,
         errci: &ErrorConstraintInfo,
@@ -179,7 +179,7 @@ impl OutlivesSuggestionBuilder {
 
     /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final
     /// suggestion including all collected constraints.
-    crate fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) {
+    pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) {
         // No constraints to add? Done.
         if self.constraints_to_add.is_empty() {
             debug!("No constraints to suggest.");
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 6f1c8daf42e..f2b5c83c5c1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -58,10 +58,10 @@ impl ConstraintDescription for ConstraintCategory {
 ///
 /// Usually we expect this to either be empty or contain a small number of items, so we can avoid
 /// allocation most of the time.
-crate type RegionErrors<'tcx> = Vec<RegionErrorKind<'tcx>>;
+pub(crate) type RegionErrors<'tcx> = Vec<RegionErrorKind<'tcx>>;
 
 #[derive(Clone, Debug)]
-crate enum RegionErrorKind<'tcx> {
+pub(crate) enum RegionErrorKind<'tcx> {
     /// A generic bound failure for a type test (`T: 'a`).
     TypeTestError { type_test: TypeTest<'tcx> },
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index c4cef5710ae..4d2a16aa609 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -15,18 +15,18 @@ use crate::{nll::ToRegionVid, universal_regions::DefiningTy, MirBorrowckCtxt};
 /// A name for a particular region used in emitting diagnostics. This name could be a generated
 /// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
 #[derive(Debug, Clone)]
-crate struct RegionName {
+pub(crate) struct RegionName {
     /// The name of the region (interned).
-    crate name: Symbol,
+    pub(crate) name: Symbol,
     /// Where the region comes from.
-    crate source: RegionNameSource,
+    pub(crate) source: RegionNameSource,
 }
 
 /// Denotes the source of a region that is named by a `RegionName`. For example, a free region that
 /// was named by the user would get `NamedFreeRegion` and `'static` lifetime would get `Static`.
 /// This helps to print the right kinds of diagnostics.
 #[derive(Debug, Clone)]
-crate enum RegionNameSource {
+pub(crate) enum RegionNameSource {
     /// A bound (not free) region that was substituted at the def site (not an HRTB).
     NamedEarlyBoundRegion(Span),
     /// A free region that the user has a name (`'a`) for.
@@ -50,7 +50,7 @@ crate enum RegionNameSource {
 /// Describes what to highlight to explain to the user that we're giving an anonymous region a
 /// synthesized name, and how to highlight it.
 #[derive(Debug, Clone)]
-crate enum RegionNameHighlight {
+pub(crate) enum RegionNameHighlight {
     /// The anonymous region corresponds to a reference that was found by traversing the type in the HIR.
     MatchedHirTy(Span),
     /// The anonymous region corresponds to a `'_` in the generics list of a struct/enum/union.
@@ -65,7 +65,7 @@ crate enum RegionNameHighlight {
 }
 
 impl RegionName {
-    crate fn was_named(&self) -> bool {
+    pub(crate) fn was_named(&self) -> bool {
         match self.source {
             RegionNameSource::NamedEarlyBoundRegion(..)
             | RegionNameSource::NamedFreeRegion(..)
@@ -79,7 +79,7 @@ impl RegionName {
         }
     }
 
-    crate fn span(&self) -> Option<Span> {
+    pub(crate) fn span(&self) -> Option<Span> {
         match self.source {
             RegionNameSource::Static => None,
             RegionNameSource::NamedEarlyBoundRegion(span)
@@ -98,7 +98,7 @@ impl RegionName {
         }
     }
 
-    crate fn highlight_region_name(&self, diag: &mut Diagnostic) {
+    pub(crate) fn highlight_region_name(&self, diag: &mut Diagnostic) {
         match &self.source {
             RegionNameSource::NamedFreeRegion(span)
             | RegionNameSource::NamedEarlyBoundRegion(span) => {
@@ -178,11 +178,11 @@ impl Display for RegionName {
 }
 
 impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
-    crate fn mir_def_id(&self) -> hir::def_id::LocalDefId {
+    pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId {
         self.body.source.def_id().as_local().unwrap()
     }
 
-    crate fn mir_hir_id(&self) -> hir::HirId {
+    pub(crate) fn mir_hir_id(&self) -> hir::HirId {
         self.infcx.tcx.hir().local_def_id_to_hir_id(self.mir_def_id())
     }
 
@@ -222,7 +222,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
     /// ```
     ///
     /// and then return the name `'1` for us to use.
-    crate fn give_region_a_name(&self, fr: RegionVid) -> Option<RegionName> {
+    pub(crate) fn give_region_a_name(&self, fr: RegionVid) -> Option<RegionName> {
         debug!(
             "give_region_a_name(fr={:?}, counter={:?})",
             fr,
diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
index 00f62806753..9ba29f04b1a 100644
--- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
@@ -7,7 +7,7 @@ use rustc_span::source_map::Span;
 use rustc_span::symbol::Symbol;
 
 impl<'tcx> RegionInferenceContext<'tcx> {
-    crate fn get_var_name_and_span_for_region(
+    pub(crate) fn get_var_name_and_span_for_region(
         &self,
         tcx: TyCtxt<'tcx>,
         body: &Body<'tcx>,
@@ -34,7 +34,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     /// Search the upvars (if any) to find one that references fr. Return its index.
-    crate fn get_upvar_index_for_region(&self, tcx: TyCtxt<'tcx>, fr: RegionVid) -> Option<usize> {
+    pub(crate) fn get_upvar_index_for_region(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        fr: RegionVid,
+    ) -> Option<usize> {
         let upvar_index =
             self.universal_regions().defining_ty.upvar_tys().position(|upvar_ty| {
                 debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty);
@@ -57,7 +61,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
     /// Given the index of an upvar, finds its name and the span from where it was
     /// declared.
-    crate fn get_upvar_name_and_span_for_region(
+    pub(crate) fn get_upvar_name_and_span_for_region(
         &self,
         tcx: TyCtxt<'tcx>,
         upvars: &[Upvar<'tcx>],
@@ -81,7 +85,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ///
     /// N.B., in the case of a closure, the index is indexing into the signature as seen by the
     /// user - in particular, index 0 is not the implicit self parameter.
-    crate fn get_argument_index_for_region(
+    pub(crate) fn get_argument_index_for_region(
         &self,
         tcx: TyCtxt<'tcx>,
         fr: RegionVid,
@@ -107,7 +111,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
     /// Given the index of an argument, finds its name (if any) and the span from where it was
     /// declared.
-    crate fn get_argument_name_and_span_for_region(
+    pub(crate) fn get_argument_name_and_span_for_region(
         &self,
         body: &Body<'tcx>,
         local_names: &IndexVec<Local, Option<Symbol>>,
diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs
index 86b719bdfa0..7f0a637c9d3 100644
--- a/compiler/rustc_borrowck/src/facts.rs
+++ b/compiler/rustc_borrowck/src/facts.rs
@@ -25,7 +25,7 @@ impl polonius_engine::FactTypes for RustcFacts {
 
 pub type AllFacts = PoloniusFacts<RustcFacts>;
 
-crate trait AllFactsExt {
+pub(crate) trait AllFactsExt {
     /// Returns `true` if there is a need to gather `AllFacts` given the
     /// current `-Z` flags.
     fn enabled(tcx: TyCtxt<'_>) -> bool;
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 4661805bb1c..a3e7c953ee3 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -2,7 +2,6 @@
 
 #![allow(rustc::potential_query_instability)]
 #![feature(box_patterns)]
-#![feature(crate_visibility_modifier)]
 #![feature(let_chains)]
 #![feature(let_else)]
 #![feature(min_specialization)]
diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs
index c89da5514fd..70a31169498 100644
--- a/compiler/rustc_borrowck/src/location.rs
+++ b/compiler/rustc_borrowck/src/location.rs
@@ -30,7 +30,7 @@ pub enum RichLocation {
 }
 
 impl LocationTable {
-    crate fn new(body: &Body<'_>) -> Self {
+    pub(crate) fn new(body: &Body<'_>) -> Self {
         let mut num_points = 0;
         let statements_before_block = body
             .basic_blocks()
diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs
index f920d9d5c3f..61838c41e39 100644
--- a/compiler/rustc_borrowck/src/member_constraints.rs
+++ b/compiler/rustc_borrowck/src/member_constraints.rs
@@ -8,7 +8,7 @@ use std::ops::Index;
 
 /// Compactly stores a set of `R0 member of [R1...Rn]` constraints,
 /// indexed by the region `R0`.
-crate struct MemberConstraintSet<'tcx, R>
+pub(crate) struct MemberConstraintSet<'tcx, R>
 where
     R: Copy + Eq,
 {
@@ -28,17 +28,17 @@ where
 }
 
 /// Represents a `R0 member of [R1..Rn]` constraint
-crate struct NllMemberConstraint<'tcx> {
+pub(crate) struct NllMemberConstraint<'tcx> {
     next_constraint: Option<NllMemberConstraintIndex>,
 
     /// The span where the hidden type was instantiated.
-    crate definition_span: Span,
+    pub(crate) definition_span: Span,
 
     /// The hidden type in which `R0` appears. (Used in error reporting.)
-    crate hidden_ty: Ty<'tcx>,
+    pub(crate) hidden_ty: Ty<'tcx>,
 
     /// The region `R0`.
-    crate member_region_vid: ty::RegionVid,
+    pub(crate) member_region_vid: ty::RegionVid,
 
     /// Index of `R1` in `choice_regions` vector from `MemberConstraintSet`.
     start_index: usize,
@@ -48,7 +48,7 @@ crate struct NllMemberConstraint<'tcx> {
 }
 
 rustc_index::newtype_index! {
-    crate struct NllMemberConstraintIndex {
+    pub(crate) struct NllMemberConstraintIndex {
         DEBUG_FORMAT = "MemberConstraintIndex({})"
     }
 }
@@ -73,7 +73,7 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
     /// within into `RegionVid` format -- it typically consults the
     /// `UniversalRegions` data structure that is known to the caller
     /// (but which this code is unaware of).
-    crate fn push_constraint(
+    pub(crate) fn push_constraint(
         &mut self,
         m_c: &MemberConstraint<'tcx>,
         mut to_region_vid: impl FnMut(ty::Region<'tcx>) -> ty::RegionVid,
@@ -106,7 +106,7 @@ where
     /// the original `RegionVid` to an scc index. In some cases, we
     /// may have multiple `R1` values mapping to the same `R2` key -- that
     /// is ok, the two sets will be merged.
-    crate fn into_mapped<R2>(
+    pub(crate) fn into_mapped<R2>(
         self,
         mut map_fn: impl FnMut(R1) -> R2,
     ) -> MemberConstraintSet<'tcx, R2>
@@ -144,14 +144,14 @@ impl<R> MemberConstraintSet<'_, R>
 where
     R: Copy + Hash + Eq,
 {
-    crate fn all_indices(&self) -> impl Iterator<Item = NllMemberConstraintIndex> + '_ {
+    pub(crate) fn all_indices(&self) -> impl Iterator<Item = NllMemberConstraintIndex> + '_ {
         self.constraints.indices()
     }
 
     /// Iterate down the constraint indices associated with a given
     /// peek-region.  You can then use `choice_regions` and other
     /// methods to access data.
-    crate fn indices(
+    pub(crate) fn indices(
         &self,
         member_region_vid: R,
     ) -> impl Iterator<Item = NllMemberConstraintIndex> + '_ {
@@ -172,7 +172,7 @@ where
     /// ```text
     /// R0 member of [R1..Rn]
     /// ```
-    crate fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] {
+    pub(crate) fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] {
         let NllMemberConstraint { start_index, end_index, .. } = &self.constraints[pci];
         &self.choice_regions[*start_index..*end_index]
     }
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 6f8fae2de29..2440ae9780d 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -42,7 +42,7 @@ pub type PoloniusOutput = Output<RustcFacts>;
 
 /// The output of `nll::compute_regions`. This includes the computed `RegionInferenceContext`, any
 /// closure requirements to propagate, and any generated errors.
-crate struct NllOutput<'tcx> {
+pub(crate) struct NllOutput<'tcx> {
     pub regioncx: RegionInferenceContext<'tcx>,
     pub opaque_type_values: VecMap<DefId, OpaqueHiddenType<'tcx>>,
     pub polonius_input: Option<Box<AllFacts>>,
@@ -457,6 +457,6 @@ impl ToRegionVid for RegionVid {
     }
 }
 
-crate trait ConstraintDescription {
+pub(crate) trait ConstraintDescription {
     fn description(&self) -> &'static str;
 }
diff --git a/compiler/rustc_borrowck/src/place_ext.rs b/compiler/rustc_borrowck/src/place_ext.rs
index 83ff1595b0b..93d202e49a1 100644
--- a/compiler/rustc_borrowck/src/place_ext.rs
+++ b/compiler/rustc_borrowck/src/place_ext.rs
@@ -5,7 +5,7 @@ use rustc_middle::mir::{Body, Mutability, Place};
 use rustc_middle::ty::{self, TyCtxt};
 
 /// Extension methods for the `Place` type.
-crate trait PlaceExt<'tcx> {
+pub(crate) trait PlaceExt<'tcx> {
     /// Returns `true` if we can safely ignore borrows of this place.
     /// This is true whenever there is no action that the user can do
     /// to the place `self` that would invalidate the borrow. This is true
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index 5a935c3b8fb..97335fd0dff 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -14,7 +14,7 @@ use std::iter;
 /// being run in the calling context, the conservative choice is to assume the compared indices
 /// are disjoint (and therefore, do not overlap).
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
-crate enum PlaceConflictBias {
+pub(crate) enum PlaceConflictBias {
     Overlap,
     NoOverlap,
 }
@@ -22,7 +22,7 @@ crate enum PlaceConflictBias {
 /// Helper function for checking if places conflict with a mutable borrow and deep access depth.
 /// This is used to check for places conflicting outside of the borrow checking code (such as in
 /// dataflow).
-crate fn places_conflict<'tcx>(
+pub(crate) fn places_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
     borrow_place: Place<'tcx>,
diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs
index 95048d50f11..f31ccd74ca6 100644
--- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs
+++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs
@@ -11,12 +11,12 @@ use rustc_graphviz as dot;
 
 impl<'tcx> RegionInferenceContext<'tcx> {
     /// Write out the region constraint graph.
-    crate fn dump_graphviz_raw_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> {
+    pub(crate) fn dump_graphviz_raw_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> {
         dot::render(&RawConstraints { regioncx: self }, &mut w)
     }
 
     /// Write out the region constraint graph.
-    crate fn dump_graphviz_scc_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> {
+    pub(crate) fn dump_graphviz_scc_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> {
         let mut nodes_per_scc: IndexVec<ConstraintSccIndex, _> =
             self.constraint_sccs.all_sccs().map(|_| Vec::new()).collect();
 
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index b2fa16ce125..dc6337c54ed 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -513,26 +513,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     /// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`.
-    crate fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
+    pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
         self.universal_regions.annotate(tcx, err)
     }
 
     /// Returns `true` if the region `r` contains the point `p`.
     ///
     /// Panics if called before `solve()` executes,
-    crate fn region_contains(&self, r: impl ToRegionVid, p: impl ToElementIndex) -> bool {
+    pub(crate) fn region_contains(&self, r: impl ToRegionVid, p: impl ToElementIndex) -> bool {
         let scc = self.constraint_sccs.scc(r.to_region_vid());
         self.scc_values.contains(scc, p)
     }
 
     /// Returns access to the value of `r` for debugging purposes.
-    crate fn region_value_str(&self, r: RegionVid) -> String {
+    pub(crate) fn region_value_str(&self, r: RegionVid) -> String {
         let scc = self.constraint_sccs.scc(r.to_region_vid());
         self.scc_values.region_value_str(scc)
     }
 
     /// Returns access to the value of `r` for debugging purposes.
-    crate fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex {
+    pub(crate) fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex {
         let scc = self.constraint_sccs.scc(r.to_region_vid());
         self.scc_universes[scc]
     }
@@ -1693,7 +1693,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ///   that cannot be named by `fr1`; in that case, we will require
     ///   that `fr1: 'static` because it is the only way to `fr1: r` to
     ///   be satisfied. (See `add_incompatible_universe`.)
-    crate fn provides_universal_region(
+    pub(crate) fn provides_universal_region(
         &self,
         r: RegionVid,
         fr1: RegionVid,
@@ -1712,7 +1712,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// If `r2` represents a placeholder region, then this returns
     /// `true` if `r1` cannot name that placeholder in its
     /// value; otherwise, returns `false`.
-    crate fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool {
+    pub(crate) fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool {
         debug!("cannot_name_value_of(r1={:?}, r2={:?})", r1, r2);
 
         match self.definitions[r2].origin {
@@ -1731,7 +1731,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         }
     }
 
-    crate fn retrieve_closure_constraint_info(
+    pub(crate) fn retrieve_closure_constraint_info(
         &self,
         _body: &Body<'tcx>,
         constraint: &OutlivesConstraint<'tcx>,
@@ -1766,7 +1766,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     /// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`.
-    crate fn find_outlives_blame_span(
+    pub(crate) fn find_outlives_blame_span(
         &self,
         body: &Body<'tcx>,
         fr1: RegionVid,
@@ -1788,7 +1788,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ///
     /// Returns: a series of constraints as well as the region `R`
     /// that passed the target test.
-    crate fn find_constraint_paths_between_regions(
+    pub(crate) fn find_constraint_paths_between_regions(
         &self,
         from_region: RegionVid,
         target_test: impl Fn(RegionVid) -> bool,
@@ -1882,7 +1882,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
     /// Finds some region R such that `fr1: R` and `R` is live at `elem`.
     #[instrument(skip(self), level = "trace")]
-    crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid {
+    pub(crate) fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid {
         trace!(scc = ?self.constraint_sccs.scc(fr1));
         trace!(universe = ?self.scc_universes[self.constraint_sccs.scc(fr1)]);
         self.find_constraint_paths_between_regions(fr1, |r| {
@@ -1919,7 +1919,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     /// Get the region outlived by `longer_fr` and live at `element`.
-    crate fn region_from_element(
+    pub(crate) fn region_from_element(
         &self,
         longer_fr: RegionVid,
         element: &RegionElement,
@@ -1939,17 +1939,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     /// Get the region definition of `r`.
-    crate fn region_definition(&self, r: RegionVid) -> &RegionDefinition<'tcx> {
+    pub(crate) fn region_definition(&self, r: RegionVid) -> &RegionDefinition<'tcx> {
         &self.definitions[r]
     }
 
     /// Check if the SCC of `r` contains `upper`.
-    crate fn upper_bound_in_region_scc(&self, r: RegionVid, upper: RegionVid) -> bool {
+    pub(crate) fn upper_bound_in_region_scc(&self, r: RegionVid, upper: RegionVid) -> bool {
         let r_scc = self.constraint_sccs.scc(r);
         self.scc_values.contains(r_scc, upper)
     }
 
-    crate fn universal_regions(&self) -> &UniversalRegions<'tcx> {
+    pub(crate) fn universal_regions(&self) -> &UniversalRegions<'tcx> {
         self.universal_regions.as_ref()
     }
 
@@ -1959,7 +1959,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// creating a constraint path that forces `R` to outlive
     /// `from_region`, and then finding the best choices within that
     /// path to blame.
-    crate fn best_blame_constraint(
+    pub(crate) fn best_blame_constraint(
         &self,
         body: &Body<'tcx>,
         from_region: RegionVid,
@@ -2171,7 +2171,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         categorized_path.remove(0)
     }
 
-    crate fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
+    pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
         self.universe_causes[&universe].clone()
     }
 }
diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
index 056907dcb16..1e6798eee3d 100644
--- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
+++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty::RegionVid;
 use std::ops::Range;
 use std::rc::Rc;
 
-crate struct ReverseSccGraph {
+pub(crate) struct ReverseSccGraph {
     graph: VecGraph<ConstraintSccIndex>,
     /// For each SCC, the range of `universal_regions` that use that SCC as
     /// their value.
diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs
index 4a70535c63b..c81ef10f7c7 100644
--- a/compiler/rustc_borrowck/src/region_infer/values.rs
+++ b/compiler/rustc_borrowck/src/region_infer/values.rs
@@ -10,7 +10,7 @@ use std::fmt::Debug;
 use std::rc::Rc;
 
 /// Maps between a `Location` and a `PointIndex` (and vice versa).
-crate struct RegionValueElements {
+pub(crate) struct RegionValueElements {
     /// For each basic block, how many points are contained within?
     statements_before_block: IndexVec<BasicBlock, usize>,
 
@@ -22,7 +22,7 @@ crate struct RegionValueElements {
 }
 
 impl RegionValueElements {
-    crate fn new(body: &Body<'_>) -> Self {
+    pub(crate) fn new(body: &Body<'_>) -> Self {
         let mut num_points = 0;
         let statements_before_block: IndexVec<BasicBlock, usize> = body
             .basic_blocks()
@@ -45,30 +45,30 @@ impl RegionValueElements {
     }
 
     /// Total number of point indices
-    crate fn num_points(&self) -> usize {
+    pub(crate) fn num_points(&self) -> usize {
         self.num_points
     }
 
     /// Converts a `Location` into a `PointIndex`. O(1).
-    crate fn point_from_location(&self, location: Location) -> PointIndex {
+    pub(crate) fn point_from_location(&self, location: Location) -> PointIndex {
         let Location { block, statement_index } = location;
         let start_index = self.statements_before_block[block];
         PointIndex::new(start_index + statement_index)
     }
 
     /// Converts a `Location` into a `PointIndex`. O(1).
-    crate fn entry_point(&self, block: BasicBlock) -> PointIndex {
+    pub(crate) fn entry_point(&self, block: BasicBlock) -> PointIndex {
         let start_index = self.statements_before_block[block];
         PointIndex::new(start_index)
     }
 
     /// Return the PointIndex for the block start of this index.
-    crate fn to_block_start(&self, index: PointIndex) -> PointIndex {
+    pub(crate) fn to_block_start(&self, index: PointIndex) -> PointIndex {
         PointIndex::new(self.statements_before_block[self.basic_blocks[index]])
     }
 
     /// Converts a `PointIndex` back to a location. O(1).
-    crate fn to_location(&self, index: PointIndex) -> Location {
+    pub(crate) fn to_location(&self, index: PointIndex) -> Location {
         assert!(index.index() < self.num_points);
         let block = self.basic_blocks[index];
         let start_index = self.statements_before_block[block];
@@ -80,7 +80,7 @@ impl RegionValueElements {
     /// out of range (because they round up to the nearest 2^N number
     /// of bits). Use this function to filter such points out if you
     /// like.
-    crate fn point_in_range(&self, index: PointIndex) -> bool {
+    pub(crate) fn point_in_range(&self, index: PointIndex) -> bool {
         index.index() < self.num_points
     }
 }
@@ -99,7 +99,7 @@ rustc_index::newtype_index! {
 /// An individual element in a region value -- the value of a
 /// particular region variable consists of a set of these elements.
 #[derive(Debug, Clone)]
-crate enum RegionElement {
+pub(crate) enum RegionElement {
     /// A point in the control-flow graph.
     Location(Location),
 
@@ -114,7 +114,7 @@ crate enum RegionElement {
 
 /// When we initially compute liveness, we use an interval matrix storing
 /// liveness ranges for each region-vid.
-crate struct LivenessValues<N: Idx> {
+pub(crate) struct LivenessValues<N: Idx> {
     elements: Rc<RegionValueElements>,
     points: SparseIntervalMatrix<N, PointIndex>,
 }
@@ -123,18 +123,18 @@ impl<N: Idx> LivenessValues<N> {
     /// Creates a new set of "region values" that tracks causal information.
     /// Each of the regions in num_region_variables will be initialized with an
     /// empty set of points and no causal information.
-    crate fn new(elements: Rc<RegionValueElements>) -> Self {
+    pub(crate) fn new(elements: Rc<RegionValueElements>) -> Self {
         Self { points: SparseIntervalMatrix::new(elements.num_points), elements }
     }
 
     /// Iterate through each region that has a value in this set.
-    crate fn rows(&self) -> impl Iterator<Item = N> {
+    pub(crate) fn rows(&self) -> impl Iterator<Item = N> {
         self.points.rows()
     }
 
     /// Adds the given element to the value for the given region. Returns whether
     /// the element is newly added (i.e., was not already present).
-    crate fn add_element(&mut self, row: N, location: Location) -> bool {
+    pub(crate) fn add_element(&mut self, row: N, location: Location) -> bool {
         debug!("LivenessValues::add(r={:?}, location={:?})", row, location);
         let index = self.elements.point_from_location(location);
         self.points.insert(row, index)
@@ -142,24 +142,24 @@ impl<N: Idx> LivenessValues<N> {
 
     /// Adds all the elements in the given bit array into the given
     /// region. Returns whether any of them are newly added.
-    crate fn add_elements(&mut self, row: N, locations: &IntervalSet<PointIndex>) -> bool {
+    pub(crate) fn add_elements(&mut self, row: N, locations: &IntervalSet<PointIndex>) -> bool {
         debug!("LivenessValues::add_elements(row={:?}, locations={:?})", row, locations);
         self.points.union_row(row, locations)
     }
 
     /// Adds all the control-flow points to the values for `r`.
-    crate fn add_all_points(&mut self, row: N) {
+    pub(crate) fn add_all_points(&mut self, row: N) {
         self.points.insert_all_into_row(row);
     }
 
     /// Returns `true` if the region `r` contains the given element.
-    crate fn contains(&self, row: N, location: Location) -> bool {
+    pub(crate) fn contains(&self, row: N, location: Location) -> bool {
         let index = self.elements.point_from_location(location);
         self.points.row(row).map_or(false, |r| r.contains(index))
     }
 
     /// Returns an iterator of all the elements contained by the region `r`
-    crate fn get_elements(&self, row: N) -> impl Iterator<Item = Location> + '_ {
+    pub(crate) fn get_elements(&self, row: N) -> impl Iterator<Item = Location> + '_ {
         self.points
             .row(row)
             .into_iter()
@@ -169,7 +169,7 @@ impl<N: Idx> LivenessValues<N> {
     }
 
     /// Returns a "pretty" string value of the region. Meant for debugging.
-    crate fn region_value_str(&self, r: N) -> String {
+    pub(crate) fn region_value_str(&self, r: N) -> String {
         region_value_str(self.get_elements(r).map(RegionElement::Location))
     }
 }
@@ -178,25 +178,28 @@ impl<N: Idx> LivenessValues<N> {
 /// rustc to the internal `PlaceholderIndex` values that are used in
 /// NLL.
 #[derive(Default)]
-crate struct PlaceholderIndices {
+pub(crate) struct PlaceholderIndices {
     indices: FxIndexSet<ty::PlaceholderRegion>,
 }
 
 impl PlaceholderIndices {
-    crate fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
+    pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
         let (index, _) = self.indices.insert_full(placeholder);
         index.into()
     }
 
-    crate fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
+    pub(crate) fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
         self.indices.get_index_of(&placeholder).unwrap().into()
     }
 
-    crate fn lookup_placeholder(&self, placeholder: PlaceholderIndex) -> ty::PlaceholderRegion {
+    pub(crate) fn lookup_placeholder(
+        &self,
+        placeholder: PlaceholderIndex,
+    ) -> ty::PlaceholderRegion {
         self.indices[placeholder.index()]
     }
 
-    crate fn len(&self) -> usize {
+    pub(crate) fn len(&self) -> usize {
         self.indices.len()
     }
 }
@@ -220,7 +223,7 @@ impl PlaceholderIndices {
 /// because (since it is returned) it must live for at least `'a`. But
 /// it would also contain various points from within the function.
 #[derive(Clone)]
-crate struct RegionValues<N: Idx> {
+pub(crate) struct RegionValues<N: Idx> {
     elements: Rc<RegionValueElements>,
     placeholder_indices: Rc<PlaceholderIndices>,
     points: SparseIntervalMatrix<N, PointIndex>,
@@ -235,7 +238,7 @@ impl<N: Idx> RegionValues<N> {
     /// Creates a new set of "region values" that tracks causal information.
     /// Each of the regions in num_region_variables will be initialized with an
     /// empty set of points and no causal information.
-    crate fn new(
+    pub(crate) fn new(
         elements: &Rc<RegionValueElements>,
         num_universal_regions: usize,
         placeholder_indices: &Rc<PlaceholderIndices>,
@@ -252,33 +255,33 @@ impl<N: Idx> RegionValues<N> {
 
     /// Adds the given element to the value for the given region. Returns whether
     /// the element is newly added (i.e., was not already present).
-    crate fn add_element(&mut self, r: N, elem: impl ToElementIndex) -> bool {
+    pub(crate) fn add_element(&mut self, r: N, elem: impl ToElementIndex) -> bool {
         debug!("add(r={:?}, elem={:?})", r, elem);
         elem.add_to_row(self, r)
     }
 
     /// Adds all the control-flow points to the values for `r`.
-    crate fn add_all_points(&mut self, r: N) {
+    pub(crate) fn add_all_points(&mut self, r: N) {
         self.points.insert_all_into_row(r);
     }
 
     /// Adds all elements in `r_from` to `r_to` (because e.g., `r_to:
     /// r_from`).
-    crate fn add_region(&mut self, r_to: N, r_from: N) -> bool {
+    pub(crate) fn add_region(&mut self, r_to: N, r_from: N) -> bool {
         self.points.union_rows(r_from, r_to)
             | self.free_regions.union_rows(r_from, r_to)
             | self.placeholders.union_rows(r_from, r_to)
     }
 
     /// Returns `true` if the region `r` contains the given element.
-    crate fn contains(&self, r: N, elem: impl ToElementIndex) -> bool {
+    pub(crate) fn contains(&self, r: N, elem: impl ToElementIndex) -> bool {
         elem.contained_in_row(self, r)
     }
 
     /// `self[to] |= values[from]`, essentially: that is, take all the
     /// elements for the region `from` from `values` and add them to
     /// the region `to` in `self`.
-    crate fn merge_liveness<M: Idx>(&mut self, to: N, from: M, values: &LivenessValues<M>) {
+    pub(crate) fn merge_liveness<M: Idx>(&mut self, to: N, from: M, values: &LivenessValues<M>) {
         if let Some(set) = values.points.row(from) {
             self.points.union_row(to, set);
         }
@@ -286,7 +289,7 @@ impl<N: Idx> RegionValues<N> {
 
     /// Returns `true` if `sup_region` contains all the CFG points that
     /// `sub_region` contains. Ignores universal regions.
-    crate fn contains_points(&self, sup_region: N, sub_region: N) -> bool {
+    pub(crate) fn contains_points(&self, sup_region: N, sub_region: N) -> bool {
         if let Some(sub_row) = self.points.row(sub_region) {
             if let Some(sup_row) = self.points.row(sup_region) {
                 sup_row.superset(sub_row)
@@ -301,7 +304,7 @@ impl<N: Idx> RegionValues<N> {
     }
 
     /// Returns the locations contained within a given region `r`.
-    crate fn locations_outlived_by<'a>(&'a self, r: N) -> impl Iterator<Item = Location> + 'a {
+    pub(crate) fn locations_outlived_by<'a>(&'a self, r: N) -> impl Iterator<Item = Location> + 'a {
         self.points.row(r).into_iter().flat_map(move |set| {
             set.iter()
                 .take_while(move |&p| self.elements.point_in_range(p))
@@ -310,7 +313,7 @@ impl<N: Idx> RegionValues<N> {
     }
 
     /// Returns just the universal regions that are contained in a given region's value.
-    crate fn universal_regions_outlived_by<'a>(
+    pub(crate) fn universal_regions_outlived_by<'a>(
         &'a self,
         r: N,
     ) -> impl Iterator<Item = RegionVid> + 'a {
@@ -318,7 +321,7 @@ impl<N: Idx> RegionValues<N> {
     }
 
     /// Returns all the elements contained in a given region's value.
-    crate fn placeholders_contained_in<'a>(
+    pub(crate) fn placeholders_contained_in<'a>(
         &'a self,
         r: N,
     ) -> impl Iterator<Item = ty::PlaceholderRegion> + 'a {
@@ -330,7 +333,10 @@ impl<N: Idx> RegionValues<N> {
     }
 
     /// Returns all the elements contained in a given region's value.
-    crate fn elements_contained_in<'a>(&'a self, r: N) -> impl Iterator<Item = RegionElement> + 'a {
+    pub(crate) fn elements_contained_in<'a>(
+        &'a self,
+        r: N,
+    ) -> impl Iterator<Item = RegionElement> + 'a {
         let points_iter = self.locations_outlived_by(r).map(RegionElement::Location);
 
         let free_regions_iter =
@@ -343,12 +349,12 @@ impl<N: Idx> RegionValues<N> {
     }
 
     /// Returns a "pretty" string value of the region. Meant for debugging.
-    crate fn region_value_str(&self, r: N) -> String {
+    pub(crate) fn region_value_str(&self, r: N) -> String {
         region_value_str(self.elements_contained_in(r))
     }
 }
 
-crate trait ToElementIndex: Debug + Copy {
+pub(crate) trait ToElementIndex: Debug + Copy {
     fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool;
 
     fn contained_in_row<N: Idx>(self, values: &RegionValues<N>, row: N) -> bool;
@@ -388,7 +394,7 @@ impl ToElementIndex for ty::PlaceholderRegion {
     }
 }
 
-crate fn location_set_str(
+pub(crate) fn location_set_str(
     elements: &RegionValueElements,
     points: impl IntoIterator<Item = PointIndex>,
 ) -> String {
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 21190a850b7..f11a94d7ddd 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -18,7 +18,7 @@ use crate::{
     universal_regions::UniversalRegions,
 };
 
-crate struct ConstraintConversion<'a, 'tcx> {
+pub(crate) struct ConstraintConversion<'a, 'tcx> {
     infcx: &'a InferCtxt<'a, 'tcx>,
     tcx: TyCtxt<'tcx>,
     universal_regions: &'a UniversalRegions<'tcx>,
@@ -32,7 +32,7 @@ crate struct ConstraintConversion<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
-    crate fn new(
+    pub(crate) fn new(
         infcx: &'a InferCtxt<'a, 'tcx>,
         universal_regions: &'a UniversalRegions<'tcx>,
         region_bound_pairs: &'a RegionBoundPairs<'tcx>,
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index f08f2e1b12d..670b5549afc 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -19,7 +19,7 @@ use crate::{
 };
 
 #[derive(Debug)]
-crate struct UniversalRegionRelations<'tcx> {
+pub(crate) struct UniversalRegionRelations<'tcx> {
     universal_regions: Rc<UniversalRegions<'tcx>>,
 
     /// Stores the outlives relations that are known to hold from the
@@ -52,13 +52,13 @@ type RegionBoundPairs<'tcx> = Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>;
 /// then the output type as the last element.
 type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
 
-crate struct CreateResult<'tcx> {
-    crate universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
-    crate region_bound_pairs: RegionBoundPairs<'tcx>,
-    crate normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
+pub(crate) struct CreateResult<'tcx> {
+    pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
+    pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>,
+    pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
 }
 
-crate fn create<'tcx>(
+pub(crate) fn create<'tcx>(
     infcx: &InferCtxt<'_, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     implicit_region_bound: Option<ty::Region<'tcx>>,
@@ -96,7 +96,7 @@ impl UniversalRegionRelations<'_> {
     ///
     /// (See `TransitiveRelation::postdom_upper_bound` for details on
     /// the postdominating upper bound in general.)
-    crate fn postdom_upper_bound(&self, fr1: RegionVid, fr2: RegionVid) -> RegionVid {
+    pub(crate) fn postdom_upper_bound(&self, fr1: RegionVid, fr2: RegionVid) -> RegionVid {
         assert!(self.universal_regions.is_universal_region(fr1));
         assert!(self.universal_regions.is_universal_region(fr2));
         self.inverse_outlives
@@ -109,7 +109,7 @@ impl UniversalRegionRelations<'_> {
     /// outlives `fr` and (b) is not local.
     ///
     /// (*) If there are multiple competing choices, we return all of them.
-    crate fn non_local_upper_bounds<'a>(&'a self, fr: RegionVid) -> Vec<RegionVid> {
+    pub(crate) fn non_local_upper_bounds<'a>(&'a self, fr: RegionVid) -> Vec<RegionVid> {
         debug!("non_local_upper_bound(fr={:?})", fr);
         let res = self.non_local_bounds(&self.inverse_outlives, fr);
         assert!(!res.is_empty(), "can't find an upper bound!?");
@@ -118,7 +118,7 @@ impl UniversalRegionRelations<'_> {
 
     /// Returns the "postdominating" bound of the set of
     /// `non_local_upper_bounds` for the given region.
-    crate fn non_local_upper_bound(&self, fr: RegionVid) -> RegionVid {
+    pub(crate) fn non_local_upper_bound(&self, fr: RegionVid) -> RegionVid {
         let upper_bounds = self.non_local_upper_bounds(fr);
 
         // In case we find more than one, reduce to one for
@@ -147,7 +147,7 @@ impl UniversalRegionRelations<'_> {
     ///
     /// (*) If there are multiple competing choices, we pick the "postdominating"
     /// one. See `TransitiveRelation::postdom_upper_bound` for details.
-    crate fn non_local_lower_bound(&self, fr: RegionVid) -> Option<RegionVid> {
+    pub(crate) fn non_local_lower_bound(&self, fr: RegionVid) -> Option<RegionVid> {
         debug!("non_local_lower_bound(fr={:?})", fr);
         let lower_bounds = self.non_local_bounds(&self.outlives, fr);
 
@@ -203,18 +203,18 @@ impl UniversalRegionRelations<'_> {
     /// Returns `true` if fr1 is known to outlive fr2.
     ///
     /// This will only ever be true for universally quantified regions.
-    crate fn outlives(&self, fr1: RegionVid, fr2: RegionVid) -> bool {
+    pub(crate) fn outlives(&self, fr1: RegionVid, fr2: RegionVid) -> bool {
         self.outlives.contains(fr1, fr2)
     }
 
     /// Returns a vector of free regions `x` such that `fr1: x` is
     /// known to hold.
-    crate fn regions_outlived_by(&self, fr1: RegionVid) -> Vec<RegionVid> {
+    pub(crate) fn regions_outlived_by(&self, fr1: RegionVid) -> Vec<RegionVid> {
         self.outlives.reachable_from(fr1)
     }
 
     /// Returns the _non-transitive_ set of known `outlives` constraints between free regions.
-    crate fn known_outlives(&self) -> impl Iterator<Item = (RegionVid, RegionVid)> + '_ {
+    pub(crate) fn known_outlives(&self) -> impl Iterator<Item = (RegionVid, RegionVid)> + '_ {
         self.outlives.base_edges()
     }
 }
@@ -232,7 +232,7 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> {
 }
 
 impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
-    crate fn create(mut self) -> CreateResult<'tcx> {
+    pub(crate) fn create(mut self) -> CreateResult<'tcx> {
         let unnormalized_input_output_tys = self
             .universal_regions
             .unnormalized_input_tys
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
index dd23683fae8..b88f6e689cc 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
@@ -18,7 +18,7 @@ use crate::region_infer::values::{PointIndex, RegionValueElements};
 /// (and code simplicity) was favored. The rationale is that we only keep
 /// a small number of `IndexVec`s throughout the entire analysis while, in
 /// contrast, we're accessing each `Local` *many* times.
-crate struct LocalUseMap {
+pub(crate) struct LocalUseMap {
     /// Head of a linked list of **definitions** of each variable --
     /// definition in this context means assignment, e.g., `x` is
     /// defined in `x = y` but not `y`; that first def is the head of
@@ -58,7 +58,11 @@ impl vll::LinkElem for Appearance {
 }
 
 impl LocalUseMap {
-    crate fn build(live_locals: &[Local], elements: &RegionValueElements, body: &Body<'_>) -> Self {
+    pub(crate) fn build(
+        live_locals: &[Local],
+        elements: &RegionValueElements,
+        body: &Body<'_>,
+    ) -> Self {
         let nones = IndexVec::from_elem_n(None, body.local_decls.len());
         let mut local_use_map = LocalUseMap {
             first_def_at: nones.clone(),
@@ -81,17 +85,17 @@ impl LocalUseMap {
         local_use_map
     }
 
-    crate fn defs(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
+    pub(crate) fn defs(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
         vll::iter(self.first_def_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 
-    crate fn uses(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
+    pub(crate) fn uses(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
         vll::iter(self.first_use_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 
-    crate fn drops(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
+    pub(crate) fn drops(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
         vll::iter(self.first_drop_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 4b905c23e15..405fd9198d3 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -94,7 +94,7 @@ mod canonical;
 mod constraint_conversion;
 pub mod free_region_relations;
 mod input_output;
-crate mod liveness;
+pub(crate) mod liveness;
 mod relate_tys;
 
 /// Type checks the given `mir` in the context of the inference
@@ -897,28 +897,29 @@ struct BorrowCheckContext<'a, 'tcx> {
     upvars: &'a [Upvar<'tcx>],
 }
 
-crate struct MirTypeckResults<'tcx> {
-    crate constraints: MirTypeckRegionConstraints<'tcx>,
-    crate universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
-    crate opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
+pub(crate) struct MirTypeckResults<'tcx> {
+    pub(crate) constraints: MirTypeckRegionConstraints<'tcx>,
+    pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
+    pub(crate) opaque_type_values:
+        VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
 }
 
 /// A collection of region constraints that must be satisfied for the
 /// program to be considered well-typed.
-crate struct MirTypeckRegionConstraints<'tcx> {
+pub(crate) struct MirTypeckRegionConstraints<'tcx> {
     /// Maps from a `ty::Placeholder` to the corresponding
     /// `PlaceholderIndex` bit that we will use for it.
     ///
     /// To keep everything in sync, do not insert this set
     /// directly. Instead, use the `placeholder_region` helper.
-    crate placeholder_indices: PlaceholderIndices,
+    pub(crate) placeholder_indices: PlaceholderIndices,
 
     /// Each time we add a placeholder to `placeholder_indices`, we
     /// also create a corresponding "representative" region vid for
     /// that wraps it. This vector tracks those. This way, when we
     /// convert the same `ty::RePlaceholder(p)` twice, we can map to
     /// the same underlying `RegionVid`.
-    crate placeholder_index_to_region: IndexVec<PlaceholderIndex, ty::Region<'tcx>>,
+    pub(crate) placeholder_index_to_region: IndexVec<PlaceholderIndex, ty::Region<'tcx>>,
 
     /// In general, the type-checker is not responsible for enforcing
     /// liveness constraints; this job falls to the region inferencer,
@@ -927,18 +928,18 @@ crate struct MirTypeckRegionConstraints<'tcx> {
     /// not otherwise appear in the MIR -- in particular, the
     /// late-bound regions that it instantiates at call-sites -- and
     /// hence it must report on their liveness constraints.
-    crate liveness_constraints: LivenessValues<RegionVid>,
+    pub(crate) liveness_constraints: LivenessValues<RegionVid>,
 
-    crate outlives_constraints: OutlivesConstraintSet<'tcx>,
+    pub(crate) outlives_constraints: OutlivesConstraintSet<'tcx>,
 
-    crate member_constraints: MemberConstraintSet<'tcx, RegionVid>,
+    pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>,
 
-    crate closure_bounds_mapping:
+    pub(crate) closure_bounds_mapping:
         FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
 
-    crate universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
+    pub(crate) universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
 
-    crate type_tests: Vec<TypeTest<'tcx>>,
+    pub(crate) type_tests: Vec<TypeTest<'tcx>>,
 }
 
 impl<'tcx> MirTypeckRegionConstraints<'tcx> {
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 0fcac9a1c6c..7b63ec516b8 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -336,7 +336,7 @@ impl<'tcx> UniversalRegions<'tcx> {
     /// that this region imposes on others. The methods in this file
     /// handle the part about dumping the inference context internal
     /// state.
-    crate fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
+    pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
         match self.defining_ty {
             DefiningTy::Closure(def_id, substs) => {
                 err.note(&format!(
diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs
index 6022a980950..cdbb60b878a 100644
--- a/compiler/rustc_borrowck/src/used_muts.rs
+++ b/compiler/rustc_borrowck/src/used_muts.rs
@@ -22,7 +22,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     ///  been assigned to - this set is used as a proxy for locals that were not initialized due to
     ///  unreachable code. These locals are then considered "used" to silence the lint for them.
     ///  See #55344 for context.
-    crate fn gather_used_muts(
+    pub(crate) fn gather_used_muts(
         &mut self,
         temporary_used_locals: FxHashSet<Local>,
         mut never_initialized_mut_locals: FxHashSet<Local>,
diff --git a/compiler/rustc_builtin_macros/src/cfg_accessible.rs b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
index 7b7db3eaea6..cb5359dd1e2 100644
--- a/compiler/rustc_builtin_macros/src/cfg_accessible.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
@@ -7,7 +7,7 @@ use rustc_parse::validate_attr;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 
-crate struct Expander;
+pub(crate) struct Expander;
 
 fn validate_input<'a>(ecx: &mut ExtCtxt<'_>, mi: &'a ast::MetaItem) -> Option<&'a ast::Path> {
     match mi.meta_item_list() {
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 4278fedfee9..6485c82a119 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -19,7 +19,7 @@ use rustc_span::symbol::sym;
 use rustc_span::Span;
 use smallvec::SmallVec;
 
-crate fn expand(
+pub(crate) fn expand(
     ecx: &mut ExtCtxt<'_>,
     _span: Span,
     meta_item: &ast::MetaItem,
@@ -30,7 +30,7 @@ crate fn expand(
     vec![cfg_eval(ecx.sess, ecx.ecfg.features, annotatable, ecx.current_expansion.lint_node_id)]
 }
 
-crate fn cfg_eval(
+pub(crate) fn cfg_eval(
     sess: &Session,
     features: Option<&Features>,
     annotatable: Annotatable,
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index 391c46d1813..7f25b23734b 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -10,7 +10,7 @@ use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 
-crate struct Expander;
+pub(crate) struct Expander;
 
 impl MultiItemModifier for Expander {
     fn expand(
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index 812d86af6e8..c678c8cbd15 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -38,8 +38,8 @@ pub mod partial_ord;
 
 pub mod generic;
 
-crate struct BuiltinDerive(
-    crate fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)),
+pub(crate) struct BuiltinDerive(
+    pub(crate) fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)),
 );
 
 impl MultiItemModifier for BuiltinDerive {
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 468ca7d7aa9..0c9e3c22bcf 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -4,7 +4,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(array_windows)]
 #![feature(box_patterns)]
-#![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
 #![feature(is_sorted)]
 #![feature(nll)]
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index d0724baf9e0..c7497bfd355 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -354,14 +354,14 @@ fn fat_lto(
     Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: serialized_bitcode })
 }
 
-crate struct Linker<'a>(&'a mut llvm::Linker<'a>);
+pub(crate) struct Linker<'a>(&'a mut llvm::Linker<'a>);
 
 impl<'a> Linker<'a> {
-    crate fn new(llmod: &'a llvm::Module) -> Self {
+    pub(crate) fn new(llmod: &'a llvm::Module) -> Self {
         unsafe { Linker(llvm::LLVMRustLinkerNew(llmod)) }
     }
 
-    crate fn add(&mut self, bytecode: &[u8]) -> Result<(), ()> {
+    pub(crate) fn add(&mut self, bytecode: &[u8]) -> Result<(), ()> {
         unsafe {
             if llvm::LLVMRustLinkerAdd(
                 self.0,
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 88b87951ecd..839018e2a75 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1412,7 +1412,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
     }
 
-    crate fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
+    pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
         let (ty, f) = self.cx.get_intrinsic(intrinsic);
         self.call(ty, f, args, None)
     }
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 4d3f3f318b8..5bbbfe9a4ab 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -212,11 +212,11 @@ pub fn ptrcast<'ll>(val: &'ll Value, ty: &'ll Type) -> &'ll Value {
 }
 
 impl<'ll> CodegenCx<'ll, '_> {
-    crate fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
+    pub(crate) fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
         unsafe { llvm::LLVMConstBitCast(val, ty) }
     }
 
-    crate fn static_addr_of_mut(
+    pub(crate) fn static_addr_of_mut(
         &self,
         cv: &'ll Value,
         align: Align,
@@ -241,7 +241,7 @@ impl<'ll> CodegenCx<'ll, '_> {
         }
     }
 
-    crate fn get_static(&self, def_id: DefId) -> &'ll Value {
+    pub(crate) fn get_static(&self, def_id: DefId) -> &'ll Value {
         let instance = Instance::mono(self.tcx, def_id);
         if let Some(&g) = self.instances.borrow().get(&instance) {
             return g;
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index d296ee3b42c..5544f0d3f60 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -330,7 +330,7 @@ pub unsafe fn create_module<'ll>(
 }
 
 impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
-    crate fn new(
+    pub(crate) fn new(
         tcx: TyCtxt<'tcx>,
         codegen_unit: &'tcx CodegenUnit<'tcx>,
         llvm_module: &'ll crate::ModuleLlvm,
@@ -447,7 +447,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
         }
     }
 
-    crate fn statics_to_rauw(&self) -> &RefCell<Vec<(&'ll Value, &'ll Value)>> {
+    pub(crate) fn statics_to_rauw(&self) -> &RefCell<Vec<(&'ll Value, &'ll Value)>> {
         &self.statics_to_rauw
     }
 
@@ -599,7 +599,7 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
 }
 
 impl<'ll> CodegenCx<'ll, '_> {
-    crate fn get_intrinsic(&self, key: &str) -> (&'ll Type, &'ll Value) {
+    pub(crate) fn get_intrinsic(&self, key: &str) -> (&'ll Type, &'ll Value) {
         if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
             return v;
         }
@@ -890,7 +890,7 @@ impl<'ll> CodegenCx<'ll, '_> {
         None
     }
 
-    crate fn eh_catch_typeinfo(&self) -> &'ll Value {
+    pub(crate) fn eh_catch_typeinfo(&self) -> &'ll Value {
         if let Some(eh_catch_typeinfo) = self.eh_catch_typeinfo.get() {
             return eh_catch_typeinfo;
         }
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 0bead4629a6..2b5154a2cf9 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -5,7 +5,6 @@
 //! This API is completely unstable and subject to change.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![feature(crate_visibility_modifier)]
 #![feature(let_chains)]
 #![feature(let_else)]
 #![feature(extern_types)]
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 13baaddccd4..37409dbb447 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -775,7 +775,7 @@ pub mod coverageinfo {
     }
 
     impl CounterMappingRegion {
-        crate fn code_region(
+        pub(crate) fn code_region(
             counter: coverage_map::Counter,
             file_id: u32,
             start_line: u32,
@@ -799,7 +799,7 @@ pub mod coverageinfo {
         // This function might be used in the future; the LLVM API is still evolving, as is coverage
         // support.
         #[allow(dead_code)]
-        crate fn branch_region(
+        pub(crate) fn branch_region(
             counter: coverage_map::Counter,
             false_counter: coverage_map::Counter,
             file_id: u32,
@@ -824,7 +824,7 @@ pub mod coverageinfo {
         // This function might be used in the future; the LLVM API is still evolving, as is coverage
         // support.
         #[allow(dead_code)]
-        crate fn expansion_region(
+        pub(crate) fn expansion_region(
             file_id: u32,
             expanded_file_id: u32,
             start_line: u32,
@@ -848,7 +848,7 @@ pub mod coverageinfo {
         // This function might be used in the future; the LLVM API is still evolving, as is coverage
         // support.
         #[allow(dead_code)]
-        crate fn skipped_region(
+        pub(crate) fn skipped_region(
             file_id: u32,
             start_line: u32,
             start_col: u32,
@@ -871,7 +871,7 @@ pub mod coverageinfo {
         // This function might be used in the future; the LLVM API is still evolving, as is coverage
         // support.
         #[allow(dead_code)]
-        crate fn gap_region(
+        pub(crate) fn gap_region(
             counter: coverage_map::Counter,
             file_id: u32,
             start_line: u32,
diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index 21b77f7dea6..cf2d3c423c3 100644
--- a/compiler/rustc_codegen_llvm/src/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
@@ -39,33 +39,33 @@ impl fmt::Debug for Type {
 }
 
 impl<'ll> CodegenCx<'ll, '_> {
-    crate fn type_named_struct(&self, name: &str) -> &'ll Type {
+    pub(crate) fn type_named_struct(&self, name: &str) -> &'ll Type {
         let name = SmallCStr::new(name);
         unsafe { llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) }
     }
 
-    crate fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) {
+    pub(crate) fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) {
         unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) }
     }
 
-    crate fn type_void(&self) -> &'ll Type {
+    pub(crate) fn type_void(&self) -> &'ll Type {
         unsafe { llvm::LLVMVoidTypeInContext(self.llcx) }
     }
 
-    crate fn type_metadata(&self) -> &'ll Type {
+    pub(crate) fn type_metadata(&self) -> &'ll Type {
         unsafe { llvm::LLVMRustMetadataTypeInContext(self.llcx) }
     }
 
     ///x Creates an integer type with the given number of bits, e.g., i24
-    crate fn type_ix(&self, num_bits: u64) -> &'ll Type {
+    pub(crate) fn type_ix(&self, num_bits: u64) -> &'ll Type {
         unsafe { llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint) }
     }
 
-    crate fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type {
+    pub(crate) fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type {
         unsafe { llvm::LLVMVectorType(ty, len as c_uint) }
     }
 
-    crate fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> {
+    pub(crate) fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> {
         unsafe {
             let n_args = llvm::LLVMCountParamTypes(ty) as usize;
             let mut args = Vec::with_capacity(n_args);
@@ -75,11 +75,11 @@ impl<'ll> CodegenCx<'ll, '_> {
         }
     }
 
-    crate fn type_bool(&self) -> &'ll Type {
+    pub(crate) fn type_bool(&self) -> &'ll Type {
         self.type_i8()
     }
 
-    crate fn type_int_from_ty(&self, t: ty::IntTy) -> &'ll Type {
+    pub(crate) fn type_int_from_ty(&self, t: ty::IntTy) -> &'ll Type {
         match t {
             ty::IntTy::Isize => self.type_isize(),
             ty::IntTy::I8 => self.type_i8(),
@@ -90,7 +90,7 @@ impl<'ll> CodegenCx<'ll, '_> {
         }
     }
 
-    crate fn type_uint_from_ty(&self, t: ty::UintTy) -> &'ll Type {
+    pub(crate) fn type_uint_from_ty(&self, t: ty::UintTy) -> &'ll Type {
         match t {
             ty::UintTy::Usize => self.type_isize(),
             ty::UintTy::U8 => self.type_i8(),
@@ -101,14 +101,14 @@ impl<'ll> CodegenCx<'ll, '_> {
         }
     }
 
-    crate fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type {
+    pub(crate) fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type {
         match t {
             ty::FloatTy::F32 => self.type_f32(),
             ty::FloatTy::F64 => self.type_f64(),
         }
     }
 
-    crate fn type_pointee_for_align(&self, align: Align) -> &'ll Type {
+    pub(crate) fn type_pointee_for_align(&self, align: Align) -> &'ll Type {
         // FIXME(eddyb) We could find a better approximation if ity.align < align.
         let ity = Integer::approximate_align(self, align);
         self.type_from_integer(ity)
@@ -116,7 +116,7 @@ impl<'ll> CodegenCx<'ll, '_> {
 
     /// Return a LLVM type that has at most the required alignment,
     /// and exactly the required size, as a best-effort padding array.
-    crate fn type_padding_filler(&self, size: Size, align: Align) -> &'ll Type {
+    pub(crate) fn type_padding_filler(&self, size: Size, align: Align) -> &'ll Type {
         let unit = Integer::approximate_align(self, align);
         let size = size.bytes();
         let unit_size = unit.size().bytes();
@@ -124,11 +124,11 @@ impl<'ll> CodegenCx<'ll, '_> {
         self.type_array(self.type_from_integer(unit), size / unit_size)
     }
 
-    crate fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
+    pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
         unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) }
     }
 
-    crate fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type {
+    pub(crate) fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type {
         unsafe { llvm::LLVMRustArrayType(ty, len) }
     }
 }
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index c5a11aaceaf..9e5b00462f3 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -163,7 +163,7 @@ impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxHashMap<K, V> {
     }
 }
 
-crate type CompileTimeEvalContext<'mir, 'tcx> =
+pub(crate) type CompileTimeEvalContext<'mir, 'tcx> =
     InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>;
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 59ea40dc2f9..5e0d1abd6c1 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -44,7 +44,7 @@ fn numeric_intrinsic<Tag>(name: Symbol, bits: u128, kind: Primitive) -> Scalar<T
 
 /// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated
 /// inside an `InterpCx` and instead have their value computed directly from rustc internal info.
-crate fn eval_nullary_intrinsic<'tcx>(
+pub(crate) fn eval_nullary_intrinsic<'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     def_id: DefId,
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
index 5ece19d7fb3..e66cb9837c9 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
@@ -15,7 +15,7 @@ use crate::interpret::{
 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
     /// frame which is not `#[track_caller]`.
-    crate fn find_closest_untracked_caller_location(&self) -> Span {
+    pub(crate) fn find_closest_untracked_caller_location(&self) -> Span {
         for frame in self.stack().iter().rev() {
             debug!("find_closest_untracked_caller_location: checking frame {:?}", frame.instance);
 
@@ -74,7 +74,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     }
 
     /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
-    crate fn alloc_caller_location(
+    pub(crate) fn alloc_caller_location(
         &mut self,
         filename: Symbol,
         line: u32,
@@ -113,7 +113,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         location
     }
 
-    crate fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
+    pub(crate) fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
         let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
         let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
         (
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
index 447797f915c..f9847742f08 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
@@ -189,7 +189,7 @@ impl Write for AbsolutePathPrinter<'_> {
 }
 
 /// Directly returns an `Allocation` containing an absolute path representation of the given type.
-crate fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
+pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
     let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
     let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes());
     tcx.intern_const_alloc(alloc)
diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs
index 69d6c8470a2..2b73ad568e0 100644
--- a/compiler/rustc_const_eval/src/interpret/mod.rs
+++ b/compiler/rustc_const_eval/src/interpret/mod.rs
@@ -29,5 +29,5 @@ pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
 pub use self::validity::{CtfeValidationMode, RefTracking};
 pub use self::visitor::{MutValueVisitor, Value, ValueVisitor};
 
-crate use self::intrinsics::eval_nullary_intrinsic;
+pub(crate) use self::intrinsics::eval_nullary_intrinsic;
 use eval_context::{from_known_layout, mir_assign_valid_types};
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 5c85c86107f..f5e1ee4e233 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -643,7 +643,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         }
     }
 
-    crate fn const_val_to_op(
+    pub(crate) fn const_val_to_op(
         &self,
         val_val: ConstValue<'tcx>,
         ty: Ty<'tcx>,
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index e17bd9a8c08..1940b573db0 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -8,7 +8,7 @@ use std::ops::ControlFlow;
 /// In case it does, returns a `TooGeneric` const eval error. Note that due to polymorphization
 /// types may be "concrete enough" even though they still contain generic parameters in
 /// case these parameters are unused.
-crate fn ensure_monomorphic_enough<'tcx, T>(tcx: TyCtxt<'tcx>, ty: T) -> InterpResult<'tcx>
+pub(crate) fn ensure_monomorphic_enough<'tcx, T>(tcx: TyCtxt<'tcx>, ty: T) -> InterpResult<'tcx>
 where
     T: TypeFoldable<'tcx>,
 {
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 8b6689ca213..eacb5978d99 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -7,7 +7,6 @@ Rust MIR: a lowered representation of Rust.
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
-#![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
 #![feature(exact_size_is_empty)]
 #![feature(let_else)]
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 909ed566f64..f130b5aa9a6 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -90,7 +90,7 @@ pub trait AddSubdiagnostic {
 pub struct Diagnostic {
     // NOTE(eddyb) this is private to disallow arbitrary after-the-fact changes,
     // outside of what methods in this crate themselves allow.
-    crate level: Level,
+    pub(crate) level: Level,
 
     pub message: Vec<(DiagnosticMessage, Style)>,
     pub code: Option<DiagnosticId>,
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 53ad6e5a0ed..6ef2c832c65 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -88,7 +88,7 @@ mod sealed_level_is_error {
     use crate::Level;
 
     /// Sealed helper trait for statically checking that a `Level` is an error.
-    crate trait IsError<const L: Level> {}
+    pub(crate) trait IsError<const L: Level> {}
 
     impl IsError<{ Level::Bug }> for () {}
     impl IsError<{ Level::DelayedBug }> for () {}
@@ -101,7 +101,7 @@ mod sealed_level_is_error {
 impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
     /// Convenience function for internal use, clients should use one of the
     /// `struct_*` methods on [`Handler`].
-    crate fn new_guaranteeing_error<M: Into<DiagnosticMessage>, const L: Level>(
+    pub(crate) fn new_guaranteeing_error<M: Into<DiagnosticMessage>, const L: Level>(
         handler: &'a Handler,
         message: M,
     ) -> Self
@@ -168,7 +168,7 @@ impl EmissionGuarantee for ErrorGuaranteed {
 impl<'a> DiagnosticBuilder<'a, ()> {
     /// Convenience function for internal use, clients should use one of the
     /// `struct_*` methods on [`Handler`].
-    crate fn new<M: Into<DiagnosticMessage>>(
+    pub(crate) fn new<M: Into<DiagnosticMessage>>(
         handler: &'a Handler,
         level: Level,
         message: M,
@@ -179,7 +179,7 @@ impl<'a> DiagnosticBuilder<'a, ()> {
 
     /// Creates a new `DiagnosticBuilder` with an already constructed
     /// diagnostic.
-    crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self {
+    pub(crate) fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self {
         debug!("Created new diagnostic");
         Self {
             inner: DiagnosticBuilderInner {
@@ -210,14 +210,14 @@ impl EmissionGuarantee for () {
 impl<'a> DiagnosticBuilder<'a, !> {
     /// Convenience function for internal use, clients should use one of the
     /// `struct_*` methods on [`Handler`].
-    crate fn new_fatal(handler: &'a Handler, message: impl Into<DiagnosticMessage>) -> Self {
+    pub(crate) fn new_fatal(handler: &'a Handler, message: impl Into<DiagnosticMessage>) -> Self {
         let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message);
         Self::new_diagnostic_fatal(handler, diagnostic)
     }
 
     /// Creates a new `DiagnosticBuilder` with an already constructed
     /// diagnostic.
-    crate fn new_diagnostic_fatal(handler: &'a Handler, diagnostic: Diagnostic) -> Self {
+    pub(crate) fn new_diagnostic_fatal(handler: &'a Handler, diagnostic: Diagnostic) -> Self {
         debug!("Created new diagnostic");
         Self {
             inner: DiagnosticBuilderInner {
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 29643eaad99..d2f50d5df54 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -3,7 +3,6 @@
 //! This module contains the code for creating and emitting diagnostics.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![feature(crate_visibility_modifier)]
 #![feature(drain_filter)]
 #![feature(backtrace)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 9ea09f7d702..6ef03d1243d 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -28,7 +28,7 @@ use std::iter;
 use std::path::PathBuf;
 use std::rc::Rc;
 
-crate use rustc_span::hygiene::MacroKind;
+pub(crate) use rustc_span::hygiene::MacroKind;
 
 // When adding new variants, make sure to
 // adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector`
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 41683db80a3..3cada372570 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -347,7 +347,7 @@ impl<'a> StripUnconfigured<'a> {
     /// Gives a compiler warning when the `cfg_attr` contains no attributes and
     /// is in the original source file. Gives a compiler error if the syntax of
     /// the attribute is incorrect.
-    crate fn expand_cfg_attr(&self, attr: Attribute, recursive: bool) -> Vec<Attribute> {
+    pub(crate) fn expand_cfg_attr(&self, attr: Attribute, recursive: bool) -> Vec<Attribute> {
         let Some((cfg_predicate, expanded_attrs)) =
             rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) else {
                 return vec![];
@@ -451,7 +451,7 @@ impl<'a> StripUnconfigured<'a> {
         attrs.iter().all(|attr| !is_cfg(attr) || self.cfg_true(attr))
     }
 
-    crate fn cfg_true(&self, attr: &Attribute) -> bool {
+    pub(crate) fn cfg_true(&self, attr: &Attribute) -> bool {
         let meta_item = match validate_attr::parse_meta(&self.sess.parse_sess, attr) {
             Ok(meta_item) => meta_item,
             Err(mut err) => {
@@ -465,7 +465,7 @@ impl<'a> StripUnconfigured<'a> {
     }
 
     /// If attributes are not allowed on expressions, emit an error for `attr`
-    crate fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
+    pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
         if !self.features.map_or(true, |features| features.stmt_expr_attributes) {
             let mut err = feature_err(
                 &self.sess.parse_sess,
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index a390e7a466d..676abc92b63 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -214,7 +214,7 @@ pub enum SupportsMacroExpansion {
 }
 
 impl AstFragmentKind {
-    crate fn dummy(self, span: Span) -> AstFragment {
+    pub(crate) fn dummy(self, span: Span) -> AstFragment {
         self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
     }
 
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index dc181ecda5b..7043ad54645 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -1,7 +1,6 @@
 #![allow(rustc::potential_query_instability)]
 #![feature(associated_type_bounds)]
 #![feature(associated_type_defaults)]
-#![feature(crate_visibility_modifier)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(let_else)]
@@ -21,7 +20,7 @@ mod placeholders;
 mod proc_macro_server;
 
 pub use mbe::macro_rules::compile_declarative_macro;
-crate use rustc_span::hygiene;
+pub(crate) use rustc_span::hygiene;
 pub mod base;
 pub mod build;
 #[macro_use]
@@ -30,7 +29,7 @@ pub mod expand;
 pub mod module;
 pub mod proc_macro;
 
-crate mod mbe;
+pub(crate) mod mbe;
 
 // HACK(Centril, #64197): These shouldn't really be here.
 // Rather, they should be with their respective modules which are defined in other crates.
diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs
index 36295da74ad..f42576b16f5 100644
--- a/compiler/rustc_expand/src/mbe.rs
+++ b/compiler/rustc_expand/src/mbe.rs
@@ -3,12 +3,12 @@
 //! why we call this module `mbe`. For external documentation, prefer the
 //! official terminology: "declarative macros".
 
-crate mod macro_check;
-crate mod macro_parser;
-crate mod macro_rules;
-crate mod metavar_expr;
-crate mod quoted;
-crate mod transcribe;
+pub(crate) mod macro_check;
+pub(crate) mod macro_parser;
+pub(crate) mod macro_rules;
+pub(crate) mod metavar_expr;
+pub(crate) mod quoted;
+pub(crate) mod transcribe;
 
 use metavar_expr::MetaVarExpr;
 use rustc_ast::token::{Delimiter, NonterminalKind, Token, TokenKind};
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index ddfbef945ef..0631a5e42c2 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -70,8 +70,8 @@
 //! eof: [a $( a )* a b ·]
 //! ```
 
-crate use NamedMatch::*;
-crate use ParseResult::*;
+pub(crate) use NamedMatch::*;
+pub(crate) use ParseResult::*;
 
 use crate::mbe::{KleeneOp, TokenTree};
 
@@ -262,7 +262,7 @@ enum EofMatcherPositions {
 }
 
 /// Represents the possible results of an attempted parse.
-crate enum ParseResult<T> {
+pub(crate) enum ParseResult<T> {
     /// Parsed successfully.
     Success(T),
     /// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected
@@ -276,7 +276,7 @@ crate enum ParseResult<T> {
 /// A `ParseResult` where the `Success` variant contains a mapping of
 /// `MacroRulesNormalizedIdent`s to `NamedMatch`es. This represents the mapping
 /// of metavars to the token trees they bind to.
-crate type NamedParseResult = ParseResult<FxHashMap<MacroRulesNormalizedIdent, NamedMatch>>;
+pub(crate) type NamedParseResult = ParseResult<FxHashMap<MacroRulesNormalizedIdent, NamedMatch>>;
 
 /// Count how many metavars declarations are in `matcher`.
 pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
@@ -340,7 +340,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
 /// ])
 /// ```
 #[derive(Debug, Clone)]
-crate enum NamedMatch {
+pub(crate) enum NamedMatch {
     MatchedSeq(Vec<NamedMatch>),
 
     // A metavar match of type `tt`.
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 4cc3169180e..b16fa7111c5 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -33,7 +33,7 @@ use std::collections::hash_map::Entry;
 use std::{mem, slice};
 use tracing::debug;
 
-crate struct ParserAnyMacro<'a> {
+pub(crate) struct ParserAnyMacro<'a> {
     parser: Parser<'a>,
 
     /// Span of the expansion site of the macro this parser is for
@@ -47,7 +47,7 @@ crate struct ParserAnyMacro<'a> {
     is_local: bool,
 }
 
-crate fn annotate_err_with_kind(err: &mut Diagnostic, kind: AstFragmentKind, span: Span) {
+pub(crate) fn annotate_err_with_kind(err: &mut Diagnostic, kind: AstFragmentKind, span: Span) {
     match kind {
         AstFragmentKind::Ty => {
             err.span_label(span, "this macro call doesn't expand to a type");
@@ -113,7 +113,7 @@ fn emit_frag_parse_err(
 }
 
 impl<'a> ParserAnyMacro<'a> {
-    crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
+    pub(crate) fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
         let ParserAnyMacro {
             site_span,
             macro_ident,
diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs
index ceeb9baff4b..ccc1c2b2ca0 100644
--- a/compiler/rustc_expand/src/mbe/metavar_expr.rs
+++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs
@@ -9,7 +9,7 @@ use rustc_span::Span;
 
 /// A meta-variable expression, for expansions based on properties of meta-variables.
 #[derive(Debug, Clone, PartialEq, Encodable, Decodable)]
-crate enum MetaVarExpr {
+pub(crate) enum MetaVarExpr {
     /// The number of repetitions of an identifier, optionally limited to a number
     /// of outer-most repetition depths. If the depth limit is `None` then the depth is unlimited.
     Count(Ident, Option<usize>),
@@ -28,7 +28,7 @@ crate enum MetaVarExpr {
 
 impl MetaVarExpr {
     /// Attempt to parse a meta-variable expression from a token stream.
-    crate fn parse<'sess>(
+    pub(crate) fn parse<'sess>(
         input: &TokenStream,
         outer_span: Span,
         sess: &'sess ParseSess,
@@ -62,7 +62,7 @@ impl MetaVarExpr {
         Ok(rslt)
     }
 
-    crate fn ident(&self) -> Option<Ident> {
+    pub(crate) fn ident(&self) -> Option<Ident> {
         match *self {
             MetaVarExpr::Count(ident, _) | MetaVarExpr::Ignore(ident) => Some(ident),
             MetaVarExpr::Index(..) | MetaVarExpr::Length(..) => None,
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index 2a059f3519d..876faad33b6 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -26,7 +26,7 @@ pub struct ModulePathSuccess {
     pub dir_ownership: DirOwnership,
 }
 
-crate struct ParsedExternalMod {
+pub(crate) struct ParsedExternalMod {
     pub items: Vec<P<Item>>,
     pub spans: ModSpans,
     pub file_path: PathBuf,
@@ -42,7 +42,7 @@ pub enum ModError<'a> {
     ParserError(DiagnosticBuilder<'a, ErrorGuaranteed>),
 }
 
-crate fn parse_external_mod(
+pub(crate) fn parse_external_mod(
     sess: &Session,
     ident: Ident,
     span: Span, // The span to blame on errors.
@@ -78,7 +78,7 @@ crate fn parse_external_mod(
     ParsedExternalMod { items, spans, file_path, dir_path, dir_ownership }
 }
 
-crate fn mod_dir_path(
+pub(crate) fn mod_dir_path(
     sess: &Session,
     ident: Ident,
     attrs: &[Attribute],
diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs
index 693159f9aec..8b7153776e4 100644
--- a/compiler/rustc_expand/src/tests.rs
+++ b/compiler/rustc_expand/src/tests.rs
@@ -22,7 +22,7 @@ fn string_to_parser(ps: &ParseSess, source_str: String) -> Parser<'_> {
     new_parser_from_source_str(ps, PathBuf::from("bogofile").into(), source_str)
 }
 
-crate fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T
+pub(crate) fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T
 where
     F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
 {
@@ -33,7 +33,7 @@ where
 }
 
 /// Maps a string to tts, using a made-up filename.
-crate fn string_to_stream(source_str: String) -> TokenStream {
+pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
     let ps = ParseSess::new(FilePathMapping::empty());
     source_file_to_stream(
         &ps,
@@ -44,7 +44,7 @@ crate fn string_to_stream(source_str: String) -> TokenStream {
 }
 
 /// Parses a string, returns a crate.
-crate fn string_to_crate(source_str: String) -> ast::Crate {
+pub(crate) fn string_to_crate(source_str: String) -> ast::Crate {
     let ps = ParseSess::new(FilePathMapping::empty());
     with_error_checking_parse(source_str, &ps, |p| p.parse_crate_mod())
 }
@@ -53,7 +53,7 @@ crate fn string_to_crate(source_str: String) -> ast::Crate {
 /// may be deleted or replaced with other whitespace to match the pattern.
 /// This function is relatively Unicode-ignorant; fortunately, the careful design
 /// of UTF-8 mitigates this ignorance. It doesn't do NKF-normalization(?).
-crate fn matches_codepattern(a: &str, b: &str) -> bool {
+pub(crate) fn matches_codepattern(a: &str, b: &str) -> bool {
     let mut a_iter = a.chars().peekable();
     let mut b_iter = b.chars().peekable();
 
@@ -109,7 +109,7 @@ struct SpanLabel {
     label: &'static str,
 }
 
-crate struct Shared<T: Write> {
+pub(crate) struct Shared<T: Write> {
     pub data: Arc<Mutex<T>>,
 }
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index ba012ba6055..2e077ae2440 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1,6 +1,6 @@
 use crate::def::{CtorKind, DefKind, Res};
 use crate::def_id::DefId;
-crate use crate::hir_id::{HirId, ItemLocalId};
+pub(crate) use crate::hir_id::{HirId, ItemLocalId};
 use crate::intravisit::FnKind;
 use crate::LangItem;
 
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index d56230e1dc5..7833571f88d 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -4,7 +4,6 @@
 
 #![feature(associated_type_defaults)]
 #![feature(const_btree_new)]
-#![feature(crate_visibility_modifier)]
 #![feature(let_else)]
 #![feature(once_cell)]
 #![feature(min_specialization)]
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 585edfc47e1..3d50ed2096e 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -2705,7 +2705,7 @@ impl SymbolName {
 }
 
 impl ClashingExternDeclarations {
-    crate fn new() -> Self {
+    pub(crate) fn new() -> Self {
         ClashingExternDeclarations { seen_decls: FxHashMap::default() }
     }
     /// Insert a new foreign item into the seen set. If a symbol with the same name already exists
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index 0ce760b64d9..772ab7fe226 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -34,7 +34,7 @@ use tracing::debug;
 
 /// Extract the `LintStore` from the query context.
 /// This function exists because we've erased `LintStore` as `dyn Any` in the context.
-crate fn unerased_lint_store(tcx: TyCtxt<'_>) -> &LintStore {
+pub(crate) fn unerased_lint_store(tcx: TyCtxt<'_>) -> &LintStore {
     let store: &dyn Any = &*tcx.lint_store;
     store.downcast_ref().unwrap()
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 0a0f292fe7a..7c68429e1e9 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -30,7 +30,6 @@
 #![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
-#![feature(crate_visibility_modifier)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(iter_order_by)]
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 62d427fcd02..55b1ba9cd96 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -651,7 +651,7 @@ declare_lint! {
 declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS]);
 
 #[derive(Clone, Copy)]
-crate enum CItemKind {
+pub(crate) enum CItemKind {
     Declaration,
     Definition,
 }
@@ -667,7 +667,10 @@ enum FfiResult<'tcx> {
     FfiUnsafe { ty: Ty<'tcx>, reason: String, help: Option<String> },
 }
 
-crate fn nonnull_optimization_guaranteed<'tcx>(tcx: TyCtxt<'tcx>, def: ty::AdtDef<'tcx>) -> bool {
+pub(crate) fn nonnull_optimization_guaranteed<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def: ty::AdtDef<'tcx>,
+) -> bool {
     tcx.has_attr(def.did(), sym::rustc_nonnull_optimization_guaranteed)
 }
 
@@ -766,7 +769,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
 /// Currently restricted to function pointers, boxes, references, `core::num::NonZero*`,
 /// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes.
 /// FIXME: This duplicates code in codegen.
-crate fn repr_nullable_ptr<'tcx>(
+pub(crate) fn repr_nullable_ptr<'tcx>(
     cx: &LateContext<'tcx>,
     ty: Ty<'tcx>,
     ckind: CItemKind,
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 3c545e6a0d2..dfc675a0494 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -70,7 +70,7 @@ pub enum LoadedMacro {
     ProcMacro(SyntaxExtension),
 }
 
-crate struct Library {
+pub(crate) struct Library {
     pub source: CrateSource,
     pub metadata: MetadataBlob,
 }
@@ -82,7 +82,7 @@ enum LoadResult {
 
 /// A reference to `CrateMetadata` that can also give access to whole crate store when necessary.
 #[derive(Clone, Copy)]
-crate struct CrateMetadataRef<'a> {
+pub(crate) struct CrateMetadataRef<'a> {
     pub cdata: &'a CrateMetadata,
     pub cstore: &'a CStore,
 }
@@ -133,7 +133,7 @@ impl CStore {
         CrateNum::new(self.metas.len() - 1)
     }
 
-    crate fn get_crate_data(&self, cnum: CrateNum) -> CrateMetadataRef<'_> {
+    pub(crate) fn get_crate_data(&self, cnum: CrateNum) -> CrateMetadataRef<'_> {
         let cdata = self.metas[cnum]
             .as_ref()
             .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum));
@@ -145,7 +145,7 @@ impl CStore {
         self.metas[cnum] = Some(Lrc::new(data));
     }
 
-    crate fn iter_crate_data(&self) -> impl Iterator<Item = (CrateNum, &CrateMetadata)> {
+    pub(crate) fn iter_crate_data(&self) -> impl Iterator<Item = (CrateNum, &CrateMetadata)> {
         self.metas
             .iter_enumerated()
             .filter_map(|(cnum, data)| data.as_ref().map(|data| (cnum, &**data)))
@@ -164,7 +164,7 @@ impl CStore {
         }
     }
 
-    crate fn crate_dependencies_in_postorder(&self, cnum: CrateNum) -> Vec<CrateNum> {
+    pub(crate) fn crate_dependencies_in_postorder(&self, cnum: CrateNum) -> Vec<CrateNum> {
         let mut deps = Vec::new();
         if cnum == LOCAL_CRATE {
             for (cnum, _) in self.iter_crate_data() {
@@ -182,15 +182,15 @@ impl CStore {
         deps
     }
 
-    crate fn injected_panic_runtime(&self) -> Option<CrateNum> {
+    pub(crate) fn injected_panic_runtime(&self) -> Option<CrateNum> {
         self.injected_panic_runtime
     }
 
-    crate fn allocator_kind(&self) -> Option<AllocatorKind> {
+    pub(crate) fn allocator_kind(&self) -> Option<AllocatorKind> {
         self.allocator_kind
     }
 
-    crate fn has_global_allocator(&self) -> bool {
+    pub(crate) fn has_global_allocator(&self) -> bool {
         self.has_global_allocator
     }
 
diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index ddc3e10fa48..245b2076ebc 100644
--- a/compiler/rustc_metadata/src/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
@@ -62,7 +62,7 @@ use rustc_session::cstore::CrateDepKind;
 use rustc_session::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
 use rustc_target::spec::PanicStrategy;
 
-crate fn calculate(tcx: TyCtxt<'_>) -> Dependencies {
+pub(crate) fn calculate(tcx: TyCtxt<'_>) -> Dependencies {
     tcx.sess
         .crate_types()
         .iter()
diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs
index 70da96154b0..2ca4cd17fdf 100644
--- a/compiler/rustc_metadata/src/foreign_modules.rs
+++ b/compiler/rustc_metadata/src/foreign_modules.rs
@@ -3,7 +3,7 @@ use rustc_hir::def::DefKind;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::cstore::ForeignModule;
 
-crate fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
+pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
     let mut modules = Vec::new();
     for id in tcx.hir().items() {
         if !matches!(tcx.def_kind(id.def_id), DefKind::ForeignMod) {
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 2d13675e615..3df18098a07 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -1,5 +1,4 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
 #![feature(drain_filter)]
 #![feature(generators)]
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 43bda7c0734..dbe53224e2a 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -239,7 +239,7 @@ use std::{cmp, fmt, fs};
 use tracing::{debug, info};
 
 #[derive(Clone)]
-crate struct CrateLocator<'a> {
+pub(crate) struct CrateLocator<'a> {
     // Immutable per-session configuration.
     only_needs_metadata: bool,
     sysroot: &'a Path,
@@ -260,19 +260,19 @@ crate struct CrateLocator<'a> {
 }
 
 #[derive(Clone)]
-crate struct CratePaths {
+pub(crate) struct CratePaths {
     name: Symbol,
     source: CrateSource,
 }
 
 impl CratePaths {
-    crate fn new(name: Symbol, source: CrateSource) -> CratePaths {
+    pub(crate) fn new(name: Symbol, source: CrateSource) -> CratePaths {
         CratePaths { name, source }
     }
 }
 
 #[derive(Copy, Clone, PartialEq)]
-crate enum CrateFlavor {
+pub(crate) enum CrateFlavor {
     Rlib,
     Rmeta,
     Dylib,
@@ -289,7 +289,7 @@ impl fmt::Display for CrateFlavor {
 }
 
 impl<'a> CrateLocator<'a> {
-    crate fn new(
+    pub(crate) fn new(
         sess: &'a Session,
         metadata_loader: &'a dyn MetadataLoader,
         crate_name: Symbol,
@@ -344,7 +344,7 @@ impl<'a> CrateLocator<'a> {
         }
     }
 
-    crate fn reset(&mut self) {
+    pub(crate) fn reset(&mut self) {
         self.crate_rejections.via_hash.clear();
         self.crate_rejections.via_triple.clear();
         self.crate_rejections.via_kind.clear();
@@ -353,7 +353,7 @@ impl<'a> CrateLocator<'a> {
         self.crate_rejections.via_invalid.clear();
     }
 
-    crate fn maybe_load_library_crate(&mut self) -> Result<Option<Library>, CrateError> {
+    pub(crate) fn maybe_load_library_crate(&mut self) -> Result<Option<Library>, CrateError> {
         if !self.exact_paths.is_empty() {
             return self.find_commandline_library();
         }
@@ -728,7 +728,7 @@ impl<'a> CrateLocator<'a> {
         Ok(self.extract_lib(rlibs, rmetas, dylibs)?.map(|(_, lib)| lib))
     }
 
-    crate fn into_error(self, root: Option<CratePaths>) -> CrateError {
+    pub(crate) fn into_error(self, root: Option<CratePaths>) -> CrateError {
         CrateError::LocatorCombined(CombinedLocatorError {
             crate_name: self.crate_name,
             root,
@@ -894,7 +894,7 @@ struct CrateRejections {
 /// Candidate rejection reasons collected during crate search.
 /// If no candidate is accepted, then these reasons are presented to the user,
 /// otherwise they are ignored.
-crate struct CombinedLocatorError {
+pub(crate) struct CombinedLocatorError {
     crate_name: Symbol,
     root: Option<CratePaths>,
     triple: TargetTriple,
@@ -903,7 +903,7 @@ crate struct CombinedLocatorError {
     crate_rejections: CrateRejections,
 }
 
-crate enum CrateError {
+pub(crate) enum CrateError {
     NonAsciiName(Symbol),
     ExternLocationNotExist(Symbol, PathBuf),
     ExternLocationNotFile(Symbol, PathBuf),
@@ -937,7 +937,7 @@ impl fmt::Display for MetadataError<'_> {
 }
 
 impl CrateError {
-    crate fn report(self, sess: &Session, span: Span, missing_core: bool) {
+    pub(crate) fn report(self, sess: &Session, span: Span, missing_core: bool) {
         let mut diag = match self {
             CrateError::NonAsciiName(crate_name) => sess.struct_span_err(
                 span,
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 628516fa138..8d044be195a 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -12,7 +12,7 @@ use rustc_session::Session;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_target::spec::abi::Abi;
 
-crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
+pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
     let mut collector = Collector { tcx, libs: Vec::new() };
     for id in tcx.hir().items() {
         collector.process_item(id);
@@ -21,7 +21,7 @@ crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
     collector.libs
 }
 
-crate fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
+pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
     match lib.cfg {
         Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, CRATE_NODE_ID, None),
         None => true,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index de1e96ebfe7..4038af38a2c 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -57,7 +57,7 @@ mod cstore_impl;
 /// A `MetadataBlob` internally is just a reference counted pointer to
 /// the actual data, so cloning it is cheap.
 #[derive(Clone)]
-crate struct MetadataBlob(Lrc<MetadataRef>);
+pub(crate) struct MetadataBlob(Lrc<MetadataRef>);
 
 // This is needed so we can create an OwningRef into the blob.
 // The data behind a `MetadataBlob` has a stable address because it is
@@ -78,9 +78,9 @@ impl std::ops::Deref for MetadataBlob {
 // local crate numbers (as generated during this session). Each external
 // crate may refer to types in other external crates, and each has their
 // own crate numbers.
-crate type CrateNumMap = IndexVec<CrateNum, CrateNum>;
+pub(crate) type CrateNumMap = IndexVec<CrateNum, CrateNum>;
 
-crate struct CrateMetadata {
+pub(crate) struct CrateMetadata {
     /// The primary crate data - binary metadata blob.
     blob: MetadataBlob,
 
@@ -744,20 +744,20 @@ where
 implement_ty_decoder!(DecodeContext<'a, 'tcx>);
 
 impl<'tcx> MetadataBlob {
-    crate fn new(metadata_ref: MetadataRef) -> MetadataBlob {
+    pub(crate) fn new(metadata_ref: MetadataRef) -> MetadataBlob {
         MetadataBlob(Lrc::new(metadata_ref))
     }
 
-    crate fn is_compatible(&self) -> bool {
+    pub(crate) fn is_compatible(&self) -> bool {
         self.blob().starts_with(METADATA_HEADER)
     }
 
-    crate fn get_rustc_version(&self) -> String {
+    pub(crate) fn get_rustc_version(&self) -> String {
         Lazy::<String>::from_position(NonZeroUsize::new(METADATA_HEADER.len() + 4).unwrap())
             .decode(self)
     }
 
-    crate fn get_root(&self) -> CrateRoot<'tcx> {
+    pub(crate) fn get_root(&self) -> CrateRoot<'tcx> {
         let slice = &self.blob()[..];
         let offset = METADATA_HEADER.len();
         let pos = (((slice[offset + 0] as u32) << 24)
@@ -767,7 +767,7 @@ impl<'tcx> MetadataBlob {
         Lazy::<CrateRoot<'tcx>>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
     }
 
-    crate fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> {
+    pub(crate) fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> {
         let root = self.get_root();
         writeln!(out, "Crate info:")?;
         writeln!(out, "name {}{}", root.name, root.extra_filename)?;
@@ -792,27 +792,27 @@ impl<'tcx> MetadataBlob {
 }
 
 impl CrateRoot<'_> {
-    crate fn is_proc_macro_crate(&self) -> bool {
+    pub(crate) fn is_proc_macro_crate(&self) -> bool {
         self.proc_macro_data.is_some()
     }
 
-    crate fn name(&self) -> Symbol {
+    pub(crate) fn name(&self) -> Symbol {
         self.name
     }
 
-    crate fn hash(&self) -> Svh {
+    pub(crate) fn hash(&self) -> Svh {
         self.hash
     }
 
-    crate fn stable_crate_id(&self) -> StableCrateId {
+    pub(crate) fn stable_crate_id(&self) -> StableCrateId {
         self.stable_crate_id
     }
 
-    crate fn triple(&self) -> &TargetTriple {
+    pub(crate) fn triple(&self) -> &TargetTriple {
         &self.triple
     }
 
-    crate fn decode_crate_deps<'a>(
+    pub(crate) fn decode_crate_deps<'a>(
         &self,
         metadata: &'a MetadataBlob,
     ) -> impl ExactSizeIterator<Item = CrateDep> + Captures<'a> {
@@ -1759,7 +1759,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 }
 
 impl CrateMetadata {
-    crate fn new(
+    pub(crate) fn new(
         sess: &Session,
         cstore: &CStore,
         blob: MetadataBlob,
@@ -1819,15 +1819,15 @@ impl CrateMetadata {
         cdata
     }
 
-    crate fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> {
+    pub(crate) fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> {
         self.dependencies.borrow()
     }
 
-    crate fn add_dependency(&self, cnum: CrateNum) {
+    pub(crate) fn add_dependency(&self, cnum: CrateNum) {
         self.dependencies.borrow_mut().push(cnum);
     }
 
-    crate fn update_extern_crate(&self, new_extern_crate: ExternCrate) -> bool {
+    pub(crate) fn update_extern_crate(&self, new_extern_crate: ExternCrate) -> bool {
         let mut extern_crate = self.extern_crate.borrow_mut();
         let update = Some(new_extern_crate.rank()) > extern_crate.as_ref().map(ExternCrate::rank);
         if update {
@@ -1836,59 +1836,59 @@ impl CrateMetadata {
         update
     }
 
-    crate fn source(&self) -> &CrateSource {
+    pub(crate) fn source(&self) -> &CrateSource {
         &*self.source
     }
 
-    crate fn dep_kind(&self) -> CrateDepKind {
+    pub(crate) fn dep_kind(&self) -> CrateDepKind {
         *self.dep_kind.lock()
     }
 
-    crate fn update_dep_kind(&self, f: impl FnOnce(CrateDepKind) -> CrateDepKind) {
+    pub(crate) fn update_dep_kind(&self, f: impl FnOnce(CrateDepKind) -> CrateDepKind) {
         self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind))
     }
 
-    crate fn panic_strategy(&self) -> PanicStrategy {
+    pub(crate) fn panic_strategy(&self) -> PanicStrategy {
         self.root.panic_strategy
     }
 
-    crate fn needs_panic_runtime(&self) -> bool {
+    pub(crate) fn needs_panic_runtime(&self) -> bool {
         self.root.needs_panic_runtime
     }
 
-    crate fn is_panic_runtime(&self) -> bool {
+    pub(crate) fn is_panic_runtime(&self) -> bool {
         self.root.panic_runtime
     }
 
-    crate fn is_profiler_runtime(&self) -> bool {
+    pub(crate) fn is_profiler_runtime(&self) -> bool {
         self.root.profiler_runtime
     }
 
-    crate fn needs_allocator(&self) -> bool {
+    pub(crate) fn needs_allocator(&self) -> bool {
         self.root.needs_allocator
     }
 
-    crate fn has_global_allocator(&self) -> bool {
+    pub(crate) fn has_global_allocator(&self) -> bool {
         self.root.has_global_allocator
     }
 
-    crate fn has_default_lib_allocator(&self) -> bool {
+    pub(crate) fn has_default_lib_allocator(&self) -> bool {
         self.root.has_default_lib_allocator
     }
 
-    crate fn is_proc_macro_crate(&self) -> bool {
+    pub(crate) fn is_proc_macro_crate(&self) -> bool {
         self.root.is_proc_macro_crate()
     }
 
-    crate fn name(&self) -> Symbol {
+    pub(crate) fn name(&self) -> Symbol {
         self.root.name
     }
 
-    crate fn stable_crate_id(&self) -> StableCrateId {
+    pub(crate) fn stable_crate_id(&self) -> StableCrateId {
         self.root.stable_crate_id
     }
 
-    crate fn hash(&self) -> Svh {
+    pub(crate) fn hash(&self) -> Svh {
         self.root.hash
     }
 
diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
index d66f2b031a8..06045bb3e3d 100644
--- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
+++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
@@ -6,7 +6,7 @@ use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap};
 use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
 use rustc_span::def_id::{DefIndex, DefPathHash};
 
-crate enum DefPathHashMapRef<'tcx> {
+pub(crate) enum DefPathHashMapRef<'tcx> {
     OwnedFromMetadata(odht::HashTable<HashMapConfig, OwningRef<MetadataBlob, [u8]>>),
     BorrowedFromTcx(&'tcx DefPathHashMap),
 }
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 1c5774db579..7ae177c3a56 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -36,7 +36,7 @@ use std::num::NonZeroUsize;
 
 pub use decoder::provide_extern;
 use decoder::DecodeContext;
-crate use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
+pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
 use encoder::EncodeContext;
 pub use encoder::{encode_metadata, EncodedMetadata};
 use rustc_span::hygiene::SyntaxContextData;
@@ -46,7 +46,7 @@ mod def_path_hash_map;
 mod encoder;
 mod table;
 
-crate fn rustc_version() -> String {
+pub(crate) fn rustc_version() -> String {
     format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version"))
 }
 
@@ -169,7 +169,7 @@ type ExpnDataTable = Lazy<Table<ExpnIndex, Lazy<ExpnData>>>;
 type ExpnHashTable = Lazy<Table<ExpnIndex, Lazy<ExpnHash>>>;
 
 #[derive(MetadataEncodable, MetadataDecodable)]
-crate struct ProcMacroData {
+pub(crate) struct ProcMacroData {
     proc_macro_decls_static: DefIndex,
     stability: Option<attr::Stability>,
     macros: Lazy<[DefIndex]>,
@@ -192,7 +192,7 @@ crate struct ProcMacroData {
 /// a normal crate, much of what we serialized would be unusable in addition
 /// to being unused.
 #[derive(MetadataEncodable, MetadataDecodable)]
-crate struct CrateRoot<'tcx> {
+pub(crate) struct CrateRoot<'tcx> {
     name: Symbol,
     triple: TargetTriple,
     extra_filename: String,
@@ -245,7 +245,7 @@ crate struct CrateRoot<'tcx> {
 /// This creates a type-safe way to enforce that we remap the CrateNum between the on-disk
 /// representation and the compilation session.
 #[derive(Copy, Clone)]
-crate struct RawDefId {
+pub(crate) struct RawDefId {
     krate: u32,
     index: u32,
 }
@@ -265,7 +265,7 @@ impl RawDefId {
 }
 
 #[derive(Encodable, Decodable)]
-crate struct CrateDep {
+pub(crate) struct CrateDep {
     pub name: Symbol,
     pub hash: Svh,
     pub host_hash: Option<Svh>,
@@ -274,13 +274,13 @@ crate struct CrateDep {
 }
 
 #[derive(MetadataEncodable, MetadataDecodable)]
-crate struct TraitImpls {
+pub(crate) struct TraitImpls {
     trait_id: (u32, DefIndex),
     impls: Lazy<[(DefIndex, Option<SimplifiedType>)]>,
 }
 
 #[derive(MetadataEncodable, MetadataDecodable)]
-crate struct IncoherentImpls {
+pub(crate) struct IncoherentImpls {
     self_ty: SimplifiedType,
     impls: Lazy<[DefIndex]>,
 }
@@ -289,7 +289,7 @@ crate struct IncoherentImpls {
 macro_rules! define_tables {
     ($($name:ident: Table<$IDX:ty, $T:ty>),+ $(,)?) => {
         #[derive(MetadataEncodable, MetadataDecodable)]
-        crate struct LazyTables<'tcx> {
+        pub(crate) struct LazyTables<'tcx> {
             $($name: Lazy!(Table<$IDX, $T>)),+
         }
 
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 8402ca3028c..555baae35f5 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -195,13 +195,16 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
 
 // WARNING: `construct` is generic and does not know that `CompileCodegenUnit` takes `Symbol`s as keys.
 // Be very careful changing this type signature!
-crate fn make_compile_codegen_unit(tcx: TyCtxt<'_>, name: Symbol) -> DepNode {
+pub(crate) fn make_compile_codegen_unit(tcx: TyCtxt<'_>, name: Symbol) -> DepNode {
     DepNode::construct(tcx, DepKind::CompileCodegenUnit, &name)
 }
 
 // WARNING: `construct` is generic and does not know that `CompileMonoItem` takes `MonoItem`s as keys.
 // Be very careful changing this type signature!
-crate fn make_compile_mono_item<'tcx>(tcx: TyCtxt<'tcx>, mono_item: &MonoItem<'tcx>) -> DepNode {
+pub(crate) fn make_compile_mono_item<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    mono_item: &MonoItem<'tcx>,
+) -> DepNode {
     DepNode::construct(tcx, DepKind::CompileMonoItem, mono_item)
 }
 
diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs
index 6bfd1b7ffab..e335cb395f8 100644
--- a/compiler/rustc_middle/src/dep_graph/mod.rs
+++ b/compiler/rustc_middle/src/dep_graph/mod.rs
@@ -12,7 +12,7 @@ pub use rustc_query_system::dep_graph::{
 };
 
 pub use dep_node::{label_strs, DepKind, DepKindStruct, DepNode, DepNodeExt};
-crate use dep_node::{make_compile_codegen_unit, make_compile_mono_item};
+pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item};
 
 pub type DepGraph = rustc_query_system::dep_graph::DepGraph<DepKind>;
 pub type TaskDeps = rustc_query_system::dep_graph::TaskDeps<DepKind>;
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index e3522e0c915..b4dd253b839 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -46,7 +46,6 @@
 #![feature(min_specialization)]
 #![feature(trusted_len)]
 #![feature(type_alias_impl_trait)]
-#![feature(crate_visibility_modifier)]
 #![feature(associated_type_bounds)]
 #![feature(rustc_attrs)]
 #![feature(half_open_range_patterns)]
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 0fa4b10399a..16ef8d68be3 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -414,7 +414,7 @@ impl<'tcx> GlobalAlloc<'tcx> {
     }
 }
 
-crate struct AllocMap<'tcx> {
+pub(crate) struct AllocMap<'tcx> {
     /// Maps `AllocId`s to their corresponding allocations.
     alloc_map: FxHashMap<AllocId, GlobalAlloc<'tcx>>,
 
@@ -430,7 +430,7 @@ crate struct AllocMap<'tcx> {
 }
 
 impl<'tcx> AllocMap<'tcx> {
-    crate fn new() -> Self {
+    pub(crate) fn new() -> Self {
         AllocMap {
             alloc_map: Default::default(),
             dedup: Default::default(),
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 1616b753433..31e131182cc 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1230,7 +1230,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    crate fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct {
+    pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct {
         &self.query_kinds[k as usize]
     }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 2cba276a7ba..8efa1621ade 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -409,7 +409,7 @@ pub struct CReaderCacheKey {
 ///   of the relevant methods.
 #[derive(PartialEq, Eq, PartialOrd, Ord)]
 #[allow(rustc::usage_of_ty_tykind)]
-crate struct TyS<'tcx> {
+pub(crate) struct TyS<'tcx> {
     /// This field shouldn't be used directly and may be removed in the future.
     /// Use `Ty::kind()` instead.
     kind: TyKind<'tcx>,
@@ -500,7 +500,7 @@ impl ty::EarlyBoundRegion {
 /// See comments on `TyS`, which apply here too (albeit for
 /// `PredicateS`/`Predicate` rather than `TyS`/`Ty`).
 #[derive(Debug)]
-crate struct PredicateS<'tcx> {
+pub(crate) struct PredicateS<'tcx> {
     kind: Binder<'tcx, PredicateKind<'tcx>>,
     flags: TypeFlags,
     /// See the comment for the corresponding field of [TyS].
diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs
index 679043bdc30..a83328c0cab 100644
--- a/compiler/rustc_mir_build/src/build/block.rs
+++ b/compiler/rustc_mir_build/src/build/block.rs
@@ -6,7 +6,7 @@ use rustc_middle::{mir::*, ty};
 use rustc_span::Span;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
-    crate fn ast_block(
+    pub(crate) fn ast_block(
         &mut self,
         destination: Place<'tcx>,
         block: BasicBlock,
diff --git a/compiler/rustc_mir_build/src/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs
index ac92b03e5f3..d7b4b1f731a 100644
--- a/compiler/rustc_mir_build/src/build/cfg.rs
+++ b/compiler/rustc_mir_build/src/build/cfg.rs
@@ -5,33 +5,33 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
 
 impl<'tcx> CFG<'tcx> {
-    crate fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
+    pub(crate) fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
         &self.basic_blocks[blk]
     }
 
-    crate fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<'tcx> {
+    pub(crate) fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<'tcx> {
         &mut self.basic_blocks[blk]
     }
 
     // llvm.org/PR32488 makes this function use an excess of stack space. Mark
     // it as #[inline(never)] to keep rustc's stack use in check.
     #[inline(never)]
-    crate fn start_new_block(&mut self) -> BasicBlock {
+    pub(crate) fn start_new_block(&mut self) -> BasicBlock {
         self.basic_blocks.push(BasicBlockData::new(None))
     }
 
-    crate fn start_new_cleanup_block(&mut self) -> BasicBlock {
+    pub(crate) fn start_new_cleanup_block(&mut self) -> BasicBlock {
         let bb = self.start_new_block();
         self.block_data_mut(bb).is_cleanup = true;
         bb
     }
 
-    crate fn push(&mut self, block: BasicBlock, statement: Statement<'tcx>) {
+    pub(crate) fn push(&mut self, block: BasicBlock, statement: Statement<'tcx>) {
         debug!("push({:?}, {:?})", block, statement);
         self.block_data_mut(block).statements.push(statement);
     }
 
-    crate fn push_assign(
+    pub(crate) fn push_assign(
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
@@ -44,7 +44,7 @@ impl<'tcx> CFG<'tcx> {
         );
     }
 
-    crate fn push_assign_constant(
+    pub(crate) fn push_assign_constant(
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
@@ -59,7 +59,7 @@ impl<'tcx> CFG<'tcx> {
         );
     }
 
-    crate fn push_assign_unit(
+    pub(crate) fn push_assign_unit(
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
@@ -78,7 +78,7 @@ impl<'tcx> CFG<'tcx> {
         );
     }
 
-    crate fn push_fake_read(
+    pub(crate) fn push_fake_read(
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
@@ -90,7 +90,7 @@ impl<'tcx> CFG<'tcx> {
         self.push(block, stmt);
     }
 
-    crate fn terminate(
+    pub(crate) fn terminate(
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
@@ -107,7 +107,7 @@ impl<'tcx> CFG<'tcx> {
     }
 
     /// In the `origin` block, push a `goto -> target` terminator.
-    crate fn goto(&mut self, origin: BasicBlock, source_info: SourceInfo, target: BasicBlock) {
+    pub(crate) fn goto(&mut self, origin: BasicBlock, source_info: SourceInfo, target: BasicBlock) {
         self.terminate(origin, source_info, TerminatorKind::Goto { target })
     }
 }
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 25ba5d570b8..035e94eecee 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -11,7 +11,7 @@ use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt};
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Compile `expr`, yielding a compile-time constant. Assumes that
     /// `expr` is a valid compile-time constant!
-    crate fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> {
+    pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> {
         let create_uneval_from_def_id =
             |tcx: TyCtxt<'tcx>, def_id: DefId, ty: Ty<'tcx>, substs: SubstsRef<'tcx>| {
                 let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);
diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
index 7eca49454ba..e707c373f0d 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
@@ -14,7 +14,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// after the current enclosing `ExprKind::Scope` has ended, so
     /// please do *not* return it from functions to avoid bad
     /// miscompiles.
-    crate fn as_local_operand(
+    pub(crate) fn as_local_operand(
         &mut self,
         block: BasicBlock,
         expr: &Expr<'tcx>,
@@ -73,7 +73,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// value to the stack.
     ///
     /// See #68034 for more details.
-    crate fn as_local_call_operand(
+    pub(crate) fn as_local_call_operand(
         &mut self,
         block: BasicBlock,
         expr: &Expr<'tcx>,
@@ -97,7 +97,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Like `as_local_call_operand`, except that the argument will
     /// not be valid once `scope` ends.
     #[instrument(level = "debug", skip(self, scope))]
-    crate fn as_operand(
+    pub(crate) fn as_operand(
         &mut self,
         mut block: BasicBlock,
         scope: Option<region::Scope>,
@@ -132,7 +132,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
-    crate fn as_call_operand(
+    pub(crate) fn as_call_operand(
         &mut self,
         mut block: BasicBlock,
         scope: Option<region::Scope>,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index fa1bb0622bd..045d6eb1c30 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -21,7 +21,7 @@ use std::iter;
 
 /// The "outermost" place that holds this value.
 #[derive(Copy, Clone, Debug, PartialEq)]
-crate enum PlaceBase {
+pub(crate) enum PlaceBase {
     /// Denotes the start of a `Place`.
     Local(Local),
 
@@ -71,7 +71,7 @@ crate enum PlaceBase {
 /// This is used internally when building a place for an expression like `a.b.c`. The fields `b`
 /// and `c` can be progressively pushed onto the place builder that is created when converting `a`.
 #[derive(Clone, Debug, PartialEq)]
-crate struct PlaceBuilder<'tcx> {
+pub(crate) struct PlaceBuilder<'tcx> {
     base: PlaceBase,
     projection: Vec<PlaceElem<'tcx>>,
 }
@@ -283,7 +283,7 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
 }
 
 impl<'tcx> PlaceBuilder<'tcx> {
-    crate fn into_place<'a>(
+    pub(crate) fn into_place<'a>(
         self,
         tcx: TyCtxt<'tcx>,
         typeck_results: &'a ty::TypeckResults<'tcx>,
@@ -314,7 +314,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
     /// not captured. This can happen because the final mir that will be
     /// generated doesn't require a read for this place. Failures will only
     /// happen inside closures.
-    crate fn try_upvars_resolved<'a>(
+    pub(crate) fn try_upvars_resolved<'a>(
         self,
         tcx: TyCtxt<'tcx>,
         typeck_results: &'a ty::TypeckResults<'tcx>,
@@ -322,19 +322,19 @@ impl<'tcx> PlaceBuilder<'tcx> {
         to_upvars_resolved_place_builder(self, tcx, typeck_results)
     }
 
-    crate fn base(&self) -> PlaceBase {
+    pub(crate) fn base(&self) -> PlaceBase {
         self.base
     }
 
-    crate fn field(self, f: Field, ty: Ty<'tcx>) -> Self {
+    pub(crate) fn field(self, f: Field, ty: Ty<'tcx>) -> Self {
         self.project(PlaceElem::Field(f, ty))
     }
 
-    crate fn deref(self) -> Self {
+    pub(crate) fn deref(self) -> Self {
         self.project(PlaceElem::Deref)
     }
 
-    crate fn downcast(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx) -> Self {
+    pub(crate) fn downcast(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx) -> Self {
         self.project(PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index))
     }
 
@@ -342,7 +342,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
         self.project(PlaceElem::Index(index))
     }
 
-    crate fn project(mut self, elem: PlaceElem<'tcx>) -> Self {
+    pub(crate) fn project(mut self, elem: PlaceElem<'tcx>) -> Self {
         self.projection.push(elem);
         self
     }
@@ -373,7 +373,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Extra care is needed if any user code is allowed to run between calling
     /// this method and using it, as is the case for `match` and index
     /// expressions.
-    crate fn as_place(
+    pub(crate) fn as_place(
         &mut self,
         mut block: BasicBlock,
         expr: &Expr<'tcx>,
@@ -384,7 +384,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
     /// This is used when constructing a compound `Place`, so that we can avoid creating
     /// intermediate `Place` values until we know the full set of projections.
-    crate fn as_place_builder(
+    pub(crate) fn as_place_builder(
         &mut self,
         block: BasicBlock,
         expr: &Expr<'tcx>,
@@ -397,7 +397,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// place. The place itself may or may not be mutable:
     /// * If this expr is a place expr like a.b, then we will return that place.
     /// * Otherwise, a temporary is created: in that event, it will be an immutable temporary.
-    crate fn as_read_only_place(
+    pub(crate) fn as_read_only_place(
         &mut self,
         mut block: BasicBlock,
         expr: &Expr<'tcx>,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index d807500f1fb..0fd67f15b75 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -21,7 +21,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// The operand returned from this function will *not be valid* after
     /// an ExprKind::Scope is passed, so please do *not* return it from
     /// functions to avoid bad miscompiles.
-    crate fn as_local_rvalue(
+    pub(crate) fn as_local_rvalue(
         &mut self,
         block: BasicBlock,
         expr: &Expr<'tcx>,
@@ -31,7 +31,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     /// Compile `expr`, yielding an rvalue.
-    crate fn as_rvalue(
+    pub(crate) fn as_rvalue(
         &mut self,
         mut block: BasicBlock,
         scope: Option<region::Scope>,
@@ -416,7 +416,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
-    crate fn build_binary_op(
+    pub(crate) fn build_binary_op(
         &mut self,
         mut block: BasicBlock,
         op: BinOp,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
index 6067da2f69b..724b72f8769 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
@@ -10,7 +10,7 @@ use rustc_middle::thir::*;
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Compile `expr` into a fresh temporary. This is used when building
     /// up rvalues so as to freeze the value that will be consumed.
-    crate fn as_temp(
+    pub(crate) fn as_temp(
         &mut self,
         block: BasicBlock,
         temp_lifetime: Option<region::Scope>,
diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs
index bcece39c620..b1a70643934 100644
--- a/compiler/rustc_mir_build/src/build/expr/category.rs
+++ b/compiler/rustc_mir_build/src/build/expr/category.rs
@@ -1,7 +1,7 @@
 use rustc_middle::thir::*;
 
 #[derive(Debug, PartialEq)]
-crate enum Category {
+pub(crate) enum Category {
     // An assignable memory location like `x`, `x.f`, `foo()[3]`, that
     // sort of thing. Something that could appear on the LHS of an `=`
     // sign.
@@ -19,7 +19,7 @@ crate enum Category {
 // Rvalues fall into different "styles" that will determine which fn
 // is best suited to generate them.
 #[derive(Debug, PartialEq)]
-crate enum RvalueFunc {
+pub(crate) enum RvalueFunc {
     // Best generated by `into`. This is generally exprs that
     // cause branching, like `match`, but also includes calls.
     Into,
@@ -31,7 +31,7 @@ crate enum RvalueFunc {
 /// Determines the category for a given expression. Note that scope
 /// and paren expressions have no category.
 impl Category {
-    crate fn of(ek: &ExprKind<'_>) -> Option<Category> {
+    pub(crate) fn of(ek: &ExprKind<'_>) -> Option<Category> {
         match *ek {
             ExprKind::Scope { .. } => None,
 
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 4399fdf8520..e912501d55f 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -15,7 +15,7 @@ use std::iter;
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Compile `expr`, storing the result into `destination`, which
     /// is assumed to be uninitialized.
-    crate fn expr_into_dest(
+    pub(crate) fn expr_into_dest(
         &mut self,
         destination: Place<'tcx>,
         mut block: BasicBlock,
diff --git a/compiler/rustc_mir_build/src/build/expr/mod.rs b/compiler/rustc_mir_build/src/build/expr/mod.rs
index 7be435cda7d..f5ae060d603 100644
--- a/compiler/rustc_mir_build/src/build/expr/mod.rs
+++ b/compiler/rustc_mir_build/src/build/expr/mod.rs
@@ -60,7 +60,7 @@
 //! basically the point where the "by value" operations are bridged
 //! over to the "by reference" mode (`as_place`).
 
-crate mod as_constant;
+pub(crate) mod as_constant;
 mod as_operand;
 pub mod as_place;
 mod as_rvalue;
diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs
index 46c616ff362..a7e1331aabc 100644
--- a/compiler/rustc_mir_build/src/build/expr/stmt.rs
+++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs
@@ -10,7 +10,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// (e.g., `some().code(&here());`) then `opt_stmt_span` is the
     /// span of that statement (including its semicolon, if any).
     /// The scope is used if a statement temporary must be dropped.
-    crate fn stmt_expr(
+    pub(crate) fn stmt_expr(
         &mut self,
         mut block: BasicBlock,
         expr: &Expr<'tcx>,
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 05b1342cf8c..83ecd185b3c 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -151,7 +151,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ///
     /// * From each pre-binding block to the next pre-binding block.
     /// * From each otherwise block to the next pre-binding block.
-    crate fn match_expr(
+    pub(crate) fn match_expr(
         &mut self,
         destination: Place<'tcx>,
         span: Span,
@@ -577,7 +577,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
-    crate fn place_into_pattern(
+    pub(crate) fn place_into_pattern(
         &mut self,
         block: BasicBlock,
         irrefutable_pat: Pat<'tcx>,
@@ -653,7 +653,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// scope for the bindings in these patterns, if such a scope had to be
     /// created. NOTE: Declaring the bindings should always be done in their
     /// drop scope.
-    crate fn declare_bindings(
+    pub(crate) fn declare_bindings(
         &mut self,
         mut visibility_scope: Option<SourceScope>,
         scope_span: Span,
@@ -690,7 +690,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         visibility_scope
     }
 
-    crate fn storage_live_binding(
+    pub(crate) fn storage_live_binding(
         &mut self,
         block: BasicBlock,
         var: HirId,
@@ -709,7 +709,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         Place::from(local_id)
     }
 
-    crate fn schedule_drop_for_binding(&mut self, var: HirId, span: Span, for_guard: ForGuard) {
+    pub(crate) fn schedule_drop_for_binding(
+        &mut self,
+        var: HirId,
+        span: Span,
+        for_guard: ForGuard,
+    ) {
         let local_id = self.var_local_id(var, for_guard);
         if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) {
             self.schedule_drop(span, region_scope, local_id, DropKind::Value);
@@ -934,7 +939,7 @@ struct Ascription<'tcx> {
 }
 
 #[derive(Clone, Debug)]
-crate struct MatchPair<'pat, 'tcx> {
+pub(crate) struct MatchPair<'pat, 'tcx> {
     // this place...
     place: PlaceBuilder<'tcx>,
 
@@ -991,7 +996,7 @@ enum TestKind<'tcx> {
 /// [`Test`] is just the test to perform; it does not include the value
 /// to be tested.
 #[derive(Debug)]
-crate struct Test<'tcx> {
+pub(crate) struct Test<'tcx> {
     span: Span,
     kind: TestKind<'tcx>,
 }
@@ -999,7 +1004,7 @@ crate struct Test<'tcx> {
 /// `ArmHasGuard` is a wrapper around a boolean flag. It indicates whether
 /// a match arm has a guard expression attached to it.
 #[derive(Copy, Clone, Debug)]
-crate struct ArmHasGuard(crate bool);
+pub(crate) struct ArmHasGuard(pub(crate) bool);
 
 ///////////////////////////////////////////////////////////////////////////
 // Main matching algorithm
@@ -1769,7 +1774,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 // Pat binding - used for `let` and function parameters as well.
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
-    crate fn lower_let_expr(
+    pub(crate) fn lower_let_expr(
         &mut self,
         mut block: BasicBlock,
         expr: &Expr<'tcx>,
diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs
index 88dd76e37c1..9a1e98d3bb1 100644
--- a/compiler/rustc_mir_build/src/build/matches/util.rs
+++ b/compiler/rustc_mir_build/src/build/matches/util.rs
@@ -8,7 +8,7 @@ use smallvec::SmallVec;
 use std::convert::TryInto;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
-    crate fn field_match_pairs<'pat>(
+    pub(crate) fn field_match_pairs<'pat>(
         &mut self,
         place: PlaceBuilder<'tcx>,
         subpatterns: &'pat [FieldPat<'tcx>],
@@ -22,7 +22,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             .collect()
     }
 
-    crate fn prefix_slice_suffix<'pat>(
+    pub(crate) fn prefix_slice_suffix<'pat>(
         &mut self,
         match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>,
         place: &PlaceBuilder<'tcx>,
@@ -79,7 +79,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Creates a false edge to `imaginary_target` and a real edge to
     /// real_target. If `imaginary_target` is none, or is the same as the real
     /// target, a Goto is generated instead to simplify the generated MIR.
-    crate fn false_edges(
+    pub(crate) fn false_edges(
         &mut self,
         from_block: BasicBlock,
         real_target: BasicBlock,
@@ -100,7 +100,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 }
 
 impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
-    crate fn new(place: PlaceBuilder<'tcx>, pattern: &'pat Pat<'tcx>) -> MatchPair<'pat, 'tcx> {
+    pub(crate) fn new(
+        place: PlaceBuilder<'tcx>,
+        pattern: &'pat Pat<'tcx>,
+    ) -> MatchPair<'pat, 'tcx> {
         MatchPair { place, pattern }
     }
 }
diff --git a/compiler/rustc_mir_build/src/build/misc.rs b/compiler/rustc_mir_build/src/build/misc.rs
index 8b1ab482ee8..86f466ff767 100644
--- a/compiler/rustc_mir_build/src/build/misc.rs
+++ b/compiler/rustc_mir_build/src/build/misc.rs
@@ -14,7 +14,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ///
     /// N.B., **No cleanup is scheduled for this temporary.** You should
     /// call `schedule_drop` once the temporary is initialized.
-    crate fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> {
+    pub(crate) fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> {
         // Mark this local as internal to avoid temporaries with types not present in the
         // user's code resulting in ICEs from the generator transform.
         let temp = self.local_decls.push(LocalDecl::new(ty, span).internal());
@@ -25,20 +25,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
     /// Convenience function for creating a literal operand, one
     /// without any user type annotation.
-    crate fn literal_operand(&mut self, span: Span, literal: ConstantKind<'tcx>) -> Operand<'tcx> {
+    pub(crate) fn literal_operand(
+        &mut self,
+        span: Span,
+        literal: ConstantKind<'tcx>,
+    ) -> Operand<'tcx> {
         let constant = Box::new(Constant { span, user_ty: None, literal });
         Operand::Constant(constant)
     }
 
     // Returns a zero literal operand for the appropriate type, works for
     // bool, char and integers.
-    crate fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
+    pub(crate) fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
         let literal = ConstantKind::from_bits(self.tcx, 0, ty::ParamEnv::empty().and(ty));
 
         self.literal_operand(span, literal)
     }
 
-    crate fn push_usize(
+    pub(crate) fn push_usize(
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
@@ -59,7 +63,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         temp
     }
 
-    crate fn consume_by_copy_or_move(&self, place: Place<'tcx>) -> Operand<'tcx> {
+    pub(crate) fn consume_by_copy_or_move(&self, place: Place<'tcx>) -> Operand<'tcx> {
         let tcx = self.tcx;
         let ty = place.ty(&self.local_decls, tcx).ty;
         if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, DUMMY_SP) {
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 1cbe8c5a68a..4ae74433df6 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -26,7 +26,7 @@ use rustc_target::spec::abi::Abi;
 
 use super::lints;
 
-crate fn mir_built<'tcx>(
+pub(crate) fn mir_built<'tcx>(
     tcx: TyCtxt<'tcx>,
     def: ty::WithOptConstParam<LocalDefId>,
 ) -> &'tcx rustc_data_structures::steal::Steal<Body<'tcx>> {
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 465bd62406e..2d14a78accf 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -177,7 +177,7 @@ struct IfThenScope {
 
 /// The target of an expression that breaks out of a scope
 #[derive(Clone, Copy, Debug)]
-crate enum BreakableTarget {
+pub(crate) enum BreakableTarget {
     Continue(region::Scope),
     Break(region::Scope),
     Return,
@@ -445,7 +445,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     // ==========================
     //  Start a breakable scope, which tracks where `continue`, `break` and
     //  `return` should branch to.
-    crate fn in_breakable_scope<F>(
+    pub(crate) fn in_breakable_scope<F>(
         &mut self,
         loop_block: Option<BasicBlock>,
         break_destination: Place<'tcx>,
@@ -507,7 +507,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// - We don't need to keep a stack of scopes in the `Builder` because the
     ///   'else' paths will only leave the innermost scope.
     /// - This is also used for match guards.
-    crate fn in_if_then_scope<F>(
+    pub(crate) fn in_if_then_scope<F>(
         &mut self,
         region_scope: region::Scope,
         f: F,
@@ -530,7 +530,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         (then_block, else_block)
     }
 
-    crate fn in_opt_scope<F, R>(
+    pub(crate) fn in_opt_scope<F, R>(
         &mut self,
         opt_scope: Option<(region::Scope, SourceInfo)>,
         f: F,
@@ -553,7 +553,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
     /// Convenience wrapper that pushes a scope and then executes `f`
     /// to build its contents, popping the scope afterwards.
-    crate fn in_scope<F, R>(
+    pub(crate) fn in_scope<F, R>(
         &mut self,
         region_scope: (region::Scope, SourceInfo),
         lint_level: LintLevel,
@@ -597,14 +597,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// scope and call `pop_scope` afterwards. Note that these two
     /// calls must be paired; using `in_scope` as a convenience
     /// wrapper maybe preferable.
-    crate fn push_scope(&mut self, region_scope: (region::Scope, SourceInfo)) {
+    pub(crate) fn push_scope(&mut self, region_scope: (region::Scope, SourceInfo)) {
         self.scopes.push_scope(region_scope, self.source_scope);
     }
 
     /// Pops a scope, which should have region scope `region_scope`,
     /// adding any drops onto the end of `block` that are needed.
     /// This must match 1-to-1 with `push_scope`.
-    crate fn pop_scope(
+    pub(crate) fn pop_scope(
         &mut self,
         region_scope: (region::Scope, SourceInfo),
         mut block: BasicBlock,
@@ -619,7 +619,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     /// Sets up the drops for breaking from `block` to `target`.
-    crate fn break_scope(
+    pub(crate) fn break_scope(
         &mut self,
         mut block: BasicBlock,
         value: Option<&Expr<'tcx>>,
@@ -698,7 +698,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         self.cfg.start_new_block().unit()
     }
 
-    crate fn break_for_else(
+    pub(crate) fn break_for_else(
         &mut self,
         block: BasicBlock,
         target: region::Scope,
@@ -756,7 +756,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     /// Creates a new source scope, nested in the current one.
-    crate fn new_source_scope(
+    pub(crate) fn new_source_scope(
         &mut self,
         span: Span,
         lint_level: LintLevel,
@@ -791,7 +791,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     /// Given a span and the current source scope, make a SourceInfo.
-    crate fn source_info(&self, span: Span) -> SourceInfo {
+    pub(crate) fn source_info(&self, span: Span) -> SourceInfo {
         SourceInfo { span, scope: self.source_scope }
     }
 
@@ -816,13 +816,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// We would allocate the box but then free it on the unwinding
     /// path; we would also emit a free on the 'success' path from
     /// panic, but that will turn out to be removed as dead-code.
-    crate fn local_scope(&self) -> region::Scope {
+    pub(crate) fn local_scope(&self) -> region::Scope {
         self.scopes.topmost()
     }
 
     // Scheduling drops
     // ================
-    crate fn schedule_drop_storage_and_value(
+    pub(crate) fn schedule_drop_storage_and_value(
         &mut self,
         span: Span,
         region_scope: region::Scope,
@@ -836,7 +836,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ///
     /// When called with `DropKind::Storage`, `place` shouldn't be the return
     /// place, or a function parameter.
-    crate fn schedule_drop(
+    pub(crate) fn schedule_drop(
         &mut self,
         span: Span,
         region_scope: region::Scope,
@@ -969,7 +969,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// spurious borrow-check errors -- the problem, ironically, is
     /// not the `DROP(_X)` itself, but the (spurious) unwind pathways
     /// that it creates. See #64391 for an example.
-    crate fn record_operands_moved(&mut self, operands: &[Operand<'tcx>]) {
+    pub(crate) fn record_operands_moved(&mut self, operands: &[Operand<'tcx>]) {
         let local_scope = self.local_scope();
         let scope = self.scopes.scopes.last_mut().unwrap();
 
@@ -1026,7 +1026,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ///
     /// This path terminates in Resume. The path isn't created until after all
     /// of the non-unwind paths in this item have been lowered.
-    crate fn diverge_from(&mut self, start: BasicBlock) {
+    pub(crate) fn diverge_from(&mut self, start: BasicBlock) {
         debug_assert!(
             matches!(
                 self.cfg.block_data(start).terminator().kind,
@@ -1048,7 +1048,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// [TerminatorKind::Yield].
     ///
     /// This path terminates in GeneratorDrop.
-    crate fn generator_drop_cleanup(&mut self, yield_block: BasicBlock) {
+    pub(crate) fn generator_drop_cleanup(&mut self, yield_block: BasicBlock) {
         debug_assert!(
             matches!(
                 self.cfg.block_data(yield_block).terminator().kind,
@@ -1078,7 +1078,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     /// Utility function for *non*-scope code to build their own drops
-    crate fn build_drop_and_replace(
+    pub(crate) fn build_drop_and_replace(
         &mut self,
         block: BasicBlock,
         span: Span,
@@ -1101,7 +1101,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Creates an `Assert` terminator and return the success block.
     /// If the boolean condition operand is not the expected value,
     /// a runtime panic will be caused with the given message.
-    crate fn assert(
+    pub(crate) fn assert(
         &mut self,
         block: BasicBlock,
         cond: Operand<'tcx>,
@@ -1126,7 +1126,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ///
     /// This is only needed for `match` arm scopes, because they have one
     /// entrance per pattern, but only one exit.
-    crate fn clear_top_scope(&mut self, region_scope: region::Scope) {
+    pub(crate) fn clear_top_scope(&mut self, region_scope: region::Scope) {
         let top_scope = self.scopes.scopes.last_mut().unwrap();
 
         assert_eq!(top_scope.region_scope, region_scope);
@@ -1262,7 +1262,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
     }
 
     /// Build the unwind and generator drop trees.
-    crate fn build_drop_trees(&mut self) {
+    pub(crate) fn build_drop_trees(&mut self) {
         if self.generator_kind.is_some() {
             self.build_generator_drop_trees();
         } else {
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 6c14f207a7d..94b2722dca8 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -678,7 +678,7 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
     visitor.visit_expr(&thir[expr]);
 }
 
-crate fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
+pub(crate) fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
     if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
         tcx.thir_check_unsafety_for_const_arg(def)
     } else {
@@ -686,7 +686,7 @@ crate fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
     }
 }
 
-crate fn thir_check_unsafety_for_const_arg<'tcx>(
+pub(crate) fn thir_check_unsafety_for_const_arg<'tcx>(
     tcx: TyCtxt<'tcx>,
     (did, param_did): (LocalDefId, DefId),
 ) {
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 4f0402bfa8b..11cd2a9aa4d 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -4,7 +4,6 @@
 #![allow(rustc::potential_query_instability)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
-#![feature(crate_visibility_modifier)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(let_else)]
diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs
index bccff379873..5470cc1262e 100644
--- a/compiler/rustc_mir_build/src/lints.rs
+++ b/compiler/rustc_mir_build/src/lints.rs
@@ -9,7 +9,7 @@ use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION;
 use rustc_span::Span;
 use std::ops::ControlFlow;
 
-crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
+pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
     let def_id = body.source.def_id().expect_local();
 
     if let Some(fn_kind) = tcx.hir().get_by_def_id(def_id).fn_kind() {
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index 30d7fdb7fec..d82e6688633 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::Symbol;
 use rustc_target::abi::Size;
 
 // FIXME Once valtrees are available, get rid of this function and the query
-crate fn lit_to_const<'tcx>(
+pub(crate) fn lit_to_const<'tcx>(
     tcx: TyCtxt<'tcx>,
     lit_input: LitToConstInput<'tcx>,
 ) -> Result<ty::Const<'tcx>, LitToConstError> {
diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs
index 2d9b5c1d98a..72ce8c24cdd 100644
--- a/compiler/rustc_mir_build/src/thir/cx/block.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/block.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty;
 use rustc_index::vec::Idx;
 
 impl<'tcx> Cx<'tcx> {
-    crate fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block {
+    pub(crate) fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block {
         // We have to eagerly lower the "spine" of the statements
         // in order to get the lexical scoping correctly.
         let stmts = self.mirror_stmts(block.hir_id.local_id, block.stmts);
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 8f5ad6b1a07..b9879b9159f 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -22,12 +22,12 @@ use rustc_span::Span;
 use rustc_target::abi::VariantIdx;
 
 impl<'tcx> Cx<'tcx> {
-    crate fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId {
+    pub(crate) fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId {
         // `mirror_expr` is recursing very deep. Make sure the stack doesn't overflow.
         ensure_sufficient_stack(|| self.mirror_expr_inner(expr))
     }
 
-    crate fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Box<[ExprId]> {
+    pub(crate) fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Box<[ExprId]> {
         exprs.iter().map(|expr| self.mirror_expr_inner(expr)).collect()
     }
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index aafc368d3fd..81eb7efad37 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -19,7 +19,7 @@ use rustc_middle::thir::*;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
 
-crate fn thir_body<'tcx>(
+pub(crate) fn thir_body<'tcx>(
     tcx: TyCtxt<'tcx>,
     owner_def: ty::WithOptConstParam<LocalDefId>,
 ) -> Result<(&'tcx Steal<Thir<'tcx>>, ExprId), ErrorGuaranteed> {
@@ -33,7 +33,7 @@ crate fn thir_body<'tcx>(
     Ok((tcx.alloc_steal_thir(cx.thir), expr))
 }
 
-crate fn thir_tree<'tcx>(
+pub(crate) fn thir_tree<'tcx>(
     tcx: TyCtxt<'tcx>,
     owner_def: ty::WithOptConstParam<LocalDefId>,
 ) -> String {
@@ -47,10 +47,10 @@ struct Cx<'tcx> {
     tcx: TyCtxt<'tcx>,
     thir: Thir<'tcx>,
 
-    crate param_env: ty::ParamEnv<'tcx>,
+    pub(crate) param_env: ty::ParamEnv<'tcx>,
 
-    crate region_scope_tree: &'tcx region::ScopeTree,
-    crate typeck_results: &'tcx ty::TypeckResults<'tcx>,
+    pub(crate) region_scope_tree: &'tcx region::ScopeTree,
+    pub(crate) typeck_results: &'tcx ty::TypeckResults<'tcx>,
 
     /// When applying adjustments to the expression
     /// with the given `HirId`, use the given `Span`,
@@ -79,7 +79,7 @@ impl<'tcx> Cx<'tcx> {
     }
 
     #[instrument(skip(self), level = "debug")]
-    crate fn const_eval_literal(
+    pub(crate) fn const_eval_literal(
         &mut self,
         lit: &'tcx ast::LitKind,
         ty: Ty<'tcx>,
@@ -96,7 +96,7 @@ impl<'tcx> Cx<'tcx> {
         }
     }
 
-    crate fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> {
+    pub(crate) fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> {
         let p = match self.tcx.hir().get(p.hir_id) {
             Node::Pat(p) | Node::Binding(p) => p,
             node => bug!("pattern became {:?}", node),
diff --git a/compiler/rustc_mir_build/src/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs
index ddbe1b0b69c..e0e6ac26654 100644
--- a/compiler/rustc_mir_build/src/thir/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/mod.rs
@@ -4,10 +4,10 @@
 //! unit-tested and separated from the Rust source and compiler data
 //! structures.
 
-crate mod constant;
+pub(crate) mod constant;
 
-crate mod cx;
+pub(crate) mod cx;
 
-crate mod pattern;
+pub(crate) mod pattern;
 
 mod util;
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index f86899021e3..dc204eb47ae 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -23,7 +23,7 @@ use rustc_session::Session;
 use rustc_span::source_map::Spanned;
 use rustc_span::{BytePos, DesugaringKind, ExpnKind, Span};
 
-crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
+pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
     let body_id = match def_id.as_local() {
         None => return,
         Some(id) => tcx.hir().body_owned_by(tcx.hir().local_def_id_to_hir_id(id)),
@@ -880,7 +880,7 @@ fn non_exhaustive_match<'p, 'tcx>(
     err.emit();
 }
 
-crate fn joined_uncovered_patterns<'p, 'tcx>(
+pub(crate) fn joined_uncovered_patterns<'p, 'tcx>(
     cx: &MatchCheckCtxt<'p, 'tcx>,
     witnesses: &[DeconstructedPat<'p, 'tcx>],
 ) -> String {
@@ -901,7 +901,7 @@ crate fn joined_uncovered_patterns<'p, 'tcx>(
     }
 }
 
-crate fn pattern_not_covered_label(
+pub(crate) fn pattern_not_covered_label(
     witnesses: &[DeconstructedPat<'_, '_>],
     joined_patterns: &str,
 ) -> String {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 55d84782c48..1f152549a63 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -27,22 +27,22 @@ use rustc_span::{Span, Symbol};
 use std::cmp::Ordering;
 
 #[derive(Clone, Debug)]
-crate enum PatternError {
+pub(crate) enum PatternError {
     AssocConstInPattern(Span),
     ConstParamInPattern(Span),
     StaticInPattern(Span),
     NonConstPath(Span),
 }
 
-crate struct PatCtxt<'a, 'tcx> {
-    crate tcx: TyCtxt<'tcx>,
-    crate param_env: ty::ParamEnv<'tcx>,
-    crate typeck_results: &'a ty::TypeckResults<'tcx>,
-    crate errors: Vec<PatternError>,
+pub(crate) struct PatCtxt<'a, 'tcx> {
+    pub(crate) tcx: TyCtxt<'tcx>,
+    pub(crate) param_env: ty::ParamEnv<'tcx>,
+    pub(crate) typeck_results: &'a ty::TypeckResults<'tcx>,
+    pub(crate) errors: Vec<PatternError>,
     include_lint_checks: bool,
 }
 
-crate fn pat_from_hir<'a, 'tcx>(
+pub(crate) fn pat_from_hir<'a, 'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     typeck_results: &'a ty::TypeckResults<'tcx>,
@@ -59,7 +59,7 @@ crate fn pat_from_hir<'a, 'tcx>(
 }
 
 impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
-    crate fn new(
+    pub(crate) fn new(
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         typeck_results: &'a ty::TypeckResults<'tcx>,
@@ -67,12 +67,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         PatCtxt { tcx, param_env, typeck_results, errors: vec![], include_lint_checks: false }
     }
 
-    crate fn include_lint_checks(&mut self) -> &mut Self {
+    pub(crate) fn include_lint_checks(&mut self) -> &mut Self {
         self.include_lint_checks = true;
         self
     }
 
-    crate fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> {
+    pub(crate) fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> {
         // When implicit dereferences have been inserted in this pattern, the unadjusted lowered
         // pattern has the type that results *after* dereferencing. For example, in this code:
         //
@@ -608,7 +608,7 @@ impl<'tcx> UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> {
     }
 }
 
-crate trait PatternFoldable<'tcx>: Sized {
+pub(crate) trait PatternFoldable<'tcx>: Sized {
     fn fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
         self.super_fold_with(folder)
     }
@@ -616,7 +616,7 @@ crate trait PatternFoldable<'tcx>: Sized {
     fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self;
 }
 
-crate trait PatternFolder<'tcx>: Sized {
+pub(crate) trait PatternFolder<'tcx>: Sized {
     fn fold_pattern(&mut self, pattern: &Pat<'tcx>) -> Pat<'tcx> {
         pattern.super_fold_with(self)
     }
@@ -746,7 +746,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
 }
 
 #[instrument(skip(tcx), level = "debug")]
-crate fn compare_const_vals<'tcx>(
+pub(crate) fn compare_const_vals<'tcx>(
     tcx: TyCtxt<'tcx>,
     a: mir::ConstantKind<'tcx>,
     b: mir::ConstantKind<'tcx>,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 4e96cfd9bbd..9e7a267ecbd 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -309,16 +309,16 @@ use smallvec::{smallvec, SmallVec};
 use std::fmt;
 use std::iter::once;
 
-crate struct MatchCheckCtxt<'p, 'tcx> {
-    crate tcx: TyCtxt<'tcx>,
+pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
+    pub(crate) tcx: TyCtxt<'tcx>,
     /// The module in which the match occurs. This is necessary for
     /// checking inhabited-ness of types because whether a type is (visibly)
     /// inhabited can depend on whether it was defined in the current module or
     /// not. E.g., `struct Foo { _private: ! }` cannot be seen to be empty
     /// outside its module and should not be matchable with an empty match statement.
-    crate module: DefId,
-    crate param_env: ty::ParamEnv<'tcx>,
-    crate pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
+    pub(crate) module: DefId,
+    pub(crate) param_env: ty::ParamEnv<'tcx>,
+    pub(crate) pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
 }
 
 impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
@@ -691,7 +691,7 @@ enum ArmType {
 ///
 /// The final `Pair(Some(_), true)` is then the resulting witness.
 #[derive(Debug)]
-crate struct Witness<'p, 'tcx>(Vec<DeconstructedPat<'p, 'tcx>>);
+pub(crate) struct Witness<'p, 'tcx>(Vec<DeconstructedPat<'p, 'tcx>>);
 
 impl<'p, 'tcx> Witness<'p, 'tcx> {
     /// Asserts that the witness contains a single pattern, and returns it.
@@ -908,16 +908,16 @@ fn is_useful<'p, 'tcx>(
 
 /// The arm of a match expression.
 #[derive(Clone, Copy, Debug)]
-crate struct MatchArm<'p, 'tcx> {
+pub(crate) struct MatchArm<'p, 'tcx> {
     /// The pattern must have been lowered through `check_match::MatchVisitor::lower_pattern`.
-    crate pat: &'p DeconstructedPat<'p, 'tcx>,
-    crate hir_id: HirId,
-    crate has_guard: bool,
+    pub(crate) pat: &'p DeconstructedPat<'p, 'tcx>,
+    pub(crate) hir_id: HirId,
+    pub(crate) has_guard: bool,
 }
 
 /// Indicates whether or not a given arm is reachable.
 #[derive(Clone, Debug)]
-crate enum Reachability {
+pub(crate) enum Reachability {
     /// The arm is reachable. This additionally carries a set of or-pattern branches that have been
     /// found to be unreachable despite the overall arm being reachable. Used only in the presence
     /// of or-patterns, otherwise it stays empty.
@@ -927,12 +927,12 @@ crate enum Reachability {
 }
 
 /// The output of checking a match for exhaustiveness and arm reachability.
-crate struct UsefulnessReport<'p, 'tcx> {
+pub(crate) struct UsefulnessReport<'p, 'tcx> {
     /// For each arm of the input, whether that arm is reachable after the arms above it.
-    crate arm_usefulness: Vec<(MatchArm<'p, 'tcx>, Reachability)>,
+    pub(crate) arm_usefulness: Vec<(MatchArm<'p, 'tcx>, Reachability)>,
     /// If the match is exhaustive, this is empty. If not, this contains witnesses for the lack of
     /// exhaustiveness.
-    crate non_exhaustiveness_witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
+    pub(crate) non_exhaustiveness_witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
 }
 
 /// The entrypoint for the usefulness algorithm. Computes whether a match is exhaustive and which
@@ -941,7 +941,7 @@ crate struct UsefulnessReport<'p, 'tcx> {
 /// Note: the input patterns must have been lowered through
 /// `check_match::MatchVisitor::lower_pattern`.
 #[instrument(skip(cx, arms), level = "debug")]
-crate fn compute_match_usefulness<'p, 'tcx>(
+pub(crate) fn compute_match_usefulness<'p, 'tcx>(
     cx: &MatchCheckCtxt<'p, 'tcx>,
     arms: &[MatchArm<'p, 'tcx>],
     scrut_hir_id: HirId,
diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs
index 82f97f22cce..c58ed1ac0b8 100644
--- a/compiler/rustc_mir_build/src/thir/util.rs
+++ b/compiler/rustc_mir_build/src/thir/util.rs
@@ -1,7 +1,7 @@
 use rustc_hir as hir;
 use rustc_middle::ty::{self, CanonicalUserType, TyCtxt, UserType};
 
-crate trait UserAnnotatedTyHelpers<'tcx> {
+pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx>;
 
     fn typeck_results(&self) -> &ty::TypeckResults<'tcx>;
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 85b7fb5eb25..017d9e74dc4 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -17,7 +17,7 @@ use crate::MirPass;
 use std::iter;
 use std::ops::{Range, RangeFrom};
 
-crate mod cycle;
+pub(crate) mod cycle;
 
 const INSTR_COST: usize = 5;
 const CALL_PENALTY: usize = 25;
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index bee6aeebcf8..fd7de2bd1dc 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -9,7 +9,7 @@ use rustc_session::Limit;
 // FIXME: check whether it is cheaper to precompute the entire call graph instead of invoking
 // this query ridiculously often.
 #[instrument(level = "debug", skip(tcx, root, target))]
-crate fn mir_callgraph_reachable<'tcx>(
+pub(crate) fn mir_callgraph_reachable<'tcx>(
     tcx: TyCtxt<'tcx>,
     (root, target): (ty::Instance<'tcx>, LocalDefId),
 ) -> bool {
@@ -136,7 +136,7 @@ crate fn mir_callgraph_reachable<'tcx>(
     )
 }
 
-crate fn mir_inliner_callees<'tcx>(
+pub(crate) fn mir_inliner_callees<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: ty::InstanceDef<'tcx>,
 ) -> &'tcx [(DefId, SubstsRef<'tcx>)] {
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index d08382700a8..1e8c373a411 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -1,7 +1,6 @@
 #![allow(rustc::potential_query_instability)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(crate_visibility_modifier)]
 #![feature(let_chains)]
 #![feature(let_else)]
 #![feature(map_try_insert)]
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index f0333d6c6da..ef4560b5ec4 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -1,5 +1,4 @@
 #![feature(array_windows)]
-#![feature(crate_visibility_modifier)]
 #![feature(control_flow_enum)]
 #![feature(let_else)]
 #![recursion_limit = "256"]
diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs
index 04baa01832b..d3aaad46015 100644
--- a/compiler/rustc_monomorphize/src/util.rs
+++ b/compiler/rustc_monomorphize/src/util.rs
@@ -7,7 +7,7 @@ use std::io::prelude::*;
 ///
 /// During the same compile all closures dump the information in the same file
 /// "closure_profile_XXXXX.csv", which is created in the directory where the compiler is invoked.
-crate fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: Instance<'tcx>) {
+pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: Instance<'tcx>) {
     let Ok(mut file) = OpenOptions::new()
         .create(true)
         .append(true)
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index ee54dd44f71..e9701ec2d7f 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -31,7 +31,7 @@ pub struct UnmatchedBrace {
     pub candidate_span: Option<Span>,
 }
 
-crate fn parse_token_trees<'a>(
+pub(crate) fn parse_token_trees<'a>(
     sess: &'a ParseSess,
     src: &'a str,
     start_pos: BytePos,
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 423cddd88ee..c46a8b58c29 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -2,7 +2,6 @@
 
 #![feature(array_windows)]
 #![feature(box_patterns)]
-#![feature(crate_visibility_modifier)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(let_else)]
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 2f90a7c54ab..3ae8bb07cd0 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -284,7 +284,7 @@ impl<'a> Parser<'a> {
     /// terminated by a semicolon.
     ///
     /// Matches `inner_attrs*`.
-    crate fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
+    pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = vec![];
         loop {
             let start_pos: u32 = self.token_cursor.num_next_calls.try_into().unwrap();
@@ -322,7 +322,7 @@ impl<'a> Parser<'a> {
         Ok(attrs)
     }
 
-    crate fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> {
+    pub(crate) fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> {
         let lit = self.parse_lit()?;
         debug!("checking if {:?} is unusuffixed", lit);
 
@@ -358,7 +358,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Matches `COMMASEP(meta_item_inner)`.
-    crate fn parse_meta_seq_top(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> {
+    pub(crate) fn parse_meta_seq_top(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> {
         // Presumably, the majority of the time there will only be one attr.
         let mut nmis = Vec::with_capacity(1);
         while self.token.kind != token::Eof {
@@ -401,7 +401,7 @@ impl<'a> Parser<'a> {
         Ok(ast::MetaItem { path, kind, span })
     }
 
-    crate fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
+    pub(crate) fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
         Ok(if self.eat(&token::Eq) {
             ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?)
         } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 3b2ce0de509..69e12063cc1 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -132,7 +132,7 @@ impl RecoverQPath for Expr {
 }
 
 /// Control whether the closing delimiter should be consumed when calling `Parser::consume_block`.
-crate enum ConsumeClosingDelim {
+pub(crate) enum ConsumeClosingDelim {
     Yes,
     No,
 }
@@ -2459,7 +2459,7 @@ impl<'a> Parser<'a> {
 
     /// Some special error handling for the "top-level" patterns in a match arm,
     /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
-    crate fn maybe_recover_colon_colon_in_pat_typo(
+    pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
         &mut self,
         mut first_pat: P<Pat>,
         ra: RecoverColon,
@@ -2575,7 +2575,7 @@ impl<'a> Parser<'a> {
         first_pat
     }
 
-    crate fn maybe_recover_unexpected_block_label(&mut self) -> bool {
+    pub(crate) fn maybe_recover_unexpected_block_label(&mut self) -> bool {
         let Some(label) = self.eat_label().filter(|_| {
             self.eat(&token::Colon) && self.token.kind == token::OpenDelim(Delimiter::Brace)
         }) else {
@@ -2596,7 +2596,7 @@ impl<'a> Parser<'a> {
 
     /// Some special error handling for the "top-level" patterns in a match arm,
     /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
-    crate fn maybe_recover_unexpected_comma(
+    pub(crate) fn maybe_recover_unexpected_comma(
         &mut self,
         lo: Span,
         rc: RecoverComma,
@@ -2643,7 +2643,7 @@ impl<'a> Parser<'a> {
         Err(err)
     }
 
-    crate fn maybe_recover_bounds_doubled_colon(&mut self, ty: &Ty) -> PResult<'a, ()> {
+    pub(crate) fn maybe_recover_bounds_doubled_colon(&mut self, ty: &Ty) -> PResult<'a, ()> {
         let TyKind::Path(qself, path) = &ty.kind else { return Ok(()) };
         let qself_position = qself.as_ref().map(|qself| qself.position);
         for (i, segments) in path.segments.windows(2).enumerate() {
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 6114e7aaa7b..b5467c659a2 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2380,7 +2380,7 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::Loop(body, opt_label), attrs))
     }
 
-    crate fn eat_label(&mut self) -> Option<Label> {
+    pub(crate) fn eat_label(&mut self) -> Option<Label> {
         self.token.lifetime().map(|ident| {
             self.bump();
             Label { ident }
@@ -3049,7 +3049,7 @@ impl<'a> Parser<'a> {
         await_expr
     }
 
-    crate fn mk_expr(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P<Expr> {
+    pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P<Expr> {
         P(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None })
     }
 
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 8081bac7cfd..1930dec8c3b 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -51,7 +51,7 @@ impl<'a> Parser<'a> {
         })
     }
 
-    crate fn parse_const_param(
+    pub(crate) fn parse_const_param(
         &mut self,
         preceding_attrs: Vec<Attribute>,
     ) -> PResult<'a, GenericParam> {
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index f32ee9fc978..5bd07c31c0e 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1415,7 +1415,7 @@ impl<'a> Parser<'a> {
     }
 }
 
-crate fn make_unclosed_delims_error(
+pub(crate) fn make_unclosed_delims_error(
     unmatched: UnmatchedBrace,
     sess: &ParseSess,
 ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 56ebac0953b..27a6a487474 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -36,7 +36,7 @@ impl<'a> Parser<'a> {
 
     /// If `force_capture` is true, forces collection of tokens regardless of whether
     /// or not we have attributes
-    crate fn parse_stmt_without_recovery(
+    pub(crate) fn parse_stmt_without_recovery(
         &mut self,
         capture_semi: bool,
         force_collect: ForceCollect,
@@ -500,7 +500,7 @@ impl<'a> Parser<'a> {
 
     /// Parses the rest of a block expression or function body.
     /// Precondition: already parsed the '{'.
-    crate fn parse_block_tail(
+    pub(crate) fn parse_block_tail(
         &mut self,
         lo: Span,
         s: BlockCheckMode,
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index d9d08488d28..2c79ac49b36 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -6,7 +6,6 @@
 
 #![allow(rustc::potential_query_instability)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![feature(crate_visibility_modifier)]
 #![feature(iter_intersperse)]
 #![feature(let_else)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 5d7768c8240..83f728d4076 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -17,7 +17,7 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut CheckNakedFunctions { tcx });
 }
 
-crate fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_naked_functions, ..*providers };
 }
 
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 2fa030f9b3f..bfc51dedbc7 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -1,7 +1,6 @@
 //! Support for serializing the dep-graph and reloading it.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![feature(crate_visibility_modifier)]
 #![feature(nll)]
 #![feature(min_specialization)]
 #![feature(once_cell)]
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index ae4ad428159..634236c0dac 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -129,7 +129,7 @@ impl<'tcx> QueryCtxt<'tcx> {
         QueryCtxt { tcx, queries }
     }
 
-    crate fn on_disk_cache(self) -> Option<&'tcx on_disk_cache::OnDiskCache<'tcx>> {
+    pub(crate) fn on_disk_cache(self) -> Option<&'tcx on_disk_cache::OnDiskCache<'tcx>> {
         self.queries.on_disk_cache.as_ref()
     }
 
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index dffec44ddbc..3879779635b 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -81,7 +81,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId, IsMacroE
 impl<'a> Resolver<'a> {
     /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
     /// otherwise, reports an error.
-    crate fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
+    pub(crate) fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
     where
         T: ToNameBinding<'a>,
     {
@@ -127,7 +127,7 @@ impl<'a> Resolver<'a> {
     /// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum,
     /// or trait), then this function returns that module's resolver representation, otherwise it
     /// returns `None`.
-    crate fn get_module(&mut self, def_id: DefId) -> Option<Module<'a>> {
+    pub(crate) fn get_module(&mut self, def_id: DefId) -> Option<Module<'a>> {
         if let module @ Some(..) = self.module_map.get(&def_id) {
             return module.copied();
         }
@@ -162,7 +162,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn expn_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
+    pub(crate) fn expn_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
         match expn_id.expn_data().macro_def_id {
             Some(def_id) => self.macro_def_scope(def_id),
             None => expn_id
@@ -172,7 +172,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn macro_def_scope(&mut self, def_id: DefId) -> Module<'a> {
+    pub(crate) fn macro_def_scope(&mut self, def_id: DefId) -> Module<'a> {
         if let Some(id) = def_id.as_local() {
             self.local_macro_def_scopes[&id]
         } else {
@@ -180,7 +180,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
+    pub(crate) fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
         match res {
             Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
             Res::NonMacroAttr(_) => Some(self.non_macro_attr.clone()),
@@ -188,7 +188,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Lrc<SyntaxExtension> {
+    pub(crate) fn get_macro_by_def_id(&mut self, def_id: DefId) -> Lrc<SyntaxExtension> {
         if let Some(ext) = self.macro_map.get(&def_id) {
             return ext.clone();
         }
@@ -202,7 +202,7 @@ impl<'a> Resolver<'a> {
         ext
     }
 
-    crate fn build_reduced_graph(
+    pub(crate) fn build_reduced_graph(
         &mut self,
         fragment: &AstFragment,
         parent_scope: ParentScope<'a>,
@@ -213,7 +213,7 @@ impl<'a> Resolver<'a> {
         visitor.parent_scope.macro_rules
     }
 
-    crate fn build_reduced_graph_external(&mut self, module: Module<'a>) {
+    pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) {
         for child in self.cstore().module_children_untracked(module.def_id(), self.session) {
             let parent_scope = ParentScope::module(module, self);
             BuildReducedGraphVisitor { r: self, parent_scope }
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index ec3b14ace4d..5dc720e0abc 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -224,7 +224,7 @@ fn calc_unused_spans(
 }
 
 impl Resolver<'_> {
-    crate fn check_unused(&mut self, krate: &ast::Crate) {
+    pub(crate) fn check_unused(&mut self, krate: &ast::Crate) {
         for import in self.potentially_unused_imports.iter() {
             match import.kind {
                 _ if import.used.get()
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index f0861103098..f9aff7fd686 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -11,7 +11,7 @@ use rustc_span::symbol::sym;
 use rustc_span::Span;
 use tracing::debug;
 
-crate fn collect_definitions(
+pub(crate) fn collect_definitions(
     resolver: &mut Resolver<'_>,
     fragment: &AstFragment,
     expansion: LocalExpnId,
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 268e2c9b69b..c199cff2038 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -41,36 +41,36 @@ mod tests;
 type Res = def::Res<ast::NodeId>;
 
 /// A vector of spans and replacements, a message and applicability.
-crate type Suggestion = (Vec<(Span, String)>, String, Applicability);
+pub(crate) type Suggestion = (Vec<(Span, String)>, String, Applicability);
 
 /// Potential candidate for an undeclared or out-of-scope label - contains the ident of a
 /// similarly named label and whether or not it is reachable.
-crate type LabelSuggestion = (Ident, bool);
+pub(crate) type LabelSuggestion = (Ident, bool);
 
-crate enum SuggestionTarget {
+pub(crate) enum SuggestionTarget {
     /// The target has a similar name as the name used by the programmer (probably a typo)
     SimilarlyNamed,
     /// The target is the only valid item that can be used in the corresponding context
     SingleItem,
 }
 
-crate struct TypoSuggestion {
+pub(crate) struct TypoSuggestion {
     pub candidate: Symbol,
     pub res: Res,
     pub target: SuggestionTarget,
 }
 
 impl TypoSuggestion {
-    crate fn typo_from_res(candidate: Symbol, res: Res) -> TypoSuggestion {
+    pub(crate) fn typo_from_res(candidate: Symbol, res: Res) -> TypoSuggestion {
         Self { candidate, res, target: SuggestionTarget::SimilarlyNamed }
     }
-    crate fn single_item_from_res(candidate: Symbol, res: Res) -> TypoSuggestion {
+    pub(crate) fn single_item_from_res(candidate: Symbol, res: Res) -> TypoSuggestion {
         Self { candidate, res, target: SuggestionTarget::SingleItem }
     }
 }
 
 /// A free importable items suggested in case of resolution failure.
-crate struct ImportSuggestion {
+pub(crate) struct ImportSuggestion {
     pub did: Option<DefId>,
     pub descr: &'static str,
     pub path: Path,
@@ -92,7 +92,7 @@ fn reduce_impl_span_to_impl_keyword(sm: &SourceMap, impl_span: Span) -> Span {
 }
 
 impl<'a> Resolver<'a> {
-    crate fn report_errors(&mut self, krate: &Crate) {
+    pub(crate) fn report_errors(&mut self, krate: &Crate) {
         self.report_with_use_injections(krate);
 
         for &(span_use, span_def) in &self.macro_expanded_macro_export_errors {
@@ -147,7 +147,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn report_conflict<'b>(
+    pub(crate) fn report_conflict<'b>(
         &mut self,
         parent: Module<'_>,
         ident: Ident,
@@ -419,7 +419,7 @@ impl<'a> Resolver<'a> {
         err.span_suggestion(span, message, String::new(), Applicability::MachineApplicable);
     }
 
-    crate fn lint_if_path_starts_with_module(
+    pub(crate) fn lint_if_path_starts_with_module(
         &mut self,
         finalize: Option<Finalize>,
         path: &[Segment],
@@ -475,7 +475,7 @@ impl<'a> Resolver<'a> {
         );
     }
 
-    crate fn add_module_candidates(
+    pub(crate) fn add_module_candidates(
         &mut self,
         module: Module<'a>,
         names: &mut Vec<TypoSuggestion>,
@@ -495,11 +495,11 @@ impl<'a> Resolver<'a> {
     ///
     /// This takes the error provided, combines it with the span and any additional spans inside the
     /// error and emits it.
-    crate fn report_error(&mut self, span: Span, resolution_error: ResolutionError<'a>) {
+    pub(crate) fn report_error(&mut self, span: Span, resolution_error: ResolutionError<'a>) {
         self.into_struct_error(span, resolution_error).emit();
     }
 
-    crate fn into_struct_error(
+    pub(crate) fn into_struct_error(
         &mut self,
         span: Span,
         resolution_error: ResolutionError<'a>,
@@ -1052,7 +1052,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn report_vis_error(
+    pub(crate) fn report_vis_error(
         &mut self,
         vis_resolution_error: VisResolutionError<'_>,
     ) -> ErrorGuaranteed {
@@ -1413,7 +1413,7 @@ impl<'a> Resolver<'a> {
     ///
     /// N.B., the method does not look into imports, but this is not a problem,
     /// since we report the definitions (thus, the de-aliased imports).
-    crate fn lookup_import_candidates<FilterFn>(
+    pub(crate) fn lookup_import_candidates<FilterFn>(
         &mut self,
         lookup_ident: Ident,
         namespace: Namespace,
@@ -1460,7 +1460,7 @@ impl<'a> Resolver<'a> {
         suggestions
     }
 
-    crate fn unresolved_macro_suggestions(
+    pub(crate) fn unresolved_macro_suggestions(
         &mut self,
         err: &mut Diagnostic,
         macro_kind: MacroKind,
@@ -1551,7 +1551,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn add_typo_suggestion(
+    pub(crate) fn add_typo_suggestion(
         &self,
         err: &mut Diagnostic,
         suggestion: Option<TypoSuggestion>,
@@ -1780,7 +1780,7 @@ impl<'a> Resolver<'a> {
         err.emit();
     }
 
-    crate fn find_similarly_named_module_or_crate(
+    pub(crate) fn find_similarly_named_module_or_crate(
         &mut self,
         ident: Symbol,
         current_module: &Module<'a>,
@@ -1807,7 +1807,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn report_path_resolution_error(
+    pub(crate) fn report_path_resolution_error(
         &mut self,
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
@@ -2680,7 +2680,7 @@ fn is_span_suitable_for_use_injection(s: Span) -> bool {
 }
 
 /// Convert the given number into the corresponding ordinal
-crate fn ordinalize(v: usize) -> String {
+pub(crate) fn ordinalize(v: usize) -> String {
     let suffix = match ((11..=13).contains(&(v % 100)), v % 10) {
         (false, 1) => "st",
         (false, 2) => "nd",
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 7ac1bb441c6..b25393c3ed8 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -28,7 +28,7 @@ impl<'a> Resolver<'a> {
     /// A generic scope visitor.
     /// Visits scopes in order to resolve some identifier in them or perform other actions.
     /// If the callback returns `Some` result, we stop visiting scopes and return it.
-    crate fn visit_scopes<T>(
+    pub(crate) fn visit_scopes<T>(
         &mut self,
         scope_set: ScopeSet<'a>,
         parent_scope: &ParentScope<'a>,
@@ -274,7 +274,7 @@ impl<'a> Resolver<'a> {
     /// Invariant: This must only be called during main resolution, not during
     /// import resolution.
     #[tracing::instrument(level = "debug", skip(self, ribs))]
-    crate fn resolve_ident_in_lexical_scope(
+    pub(crate) fn resolve_ident_in_lexical_scope(
         &mut self,
         mut ident: Ident,
         ns: Namespace,
@@ -368,7 +368,7 @@ impl<'a> Resolver<'a> {
     /// The function is used for resolving initial segments of macro paths (e.g., `foo` in
     /// `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition.
     #[tracing::instrument(level = "debug", skip(self, scope_set))]
-    crate fn early_resolve_ident_in_lexical_scope(
+    pub(crate) fn early_resolve_ident_in_lexical_scope(
         &mut self,
         orig_ident: Ident,
         scope_set: ScopeSet<'a>,
@@ -717,7 +717,7 @@ impl<'a> Resolver<'a> {
     }
 
     #[tracing::instrument(level = "debug", skip(self))]
-    crate fn maybe_resolve_ident_in_module(
+    pub(crate) fn maybe_resolve_ident_in_module(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
         ident: Ident,
@@ -729,7 +729,7 @@ impl<'a> Resolver<'a> {
     }
 
     #[tracing::instrument(level = "debug", skip(self))]
-    crate fn resolve_ident_in_module(
+    pub(crate) fn resolve_ident_in_module(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
         ident: Ident,
@@ -1303,7 +1303,7 @@ impl<'a> Resolver<'a> {
     }
 
     #[tracing::instrument(level = "debug", skip(self))]
-    crate fn maybe_resolve_path(
+    pub(crate) fn maybe_resolve_path(
         &mut self,
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
@@ -1313,7 +1313,7 @@ impl<'a> Resolver<'a> {
     }
 
     #[tracing::instrument(level = "debug", skip(self))]
-    crate fn resolve_path(
+    pub(crate) fn resolve_path(
         &mut self,
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
@@ -1324,7 +1324,7 @@ impl<'a> Resolver<'a> {
         self.resolve_path_with_ribs(path, opt_ns, parent_scope, finalize, None, ignore_binding)
     }
 
-    crate fn resolve_path_with_ribs(
+    pub(crate) fn resolve_path_with_ribs(
         &mut self,
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 3d0e2b9921d..a8c8c674d2d 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -64,7 +64,7 @@ pub enum ImportKind<'a> {
 
 /// One import.
 #[derive(Debug, Clone)]
-crate struct Import<'a> {
+pub(crate) struct Import<'a> {
     pub kind: ImportKind<'a>,
 
     /// The ID of the `extern crate`, `UseTree` etc that imported this `Import`.
@@ -125,7 +125,7 @@ impl<'a> Import<'a> {
 
 /// Records information about the resolution of a name in a namespace of a module.
 #[derive(Clone, Default, Debug)]
-crate struct NameResolution<'a> {
+pub(crate) struct NameResolution<'a> {
     /// Single imports that may define the name in the namespace.
     /// Imports are arena-allocated, so it's ok to use pointers as keys.
     pub single_imports: FxHashSet<Interned<'a, Import<'a>>>,
@@ -146,7 +146,7 @@ impl<'a> NameResolution<'a> {
         })
     }
 
-    crate fn add_single_import(&mut self, import: &'a Import<'a>) {
+    pub(crate) fn add_single_import(&mut self, import: &'a Import<'a>) {
         self.single_imports.insert(Interned::new_unchecked(import));
     }
 }
@@ -169,7 +169,7 @@ fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBindi
 impl<'a> Resolver<'a> {
     // Given a binding and an import that resolves to it,
     // return the corresponding binding defined by the import.
-    crate fn import(
+    pub(crate) fn import(
         &self,
         binding: &'a NameBinding<'a>,
         import: &'a Import<'a>,
@@ -198,7 +198,7 @@ impl<'a> Resolver<'a> {
     }
 
     // Define the name or return the existing binding if there is a collision.
-    crate fn try_define(
+    pub(crate) fn try_define(
         &mut self,
         module: Module<'a>,
         key: BindingKey,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index f05090d046f..ff87baeef3e 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -37,7 +37,7 @@ use std::mem::{replace, take};
 use tracing::debug;
 
 mod diagnostics;
-crate mod lifetimes;
+pub(crate) mod lifetimes;
 
 type Res = def::Res<NodeId>;
 
@@ -90,7 +90,7 @@ enum PatBoundCtx {
 
 /// Does this the item (from the item rib scope) allow generic parameters?
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
-crate enum HasGenericParams {
+pub(crate) enum HasGenericParams {
     Yes,
     No,
 }
@@ -102,7 +102,7 @@ impl HasGenericParams {
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
-crate enum ConstantItemKind {
+pub(crate) enum ConstantItemKind {
     Const,
     Static,
 }
@@ -110,7 +110,7 @@ crate enum ConstantItemKind {
 /// The rib kind restricts certain accesses,
 /// e.g. to a `Res::Local` of an outer item.
 #[derive(Copy, Clone, Debug)]
-crate enum RibKind<'a> {
+pub(crate) enum RibKind<'a> {
     /// No restriction needs to be applied.
     NormalRibKind,
 
@@ -159,7 +159,7 @@ crate enum RibKind<'a> {
 impl RibKind<'_> {
     /// Whether this rib kind contains generic parameters, as opposed to local
     /// variables.
-    crate fn contains_params(&self) -> bool {
+    pub(crate) fn contains_params(&self) -> bool {
         match self {
             NormalRibKind
             | ClosureOrAsyncRibKind
@@ -187,7 +187,7 @@ impl RibKind<'_> {
 /// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
 /// resolving, the name is looked up from inside out.
 #[derive(Debug)]
-crate struct Rib<'a, R = Res> {
+pub(crate) struct Rib<'a, R = Res> {
     pub bindings: IdentMap<R>,
     pub kind: RibKind<'a>,
 }
@@ -278,13 +278,13 @@ impl LifetimeRib {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-crate enum AliasPossibility {
+pub(crate) enum AliasPossibility {
     No,
     Maybe,
 }
 
 #[derive(Copy, Clone, Debug)]
-crate enum PathSource<'a> {
+pub(crate) enum PathSource<'a> {
     // Type paths `Path`.
     Type,
     // Trait paths in bounds or impls.
@@ -366,7 +366,7 @@ impl<'a> PathSource<'a> {
         matches!(self, PathSource::Expr(Some(&Expr { kind: ExprKind::Call(..), .. })))
     }
 
-    crate fn is_expected(self, res: Res) -> bool {
+    pub(crate) fn is_expected(self, res: Res) -> bool {
         match self {
             PathSource::Type => matches!(
                 res,
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 318bb8280ec..673b2e3a55a 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -59,13 +59,13 @@ impl AssocSuggestion {
     }
 }
 
-crate enum MissingLifetimeSpot<'tcx> {
+pub(crate) enum MissingLifetimeSpot<'tcx> {
     Generics(&'tcx hir::Generics<'tcx>),
     HigherRanked { span: Span, span_type: ForLifetimeSpanType },
     Static,
 }
 
-crate enum ForLifetimeSpanType {
+pub(crate) enum ForLifetimeSpanType {
     BoundEmpty,
     BoundTail,
     TypeEmpty,
@@ -73,14 +73,14 @@ crate enum ForLifetimeSpanType {
 }
 
 impl ForLifetimeSpanType {
-    crate fn descr(&self) -> &'static str {
+    pub(crate) fn descr(&self) -> &'static str {
         match self {
             Self::BoundEmpty | Self::BoundTail => "bound",
             Self::TypeEmpty | Self::TypeTail => "type",
         }
     }
 
-    crate fn suggestion(&self, sugg: &str) -> String {
+    pub(crate) fn suggestion(&self, sugg: &str) -> String {
         match self {
             Self::BoundEmpty | Self::TypeEmpty => format!("for<{}> ", sugg),
             Self::BoundTail | Self::TypeTail => format!(", {}", sugg),
@@ -1221,7 +1221,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
 
     /// Given the target `ident` and `kind`, search for the similarly named associated item
     /// in `self.current_trait_ref`.
-    crate fn find_similarly_named_assoc_item(
+    pub(crate) fn find_similarly_named_assoc_item(
         &mut self,
         ident: Symbol,
         kind: &AssocItemKind,
@@ -1729,7 +1729,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         }
     }
 
-    crate fn report_missing_type_error(
+    pub(crate) fn report_missing_type_error(
         &self,
         path: &[Segment],
     ) -> Option<(Span, &'static str, String, Applicability)> {
@@ -1809,7 +1809,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
 
     /// Given the target `label`, search the `rib_index`th label rib for similarly named labels,
     /// optionally returning the closest match and whether it is reachable.
-    crate fn suggestion_for_label_in_rib(
+    pub(crate) fn suggestion_for_label_in_rib(
         &self,
         rib_index: usize,
         label: Ident,
@@ -1834,7 +1834,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         })
     }
 
-    crate fn maybe_report_lifetime_uses(
+    pub(crate) fn maybe_report_lifetime_uses(
         &mut self,
         generics_span: Span,
         params: &[ast::GenericParam],
@@ -1904,7 +1904,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         }
     }
 
-    crate fn emit_undeclared_lifetime_error(
+    pub(crate) fn emit_undeclared_lifetime_error(
         &self,
         lifetime_ref: &ast::Lifetime,
         outer_lifetime_ref: Option<Ident>,
@@ -2000,7 +2000,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         err.emit();
     }
 
-    crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
+    pub(crate) fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
         struct_span_err!(
             self.r.session,
             lifetime_ref.ident.span,
@@ -2018,7 +2018,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
     /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
     /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
     /// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
-    crate fn maybe_emit_forbidden_non_static_lifetime_error(&self, lifetime_ref: &ast::Lifetime) {
+    pub(crate) fn maybe_emit_forbidden_non_static_lifetime_error(
+        &self,
+        lifetime_ref: &ast::Lifetime,
+    ) {
         let feature_active = self.r.session.features_untracked().generic_const_exprs;
         if !feature_active {
             feature_err(
@@ -2033,7 +2036,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
 }
 
 impl<'tcx> LifetimeContext<'_, 'tcx> {
-    crate fn report_missing_lifetime_specifiers(
+    pub(crate) fn report_missing_lifetime_specifiers(
         &self,
         spans: Vec<Span>,
         count: usize,
@@ -2048,7 +2051,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
     }
 
     /// Returns whether to add `'static` lifetime to the suggested lifetime list.
-    crate fn report_elision_failure(
+    pub(crate) fn report_elision_failure(
         &mut self,
         diag: &mut Diagnostic,
         params: &[ElisionFailureInfo],
@@ -2126,7 +2129,10 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
         }
     }
 
-    crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool {
+    pub(crate) fn is_trait_ref_fn_scope(
+        &mut self,
+        trait_ref: &'tcx hir::PolyTraitRef<'tcx>,
+    ) -> bool {
         if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res {
             if [
                 self.tcx.lang_items().fn_once_trait(),
@@ -2147,7 +2153,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
         false
     }
 
-    crate fn add_missing_lifetime_specifiers_label(
+    pub(crate) fn add_missing_lifetime_specifiers_label(
         &self,
         err: &mut Diagnostic,
         mut spans_with_counts: Vec<(Span, usize)>,
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index cacb851c4f0..2fe65441ac9 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -151,8 +151,8 @@ struct NamedRegionMap {
     scope_for_path: Option<FxHashMap<LocalDefId, FxHashMap<ItemLocalId, LifetimeScopeForPath>>>,
 }
 
-crate struct LifetimeContext<'a, 'tcx> {
-    crate tcx: TyCtxt<'tcx>,
+pub(crate) struct LifetimeContext<'a, 'tcx> {
+    pub(crate) tcx: TyCtxt<'tcx>,
     map: &'a mut NamedRegionMap,
     scope: ScopeRef<'a>,
 
@@ -169,7 +169,7 @@ crate struct LifetimeContext<'a, 'tcx> {
 
     /// When encountering an undefined named lifetime, we will suggest introducing it in these
     /// places.
-    crate missing_named_lifetime_spots: Vec<MissingLifetimeSpot<'tcx>>,
+    pub(crate) missing_named_lifetime_spots: Vec<MissingLifetimeSpot<'tcx>>,
 }
 
 #[derive(Debug)]
@@ -335,14 +335,14 @@ enum Elide {
 }
 
 #[derive(Clone, Debug)]
-crate struct ElisionFailureInfo {
+pub(crate) struct ElisionFailureInfo {
     /// Where we can find the argument pattern.
-    crate parent: Option<hir::BodyId>,
+    pub(crate) parent: Option<hir::BodyId>,
     /// The index of the argument in the original definition.
-    crate index: usize,
-    crate lifetime_count: usize,
-    crate have_bound_regions: bool,
-    crate span: Span,
+    pub(crate) index: usize,
+    pub(crate) lifetime_count: usize,
+    pub(crate) have_bound_regions: bool,
+    pub(crate) span: Span,
 }
 
 type ScopeRef<'a> = &'a Scope<'a>;
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 6c0148a17a1..73c8a9d28bd 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -9,7 +9,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(box_patterns)]
 #![feature(drain_filter)]
-#![feature(crate_visibility_modifier)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(let_else)]
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 2337f72f1e8..7e6375968ae 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -41,10 +41,10 @@ type Res = def::Res<NodeId>;
 /// Not modularized, can shadow previous `macro_rules` bindings, etc.
 #[derive(Debug)]
 pub struct MacroRulesBinding<'a> {
-    crate binding: &'a NameBinding<'a>,
+    pub(crate) binding: &'a NameBinding<'a>,
     /// `macro_rules` scope into which the `macro_rules` item was planted.
-    crate parent_macro_rules_scope: MacroRulesScopeRef<'a>,
-    crate ident: Ident,
+    pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'a>,
+    pub(crate) ident: Ident,
 }
 
 /// The scope introduced by a `macro_rules!` macro.
@@ -74,7 +74,10 @@ pub(crate) type MacroRulesScopeRef<'a> = Interned<'a, Cell<MacroRulesScope<'a>>>
 /// Macro namespace is separated into two sub-namespaces, one for bang macros and
 /// one for attribute-like macros (attributes, derives).
 /// We ignore resolutions from one sub-namespace when searching names in scope for another.
-crate fn sub_namespace_match(candidate: Option<MacroKind>, requirement: Option<MacroKind>) -> bool {
+pub(crate) fn sub_namespace_match(
+    candidate: Option<MacroKind>,
+    requirement: Option<MacroKind>,
+) -> bool {
     #[derive(PartialEq)]
     enum SubNS {
         Bang,
@@ -140,7 +143,7 @@ fn registered_idents(
     registered
 }
 
-crate fn registered_attrs_and_tools(
+pub(crate) fn registered_attrs_and_tools(
     sess: &Session,
     attrs: &[ast::Attribute],
 ) -> (FxHashSet<Ident>, FxHashSet<Ident>) {
@@ -651,7 +654,7 @@ impl<'a> Resolver<'a> {
         res.map(|res| (self.get_macro(res), res))
     }
 
-    crate fn finalize_macro_resolutions(&mut self) {
+    pub(crate) fn finalize_macro_resolutions(&mut self) {
         let check_consistency = |this: &mut Self,
                                  path: &[Segment],
                                  span,
@@ -839,7 +842,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
+    pub(crate) fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
         // Reserve some names that are not quite covered by the general check
         // performed on `Resolver::builtin_attrs`.
         if ident.name == sym::cfg || ident.name == sym::cfg_attr {
@@ -856,7 +859,7 @@ impl<'a> Resolver<'a> {
     /// Compile the macro into a `SyntaxExtension` and its rule spans.
     ///
     /// Possibly replace its expander to a pre-defined one for built-in macros.
-    crate fn compile_macro(
+    pub(crate) fn compile_macro(
         &mut self,
         item: &ast::Item,
         edition: Edition,
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index e1e398a06ed..997f361737b 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1912,7 +1912,7 @@ fn select_debuginfo(
     }
 }
 
-crate fn parse_assert_incr_state(
+pub(crate) fn parse_assert_incr_state(
     opt_assertion: &Option<String>,
     error_format: ErrorOutputType,
 ) -> Option<IncrementalStateAssertion> {
@@ -2755,7 +2755,7 @@ impl PpMode {
 /// `Hash` implementation for `DepTrackingHash`. It's important though that
 /// we have an opt-in scheme here, so one is hopefully forced to think about
 /// how the hash should be calculated when adding a new command-line argument.
-crate mod dep_tracking {
+pub(crate) mod dep_tracking {
     use super::{
         BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, ErrorOutputType,
         InstrumentCoverage, LdImpl, LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel,
@@ -2933,7 +2933,7 @@ crate mod dep_tracking {
     }
 
     // This is a stable hash because BTreeMap is a sorted container
-    crate fn stable_hash(
+    pub(crate) fn stable_hash(
         sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
         hasher: &mut DefaultHasher,
         error_format: ErrorOutputType,
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 054b18b6b63..f84a154950f 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,4 +1,3 @@
-#![feature(crate_visibility_modifier)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![cfg_attr(bootstrap, feature(derive_default_enum))]
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 14e918660dd..12e00ef5114 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -421,12 +421,12 @@ mod desc {
 }
 
 mod parse {
-    crate use super::*;
+    pub(crate) use super::*;
     use std::str::FromStr;
 
     /// This is for boolean options that don't take a value and start with
     /// `no-`. This style of option is deprecated.
-    crate fn parse_no_flag(slot: &mut bool, v: Option<&str>) -> bool {
+    pub(crate) fn parse_no_flag(slot: &mut bool, v: Option<&str>) -> bool {
         match v {
             None => {
                 *slot = true;
@@ -437,7 +437,7 @@ mod parse {
     }
 
     /// Use this for any boolean option that has a static default.
-    crate fn parse_bool(slot: &mut bool, v: Option<&str>) -> bool {
+    pub(crate) fn parse_bool(slot: &mut bool, v: Option<&str>) -> bool {
         match v {
             Some("y") | Some("yes") | Some("on") | None => {
                 *slot = true;
@@ -454,7 +454,7 @@ mod parse {
     /// Use this for any boolean option that lacks a static default. (The
     /// actions taken when such an option is not specified will depend on
     /// other factors, such as other options, or target options.)
-    crate fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
         match v {
             Some("y") | Some("yes") | Some("on") | None => {
                 *slot = Some(true);
@@ -469,7 +469,7 @@ mod parse {
     }
 
     /// Use this for any string option that has a static default.
-    crate fn parse_string(slot: &mut String, v: Option<&str>) -> bool {
+    pub(crate) fn parse_string(slot: &mut String, v: Option<&str>) -> bool {
         match v {
             Some(s) => {
                 *slot = s.to_string();
@@ -480,7 +480,7 @@ mod parse {
     }
 
     /// Use this for any string option that lacks a static default.
-    crate fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool {
         match v {
             Some(s) => {
                 *slot = Some(s.to_string());
@@ -491,7 +491,7 @@ mod parse {
     }
 
     /// Parse an optional language identifier, e.g. `en-US` or `zh-CN`.
-    crate fn parse_opt_langid(slot: &mut Option<LanguageIdentifier>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_opt_langid(slot: &mut Option<LanguageIdentifier>, v: Option<&str>) -> bool {
         match v {
             Some(s) => {
                 *slot = rustc_errors::LanguageIdentifier::from_str(s).ok();
@@ -501,7 +501,7 @@ mod parse {
         }
     }
 
-    crate fn parse_opt_pathbuf(slot: &mut Option<PathBuf>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_opt_pathbuf(slot: &mut Option<PathBuf>, v: Option<&str>) -> bool {
         match v {
             Some(s) => {
                 *slot = Some(PathBuf::from(s));
@@ -511,7 +511,7 @@ mod parse {
         }
     }
 
-    crate fn parse_string_push(slot: &mut Vec<String>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_string_push(slot: &mut Vec<String>, v: Option<&str>) -> bool {
         match v {
             Some(s) => {
                 slot.push(s.to_string());
@@ -521,7 +521,7 @@ mod parse {
         }
     }
 
-    crate fn parse_list(slot: &mut Vec<String>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_list(slot: &mut Vec<String>, v: Option<&str>) -> bool {
         match v {
             Some(s) => {
                 slot.extend(s.split_whitespace().map(|s| s.to_string()));
@@ -531,7 +531,10 @@ mod parse {
         }
     }
 
-    crate fn parse_list_with_polarity(slot: &mut Vec<(String, bool)>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_list_with_polarity(
+        slot: &mut Vec<(String, bool)>,
+        v: Option<&str>,
+    ) -> bool {
         match v {
             Some(s) => {
                 for s in s.split(",") {
@@ -544,7 +547,7 @@ mod parse {
         }
     }
 
-    crate fn parse_location_detail(ld: &mut LocationDetail, v: Option<&str>) -> bool {
+    pub(crate) fn parse_location_detail(ld: &mut LocationDetail, v: Option<&str>) -> bool {
         if let Some(v) = v {
             ld.line = false;
             ld.file = false;
@@ -563,7 +566,7 @@ mod parse {
         }
     }
 
-    crate fn parse_opt_comma_list(slot: &mut Option<Vec<String>>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_opt_comma_list(slot: &mut Option<Vec<String>>, v: Option<&str>) -> bool {
         match v {
             Some(s) => {
                 let mut v: Vec<_> = s.split(',').map(|s| s.to_string()).collect();
@@ -575,7 +578,7 @@ mod parse {
         }
     }
 
-    crate fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool {
+    pub(crate) fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool {
         match v.and_then(|s| s.parse().ok()) {
             Some(0) => {
                 *slot = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get);
@@ -590,7 +593,7 @@ mod parse {
     }
 
     /// Use this for any numeric option that has a static default.
-    crate fn parse_number<T: Copy + FromStr>(slot: &mut T, v: Option<&str>) -> bool {
+    pub(crate) fn parse_number<T: Copy + FromStr>(slot: &mut T, v: Option<&str>) -> bool {
         match v.and_then(|s| s.parse().ok()) {
             Some(i) => {
                 *slot = i;
@@ -601,7 +604,10 @@ mod parse {
     }
 
     /// Use this for any numeric option that lacks a static default.
-    crate fn parse_opt_number<T: Copy + FromStr>(slot: &mut Option<T>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_opt_number<T: Copy + FromStr>(
+        slot: &mut Option<T>,
+        v: Option<&str>,
+    ) -> bool {
         match v {
             Some(s) => {
                 *slot = s.parse().ok();
@@ -611,7 +617,7 @@ mod parse {
         }
     }
 
-    crate fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
+    pub(crate) fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
         match v {
             Some("all") => {
                 *slot = Passes::All;
@@ -629,7 +635,10 @@ mod parse {
         }
     }
 
-    crate fn parse_opt_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_opt_panic_strategy(
+        slot: &mut Option<PanicStrategy>,
+        v: Option<&str>,
+    ) -> bool {
         match v {
             Some("unwind") => *slot = Some(PanicStrategy::Unwind),
             Some("abort") => *slot = Some(PanicStrategy::Abort),
@@ -638,7 +647,7 @@ mod parse {
         true
     }
 
-    crate fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool {
+    pub(crate) fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool {
         match v {
             Some("unwind") => *slot = PanicStrategy::Unwind,
             Some("abort") => *slot = PanicStrategy::Abort,
@@ -647,7 +656,7 @@ mod parse {
         true
     }
 
-    crate fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool {
+    pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool {
         match v {
             Some("panic") => *slot = OomStrategy::Panic,
             Some("abort") => *slot = OomStrategy::Abort,
@@ -656,7 +665,7 @@ mod parse {
         true
     }
 
-    crate fn parse_relro_level(slot: &mut Option<RelroLevel>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_relro_level(slot: &mut Option<RelroLevel>, v: Option<&str>) -> bool {
         match v {
             Some(s) => match s.parse::<RelroLevel>() {
                 Ok(level) => *slot = Some(level),
@@ -667,7 +676,7 @@ mod parse {
         true
     }
 
-    crate fn parse_sanitizers(slot: &mut SanitizerSet, v: Option<&str>) -> bool {
+    pub(crate) fn parse_sanitizers(slot: &mut SanitizerSet, v: Option<&str>) -> bool {
         if let Some(v) = v {
             for s in v.split(',') {
                 *slot |= match s {
@@ -687,7 +696,7 @@ mod parse {
         }
     }
 
-    crate fn parse_sanitizer_memory_track_origins(slot: &mut usize, v: Option<&str>) -> bool {
+    pub(crate) fn parse_sanitizer_memory_track_origins(slot: &mut usize, v: Option<&str>) -> bool {
         match v {
             Some("2") | None => {
                 *slot = 2;
@@ -705,7 +714,7 @@ mod parse {
         }
     }
 
-    crate fn parse_strip(slot: &mut Strip, v: Option<&str>) -> bool {
+    pub(crate) fn parse_strip(slot: &mut Strip, v: Option<&str>) -> bool {
         match v {
             Some("none") => *slot = Strip::None,
             Some("debuginfo") => *slot = Strip::Debuginfo,
@@ -715,7 +724,7 @@ mod parse {
         true
     }
 
-    crate fn parse_cfguard(slot: &mut CFGuard, v: Option<&str>) -> bool {
+    pub(crate) fn parse_cfguard(slot: &mut CFGuard, v: Option<&str>) -> bool {
         if v.is_some() {
             let mut bool_arg = None;
             if parse_opt_bool(&mut bool_arg, v) {
@@ -733,7 +742,7 @@ mod parse {
         true
     }
 
-    crate fn parse_cfprotection(slot: &mut CFProtection, v: Option<&str>) -> bool {
+    pub(crate) fn parse_cfprotection(slot: &mut CFProtection, v: Option<&str>) -> bool {
         if v.is_some() {
             let mut bool_arg = None;
             if parse_opt_bool(&mut bool_arg, v) {
@@ -752,7 +761,7 @@ mod parse {
         true
     }
 
-    crate fn parse_linker_flavor(slot: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
         match v.and_then(LinkerFlavor::from_str) {
             Some(lf) => *slot = Some(lf),
             _ => return false,
@@ -760,7 +769,10 @@ mod parse {
         true
     }
 
-    crate fn parse_optimization_fuel(slot: &mut Option<(String, u64)>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_optimization_fuel(
+        slot: &mut Option<(String, u64)>,
+        v: Option<&str>,
+    ) -> bool {
         match v {
             None => false,
             Some(s) => {
@@ -779,7 +791,7 @@ mod parse {
         }
     }
 
-    crate fn parse_unpretty(slot: &mut Option<String>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_unpretty(slot: &mut Option<String>, v: Option<&str>) -> bool {
         match v {
             None => false,
             Some(s) if s.split('=').count() <= 2 => {
@@ -790,7 +802,7 @@ mod parse {
         }
     }
 
-    crate fn parse_mir_spanview(slot: &mut Option<MirSpanview>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_mir_spanview(slot: &mut Option<MirSpanview>, v: Option<&str>) -> bool {
         if v.is_some() {
             let mut bool_arg = None;
             if parse_opt_bool(&mut bool_arg, v) {
@@ -813,7 +825,7 @@ mod parse {
         true
     }
 
-    crate fn parse_instrument_coverage(
+    pub(crate) fn parse_instrument_coverage(
         slot: &mut Option<InstrumentCoverage>,
         v: Option<&str>,
     ) -> bool {
@@ -844,7 +856,7 @@ mod parse {
         true
     }
 
-    crate fn parse_treat_err_as_bug(slot: &mut Option<NonZeroUsize>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_treat_err_as_bug(slot: &mut Option<NonZeroUsize>, v: Option<&str>) -> bool {
         match v {
             Some(s) => {
                 *slot = s.parse().ok();
@@ -857,7 +869,7 @@ mod parse {
         }
     }
 
-    crate fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool {
+    pub(crate) fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool {
         if v.is_some() {
             let mut bool_arg = None;
             if parse_opt_bool(&mut bool_arg, v) {
@@ -875,7 +887,7 @@ mod parse {
         true
     }
 
-    crate fn parse_linker_plugin_lto(slot: &mut LinkerPluginLto, v: Option<&str>) -> bool {
+    pub(crate) fn parse_linker_plugin_lto(slot: &mut LinkerPluginLto, v: Option<&str>) -> bool {
         if v.is_some() {
             let mut bool_arg = None;
             if parse_opt_bool(&mut bool_arg, v) {
@@ -895,7 +907,10 @@ mod parse {
         true
     }
 
-    crate fn parse_switch_with_opt_path(slot: &mut SwitchWithOptPath, v: Option<&str>) -> bool {
+    pub(crate) fn parse_switch_with_opt_path(
+        slot: &mut SwitchWithOptPath,
+        v: Option<&str>,
+    ) -> bool {
         *slot = match v {
             None => SwitchWithOptPath::Enabled(None),
             Some(path) => SwitchWithOptPath::Enabled(Some(PathBuf::from(path))),
@@ -903,7 +918,10 @@ mod parse {
         true
     }
 
-    crate fn parse_merge_functions(slot: &mut Option<MergeFunctions>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_merge_functions(
+        slot: &mut Option<MergeFunctions>,
+        v: Option<&str>,
+    ) -> bool {
         match v.and_then(|s| MergeFunctions::from_str(s).ok()) {
             Some(mergefunc) => *slot = Some(mergefunc),
             _ => return false,
@@ -911,7 +929,7 @@ mod parse {
         true
     }
 
-    crate fn parse_relocation_model(slot: &mut Option<RelocModel>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_relocation_model(slot: &mut Option<RelocModel>, v: Option<&str>) -> bool {
         match v.and_then(|s| RelocModel::from_str(s).ok()) {
             Some(relocation_model) => *slot = Some(relocation_model),
             None if v == Some("default") => *slot = None,
@@ -920,7 +938,7 @@ mod parse {
         true
     }
 
-    crate fn parse_code_model(slot: &mut Option<CodeModel>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_code_model(slot: &mut Option<CodeModel>, v: Option<&str>) -> bool {
         match v.and_then(|s| CodeModel::from_str(s).ok()) {
             Some(code_model) => *slot = Some(code_model),
             _ => return false,
@@ -928,7 +946,7 @@ mod parse {
         true
     }
 
-    crate fn parse_tls_model(slot: &mut Option<TlsModel>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_tls_model(slot: &mut Option<TlsModel>, v: Option<&str>) -> bool {
         match v.and_then(|s| TlsModel::from_str(s).ok()) {
             Some(tls_model) => *slot = Some(tls_model),
             _ => return false,
@@ -936,7 +954,7 @@ mod parse {
         true
     }
 
-    crate fn parse_symbol_mangling_version(
+    pub(crate) fn parse_symbol_mangling_version(
         slot: &mut Option<SymbolManglingVersion>,
         v: Option<&str>,
     ) -> bool {
@@ -948,7 +966,7 @@ mod parse {
         true
     }
 
-    crate fn parse_src_file_hash(
+    pub(crate) fn parse_src_file_hash(
         slot: &mut Option<SourceFileHashAlgorithm>,
         v: Option<&str>,
     ) -> bool {
@@ -959,7 +977,7 @@ mod parse {
         true
     }
 
-    crate fn parse_target_feature(slot: &mut String, v: Option<&str>) -> bool {
+    pub(crate) fn parse_target_feature(slot: &mut String, v: Option<&str>) -> bool {
         match v {
             Some(s) => {
                 if !slot.is_empty() {
@@ -972,7 +990,7 @@ mod parse {
         }
     }
 
-    crate fn parse_wasi_exec_model(slot: &mut Option<WasiExecModel>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_wasi_exec_model(slot: &mut Option<WasiExecModel>, v: Option<&str>) -> bool {
         match v {
             Some("command") => *slot = Some(WasiExecModel::Command),
             Some("reactor") => *slot = Some(WasiExecModel::Reactor),
@@ -981,7 +999,10 @@ mod parse {
         true
     }
 
-    crate fn parse_split_debuginfo(slot: &mut Option<SplitDebuginfo>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_split_debuginfo(
+        slot: &mut Option<SplitDebuginfo>,
+        v: Option<&str>,
+    ) -> bool {
         match v.and_then(|s| SplitDebuginfo::from_str(s).ok()) {
             Some(e) => *slot = Some(e),
             _ => return false,
@@ -989,7 +1010,7 @@ mod parse {
         true
     }
 
-    crate fn parse_split_dwarf_kind(slot: &mut SplitDwarfKind, v: Option<&str>) -> bool {
+    pub(crate) fn parse_split_dwarf_kind(slot: &mut SplitDwarfKind, v: Option<&str>) -> bool {
         match v.and_then(|s| SplitDwarfKind::from_str(s).ok()) {
             Some(e) => *slot = e,
             _ => return false,
@@ -997,7 +1018,7 @@ mod parse {
         true
     }
 
-    crate fn parse_gcc_ld(slot: &mut Option<LdImpl>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_gcc_ld(slot: &mut Option<LdImpl>, v: Option<&str>) -> bool {
         match v {
             None => *slot = None,
             Some("lld") => *slot = Some(LdImpl::Lld),
@@ -1006,7 +1027,7 @@ mod parse {
         true
     }
 
-    crate fn parse_stack_protector(slot: &mut StackProtector, v: Option<&str>) -> bool {
+    pub(crate) fn parse_stack_protector(slot: &mut StackProtector, v: Option<&str>) -> bool {
         match v.and_then(|s| StackProtector::from_str(s).ok()) {
             Some(ssp) => *slot = ssp,
             _ => return false,
@@ -1014,7 +1035,10 @@ mod parse {
         true
     }
 
-    crate fn parse_branch_protection(slot: &mut Option<BranchProtection>, v: Option<&str>) -> bool {
+    pub(crate) fn parse_branch_protection(
+        slot: &mut Option<BranchProtection>,
+        v: Option<&str>,
+    ) -> bool {
         match v {
             Some(s) => {
                 let slot = slot.get_or_insert_default();
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index f194cf50211..59f2badbabb 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -352,7 +352,7 @@ pub struct HygieneData {
 }
 
 impl HygieneData {
-    crate fn new(edition: Edition) -> Self {
+    pub(crate) fn new(edition: Edition) -> Self {
         let root_data = ExpnData::default(
             ExpnKind::Root,
             DUMMY_SP,
@@ -668,17 +668,17 @@ impl SyntaxContext {
     }
 
     #[inline]
-    crate fn as_u32(self) -> u32 {
+    pub(crate) fn as_u32(self) -> u32 {
         self.0
     }
 
     #[inline]
-    crate fn from_u32(raw: u32) -> SyntaxContext {
+    pub(crate) fn from_u32(raw: u32) -> SyntaxContext {
         SyntaxContext(raw)
     }
 
     /// Extend a syntax context with a given expansion and transparency.
-    crate fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
+    pub(crate) fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
         HygieneData::with(|data| data.apply_mark(self, expn_id, transparency))
     }
 
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 1f4578c08a3..8737e45487e 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -15,7 +15,6 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(array_windows)]
-#![feature(crate_visibility_modifier)]
 #![feature(let_else)]
 #![feature(if_let_guard)]
 #![feature(negative_impls)]
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 0dd497448ca..f46e8ff0004 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -14,7 +14,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
-#![feature(crate_visibility_modifier)]
 #![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(drain_filter)]
 #![feature(hash_drain_filter)]
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index 238c6d99990..452b0d73c97 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -500,7 +500,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
 /// Requires that trait definitions have been processed so that we can
 /// elaborate predicates and walk supertraits.
 #[instrument(skip(tcx, predicates), level = "debug")]
-crate fn required_region_bounds<'tcx>(
+pub(crate) fn required_region_bounds<'tcx>(
     tcx: TyCtxt<'tcx>,
     erased_self_ty: Ty<'tcx>,
     predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
index 93c2f202545..592b0ab477a 100644
--- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
@@ -17,7 +17,7 @@ pub struct FulfillmentContext<'tcx> {
 }
 
 impl FulfillmentContext<'_> {
-    crate fn new() -> Self {
+    pub(crate) fn new() -> Self {
         FulfillmentContext {
             obligations: FxIndexSet::default(),
             relationships: FxHashMap::default(),
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index c3ee849d857..a51e6e58f67 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1488,7 +1488,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         expected_ref: ty::PolyTraitRef<'tcx>,
         found: ty::PolyTraitRef<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
-        crate fn build_fn_sig_string<'tcx>(
+        pub(crate) fn build_fn_sig_string<'tcx>(
             tcx: TyCtxt<'tcx>,
             trait_ref: ty::PolyTraitRef<'tcx>,
         ) -> String {
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index beaa56e1c1c..a71621a4d52 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -2116,7 +2116,7 @@ fn assoc_def(
     }
 }
 
-crate trait ProjectionCacheKeyExt<'cx, 'tcx>: Sized {
+pub(crate) trait ProjectionCacheKeyExt<'cx, 'tcx>: Sized {
     fn from_poly_projection_predicate(
         selcx: &mut SelectionContext<'cx, 'tcx>,
         predicate: ty::PolyProjectionPredicate<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 9a1128f2f28..b0b17d0f9e6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -332,7 +332,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
     }
 
-    crate fn select_from_obligation(
+    pub(crate) fn select_from_obligation(
         &mut self,
         obligation: &TraitObligation<'tcx>,
     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index bca1d15ada9..95f1e224a4c 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -486,7 +486,7 @@ fn report_conflicting_impls(
 
 /// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
 /// string.
-crate fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> {
+pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> {
     use std::fmt::Write;
 
     let trait_ref = tcx.impl_trait_ref(impl_def_id)?;
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index e3c865ce9e6..2b7ba22c4de 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -44,7 +44,7 @@ use std::collections::btree_map::{BTreeMap, Entry};
 use std::ops::ControlFlow;
 
 /// Essentially an `Into` with a `&RustInterner` parameter
-crate trait LowerInto<'tcx, T> {
+pub(crate) trait LowerInto<'tcx, T> {
     /// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk type, consuming `self`.
     fn lower_into(self, interner: RustInterner<'tcx>) -> T;
 }
@@ -836,7 +836,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>
 /// It's important to note that because of prior substitution, we may have
 /// late-bound regions, even outside of fn contexts, since this is the best way
 /// to prep types for chalk lowering.
-crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>(
+pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>(
     interner: RustInterner<'tcx>,
     tcx: TyCtxt<'tcx>,
     ty: Binder<'tcx, T>,
@@ -870,14 +870,14 @@ crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>(
     (new_ty, binders, named_parameters)
 }
 
-crate struct BoundVarsCollector<'tcx> {
+pub(crate) struct BoundVarsCollector<'tcx> {
     binder_index: ty::DebruijnIndex,
-    crate parameters: BTreeMap<u32, chalk_ir::VariableKind<RustInterner<'tcx>>>,
-    crate named_parameters: Vec<DefId>,
+    pub(crate) parameters: BTreeMap<u32, chalk_ir::VariableKind<RustInterner<'tcx>>>,
+    pub(crate) named_parameters: Vec<DefId>,
 }
 
 impl<'tcx> BoundVarsCollector<'tcx> {
-    crate fn new() -> Self {
+    pub(crate) fn new() -> Self {
         BoundVarsCollector {
             binder_index: ty::INNERMOST,
             parameters: BTreeMap::new(),
@@ -1001,17 +1001,17 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> {
 
 /// Used to substitute `Param`s with placeholders. We do this since Chalk
 /// have a notion of `Param`s.
-crate struct ParamsSubstitutor<'tcx> {
+pub(crate) struct ParamsSubstitutor<'tcx> {
     tcx: TyCtxt<'tcx>,
     binder_index: ty::DebruijnIndex,
     list: Vec<rustc_middle::ty::ParamTy>,
     next_ty_placeholder: usize,
-    crate params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
-    crate named_regions: BTreeMap<DefId, u32>,
+    pub(crate) params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
+    pub(crate) named_regions: BTreeMap<DefId, u32>,
 }
 
 impl<'tcx> ParamsSubstitutor<'tcx> {
-    crate fn new(tcx: TyCtxt<'tcx>, next_ty_placeholder: usize) -> Self {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>, next_ty_placeholder: usize) -> Self {
         ParamsSubstitutor {
             tcx,
             binder_index: ty::INNERMOST,
@@ -1083,13 +1083,13 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
     }
 }
 
-crate struct ReverseParamsSubstitutor<'tcx> {
+pub(crate) struct ReverseParamsSubstitutor<'tcx> {
     tcx: TyCtxt<'tcx>,
     params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
 }
 
 impl<'tcx> ReverseParamsSubstitutor<'tcx> {
-    crate fn new(
+    pub(crate) fn new(
         tcx: TyCtxt<'tcx>,
         params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
     ) -> Self {
@@ -1117,14 +1117,14 @@ impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> {
 }
 
 /// Used to collect `Placeholder`s.
-crate struct PlaceholdersCollector {
+pub(crate) struct PlaceholdersCollector {
     universe_index: ty::UniverseIndex,
-    crate next_ty_placeholder: usize,
-    crate next_anon_region_placeholder: u32,
+    pub(crate) next_ty_placeholder: usize,
+    pub(crate) next_anon_region_placeholder: u32,
 }
 
 impl PlaceholdersCollector {
-    crate fn new() -> Self {
+    pub(crate) fn new() -> Self {
         PlaceholdersCollector {
             universe_index: ty::UniverseIndex::ROOT,
             next_ty_placeholder: 0,
diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs
index 4e19479da87..59cf37fee9c 100644
--- a/compiler/rustc_traits/src/chalk/mod.rs
+++ b/compiler/rustc_traits/src/chalk/mod.rs
@@ -3,8 +3,8 @@
 //! In order to call `chalk-solve`, this file must convert a `CanonicalChalkEnvironmentAndGoal` into
 //! a Chalk uncanonical goal. It then calls Chalk, and converts the answer back into rustc solution.
 
-crate mod db;
-crate mod lowering;
+pub(crate) mod db;
+pub(crate) mod lowering;
 
 use rustc_data_structures::fx::FxHashMap;
 
@@ -27,11 +27,11 @@ use crate::chalk::lowering::{ParamsSubstitutor, PlaceholdersCollector, ReversePa
 
 use chalk_solve::Solution;
 
-crate fn provide(p: &mut Providers) {
+pub(crate) fn provide(p: &mut Providers) {
     *p = Providers { evaluate_goal, ..*p };
 }
 
-crate fn evaluate_goal<'tcx>(
+pub(crate) fn evaluate_goal<'tcx>(
     tcx: TyCtxt<'tcx>,
     obligation: CanonicalChalkEnvironmentAndGoal<'tcx>,
 ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, traits::query::NoSolution> {
diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs
index 3fd0bb1814a..a20de08b4ef 100644
--- a/compiler/rustc_traits/src/dropck_outlives.rs
+++ b/compiler/rustc_traits/src/dropck_outlives.rs
@@ -17,7 +17,7 @@ use rustc_trait_selection::traits::{
     Normalized, ObligationCause, TraitEngine, TraitEngineExt as _,
 };
 
-crate fn provide(p: &mut Providers) {
+pub(crate) fn provide(p: &mut Providers) {
     *p = Providers { dropck_outlives, adt_dtorck_constraint, ..*p };
 }
 
@@ -304,7 +304,7 @@ fn dtorck_constraint_for_ty<'tcx>(
 }
 
 /// Calculates the dtorck constraint for a type.
-crate fn adt_dtorck_constraint(
+pub(crate) fn adt_dtorck_constraint(
     tcx: TyCtxt<'_>,
     def_id: DefId,
 ) -> Result<&DropckConstraint<'_>, NoSolution> {
diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs
index 2404b7ff4b5..3fc141471b9 100644
--- a/compiler/rustc_traits/src/evaluate_obligation.rs
+++ b/compiler/rustc_traits/src/evaluate_obligation.rs
@@ -7,7 +7,7 @@ use rustc_trait_selection::traits::{
     EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode,
 };
 
-crate fn provide(p: &mut Providers) {
+pub(crate) fn provide(p: &mut Providers) {
     *p = Providers { evaluate_obligation, ..*p };
 }
 
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index 90c698db8fb..965324113d5 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -18,7 +18,7 @@ use rustc_trait_selection::traits::FulfillmentContext;
 use rustc_trait_selection::traits::TraitEngine;
 use smallvec::{smallvec, SmallVec};
 
-crate fn provide(p: &mut Providers) {
+pub(crate) fn provide(p: &mut Providers) {
     *p = Providers { implied_outlives_bounds, ..*p };
 }
 
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index 73fd95e98ca..6489bd2202d 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -1,7 +1,6 @@
 //! New recursive solver modeled on Chalk's recursive solver. Most of
 //! the guts are broken up into modules; see the comments in those modules.
 
-#![feature(crate_visibility_modifier)]
 #![feature(let_else)]
 #![feature(nll)]
 #![recursion_limit = "256"]
diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index a4aa965ec95..a8a324dec97 100644
--- a/compiler/rustc_traits/src/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
@@ -6,7 +6,7 @@ use rustc_trait_selection::traits::query::normalize::AtExt;
 use rustc_trait_selection::traits::{Normalized, ObligationCause};
 use std::sync::atomic::Ordering;
 
-crate fn provide(p: &mut Providers) {
+pub(crate) fn provide(p: &mut Providers) {
     *p = Providers {
         try_normalize_generic_arg_after_erasing_regions: |tcx, goal| {
             debug!("try_normalize_generic_arg_after_erasing_regions(goal={:#?}", goal);
diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs
index 1de50bae31b..98bb42c9afd 100644
--- a/compiler/rustc_traits/src/normalize_projection_ty.rs
+++ b/compiler/rustc_traits/src/normalize_projection_ty.rs
@@ -10,7 +10,7 @@ use rustc_trait_selection::traits::query::{
 use rustc_trait_selection::traits::{self, ObligationCause, SelectionContext};
 use std::sync::atomic::Ordering;
 
-crate fn provide(p: &mut Providers) {
+pub(crate) fn provide(p: &mut Providers) {
     *p = Providers { normalize_projection_ty, ..*p };
 }
 
diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs
index 861d3bc564f..f8bac1d7b26 100644
--- a/compiler/rustc_traits/src/type_op.rs
+++ b/compiler/rustc_traits/src/type_op.rs
@@ -23,7 +23,7 @@ use rustc_trait_selection::traits::query::{Fallible, NoSolution};
 use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, TraitEngine};
 use std::fmt;
 
-crate fn provide(p: &mut Providers) {
+pub(crate) fn provide(p: &mut Providers) {
     *p = Providers {
         type_op_ascribe_user_type,
         type_op_eq,
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 2ff32bdf978..96d083bb94f 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -640,7 +640,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         assoc_bindings
     }
 
-    crate fn create_substs_for_associated_item(
+    pub(crate) fn create_substs_for_associated_item(
         &self,
         tcx: TyCtxt<'tcx>,
         span: Span,
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index 71957a2d1b0..a17b13d49fd 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -1351,7 +1351,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
     /// is a forced-unit case, and hence `expression_ty` must be
     /// `Nil`.
     #[instrument(skip(self, fcx, augment_error, label_expression_as_expected), level = "debug")]
-    crate fn coerce_inner<'a>(
+    pub(crate) fn coerce_inner<'a>(
         &mut self,
         fcx: &FnCtxt<'a, 'tcx>,
         cause: &ObligationCause<'tcx>,
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index b857679520b..277bc1cf0f0 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -28,7 +28,7 @@ use super::{potentially_plural_count, FnCtxt, Inherited};
 /// - `impl_m_span`: span to use for reporting errors
 /// - `trait_m`: the method in the trait
 /// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation
-crate fn compare_impl_method<'tcx>(
+pub(crate) fn compare_impl_method<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_m: &ty::AssocItem,
     impl_m_span: Span,
@@ -1038,7 +1038,7 @@ fn compare_generic_param_kinds<'tcx>(
     Ok(())
 }
 
-crate fn compare_const_impl<'tcx>(
+pub(crate) fn compare_const_impl<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_c: &ty::AssocItem,
     impl_c_span: Span,
@@ -1144,7 +1144,7 @@ crate fn compare_const_impl<'tcx>(
     });
 }
 
-crate fn compare_ty_impl<'tcx>(
+pub(crate) fn compare_ty_impl<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_ty: &ty::AssocItem,
     impl_ty_span: Span,
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index ede2180a8e9..ceb57386e30 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -503,7 +503,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    crate fn maybe_get_struct_pattern_shorthand_field(
+    pub(crate) fn maybe_get_struct_pattern_shorthand_field(
         &self,
         expr: &hir::Expr<'_>,
     ) -> Option<Symbol> {
@@ -539,7 +539,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// If the given `HirId` corresponds to a block with a trailing expression, return that expression
-    crate fn maybe_get_block_expr(&self, expr: &hir::Expr<'tcx>) -> Option<&'tcx hir::Expr<'tcx>> {
+    pub(crate) fn maybe_get_block_expr(
+        &self,
+        expr: &hir::Expr<'tcx>,
+    ) -> Option<&'tcx hir::Expr<'tcx>> {
         match expr {
             hir::Expr { kind: hir::ExprKind::Block(block, ..), .. } => block.expr,
             _ => None,
@@ -547,7 +550,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Returns whether the given expression is an `else if`.
-    crate fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool {
+    pub(crate) fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool {
         if let hir::ExprKind::If(..) = expr.kind {
             let parent_id = self.tcx.hir().get_parent_node(expr.hir_id);
             if let Some(Node::Expr(hir::Expr {
diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs
index f8853014d2f..307064327c5 100644
--- a/compiler/rustc_typeck/src/check/dropck.rs
+++ b/compiler/rustc_typeck/src/check/dropck.rs
@@ -231,7 +231,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
 /// This function is not only checking that the dropck obligations are met for
 /// the given type, but it's also currently preventing non-regular recursion in
 /// types from causing stack overflows (dropck_no_diverge_on_nonregular_*.rs).
-crate fn check_drop_obligations<'a, 'tcx>(
+pub(crate) fn check_drop_obligations<'a, 'tcx>(
     rcx: &mut RegionCtxt<'a, 'tcx>,
     ty: Ty<'tcx>,
     span: Span,
@@ -248,7 +248,7 @@ crate fn check_drop_obligations<'a, 'tcx>(
 // This is an implementation of the TypeRelation trait with the
 // aim of simply comparing for equality (without side-effects).
 // It is not intended to be used anywhere else other than here.
-crate struct SimpleEqRelation<'tcx> {
+pub(crate) struct SimpleEqRelation<'tcx> {
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
 }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 151df84ca31..09b0dc0a0ea 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -2430,7 +2430,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err
     }
 
-    crate fn get_field_candidates(
+    pub(crate) fn get_field_candidates(
         &self,
         span: Span,
         base_t: Ty<'tcx>,
@@ -2455,7 +2455,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// This method is called after we have encountered a missing field error to recursively
     /// search for the field
-    crate fn check_for_nested_field_satisfying(
+    pub(crate) fn check_for_nested_field_satisfying(
         &self,
         span: Span,
         matches: &impl Fn(&ty::FieldDef, Ty<'tcx>) -> bool,
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 501ce31557d..3249157c4f4 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -1486,7 +1486,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Add all the obligations that are required, substituting and normalized appropriately.
-    crate fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
+    pub(crate) fn add_required_obligations(
+        &self,
+        span: Span,
+        def_id: DefId,
+        substs: &SubstsRef<'tcx>,
+    ) {
         self.add_required_obligations_with_code(
             span,
             def_id,
diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs
index cb359434fdb..d4c5caa6e92 100644
--- a/compiler/rustc_typeck/src/check/method/mod.rs
+++ b/compiler/rustc_typeck/src/check/method/mod.rs
@@ -116,7 +116,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Adds a suggestion to call the given method to the provided diagnostic.
     #[instrument(level = "debug", skip(self, err, call_expr))]
-    crate fn suggest_method_call(
+    pub(crate) fn suggest_method_call(
         &self,
         err: &mut Diagnostic,
         msg: &str,
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 7d873556ab7..f9c0ea82e02 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -1343,7 +1343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         false
     }
 
-    crate fn note_unmet_impls_on_type(
+    pub(crate) fn note_unmet_impls_on_type(
         &self,
         err: &mut Diagnostic,
         errors: Vec<FulfillmentError<'tcx>>,
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index 72a50d02ad8..583958ade62 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -646,7 +646,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     }
 }
 
-crate trait Locatable {
+pub(crate) trait Locatable {
     fn to_span(&self, tcx: TyCtxt<'_>) -> Span;
 }
 
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 7f43f96c9a2..c7823b444bf 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -110,7 +110,7 @@ pub struct ItemCtxt<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 
 #[derive(Default)]
-crate struct HirPlaceholderCollector(crate Vec<Span>);
+pub(crate) struct HirPlaceholderCollector(pub(crate) Vec<Span>);
 
 impl<'v> Visitor<'v> for HirPlaceholderCollector {
     fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
@@ -144,7 +144,7 @@ struct CollectItemTypesVisitor<'tcx> {
 /// If there are any placeholder types (`_`), emit an error explaining that this is not allowed
 /// and suggest adding type parameters in the appropriate place, taking into consideration any and
 /// all already existing generic type parameters to avoid suggesting a name that is already in use.
-crate fn placeholder_type_error<'tcx>(
+pub(crate) fn placeholder_type_error<'tcx>(
     tcx: TyCtxt<'tcx>,
     generics: Option<&hir::Generics<'_>>,
     placeholder_types: Vec<Span>,
@@ -160,7 +160,7 @@ crate fn placeholder_type_error<'tcx>(
         .emit();
 }
 
-crate fn placeholder_type_error_diag<'tcx>(
+pub(crate) fn placeholder_type_error_diag<'tcx>(
     tcx: TyCtxt<'tcx>,
     generics: Option<&hir::Generics<'_>>,
     placeholder_types: Vec<Span>,
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 67c6e791bfe..4ffd199b133 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -59,7 +59,6 @@ This API is completely unstable and subject to change.
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
-#![feature(crate_visibility_modifier)]
 #![feature(drain_filter)]
 #![feature(hash_drain_filter)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_typeck/src/mem_categorization.rs b/compiler/rustc_typeck/src/mem_categorization.rs
index 3d7b6593a64..21916352532 100644
--- a/compiler/rustc_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_typeck/src/mem_categorization.rs
@@ -65,7 +65,7 @@ use rustc_span::Span;
 use rustc_target::abi::VariantIdx;
 use rustc_trait_selection::infer::InferCtxtExt;
 
-crate trait HirNode {
+pub(crate) trait HirNode {
     fn hir_id(&self) -> hir::HirId;
     fn span(&self) -> Span;
 }
@@ -89,19 +89,19 @@ impl HirNode for hir::Pat<'_> {
 }
 
 #[derive(Clone)]
-crate struct MemCategorizationContext<'a, 'tcx> {
-    crate typeck_results: &'a ty::TypeckResults<'tcx>,
+pub(crate) struct MemCategorizationContext<'a, 'tcx> {
+    pub(crate) typeck_results: &'a ty::TypeckResults<'tcx>,
     infcx: &'a InferCtxt<'a, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     body_owner: LocalDefId,
     upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
 }
 
-crate type McResult<T> = Result<T, ()>;
+pub(crate) type McResult<T> = Result<T, ()>;
 
 impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     /// Creates a `MemCategorizationContext`.
-    crate fn new(
+    pub(crate) fn new(
         infcx: &'a InferCtxt<'a, 'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         body_owner: LocalDefId,
@@ -116,11 +116,11 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         }
     }
 
-    crate fn tcx(&self) -> TyCtxt<'tcx> {
+    pub(crate) fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
-    crate fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {
+    pub(crate) fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {
         self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span)
     }
 
@@ -162,7 +162,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         }
     }
 
-    crate fn node_ty(&self, hir_id: hir::HirId) -> McResult<Ty<'tcx>> {
+    pub(crate) fn node_ty(&self, hir_id: hir::HirId) -> McResult<Ty<'tcx>> {
         self.resolve_type_vars_or_error(hir_id, self.typeck_results.node_type_opt(hir_id))
     }
 
@@ -170,7 +170,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_opt(expr))
     }
 
-    crate fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
+    pub(crate) fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
         self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_adjusted_opt(expr))
     }
 
@@ -184,7 +184,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     ///   implicit deref patterns attached (e.g., it is really
     ///   `&Some(x)`). In that case, we return the "outermost" type
     ///   (e.g., `&Option<T>).
-    crate fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> McResult<Ty<'tcx>> {
+    pub(crate) fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> McResult<Ty<'tcx>> {
         // Check for implicit `&` types wrapping the pattern; note
         // that these are never attached to binding patterns, so
         // actually this is somewhat "disjoint" from the code below
@@ -236,7 +236,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         Ok(ret_ty)
     }
 
-    crate fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult<PlaceWithHirId<'tcx>> {
+    pub(crate) fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult<PlaceWithHirId<'tcx>> {
         // This recursion helper avoids going through *too many*
         // adjustments, since *only* non-overloaded deref recurses.
         fn helper<'a, 'tcx>(
@@ -255,7 +255,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         helper(self, expr, self.typeck_results.expr_adjustments(expr))
     }
 
-    crate fn cat_expr_adjusted(
+    pub(crate) fn cat_expr_adjusted(
         &self,
         expr: &hir::Expr<'_>,
         previous: PlaceWithHirId<'tcx>,
@@ -298,7 +298,10 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         }
     }
 
-    crate fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> McResult<PlaceWithHirId<'tcx>> {
+    pub(crate) fn cat_expr_unadjusted(
+        &self,
+        expr: &hir::Expr<'_>,
+    ) -> McResult<PlaceWithHirId<'tcx>> {
         debug!("cat_expr: id={} expr={:?}", expr.hir_id, expr);
 
         let expr_ty = self.expr_ty(expr)?;
@@ -383,7 +386,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         }
     }
 
-    crate fn cat_res(
+    pub(crate) fn cat_res(
         &self,
         hir_id: hir::HirId,
         span: Span,
@@ -440,7 +443,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         Ok(ret)
     }
 
-    crate fn cat_rvalue(
+    pub(crate) fn cat_rvalue(
         &self,
         hir_id: hir::HirId,
         span: Span,
@@ -452,7 +455,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         ret
     }
 
-    crate fn cat_projection<N: HirNode>(
+    pub(crate) fn cat_projection<N: HirNode>(
         &self,
         node: &N,
         base_place: PlaceWithHirId<'tcx>,
@@ -521,7 +524,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         Ok(ret)
     }
 
-    crate fn cat_pattern<F>(
+    pub(crate) fn cat_pattern<F>(
         &self,
         place: PlaceWithHirId<'tcx>,
         pat: &hir::Pat<'_>,
diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs
index 139be8a42de..dccfee19960 100644
--- a/compiler/rustc_typeck/src/outlives/mod.rs
+++ b/compiler/rustc_typeck/src/outlives/mod.rs
@@ -9,7 +9,7 @@ use rustc_span::Span;
 
 mod explicit;
 mod implicit_infer;
-crate mod outlives_bounds;
+pub(crate) mod outlives_bounds;
 /// Code to write unit test for outlives.
 pub mod test;
 mod utils;
diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
index 5cd7a7d578e..f1dc3cbbac4 100644
--- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
@@ -15,28 +15,28 @@ use GenericArgsInfo::*;
 
 /// Handles the `wrong number of type / lifetime / ... arguments` family of error messages.
 pub struct WrongNumberOfGenericArgs<'a, 'tcx> {
-    crate tcx: TyCtxt<'tcx>,
+    pub(crate) tcx: TyCtxt<'tcx>,
 
-    crate angle_brackets: AngleBrackets,
+    pub(crate) angle_brackets: AngleBrackets,
 
-    crate gen_args_info: GenericArgsInfo,
+    pub(crate) gen_args_info: GenericArgsInfo,
 
     /// Offending path segment
-    crate path_segment: &'a hir::PathSegment<'a>,
+    pub(crate) path_segment: &'a hir::PathSegment<'a>,
 
     /// Generic parameters as expected by type or trait
-    crate gen_params: &'a ty::Generics,
+    pub(crate) gen_params: &'a ty::Generics,
 
     /// Index offset into parameters. Depends on whether `Self` is included and on
     /// number of lifetime parameters in case we're processing missing or redundant
     /// type or constant arguments.
-    crate params_offset: usize,
+    pub(crate) params_offset: usize,
 
     /// Generic arguments as provided by user
-    crate gen_args: &'a hir::GenericArgs<'a>,
+    pub(crate) gen_args: &'a hir::GenericArgs<'a>,
 
     /// DefId of the generic type
-    crate def_id: DefId,
+    pub(crate) def_id: DefId,
 }
 
 // Provides information about the kind of arguments that were provided for
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index fffd9499209..27fb4709982 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -20,12 +20,12 @@ struct RegionDeps<'tcx> {
     smaller: FxHashSet<RegionTarget<'tcx>>,
 }
 
-crate struct AutoTraitFinder<'a, 'tcx> {
-    crate cx: &'a mut core::DocContext<'tcx>,
+pub(crate) struct AutoTraitFinder<'a, 'tcx> {
+    pub(crate) cx: &'a mut core::DocContext<'tcx>,
 }
 
 impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
-    crate fn new(cx: &'a mut core::DocContext<'tcx>) -> Self {
+    pub(crate) fn new(cx: &'a mut core::DocContext<'tcx>) -> Self {
         AutoTraitFinder { cx }
     }
 
@@ -130,7 +130,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
         })
     }
 
-    crate fn get_auto_trait_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
+    pub(crate) fn get_auto_trait_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
         let tcx = self.cx.tcx;
         let param_env = tcx.param_env(item_def_id);
         let ty = tcx.type_of(item_def_id);
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 805cc5c71d8..c591c591331 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -8,12 +8,12 @@ use rustc_span::DUMMY_SP;
 
 use super::*;
 
-crate struct BlanketImplFinder<'a, 'tcx> {
-    crate cx: &'a mut core::DocContext<'tcx>,
+pub(crate) struct BlanketImplFinder<'a, 'tcx> {
+    pub(crate) cx: &'a mut core::DocContext<'tcx>,
 }
 
 impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
-    crate fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
+    pub(crate) fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
         let param_env = self.cx.tcx.param_env(item_def_id);
         let ty = self.cx.tcx.bound_type_of(item_def_id);
 
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 9e9c4dfb506..deac1723b26 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -21,7 +21,7 @@ use crate::html::escape::Escape;
 mod tests;
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
-crate enum Cfg {
+pub(crate) enum Cfg {
     /// Accepts all configurations.
     True,
     /// Denies all configurations.
@@ -37,9 +37,9 @@ crate enum Cfg {
 }
 
 #[derive(PartialEq, Debug)]
-crate struct InvalidCfgError {
-    crate msg: &'static str,
-    crate span: Span,
+pub(crate) struct InvalidCfgError {
+    pub(crate) msg: &'static str,
+    pub(crate) span: Span,
 }
 
 impl Cfg {
@@ -56,7 +56,7 @@ impl Cfg {
         }
     }
 
-    crate fn parse_without(
+    pub(crate) fn parse_without(
         cfg: &MetaItem,
         exclude: &FxHashSet<Cfg>,
     ) -> Result<Option<Cfg>, InvalidCfgError> {
@@ -117,7 +117,7 @@ impl Cfg {
     ///
     /// If the content is not properly formatted, it will return an error indicating what and where
     /// the error is.
-    crate fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
+    pub(crate) fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
         Self::parse_without(cfg, &FxHashSet::default()).map(|ret| ret.unwrap())
     }
 
@@ -125,7 +125,7 @@ impl Cfg {
     ///
     /// Equivalent to `attr::cfg_matches`.
     // FIXME: Actually make use of `features`.
-    crate fn matches(&self, parse_sess: &ParseSess, features: Option<&Features>) -> bool {
+    pub(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/inline.rs b/src/librustdoc/clean/inline.rs
index 9a579cb5311..1b6658bb4ca 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -38,7 +38,7 @@ type Attrs<'hir> = &'hir [ast::Attribute];
 /// and `Some` of a vector of items if it was successfully expanded.
 ///
 /// `parent_module` refers to the parent of the *re-export*, not the original item.
-crate fn try_inline(
+pub(crate) fn try_inline(
     cx: &mut DocContext<'_>,
     parent_module: DefId,
     import_def_id: Option<DefId>,
@@ -134,7 +134,7 @@ crate fn try_inline(
     Some(ret)
 }
 
-crate fn try_inline_glob(
+pub(crate) fn try_inline_glob(
     cx: &mut DocContext<'_>,
     res: Res,
     visited: &mut FxHashSet<DefId>,
@@ -154,7 +154,7 @@ crate fn try_inline_glob(
     }
 }
 
-crate fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> {
+pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> {
     cx.tcx.get_attrs_unchecked(did)
 }
 
@@ -162,7 +162,7 @@ crate fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> {
 ///
 /// These names are used later on by HTML rendering to generate things like
 /// source links back to the original item.
-crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) {
+pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) {
     let crate_name = cx.tcx.crate_name(did.krate);
 
     let relative =
@@ -190,7 +190,7 @@ crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType)
     }
 }
 
-crate fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
+pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
     let trait_items = cx
         .tcx
         .associated_items(did)
@@ -274,7 +274,7 @@ fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef {
 }
 
 /// Builds all inherent implementations of an ADT (struct/union/enum) or Trait item/path/reexport.
-crate fn build_impls(
+pub(crate) fn build_impls(
     cx: &mut DocContext<'_>,
     parent_module: Option<DefId>,
     did: DefId,
@@ -318,7 +318,7 @@ fn merge_attrs(
 }
 
 /// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl`.
-crate fn build_impl(
+pub(crate) fn build_impl(
     cx: &mut DocContext<'_>,
     parent_module: Option<DefId>,
     did: DefId,
@@ -565,7 +565,7 @@ fn build_module(
     clean::Module { items, span }
 }
 
-crate fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
+pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
     if let Some(did) = did.as_local() {
         let hir_id = tcx.hir().local_def_id_to_hir_id(did);
         rustc_hir_pretty::id_to_string(&tcx.hir(), hir_id)
@@ -670,7 +670,7 @@ fn separate_supertrait_bounds(
     (g, ty_bounds)
 }
 
-crate fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) {
+pub(crate) fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) {
     if did.is_local() {
         return;
     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 6e18f381c59..4f66b4a240c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -3,12 +3,12 @@
 
 mod auto_trait;
 mod blanket_impl;
-crate mod cfg;
-crate mod inline;
+pub(crate) mod cfg;
+pub(crate) mod inline;
 mod render_macro_matchers;
 mod simplify;
-crate mod types;
-crate mod utils;
+pub(crate) mod types;
+pub(crate) mod utils;
 
 use rustc_ast as ast;
 use rustc_attr as attr;
@@ -41,10 +41,10 @@ use crate::visit_ast::Module as DocModule;
 
 use utils::*;
 
-crate use self::types::*;
-crate use self::utils::{get_auto_trait_and_blanket_impls, krate, register_res};
+pub(crate) use self::types::*;
+pub(crate) use self::utils::{get_auto_trait_and_blanket_impls, krate, register_res};
 
-crate trait Clean<T> {
+pub(crate) trait Clean<T> {
     fn clean(&self, cx: &mut DocContext<'_>) -> T;
 }
 
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 194c25a795a..af7813a7740 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;
 
-crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
+pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     // First, partition the where clause into its separate components.
     //
     // We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to
@@ -79,7 +79,7 @@ crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     clauses
 }
 
-crate fn merge_bounds(
+pub(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 456d860f125..edf7ddb30db 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -44,22 +44,22 @@ use crate::formats::item_type::ItemType;
 use crate::html::render::Context;
 use crate::passes::collect_intra_doc_links::UrlFragment;
 
-crate use self::FnRetTy::*;
-crate use self::ItemKind::*;
-crate use self::SelfTy::*;
-crate use self::Type::{
+pub(crate) use self::FnRetTy::*;
+pub(crate) use self::ItemKind::*;
+pub(crate) use self::SelfTy::*;
+pub(crate) use self::Type::{
     Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
     RawPointer, Slice, Tuple,
 };
-crate use self::Visibility::{Inherited, Public};
+pub(crate) use self::Visibility::{Inherited, Public};
 
 #[cfg(test)]
 mod tests;
 
-crate type ItemIdSet = FxHashSet<ItemId>;
+pub(crate) type ItemIdSet = FxHashSet<ItemId>;
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
-crate enum ItemId {
+pub(crate) enum ItemId {
     /// A "normal" item that uses a [`DefId`] for identification.
     DefId(DefId),
     /// Identifier that is used for auto traits.
@@ -72,7 +72,7 @@ crate enum ItemId {
 
 impl ItemId {
     #[inline]
-    crate fn is_local(self) -> bool {
+    pub(crate) fn is_local(self) -> bool {
         match self {
             ItemId::Auto { for_: id, .. }
             | ItemId::Blanket { for_: id, .. }
@@ -83,13 +83,13 @@ impl ItemId {
 
     #[inline]
     #[track_caller]
-    crate fn expect_def_id(self) -> DefId {
+    pub(crate) fn expect_def_id(self) -> DefId {
         self.as_def_id()
             .unwrap_or_else(|| panic!("ItemId::expect_def_id: `{:?}` isn't a DefId", self))
     }
 
     #[inline]
-    crate fn as_def_id(self) -> Option<DefId> {
+    pub(crate) fn as_def_id(self) -> Option<DefId> {
         match self {
             ItemId::DefId(id) => Some(id),
             _ => None,
@@ -97,7 +97,7 @@ impl ItemId {
     }
 
     #[inline]
-    crate fn krate(self) -> CrateNum {
+    pub(crate) fn krate(self) -> CrateNum {
         match self {
             ItemId::Auto { for_: id, .. }
             | ItemId::Blanket { for_: id, .. }
@@ -115,11 +115,11 @@ impl From<DefId> for ItemId {
 
 /// The crate currently being documented.
 #[derive(Clone, Debug)]
-crate struct Crate {
-    crate module: Item,
-    crate primitives: ThinVec<(DefId, PrimitiveType)>,
+pub(crate) struct Crate {
+    pub(crate) module: Item,
+    pub(crate) primitives: ThinVec<(DefId, PrimitiveType)>,
     /// Only here so that they can be filtered through the rustdoc passes.
-    crate external_traits: Rc<RefCell<FxHashMap<DefId, TraitWithExtraInfo>>>,
+    pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, TraitWithExtraInfo>>>,
 }
 
 // `Crate` is frequently moved by-value. Make sure it doesn't unintentionally get bigger.
@@ -127,45 +127,45 @@ crate struct Crate {
 rustc_data_structures::static_assert_size!(Crate, 72);
 
 impl Crate {
-    crate fn name(&self, tcx: TyCtxt<'_>) -> Symbol {
+    pub(crate) fn name(&self, tcx: TyCtxt<'_>) -> Symbol {
         ExternalCrate::LOCAL.name(tcx)
     }
 
-    crate fn src(&self, tcx: TyCtxt<'_>) -> FileName {
+    pub(crate) fn src(&self, tcx: TyCtxt<'_>) -> FileName {
         ExternalCrate::LOCAL.src(tcx)
     }
 }
 
 /// This struct is used to wrap additional information added by rustdoc on a `trait` item.
 #[derive(Clone, Debug)]
-crate struct TraitWithExtraInfo {
-    crate trait_: Trait,
-    crate is_notable: bool,
+pub(crate) struct TraitWithExtraInfo {
+    pub(crate) trait_: Trait,
+    pub(crate) is_notable: bool,
 }
 
 #[derive(Copy, Clone, Debug)]
-crate struct ExternalCrate {
-    crate crate_num: CrateNum,
+pub(crate) struct ExternalCrate {
+    pub(crate) crate_num: CrateNum,
 }
 
 impl ExternalCrate {
     const LOCAL: Self = Self { crate_num: LOCAL_CRATE };
 
     #[inline]
-    crate fn def_id(&self) -> DefId {
+    pub(crate) fn def_id(&self) -> DefId {
         self.crate_num.as_def_id()
     }
 
-    crate fn src(&self, tcx: TyCtxt<'_>) -> FileName {
+    pub(crate) fn src(&self, tcx: TyCtxt<'_>) -> FileName {
         let krate_span = tcx.def_span(self.def_id());
         tcx.sess.source_map().span_to_filename(krate_span)
     }
 
-    crate fn name(&self, tcx: TyCtxt<'_>) -> Symbol {
+    pub(crate) fn name(&self, tcx: TyCtxt<'_>) -> Symbol {
         tcx.crate_name(self.crate_num)
     }
 
-    crate fn src_root(&self, tcx: TyCtxt<'_>) -> PathBuf {
+    pub(crate) fn src_root(&self, tcx: TyCtxt<'_>) -> PathBuf {
         match self.src(tcx) {
             FileName::Real(ref p) => match p.local_path_if_available().parent() {
                 Some(p) => p.to_path_buf(),
@@ -177,7 +177,7 @@ impl ExternalCrate {
 
     /// Attempts to find where an external crate is located, given that we're
     /// rendering in to the specified source destination.
-    crate fn location(
+    pub(crate) fn location(
         &self,
         extern_url: Option<&str>,
         extern_url_takes_precedence: bool,
@@ -221,7 +221,7 @@ impl ExternalCrate {
             .unwrap_or(Unknown) // Well, at least we tried.
     }
 
-    crate fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> {
+    pub(crate) fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> {
         let root = self.def_id();
 
         let as_keyword = |res: Res<!>| {
@@ -268,7 +268,7 @@ impl ExternalCrate {
         }
     }
 
-    crate fn primitives(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, PrimitiveType)> {
+    pub(crate) fn primitives(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, PrimitiveType)> {
         let root = self.def_id();
 
         // Collect all inner modules which are tagged as implementations of
@@ -341,7 +341,7 @@ impl ExternalCrate {
 
 /// Indicates where an external crate can be found.
 #[derive(Debug)]
-crate enum ExternalLocation {
+pub(crate) enum ExternalLocation {
     /// Remote URL root of the external crate
     Remote(String),
     /// This external crate can be found in the local doc/ folder
@@ -354,18 +354,18 @@ crate enum ExternalLocation {
 /// 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)]
-crate struct Item {
+pub(crate) struct Item {
     /// The name of this item.
     /// Optional because not every item has a name, e.g. impls.
-    crate name: Option<Symbol>,
-    crate attrs: Box<Attributes>,
-    crate visibility: Visibility,
+    pub(crate) name: Option<Symbol>,
+    pub(crate) attrs: Box<Attributes>,
+    pub(crate) visibility: Visibility,
     /// Information about this item that is specific to what kind of item it is.
     /// E.g., struct vs enum vs function.
-    crate kind: Box<ItemKind>,
-    crate item_id: ItemId,
+    pub(crate) kind: Box<ItemKind>,
+    pub(crate) item_id: ItemId,
 
-    crate cfg: Option<Arc<Cfg>>,
+    pub(crate) cfg: Option<Arc<Cfg>>,
 }
 
 /// NOTE: this does NOT unconditionally print every item, to avoid thousands of lines of logs.
@@ -393,7 +393,7 @@ impl fmt::Debug for Item {
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Item, 56);
 
-crate fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span {
+pub(crate) fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span {
     Span::new(def_id.as_local().map_or_else(
         || tcx.def_span(def_id),
         |local| {
@@ -404,26 +404,26 @@ crate fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span {
 }
 
 impl Item {
-    crate fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<Stability> {
+    pub(crate) fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<Stability> {
         self.item_id.as_def_id().and_then(|did| tcx.lookup_stability(did))
     }
 
-    crate fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<ConstStability> {
+    pub(crate) fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<ConstStability> {
         self.item_id.as_def_id().and_then(|did| tcx.lookup_const_stability(did))
     }
 
-    crate fn deprecation(&self, tcx: TyCtxt<'_>) -> Option<Deprecation> {
+    pub(crate) fn deprecation(&self, tcx: TyCtxt<'_>) -> Option<Deprecation> {
         self.item_id.as_def_id().and_then(|did| tcx.lookup_deprecation(did))
     }
 
-    crate fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
+    pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
         self.item_id
             .as_def_id()
             .map(|did| tcx.get_attrs_unchecked(did).inner_docs())
             .unwrap_or(false)
     }
 
-    crate fn span(&self, tcx: TyCtxt<'_>) -> Span {
+    pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Span {
         let kind = match &*self.kind {
             ItemKind::StrippedItem(k) => k,
             _ => &*self.kind,
@@ -444,19 +444,19 @@ impl Item {
         }
     }
 
-    crate fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span {
+    pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span {
         crate::passes::span_of_attrs(&self.attrs).unwrap_or_else(|| self.span(tcx).inner())
     }
 
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
-    crate fn doc_value(&self) -> Option<String> {
+    pub(crate) fn doc_value(&self) -> Option<String> {
         self.attrs.doc_value()
     }
 
     /// Convenience wrapper around [`Self::from_def_id_and_parts`] which converts
     /// `hir_id` to a [`DefId`]
-    crate fn from_hir_id_and_parts(
+    pub(crate) fn from_hir_id_and_parts(
         hir_id: hir::HirId,
         name: Option<Symbol>,
         kind: ItemKind,
@@ -465,7 +465,7 @@ impl Item {
         Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx)
     }
 
-    crate fn from_def_id_and_parts(
+    pub(crate) fn from_def_id_and_parts(
         def_id: DefId,
         name: Option<Symbol>,
         kind: ItemKind,
@@ -483,7 +483,7 @@ impl Item {
         )
     }
 
-    crate fn from_def_id_and_attrs_and_parts(
+    pub(crate) fn from_def_id_and_attrs_and_parts(
         def_id: DefId,
         name: Option<Symbol>,
         kind: ItemKind,
@@ -508,11 +508,11 @@ impl Item {
 
     /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
     /// with newlines.
-    crate fn collapsed_doc_value(&self) -> Option<String> {
+    pub(crate) fn collapsed_doc_value(&self) -> Option<String> {
         self.attrs.collapsed_doc_value()
     }
 
-    crate fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> {
+    pub(crate) fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> {
         use crate::html::format::href;
 
         cx.cache()
@@ -544,7 +544,7 @@ impl Item {
     /// This is used for generating summary text, which does not include
     /// the link text, but does need to know which `[]`-bracketed names
     /// are actually links.
-    crate fn link_names(&self, cache: &Cache) -> Vec<RenderedLink> {
+    pub(crate) fn link_names(&self, cache: &Cache) -> Vec<RenderedLink> {
         cache
             .intra_doc_links
             .get(&self.item_id)
@@ -558,68 +558,68 @@ impl Item {
             .collect()
     }
 
-    crate fn is_crate(&self) -> bool {
+    pub(crate) fn is_crate(&self) -> bool {
         self.is_mod() && self.item_id.as_def_id().map_or(false, |did| did.is_crate_root())
     }
-    crate fn is_mod(&self) -> bool {
+    pub(crate) fn is_mod(&self) -> bool {
         self.type_() == ItemType::Module
     }
-    crate fn is_trait(&self) -> bool {
+    pub(crate) fn is_trait(&self) -> bool {
         self.type_() == ItemType::Trait
     }
-    crate fn is_struct(&self) -> bool {
+    pub(crate) fn is_struct(&self) -> bool {
         self.type_() == ItemType::Struct
     }
-    crate fn is_enum(&self) -> bool {
+    pub(crate) fn is_enum(&self) -> bool {
         self.type_() == ItemType::Enum
     }
-    crate fn is_variant(&self) -> bool {
+    pub(crate) fn is_variant(&self) -> bool {
         self.type_() == ItemType::Variant
     }
-    crate fn is_associated_type(&self) -> bool {
+    pub(crate) fn is_associated_type(&self) -> bool {
         matches!(&*self.kind, AssocTypeItem(..) | StrippedItem(box AssocTypeItem(..)))
     }
-    crate fn is_ty_associated_type(&self) -> bool {
+    pub(crate) fn is_ty_associated_type(&self) -> bool {
         matches!(&*self.kind, TyAssocTypeItem(..) | StrippedItem(box TyAssocTypeItem(..)))
     }
-    crate fn is_associated_const(&self) -> bool {
+    pub(crate) fn is_associated_const(&self) -> bool {
         matches!(&*self.kind, AssocConstItem(..) | StrippedItem(box AssocConstItem(..)))
     }
-    crate fn is_ty_associated_const(&self) -> bool {
+    pub(crate) fn is_ty_associated_const(&self) -> bool {
         matches!(&*self.kind, TyAssocConstItem(..) | StrippedItem(box TyAssocConstItem(..)))
     }
-    crate fn is_method(&self) -> bool {
+    pub(crate) fn is_method(&self) -> bool {
         self.type_() == ItemType::Method
     }
-    crate fn is_ty_method(&self) -> bool {
+    pub(crate) fn is_ty_method(&self) -> bool {
         self.type_() == ItemType::TyMethod
     }
-    crate fn is_typedef(&self) -> bool {
+    pub(crate) fn is_typedef(&self) -> bool {
         self.type_() == ItemType::Typedef
     }
-    crate fn is_primitive(&self) -> bool {
+    pub(crate) fn is_primitive(&self) -> bool {
         self.type_() == ItemType::Primitive
     }
-    crate fn is_union(&self) -> bool {
+    pub(crate) fn is_union(&self) -> bool {
         self.type_() == ItemType::Union
     }
-    crate fn is_import(&self) -> bool {
+    pub(crate) fn is_import(&self) -> bool {
         self.type_() == ItemType::Import
     }
-    crate fn is_extern_crate(&self) -> bool {
+    pub(crate) fn is_extern_crate(&self) -> bool {
         self.type_() == ItemType::ExternCrate
     }
-    crate fn is_keyword(&self) -> bool {
+    pub(crate) fn is_keyword(&self) -> bool {
         self.type_() == ItemType::Keyword
     }
-    crate fn is_stripped(&self) -> bool {
+    pub(crate) fn is_stripped(&self) -> bool {
         match *self.kind {
             StrippedItem(..) => true,
             ImportItem(ref i) => !i.should_be_displayed,
             _ => false,
         }
     }
-    crate fn has_stripped_fields(&self) -> Option<bool> {
+    pub(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),
@@ -628,7 +628,7 @@ impl Item {
         }
     }
 
-    crate fn stability_class(&self, tcx: TyCtxt<'_>) -> Option<String> {
+    pub(crate) fn stability_class(&self, tcx: TyCtxt<'_>) -> Option<String> {
         self.stability(tcx).as_ref().and_then(|s| {
             let mut classes = Vec::with_capacity(2);
 
@@ -645,30 +645,30 @@ impl Item {
         })
     }
 
-    crate fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
+    pub(crate) fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
         match self.stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since),
             StabilityLevel::Unstable { .. } => None,
         }
     }
 
-    crate fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
+    pub(crate) fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
         match self.const_stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since),
             StabilityLevel::Unstable { .. } => None,
         }
     }
 
-    crate fn is_non_exhaustive(&self) -> bool {
+    pub(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.
-    crate fn type_(&self) -> ItemType {
+    pub(crate) fn type_(&self) -> ItemType {
         ItemType::from(self)
     }
 
-    crate fn is_default(&self) -> bool {
+    pub(crate) fn is_default(&self) -> bool {
         match *self.kind {
             ItemKind::MethodItem(_, Some(defaultness)) => {
                 defaultness.has_value() && !defaultness.is_final()
@@ -678,7 +678,7 @@ impl Item {
     }
 
     /// Returns a `FnHeader` if `self` is a function item, otherwise returns `None`.
-    crate fn fn_header(&self, tcx: TyCtxt<'_>) -> Option<hir::FnHeader> {
+    pub(crate) fn fn_header(&self, tcx: TyCtxt<'_>) -> Option<hir::FnHeader> {
         fn build_fn_header(
             def_id: DefId,
             tcx: TyCtxt<'_>,
@@ -721,7 +721,7 @@ impl Item {
 }
 
 #[derive(Clone, Debug)]
-crate enum ItemKind {
+pub(crate) enum ItemKind {
     ExternCrateItem {
         /// The crate's name, *not* the name it's imported as.
         src: Option<Symbol>,
@@ -774,7 +774,7 @@ crate enum ItemKind {
 impl ItemKind {
     /// Some items contain others such as structs (for their fields) and Enums
     /// (for their variants). This method returns those contained items.
-    crate fn inner_items(&self) -> impl Iterator<Item = &Item> {
+    pub(crate) fn inner_items(&self) -> impl Iterator<Item = &Item> {
         match self {
             StructItem(s) => s.fields.iter(),
             UnionItem(u) => u.fields.iter(),
@@ -813,12 +813,12 @@ impl ItemKind {
 }
 
 #[derive(Clone, Debug)]
-crate struct Module {
-    crate items: Vec<Item>,
-    crate span: Span,
+pub(crate) struct Module {
+    pub(crate) items: Vec<Item>,
+    pub(crate) span: Span,
 }
 
-crate trait AttributesExt {
+pub(crate) trait AttributesExt {
     type AttributeIterator<'a>: Iterator<Item = ast::NestedMetaItem>
     where
         Self: 'a;
@@ -949,7 +949,7 @@ impl AttributesExt for [ast::Attribute] {
     }
 }
 
-crate trait NestedAttributesExt {
+pub(crate) trait NestedAttributesExt {
     /// Returns `true` if the attribute list contains a specific `word`
     fn has_word(self, word: Symbol) -> bool
     where
@@ -978,16 +978,16 @@ impl<I: Iterator<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)]
-crate struct DocFragment {
-    crate span: rustc_span::Span,
+pub(crate) struct DocFragment {
+    pub(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.
-    crate parent_module: Option<DefId>,
-    crate doc: Symbol,
-    crate kind: DocFragmentKind,
-    crate indent: usize,
+    pub(crate) parent_module: Option<DefId>,
+    pub(crate) doc: Symbol,
+    pub(crate) kind: DocFragmentKind,
+    pub(crate) indent: usize,
 }
 
 // `DocFragment` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -995,7 +995,7 @@ crate struct DocFragment {
 rustc_data_structures::static_assert_size!(DocFragment, 32);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
-crate enum DocFragmentKind {
+pub(crate) enum DocFragmentKind {
     /// A doc fragment created from a `///` or `//!` doc comment.
     SugaredDoc,
     /// A doc fragment created from a "raw" `#[doc=""]` attribute.
@@ -1027,7 +1027,7 @@ fn add_doc_fragment(out: &mut String, frag: &DocFragment) {
 
 /// Collapse a collection of [`DocFragment`]s into one string,
 /// handling indentation and newlines as needed.
-crate fn collapse_doc_fragments(doc_strings: &[DocFragment]) -> String {
+pub(crate) fn collapse_doc_fragments(doc_strings: &[DocFragment]) -> String {
     let mut acc = String::new();
     for frag in doc_strings {
         add_doc_fragment(&mut acc, frag);
@@ -1120,44 +1120,44 @@ fn unindent_doc_fragments(docs: &mut Vec<DocFragment>) {
 ///
 /// This link will be turned into a rendered link by [`Item::links`].
 #[derive(Clone, Debug, PartialEq, Eq)]
-crate struct ItemLink {
+pub(crate) struct ItemLink {
     /// The original link written in the markdown
-    crate link: String,
+    pub(crate) link: String,
     /// The link text displayed in the HTML.
     ///
     /// This may not be the same as `link` if there was a disambiguator
     /// in an intra-doc link (e.g. \[`fn@f`\])
-    crate link_text: String,
-    crate did: DefId,
+    pub(crate) link_text: String,
+    pub(crate) did: DefId,
     /// The url fragment to append to the link
-    crate fragment: Option<UrlFragment>,
+    pub(crate) fragment: Option<UrlFragment>,
 }
 
 pub struct RenderedLink {
     /// The text the link was original written as.
     ///
     /// This could potentially include disambiguators and backticks.
-    crate original_text: String,
+    pub(crate) original_text: String,
     /// The text to display in the HTML
-    crate new_text: String,
+    pub(crate) new_text: String,
     /// The URL to put in the `href`
-    crate href: String,
+    pub(crate) href: String,
 }
 
 /// The attributes on an [`Item`], including attributes like `#[derive(...)]` and `#[inline]`,
 /// as well as doc comments.
 #[derive(Clone, Debug, Default)]
-crate struct Attributes {
-    crate doc_strings: Vec<DocFragment>,
-    crate other_attrs: Vec<ast::Attribute>,
+pub(crate) struct Attributes {
+    pub(crate) doc_strings: Vec<DocFragment>,
+    pub(crate) other_attrs: Vec<ast::Attribute>,
 }
 
 impl Attributes {
-    crate fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::NestedMetaItem> + '_ {
+    pub(crate) fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::NestedMetaItem> + '_ {
         self.other_attrs.lists(name)
     }
 
-    crate fn has_doc_flag(&self, flag: Symbol) -> bool {
+    pub(crate) fn has_doc_flag(&self, flag: Symbol) -> bool {
         for attr in &self.other_attrs {
             if !attr.has_name(sym::doc) {
                 continue;
@@ -1173,7 +1173,7 @@ impl Attributes {
         false
     }
 
-    crate fn from_ast(
+    pub(crate) fn from_ast(
         attrs: &[ast::Attribute],
         additional_attrs: Option<(&[ast::Attribute], DefId)>,
     ) -> Attributes {
@@ -1185,7 +1185,7 @@ impl Attributes {
         Attributes::from_ast_iter(attrs1.chain(attrs2), false)
     }
 
-    crate fn from_ast_iter<'a>(
+    pub(crate) fn from_ast_iter<'a>(
         attrs: impl Iterator<Item = (&'a ast::Attribute, Option<DefId>)>,
         doc_only: bool,
     ) -> Attributes {
@@ -1214,7 +1214,7 @@ impl Attributes {
 
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
-    crate fn doc_value(&self) -> Option<String> {
+    pub(crate) fn doc_value(&self) -> Option<String> {
         let mut iter = self.doc_strings.iter();
 
         let ori = iter.next()?;
@@ -1232,7 +1232,7 @@ impl Attributes {
     ///
     /// The last newline is not trimmed so the produced strings are reusable between
     /// early and late doc link resolution regardless of their position.
-    crate fn prepare_to_doc_link_resolution(&self) -> FxHashMap<Option<DefId>, String> {
+    pub(crate) fn prepare_to_doc_link_resolution(&self) -> FxHashMap<Option<DefId>, String> {
         let mut res = FxHashMap::default();
         for fragment in &self.doc_strings {
             let out_str = res.entry(fragment.parent_module).or_default();
@@ -1243,7 +1243,7 @@ impl Attributes {
 
     /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
     /// with newlines.
-    crate fn collapsed_doc_value(&self) -> Option<String> {
+    pub(crate) fn collapsed_doc_value(&self) -> Option<String> {
         if self.doc_strings.is_empty() {
             None
         } else {
@@ -1251,7 +1251,7 @@ impl Attributes {
         }
     }
 
-    crate fn get_doc_aliases(&self) -> Box<[Symbol]> {
+    pub(crate) fn get_doc_aliases(&self) -> Box<[Symbol]> {
         let mut aliases = FxHashSet::default();
 
         for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) {
@@ -1286,13 +1286,13 @@ impl PartialEq for Attributes {
 impl Eq for Attributes {}
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate enum GenericBound {
+pub(crate) enum GenericBound {
     TraitBound(PolyTrait, hir::TraitBoundModifier),
     Outlives(Lifetime),
 }
 
 impl GenericBound {
-    crate fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
+    pub(crate) fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
         let did = cx.tcx.require_lang_item(LangItem::Sized, None);
         let empty = cx.tcx.intern_substs(&[]);
         let path = external_path(cx, did, false, vec![], empty);
@@ -1303,7 +1303,7 @@ impl GenericBound {
         )
     }
 
-    crate fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
+    pub(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 Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() {
@@ -1313,14 +1313,14 @@ impl GenericBound {
         false
     }
 
-    crate fn get_poly_trait(&self) -> Option<PolyTrait> {
+    pub(crate) fn get_poly_trait(&self) -> Option<PolyTrait> {
         if let GenericBound::TraitBound(ref p, _) = *self {
             return Some(p.clone());
         }
         None
     }
 
-    crate fn get_trait_path(&self) -> Option<Path> {
+    pub(crate) fn get_trait_path(&self) -> Option<Path> {
         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
             Some(trait_.clone())
         } else {
@@ -1330,27 +1330,27 @@ impl GenericBound {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct Lifetime(pub Symbol);
+pub(crate) struct Lifetime(pub Symbol);
 
 impl Lifetime {
-    crate fn statik() -> Lifetime {
+    pub(crate) fn statik() -> Lifetime {
         Lifetime(kw::StaticLifetime)
     }
 
-    crate fn elided() -> Lifetime {
+    pub(crate) fn elided() -> Lifetime {
         Lifetime(kw::UnderscoreLifetime)
     }
 }
 
 #[derive(Clone, Debug)]
-crate enum WherePredicate {
+pub(crate) enum WherePredicate {
     BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<Lifetime> },
     RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
     EqPredicate { lhs: Type, rhs: Term },
 }
 
 impl WherePredicate {
-    crate fn get_bounds(&self) -> Option<&[GenericBound]> {
+    pub(crate) fn get_bounds(&self) -> Option<&[GenericBound]> {
         match *self {
             WherePredicate::BoundPredicate { ref bounds, .. } => Some(bounds),
             WherePredicate::RegionPredicate { ref bounds, .. } => Some(bounds),
@@ -1360,22 +1360,22 @@ impl WherePredicate {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate enum GenericParamDefKind {
+pub(crate) enum GenericParamDefKind {
     Lifetime { outlives: Vec<Lifetime> },
     Type { did: DefId, bounds: Vec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
     Const { did: DefId, ty: Box<Type>, default: Option<Box<String>> },
 }
 
 impl GenericParamDefKind {
-    crate fn is_type(&self) -> bool {
+    pub(crate) fn is_type(&self) -> bool {
         matches!(self, GenericParamDefKind::Type { .. })
     }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct GenericParamDef {
-    crate name: Symbol,
-    crate kind: GenericParamDefKind,
+pub(crate) struct GenericParamDef {
+    pub(crate) name: Symbol,
+    pub(crate) kind: GenericParamDefKind,
 }
 
 // `GenericParamDef` is used in many places. Make sure it doesn't unintentionally get bigger.
@@ -1383,18 +1383,18 @@ crate struct GenericParamDef {
 rustc_data_structures::static_assert_size!(GenericParamDef, 56);
 
 impl GenericParamDef {
-    crate fn is_synthetic_type_param(&self) -> bool {
+    pub(crate) fn is_synthetic_type_param(&self) -> bool {
         match self.kind {
             GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false,
             GenericParamDefKind::Type { synthetic, .. } => synthetic,
         }
     }
 
-    crate fn is_type(&self) -> bool {
+    pub(crate) fn is_type(&self) -> bool {
         self.kind.is_type()
     }
 
-    crate fn get_bounds(&self) -> Option<&[GenericBound]> {
+    pub(crate) fn get_bounds(&self) -> Option<&[GenericBound]> {
         match self.kind {
             GenericParamDefKind::Type { ref bounds, .. } => Some(bounds),
             _ => None,
@@ -1404,26 +1404,26 @@ impl GenericParamDef {
 
 // maybe use a Generic enum and use Vec<Generic>?
 #[derive(Clone, Debug, Default)]
-crate struct Generics {
-    crate params: Vec<GenericParamDef>,
-    crate where_predicates: Vec<WherePredicate>,
+pub(crate) struct Generics {
+    pub(crate) params: Vec<GenericParamDef>,
+    pub(crate) where_predicates: Vec<WherePredicate>,
 }
 
 #[derive(Clone, Debug)]
-crate struct Function {
-    crate decl: FnDecl,
-    crate generics: Generics,
+pub(crate) struct Function {
+    pub(crate) decl: FnDecl,
+    pub(crate) generics: Generics,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct FnDecl {
-    crate inputs: Arguments,
-    crate output: FnRetTy,
-    crate c_variadic: bool,
+pub(crate) struct FnDecl {
+    pub(crate) inputs: Arguments,
+    pub(crate) output: FnRetTy,
+    pub(crate) c_variadic: bool,
 }
 
 impl FnDecl {
-    crate fn self_type(&self) -> Option<SelfTy> {
+    pub(crate) fn self_type(&self) -> Option<SelfTy> {
         self.inputs.values.get(0).and_then(|v| v.to_self())
     }
 
@@ -1436,7 +1436,7 @@ impl FnDecl {
     ///
     /// This function will panic if the return type does not match the expected sugaring for async
     /// functions.
-    crate fn sugared_async_return_type(&self) -> FnRetTy {
+    pub(crate) fn sugared_async_return_type(&self) -> FnRetTy {
         match &self.output {
             FnRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] {
                 GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
@@ -1453,28 +1453,28 @@ impl FnDecl {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct Arguments {
-    crate values: Vec<Argument>,
+pub(crate) struct Arguments {
+    pub(crate) values: Vec<Argument>,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct Argument {
-    crate type_: Type,
-    crate name: Symbol,
+pub(crate) struct Argument {
+    pub(crate) type_: Type,
+    pub(crate) name: Symbol,
     /// This field is used to represent "const" arguments from the `rustc_legacy_const_generics`
     /// feature. More information in <https://github.com/rust-lang/rust/issues/83167>.
-    crate is_const: bool,
+    pub(crate) is_const: bool,
 }
 
 #[derive(Clone, PartialEq, Debug)]
-crate enum SelfTy {
+pub(crate) enum SelfTy {
     SelfValue,
     SelfBorrowed(Option<Lifetime>, Mutability),
     SelfExplicit(Type),
 }
 
 impl Argument {
-    crate fn to_self(&self) -> Option<SelfTy> {
+    pub(crate) fn to_self(&self) -> Option<SelfTy> {
         if self.name != kw::SelfLower {
             return None;
         }
@@ -1491,13 +1491,13 @@ impl Argument {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate enum FnRetTy {
+pub(crate) enum FnRetTy {
     Return(Type),
     DefaultReturn,
 }
 
 impl FnRetTy {
-    crate fn as_return(&self) -> Option<&Type> {
+    pub(crate) fn as_return(&self) -> Option<&Type> {
         match self {
             Return(ret) => Some(ret),
             DefaultReturn => None,
@@ -1506,30 +1506,30 @@ impl FnRetTy {
 }
 
 #[derive(Clone, Debug)]
-crate struct Trait {
-    crate unsafety: hir::Unsafety,
-    crate items: Vec<Item>,
-    crate generics: Generics,
-    crate bounds: Vec<GenericBound>,
-    crate is_auto: bool,
+pub(crate) struct Trait {
+    pub(crate) unsafety: hir::Unsafety,
+    pub(crate) items: Vec<Item>,
+    pub(crate) generics: Generics,
+    pub(crate) bounds: Vec<GenericBound>,
+    pub(crate) is_auto: bool,
 }
 
 #[derive(Clone, Debug)]
-crate struct TraitAlias {
-    crate generics: Generics,
-    crate bounds: Vec<GenericBound>,
+pub(crate) struct TraitAlias {
+    pub(crate) generics: Generics,
+    pub(crate) bounds: Vec<GenericBound>,
 }
 
 /// A trait reference, which may have higher ranked lifetimes.
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct PolyTrait {
-    crate trait_: Path,
-    crate generic_params: Vec<GenericParamDef>,
+pub(crate) struct PolyTrait {
+    pub(crate) trait_: Path,
+    pub(crate) generic_params: Vec<GenericParamDef>,
 }
 
 /// Rustdoc's representation of types, mostly based on the [`hir::Ty`].
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate enum Type {
+pub(crate) enum Type {
     /// A named type, which could be a trait.
     ///
     /// This is mostly Rustdoc's version of [`hir::Path`].
@@ -1580,7 +1580,7 @@ rustc_data_structures::static_assert_size!(Type, 80);
 
 impl Type {
     /// When comparing types for equality, it can help to ignore `&` wrapping.
-    crate fn without_borrowed_ref(&self) -> &Type {
+    pub(crate) fn without_borrowed_ref(&self) -> &Type {
         let mut result = self;
         while let Type::BorrowedRef { type_, .. } = result {
             result = &*type_;
@@ -1591,7 +1591,7 @@ impl Type {
     /// Check if two types are "potentially the same".
     /// This is different from `Eq`, because it knows that things like
     /// `Placeholder` are possible matches for everything.
-    crate fn is_same(&self, other: &Self, cache: &Cache) -> bool {
+    pub(crate) fn is_same(&self, other: &Self, cache: &Cache) -> bool {
         match (self, other) {
             // Recursive cases.
             (Type::Tuple(a), Type::Tuple(b)) => {
@@ -1618,7 +1618,7 @@ impl Type {
         }
     }
 
-    crate fn primitive_type(&self) -> Option<PrimitiveType> {
+    pub(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),
@@ -1637,36 +1637,36 @@ impl Type {
     }
 
     /// Checks if this is a `T::Name` path for an associated type.
-    crate fn is_assoc_ty(&self) -> bool {
+    pub(crate) fn is_assoc_ty(&self) -> bool {
         match self {
             Type::Path { path, .. } => path.is_assoc_ty(),
             _ => false,
         }
     }
 
-    crate fn is_self_type(&self) -> bool {
+    pub(crate) fn is_self_type(&self) -> bool {
         match *self {
             Generic(name) => name == kw::SelfUpper,
             _ => false,
         }
     }
 
-    crate fn generics(&self) -> Option<Vec<&Type>> {
+    pub(crate) fn generics(&self) -> Option<Vec<&Type>> {
         match self {
             Type::Path { path, .. } => path.generics(),
             _ => None,
         }
     }
 
-    crate fn is_full_generic(&self) -> bool {
+    pub(crate) fn is_full_generic(&self) -> bool {
         matches!(self, Type::Generic(_))
     }
 
-    crate fn is_primitive(&self) -> bool {
+    pub(crate) fn is_primitive(&self) -> bool {
         self.primitive_type().is_some()
     }
 
-    crate fn projection(&self) -> Option<(&Type, DefId, PathSegment)> {
+    pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> {
         if let QPath { self_type, trait_, assoc, .. } = self {
             Some((&self_type, trait_.def_id(), *assoc.clone()))
         } else {
@@ -1701,7 +1701,7 @@ impl Type {
     /// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s.
     ///
     /// [clean]: crate::clean
-    crate fn def_id(&self, cache: &Cache) -> Option<DefId> {
+    pub(crate) fn def_id(&self, cache: &Cache) -> Option<DefId> {
         self.inner_def_id(Some(cache))
     }
 }
@@ -1713,7 +1713,7 @@ impl Type {
 /// N.B. This has to be different from [`hir::PrimTy`] because it also includes types that aren't
 /// paths, like [`Self::Unit`].
 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
-crate enum PrimitiveType {
+pub(crate) enum PrimitiveType {
     Isize,
     I8,
     I16,
@@ -1743,7 +1743,7 @@ crate enum PrimitiveType {
 
 type SimplifiedTypes = FxHashMap<PrimitiveType, ArrayVec<SimplifiedType, 2>>;
 impl PrimitiveType {
-    crate fn from_hir(prim: hir::PrimTy) -> PrimitiveType {
+    pub(crate) fn from_hir(prim: hir::PrimTy) -> PrimitiveType {
         use ast::{FloatTy, IntTy, UintTy};
         match prim {
             hir::PrimTy::Int(IntTy::Isize) => PrimitiveType::Isize,
@@ -1766,7 +1766,7 @@ impl PrimitiveType {
         }
     }
 
-    crate fn from_symbol(s: Symbol) -> Option<PrimitiveType> {
+    pub(crate) fn from_symbol(s: Symbol) -> Option<PrimitiveType> {
         match s {
             sym::isize => Some(PrimitiveType::Isize),
             sym::i8 => Some(PrimitiveType::I8),
@@ -1797,7 +1797,7 @@ impl PrimitiveType {
         }
     }
 
-    crate fn simplified_types() -> &'static SimplifiedTypes {
+    pub(crate) fn simplified_types() -> &'static SimplifiedTypes {
         use ty::fast_reject::SimplifiedTypeGen::*;
         use ty::{FloatTy, IntTy, UintTy};
         use PrimitiveType::*;
@@ -1842,7 +1842,7 @@ impl PrimitiveType {
         })
     }
 
-    crate fn impls<'tcx>(&self, tcx: TyCtxt<'tcx>) -> impl Iterator<Item = DefId> + 'tcx {
+    pub(crate) fn impls<'tcx>(&self, tcx: TyCtxt<'tcx>) -> impl Iterator<Item = DefId> + 'tcx {
         Self::simplified_types()
             .get(self)
             .into_iter()
@@ -1851,7 +1851,7 @@ impl PrimitiveType {
             .copied()
     }
 
-    crate fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> + '_ {
+    pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> + '_ {
         Self::simplified_types()
             .values()
             .flatten()
@@ -1859,7 +1859,7 @@ impl PrimitiveType {
             .copied()
     }
 
-    crate fn as_sym(&self) -> Symbol {
+    pub(crate) fn as_sym(&self) -> Symbol {
         use PrimitiveType::*;
         match self {
             Isize => sym::isize,
@@ -1897,7 +1897,7 @@ impl PrimitiveType {
     /// but otherwise, if multiple crates define the same primitive, there is no guarantee of which will be picked.
     /// In particular, if a crate depends on both `std` and another crate that also defines `doc(primitive)`, then
     /// it's entirely random whether `std` or the other crate is picked. (no_std crates are usually fine unless multiple dependencies define a primitive.)
-    crate fn primitive_locations(tcx: TyCtxt<'_>) -> &FxHashMap<PrimitiveType, DefId> {
+    pub(crate) fn primitive_locations(tcx: TyCtxt<'_>) -> &FxHashMap<PrimitiveType, DefId> {
         static PRIMITIVE_LOCATIONS: OnceCell<FxHashMap<PrimitiveType, DefId>> = OnceCell::new();
         PRIMITIVE_LOCATIONS.get_or_init(|| {
             let mut primitive_locations = FxHashMap::default();
@@ -2008,7 +2008,7 @@ impl From<hir::PrimTy> for PrimitiveType {
 }
 
 #[derive(Copy, Clone, Debug)]
-crate enum Visibility {
+pub(crate) enum Visibility {
     /// `pub`
     Public,
     /// Visibility inherited from parent.
@@ -2020,45 +2020,45 @@ crate enum Visibility {
 }
 
 impl Visibility {
-    crate fn is_public(&self) -> bool {
+    pub(crate) fn is_public(&self) -> bool {
         matches!(self, Visibility::Public)
     }
 }
 
 #[derive(Clone, Debug)]
-crate struct Struct {
-    crate struct_type: CtorKind,
-    crate generics: Generics,
-    crate fields: Vec<Item>,
-    crate fields_stripped: bool,
+pub(crate) struct Struct {
+    pub(crate) struct_type: CtorKind,
+    pub(crate) generics: Generics,
+    pub(crate) fields: Vec<Item>,
+    pub(crate) fields_stripped: bool,
 }
 
 #[derive(Clone, Debug)]
-crate struct Union {
-    crate generics: Generics,
-    crate fields: Vec<Item>,
-    crate fields_stripped: bool,
+pub(crate) struct Union {
+    pub(crate) generics: Generics,
+    pub(crate) fields: Vec<Item>,
+    pub(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)]
-crate struct VariantStruct {
-    crate struct_type: CtorKind,
-    crate fields: Vec<Item>,
-    crate fields_stripped: bool,
+pub(crate) struct VariantStruct {
+    pub(crate) struct_type: CtorKind,
+    pub(crate) fields: Vec<Item>,
+    pub(crate) fields_stripped: bool,
 }
 
 #[derive(Clone, Debug)]
-crate struct Enum {
-    crate variants: IndexVec<VariantIdx, Item>,
-    crate generics: Generics,
-    crate variants_stripped: bool,
+pub(crate) struct Enum {
+    pub(crate) variants: IndexVec<VariantIdx, Item>,
+    pub(crate) generics: Generics,
+    pub(crate) variants_stripped: bool,
 }
 
 #[derive(Clone, Debug)]
-crate enum Variant {
+pub(crate) enum Variant {
     CLike,
     Tuple(Vec<Item>),
     Struct(VariantStruct),
@@ -2067,63 +2067,63 @@ crate enum Variant {
 /// Small wrapper around [`rustc_span::Span`] that adds helper methods
 /// and enforces calling [`rustc_span::Span::source_callsite()`].
 #[derive(Copy, Clone, Debug)]
-crate struct Span(rustc_span::Span);
+pub(crate) struct Span(rustc_span::Span);
 
 impl Span {
     /// Wraps a [`rustc_span::Span`]. In case this span is the result of a macro expansion, the
     /// span will be updated to point to the macro invocation instead of the macro definition.
     ///
     /// (See rust-lang/rust#39726)
-    crate fn new(sp: rustc_span::Span) -> Self {
+    pub(crate) fn new(sp: rustc_span::Span) -> Self {
         Self(sp.source_callsite())
     }
 
-    crate fn inner(&self) -> rustc_span::Span {
+    pub(crate) fn inner(&self) -> rustc_span::Span {
         self.0
     }
 
-    crate fn dummy() -> Self {
+    pub(crate) fn dummy() -> Self {
         Self(rustc_span::DUMMY_SP)
     }
 
-    crate fn is_dummy(&self) -> bool {
+    pub(crate) fn is_dummy(&self) -> bool {
         self.0.is_dummy()
     }
 
-    crate fn filename(&self, sess: &Session) -> FileName {
+    pub(crate) fn filename(&self, sess: &Session) -> FileName {
         sess.source_map().span_to_filename(self.0)
     }
 
-    crate fn lo(&self, sess: &Session) -> Loc {
+    pub(crate) fn lo(&self, sess: &Session) -> Loc {
         sess.source_map().lookup_char_pos(self.0.lo())
     }
 
-    crate fn hi(&self, sess: &Session) -> Loc {
+    pub(crate) fn hi(&self, sess: &Session) -> Loc {
         sess.source_map().lookup_char_pos(self.0.hi())
     }
 
-    crate fn cnum(&self, sess: &Session) -> CrateNum {
+    pub(crate) fn cnum(&self, sess: &Session) -> CrateNum {
         // FIXME: is there a time when the lo and hi crate would be different?
         self.lo(sess).file.cnum
     }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct Path {
-    crate res: Res,
-    crate segments: Vec<PathSegment>,
+pub(crate) struct Path {
+    pub(crate) res: Res,
+    pub(crate) segments: Vec<PathSegment>,
 }
 
 impl Path {
-    crate fn def_id(&self) -> DefId {
+    pub(crate) fn def_id(&self) -> DefId {
         self.res.def_id()
     }
 
-    crate fn last(&self) -> Symbol {
+    pub(crate) fn last(&self) -> Symbol {
         self.segments.last().expect("segments were empty").name
     }
 
-    crate fn whole_name(&self) -> String {
+    pub(crate) fn whole_name(&self) -> String {
         self.segments
             .iter()
             .map(|s| if s.name == kw::PathRoot { String::new() } else { s.name.to_string() })
@@ -2132,7 +2132,7 @@ impl Path {
     }
 
     /// Checks if this is a `T::Name` path for an associated type.
-    crate fn is_assoc_ty(&self) -> bool {
+    pub(crate) fn is_assoc_ty(&self) -> bool {
         match self.res {
             Res::SelfTy { .. } if self.segments.len() != 1 => true,
             Res::Def(DefKind::TyParam, _) if self.segments.len() != 1 => true,
@@ -2141,7 +2141,7 @@ impl Path {
         }
     }
 
-    crate fn generics(&self) -> Option<Vec<&Type>> {
+    pub(crate) fn generics(&self) -> Option<Vec<&Type>> {
         self.segments.last().and_then(|seg| {
             if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
                 Some(
@@ -2158,7 +2158,7 @@ impl Path {
         })
     }
 
-    crate fn bindings(&self) -> Option<&[TypeBinding]> {
+    pub(crate) fn bindings(&self) -> Option<&[TypeBinding]> {
         self.segments.last().and_then(|seg| {
             if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
                 Some(&**bindings)
@@ -2170,7 +2170,7 @@ impl Path {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate enum GenericArg {
+pub(crate) enum GenericArg {
     Lifetime(Lifetime),
     Type(Type),
     Const(Box<Constant>),
@@ -2183,7 +2183,7 @@ crate enum GenericArg {
 rustc_data_structures::static_assert_size!(GenericArg, 88);
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate enum GenericArgs {
+pub(crate) enum GenericArgs {
     AngleBracketed { args: Vec<GenericArg>, bindings: ThinVec<TypeBinding> },
     Parenthesized { inputs: Vec<Type>, output: Option<Box<Type>> },
 }
@@ -2194,9 +2194,9 @@ crate enum GenericArgs {
 rustc_data_structures::static_assert_size!(GenericArgs, 40);
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct PathSegment {
-    crate name: Symbol,
-    crate args: GenericArgs,
+pub(crate) struct PathSegment {
+    pub(crate) name: Symbol,
+    pub(crate) args: GenericArgs,
 }
 
 // `PathSegment` usually occurs multiple times in every `Path`, so its size can
@@ -2205,53 +2205,53 @@ crate struct PathSegment {
 rustc_data_structures::static_assert_size!(PathSegment, 48);
 
 #[derive(Clone, Debug)]
-crate struct Typedef {
-    crate type_: Type,
-    crate generics: Generics,
+pub(crate) struct Typedef {
+    pub(crate) type_: Type,
+    pub(crate) generics: Generics,
     /// `type_` can come from either the HIR or from metadata. If it comes from HIR, it may be a type
     /// alias instead of the final type. This will always have the final type, regardless of whether
     /// `type_` came from HIR or from metadata.
     ///
     /// If `item_type.is_none()`, `type_` is guaranteed to come from metadata (and therefore hold the
     /// final type).
-    crate item_type: Option<Type>,
+    pub(crate) item_type: Option<Type>,
 }
 
 #[derive(Clone, Debug)]
-crate struct OpaqueTy {
-    crate bounds: Vec<GenericBound>,
-    crate generics: Generics,
+pub(crate) struct OpaqueTy {
+    pub(crate) bounds: Vec<GenericBound>,
+    pub(crate) generics: Generics,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct BareFunctionDecl {
-    crate unsafety: hir::Unsafety,
-    crate generic_params: Vec<GenericParamDef>,
-    crate decl: FnDecl,
-    crate abi: Abi,
+pub(crate) struct BareFunctionDecl {
+    pub(crate) unsafety: hir::Unsafety,
+    pub(crate) generic_params: Vec<GenericParamDef>,
+    pub(crate) decl: FnDecl,
+    pub(crate) abi: Abi,
 }
 
 #[derive(Clone, Debug)]
-crate struct Static {
-    crate type_: Type,
-    crate mutability: Mutability,
-    crate expr: Option<BodyId>,
+pub(crate) struct Static {
+    pub(crate) type_: Type,
+    pub(crate) mutability: Mutability,
+    pub(crate) expr: Option<BodyId>,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
-crate struct Constant {
-    crate type_: Type,
-    crate kind: ConstantKind,
+pub(crate) struct Constant {
+    pub(crate) type_: Type,
+    pub(crate) kind: ConstantKind,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
-crate enum Term {
+pub(crate) enum Term {
     Type(Type),
     Constant(Constant),
 }
 
 impl Term {
-    crate fn ty(&self) -> Option<&Type> {
+    pub(crate) fn ty(&self) -> Option<&Type> {
         if let Term::Type(ty) = self { Some(ty) } else { None }
     }
 }
@@ -2263,7 +2263,7 @@ impl From<Type> for Term {
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
-crate enum ConstantKind {
+pub(crate) enum ConstantKind {
     /// This is the wrapper around `ty::Const` for a non-local constant. Because it doesn't have a
     /// `BodyId`, we need to handle it on its own.
     ///
@@ -2281,21 +2281,21 @@ crate enum ConstantKind {
 }
 
 impl Constant {
-    crate fn expr(&self, tcx: TyCtxt<'_>) -> String {
+    pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> String {
         self.kind.expr(tcx)
     }
 
-    crate fn value(&self, tcx: TyCtxt<'_>) -> Option<String> {
+    pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> Option<String> {
         self.kind.value(tcx)
     }
 
-    crate fn is_literal(&self, tcx: TyCtxt<'_>) -> bool {
+    pub(crate) fn is_literal(&self, tcx: TyCtxt<'_>) -> bool {
         self.kind.is_literal(tcx)
     }
 }
 
 impl ConstantKind {
-    crate fn expr(&self, tcx: TyCtxt<'_>) -> String {
+    pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> String {
         match *self {
             ConstantKind::TyConst { ref expr } => expr.clone(),
             ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id),
@@ -2305,7 +2305,7 @@ impl ConstantKind {
         }
     }
 
-    crate fn value(&self, tcx: TyCtxt<'_>) -> Option<String> {
+    pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> Option<String> {
         match *self {
             ConstantKind::TyConst { .. } | ConstantKind::Anonymous { .. } => None,
             ConstantKind::Extern { def_id } | ConstantKind::Local { def_id, .. } => {
@@ -2314,7 +2314,7 @@ impl ConstantKind {
         }
     }
 
-    crate fn is_literal(&self, tcx: TyCtxt<'_>) -> bool {
+    pub(crate) fn is_literal(&self, tcx: TyCtxt<'_>) -> bool {
         match *self {
             ConstantKind::TyConst { .. } => false,
             ConstantKind::Extern { def_id } => def_id.as_local().map_or(false, |def_id| {
@@ -2328,18 +2328,18 @@ impl ConstantKind {
 }
 
 #[derive(Clone, Debug)]
-crate struct Impl {
-    crate unsafety: hir::Unsafety,
-    crate generics: Generics,
-    crate trait_: Option<Path>,
-    crate for_: Type,
-    crate items: Vec<Item>,
-    crate polarity: ty::ImplPolarity,
-    crate kind: ImplKind,
+pub(crate) struct Impl {
+    pub(crate) unsafety: hir::Unsafety,
+    pub(crate) generics: Generics,
+    pub(crate) trait_: Option<Path>,
+    pub(crate) for_: Type,
+    pub(crate) items: Vec<Item>,
+    pub(crate) polarity: ty::ImplPolarity,
+    pub(crate) kind: ImplKind,
 }
 
 impl Impl {
-    crate fn provided_trait_methods(&self, tcx: TyCtxt<'_>) -> FxHashSet<Symbol> {
+    pub(crate) fn provided_trait_methods(&self, tcx: TyCtxt<'_>) -> FxHashSet<Symbol> {
         self.trait_
             .as_ref()
             .map(|t| t.def_id())
@@ -2349,22 +2349,22 @@ impl Impl {
 }
 
 #[derive(Clone, Debug)]
-crate enum ImplKind {
+pub(crate) enum ImplKind {
     Normal,
     Auto,
     Blanket(Box<Type>),
 }
 
 impl ImplKind {
-    crate fn is_auto(&self) -> bool {
+    pub(crate) fn is_auto(&self) -> bool {
         matches!(self, ImplKind::Auto)
     }
 
-    crate fn is_blanket(&self) -> bool {
+    pub(crate) fn is_blanket(&self) -> bool {
         matches!(self, ImplKind::Blanket(_))
     }
 
-    crate fn as_blanket_ty(&self) -> Option<&Type> {
+    pub(crate) fn as_blanket_ty(&self) -> Option<&Type> {
         match self {
             ImplKind::Blanket(ty) => Some(ty),
             _ => None,
@@ -2373,24 +2373,28 @@ impl ImplKind {
 }
 
 #[derive(Clone, Debug)]
-crate struct Import {
-    crate kind: ImportKind,
-    crate source: ImportSource,
-    crate should_be_displayed: bool,
+pub(crate) struct Import {
+    pub(crate) kind: ImportKind,
+    pub(crate) source: ImportSource,
+    pub(crate) should_be_displayed: bool,
 }
 
 impl Import {
-    crate fn new_simple(name: Symbol, source: ImportSource, should_be_displayed: bool) -> Self {
+    pub(crate) fn new_simple(
+        name: Symbol,
+        source: ImportSource,
+        should_be_displayed: bool,
+    ) -> Self {
         Self { kind: ImportKind::Simple(name), source, should_be_displayed }
     }
 
-    crate fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self {
+    pub(crate) fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self {
         Self { kind: ImportKind::Glob, source, should_be_displayed }
     }
 }
 
 #[derive(Clone, Debug)]
-crate enum ImportKind {
+pub(crate) enum ImportKind {
     // use source as str;
     Simple(Symbol),
     // use source::*;
@@ -2398,38 +2402,38 @@ crate enum ImportKind {
 }
 
 #[derive(Clone, Debug)]
-crate struct ImportSource {
-    crate path: Path,
-    crate did: Option<DefId>,
+pub(crate) struct ImportSource {
+    pub(crate) path: Path,
+    pub(crate) did: Option<DefId>,
 }
 
 #[derive(Clone, Debug)]
-crate struct Macro {
-    crate source: String,
+pub(crate) struct Macro {
+    pub(crate) source: String,
 }
 
 #[derive(Clone, Debug)]
-crate struct ProcMacro {
-    crate kind: MacroKind,
-    crate helpers: Vec<Symbol>,
+pub(crate) struct ProcMacro {
+    pub(crate) kind: MacroKind,
+    pub(crate) helpers: Vec<Symbol>,
 }
 
 /// 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)]
-crate struct TypeBinding {
-    crate assoc: PathSegment,
-    crate kind: TypeBindingKind,
+pub(crate) struct TypeBinding {
+    pub(crate) assoc: PathSegment,
+    pub(crate) kind: TypeBindingKind,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate enum TypeBindingKind {
+pub(crate) enum TypeBindingKind {
     Equality { term: Term },
     Constraint { bounds: Vec<GenericBound> },
 }
 
 impl TypeBinding {
-    crate fn term(&self) -> &Term {
+    pub(crate) fn term(&self) -> &Term {
         match self.kind {
             TypeBindingKind::Equality { ref term } => term,
             _ => panic!("expected equality type binding for parenthesized generic args"),
@@ -2450,18 +2454,18 @@ impl TypeBinding {
 ///
 /// `public_fn`'s docs will show it as returning `Vec<i32>`, since `PrivAlias` is private.
 /// [`SubstParam`] is used to record that `T` should be mapped to `i32`.
-crate enum SubstParam {
+pub(crate) enum SubstParam {
     Type(Type),
     Lifetime(Lifetime),
     Constant(Constant),
 }
 
 impl SubstParam {
-    crate fn as_ty(&self) -> Option<&Type> {
+    pub(crate) fn as_ty(&self) -> Option<&Type> {
         if let Self::Type(ty) = self { Some(ty) } else { None }
     }
 
-    crate fn as_lt(&self) -> Option<&Lifetime> {
+    pub(crate) fn as_lt(&self) -> Option<&Lifetime> {
         if let Self::Lifetime(lt) = self { Some(lt) } else { None }
     }
 }
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index c67b92df643..7a12ea0d5c2 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -25,7 +25,7 @@ use std::mem;
 #[cfg(test)]
 mod tests;
 
-crate fn krate(cx: &mut DocContext<'_>) -> Crate {
+pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
     let module = crate::visit_ast::RustdocVisitor::new(cx).visit();
 
     for &cnum in cx.tcx.crates(()) {
@@ -75,7 +75,7 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
     Crate { module, primitives, external_traits: cx.external_traits.clone() }
 }
 
-crate fn substs_to_args(
+pub(crate) fn substs_to_args(
     cx: &mut DocContext<'_>,
     substs: &[ty::subst::GenericArg<'_>],
     mut skip_first: bool,
@@ -146,7 +146,7 @@ pub(super) fn external_path(
 }
 
 /// Remove the generic arguments from a path.
-crate fn strip_path_generics(mut path: Path) -> Path {
+pub(crate) fn strip_path_generics(mut path: Path) -> Path {
     for ps in path.segments.iter_mut() {
         ps.args = GenericArgs::AngleBracketed { args: vec![], bindings: ThinVec::new() }
     }
@@ -154,7 +154,7 @@ crate fn strip_path_generics(mut path: Path) -> Path {
     path
 }
 
-crate fn qpath_to_string(p: &hir::QPath<'_>) -> String {
+pub(crate) fn qpath_to_string(p: &hir::QPath<'_>) -> String {
     let segments = match *p {
         hir::QPath::Resolved(_, path) => &path.segments,
         hir::QPath::TypeRelative(_, segment) => return segment.ident.to_string(),
@@ -173,7 +173,11 @@ crate fn qpath_to_string(p: &hir::QPath<'_>) -> String {
     s
 }
 
-crate fn build_deref_target_impls(cx: &mut DocContext<'_>, items: &[Item], ret: &mut Vec<Item>) {
+pub(crate) fn build_deref_target_impls(
+    cx: &mut DocContext<'_>,
+    items: &[Item],
+    ret: &mut Vec<Item>,
+) {
     let tcx = cx.tcx;
 
     for item in items {
@@ -196,7 +200,7 @@ crate fn build_deref_target_impls(cx: &mut DocContext<'_>, items: &[Item], ret:
     }
 }
 
-crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
+pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
     use rustc_hir::*;
     debug!("trying to get a name from pattern: {:?}", p);
 
@@ -229,7 +233,7 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
     })
 }
 
-crate fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
+pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
     match n.val() {
         ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => {
             let mut s = if let Some(def) = def.as_local() {
@@ -259,7 +263,7 @@ crate fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
     }
 }
 
-crate fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<String> {
+pub(crate) fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<String> {
     tcx.const_eval_poly(def_id).ok().and_then(|val| {
         let ty = tcx.type_of(def_id);
         match (val, ty.kind()) {
@@ -323,7 +327,7 @@ fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: ty::Const<'_>) -> S
     }
 }
 
-crate fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
+pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
     if let hir::Node::Expr(expr) = tcx.hir().get(hir_id) {
         if let hir::ExprKind::Lit(_) = &expr.kind {
             return true;
@@ -339,7 +343,7 @@ crate fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
     false
 }
 
-crate fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String {
+pub(crate) fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String {
     let hir = tcx.hir();
     let value = &hir.body(body).value;
 
@@ -353,7 +357,7 @@ crate fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String {
 }
 
 /// Given a type Path, resolve it to a Type using the TyCtxt
-crate fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
+pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
     debug!("resolve_type({:?})", path);
 
     match path.res {
@@ -367,7 +371,7 @@ crate fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
     }
 }
 
-crate fn get_auto_trait_and_blanket_impls(
+pub(crate) fn get_auto_trait_and_blanket_impls(
     cx: &mut DocContext<'_>,
     item_def_id: DefId,
 ) -> impl Iterator<Item = Item> {
@@ -389,7 +393,7 @@ crate fn get_auto_trait_and_blanket_impls(
 /// This is later used by [`href()`] to determine the HTML link for the item.
 ///
 /// [`href()`]: crate::html::format::href
-crate fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
+pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
     use DefKind::*;
     debug!("register_res({:?})", res);
 
@@ -428,14 +432,14 @@ crate fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
     did
 }
 
-crate fn resolve_use_source(cx: &mut DocContext<'_>, path: Path) -> ImportSource {
+pub(crate) fn resolve_use_source(cx: &mut DocContext<'_>, path: Path) -> ImportSource {
     ImportSource {
         did: if path.res.opt_def_id().is_none() { None } else { Some(register_res(cx, path.res)) },
         path,
     }
 }
 
-crate fn enter_impl_trait<F, R>(cx: &mut DocContext<'_>, f: F) -> R
+pub(crate) fn enter_impl_trait<F, R>(cx: &mut DocContext<'_>, f: F) -> R
 where
     F: FnOnce(&mut DocContext<'_>) -> R,
 {
@@ -447,7 +451,7 @@ where
 }
 
 /// Find the nearest parent module of a [`DefId`].
-crate fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
+pub(crate) fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
     if def_id.is_top_level_module() {
         // The crate root has no parent. Use it as the root instead.
         Some(def_id)
@@ -474,7 +478,7 @@ crate fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option<De
 ///
 /// This function exists because it runs on `hir::Attributes` whereas the other is a
 /// `clean::Attributes` method.
-crate fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool {
+pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool {
     tcx.get_attrs(did, sym::doc).any(|attr| {
         attr.meta_item_list().map_or(false, |l| rustc_attr::list_contains_name(&l, flag))
     })
@@ -484,7 +488,7 @@ crate fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool {
 /// so that the channel is consistent.
 ///
 /// Set by `bootstrap::Builder::doc_rust_lang_org_channel` in order to keep tests passing on beta/stable.
-crate const DOC_RUST_LANG_ORG_CHANNEL: &str = env!("DOC_RUST_LANG_ORG_CHANNEL");
+pub(crate) const DOC_RUST_LANG_ORG_CHANNEL: &str = env!("DOC_RUST_LANG_ORG_CHANNEL");
 
 /// Render a sequence of macro arms in a format suitable for displaying to the user
 /// as part of an item declaration.
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 1ff2c8191e5..b934a1a59d7 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -31,7 +31,7 @@ use crate::scrape_examples::{AllCallLocations, ScrapeExamplesOptions};
 use crate::theme;
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-crate enum OutputFormat {
+pub(crate) enum OutputFormat {
     Json,
     Html,
 }
@@ -43,7 +43,7 @@ impl Default for OutputFormat {
 }
 
 impl OutputFormat {
-    crate fn is_json(&self) -> bool {
+    pub(crate) fn is_json(&self) -> bool {
         matches!(self, OutputFormat::Json)
     }
 }
@@ -62,100 +62,100 @@ impl TryFrom<&str> for OutputFormat {
 
 /// Configuration options for rustdoc.
 #[derive(Clone)]
-crate struct Options {
+pub(crate) struct Options {
     // Basic options / Options passed directly to rustc
     /// The crate root or Markdown file to load.
-    crate input: PathBuf,
+    pub(crate) input: PathBuf,
     /// The name of the crate being documented.
-    crate crate_name: Option<String>,
+    pub(crate) crate_name: Option<String>,
     /// Whether or not this is a proc-macro crate
-    crate proc_macro_crate: bool,
+    pub(crate) proc_macro_crate: bool,
     /// How to format errors and warnings.
-    crate error_format: ErrorOutputType,
+    pub(crate) error_format: ErrorOutputType,
     /// Library search paths to hand to the compiler.
-    crate libs: Vec<SearchPath>,
+    pub(crate) libs: Vec<SearchPath>,
     /// Library search paths strings to hand to the compiler.
-    crate lib_strs: Vec<String>,
+    pub(crate) lib_strs: Vec<String>,
     /// The list of external crates to link against.
-    crate externs: Externs,
+    pub(crate) externs: Externs,
     /// The list of external crates strings to link against.
-    crate extern_strs: Vec<String>,
+    pub(crate) extern_strs: Vec<String>,
     /// List of `cfg` flags to hand to the compiler. Always includes `rustdoc`.
-    crate cfgs: Vec<String>,
+    pub(crate) cfgs: Vec<String>,
     /// List of check cfg flags to hand to the compiler.
-    crate check_cfgs: Vec<String>,
+    pub(crate) check_cfgs: Vec<String>,
     /// Codegen options to hand to the compiler.
-    crate codegen_options: CodegenOptions,
+    pub(crate) codegen_options: CodegenOptions,
     /// Codegen options strings to hand to the compiler.
-    crate codegen_options_strs: Vec<String>,
+    pub(crate) codegen_options_strs: Vec<String>,
     /// Debugging (`-Z`) options to pass to the compiler.
-    crate debugging_opts: DebuggingOptions,
+    pub(crate) debugging_opts: DebuggingOptions,
     /// Debugging (`-Z`) options strings to pass to the compiler.
-    crate debugging_opts_strs: Vec<String>,
+    pub(crate) debugging_opts_strs: Vec<String>,
     /// The target used to compile the crate against.
-    crate target: TargetTriple,
+    pub(crate) target: TargetTriple,
     /// Edition used when reading the crate. Defaults to "2015". Also used by default when
     /// compiling doctests from the crate.
-    crate edition: Edition,
+    pub(crate) edition: Edition,
     /// The path to the sysroot. Used during the compilation process.
-    crate maybe_sysroot: Option<PathBuf>,
+    pub(crate) maybe_sysroot: Option<PathBuf>,
     /// Lint information passed over the command-line.
-    crate lint_opts: Vec<(String, Level)>,
+    pub(crate) lint_opts: Vec<(String, Level)>,
     /// Whether to ask rustc to describe the lints it knows.
-    crate describe_lints: bool,
+    pub(crate) describe_lints: bool,
     /// What level to cap lints at.
-    crate lint_cap: Option<Level>,
+    pub(crate) lint_cap: Option<Level>,
 
     // Options specific to running doctests
     /// Whether we should run doctests instead of generating docs.
-    crate should_test: bool,
+    pub(crate) should_test: bool,
     /// List of arguments to pass to the test harness, if running tests.
-    crate test_args: Vec<String>,
+    pub(crate) test_args: Vec<String>,
     /// The working directory in which to run tests.
-    crate test_run_directory: Option<PathBuf>,
+    pub(crate) test_run_directory: Option<PathBuf>,
     /// Optional path to persist the doctest executables to, defaults to a
     /// temporary directory if not set.
-    crate persist_doctests: Option<PathBuf>,
+    pub(crate) persist_doctests: Option<PathBuf>,
     /// Runtool to run doctests with
-    crate runtool: Option<String>,
+    pub(crate) runtool: Option<String>,
     /// Arguments to pass to the runtool
-    crate runtool_args: Vec<String>,
+    pub(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
-    crate enable_per_target_ignores: bool,
+    pub(crate) enable_per_target_ignores: bool,
     /// Do not run doctests, compile them if should_test is active.
-    crate no_run: bool,
+    pub(crate) no_run: bool,
 
     /// The path to a rustc-like binary to build tests with. If not set, we
     /// default to loading from `$sysroot/bin/rustc`.
-    crate test_builder: Option<PathBuf>,
+    pub(crate) test_builder: Option<PathBuf>,
 
     // Options that affect the documentation process
     /// Whether to run the `calculate-doc-coverage` pass, which counts the number of public items
     /// with and without documentation.
-    crate show_coverage: bool,
+    pub(crate) show_coverage: bool,
 
     // Options that alter generated documentation pages
     /// Crate version to note on the sidebar of generated docs.
-    crate crate_version: Option<String>,
+    pub(crate) crate_version: Option<String>,
     /// Collected options specific to outputting final pages.
-    crate render_options: RenderOptions,
+    pub(crate) render_options: RenderOptions,
     /// The format that we output when rendering.
     ///
     /// Currently used only for the `--show-coverage` option.
-    crate output_format: OutputFormat,
+    pub(crate) output_format: OutputFormat,
     /// If this option is set to `true`, rustdoc will only run checks and not generate
     /// documentation.
-    crate run_check: bool,
+    pub(crate) run_check: bool,
     /// Whether doctests should emit unused externs
-    crate json_unused_externs: JsonUnusedExterns,
+    pub(crate) json_unused_externs: JsonUnusedExterns,
     /// Whether to skip capturing stdout and stderr of tests.
-    crate nocapture: bool,
+    pub(crate) nocapture: bool,
 
     /// Configuration for scraping examples from the current crate. If this option is Some(..) then
     /// the compiler will scrape examples and not generate documentation.
-    crate scrape_examples_options: Option<ScrapeExamplesOptions>,
+    pub(crate) scrape_examples_options: Option<ScrapeExamplesOptions>,
 }
 
 impl fmt::Debug for Options {
@@ -205,83 +205,83 @@ impl fmt::Debug for Options {
 
 /// Configuration options for the HTML page-creation process.
 #[derive(Clone, Debug)]
-crate struct RenderOptions {
+pub(crate) struct RenderOptions {
     /// Output directory to generate docs into. Defaults to `doc`.
-    crate output: PathBuf,
+    pub(crate) output: PathBuf,
     /// External files to insert into generated pages.
-    crate external_html: ExternalHtml,
+    pub(crate) external_html: ExternalHtml,
     /// A pre-populated `IdMap` with the default headings and any headings added by Markdown files
     /// processed by `external_html`.
-    crate id_map: IdMap,
+    pub(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!
-    crate playground_url: Option<String>,
+    pub(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.
-    crate sort_modules_alphabetically: bool,
+    pub(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.
-    crate themes: Vec<StylePath>,
+    pub(crate) themes: Vec<StylePath>,
     /// If present, CSS file that contains rules to add to the default CSS.
-    crate extension_css: Option<PathBuf>,
+    pub(crate) extension_css: Option<PathBuf>,
     /// A map of crate names to the URL to use instead of querying the crate's `html_root_url`.
-    crate extern_html_root_urls: BTreeMap<String, String>,
+    pub(crate) extern_html_root_urls: BTreeMap<String, String>,
     /// Whether to give precedence to `html_root_url` or `--exten-html-root-url`.
-    crate extern_html_root_takes_precedence: bool,
+    pub(crate) extern_html_root_takes_precedence: bool,
     /// A map of the default settings (values are as for DOM storage API). Keys should lack the
     /// `rustdoc-` prefix.
-    crate default_settings: FxHashMap<String, String>,
+    pub(crate) default_settings: FxHashMap<String, String>,
     /// If present, suffix added to CSS/JavaScript files when referencing them in generated pages.
-    crate resource_suffix: String,
+    pub(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.
-    crate enable_minification: bool,
+    pub(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.
-    crate enable_index_page: bool,
+    pub(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.
-    crate index_page: Option<PathBuf>,
+    pub(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.
-    crate static_root_path: Option<String>,
+    pub(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.
-    crate markdown_no_toc: bool,
+    pub(crate) markdown_no_toc: bool,
     /// Additional CSS files to link in pages generated from standalone Markdown files.
-    crate markdown_css: Vec<String>,
+    pub(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.
-    crate markdown_playground_url: Option<String>,
+    pub(crate) markdown_playground_url: Option<String>,
     /// Document items that have lower than `pub` visibility.
-    crate document_private: bool,
+    pub(crate) document_private: bool,
     /// Document items that have `doc(hidden)`.
-    crate document_hidden: bool,
+    pub(crate) document_hidden: bool,
     /// If `true`, generate a JSON file in the crate folder instead of HTML redirection files.
-    crate generate_redirect_map: bool,
+    pub(crate) generate_redirect_map: bool,
     /// Show the memory layout of types in the docs.
-    crate show_type_layout: bool,
-    crate unstable_features: rustc_feature::UnstableFeatures,
-    crate emit: Vec<EmitType>,
+    pub(crate) show_type_layout: bool,
+    pub(crate) unstable_features: rustc_feature::UnstableFeatures,
+    pub(crate) emit: Vec<EmitType>,
     /// If `true`, HTML source pages will generate links for items to their definition.
-    crate generate_link_to_definition: bool,
+    pub(crate) generate_link_to_definition: bool,
     /// Set of function-call locations to include as examples
-    crate call_locations: AllCallLocations,
+    pub(crate) call_locations: AllCallLocations,
     /// If `true`, Context::init will not emit shared files.
-    crate no_emit_shared: bool,
+    pub(crate) no_emit_shared: bool,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
-crate enum EmitType {
+pub(crate) enum EmitType {
     Unversioned,
     Toolchain,
     InvocationSpecific,
@@ -302,7 +302,7 @@ impl FromStr for EmitType {
 }
 
 impl RenderOptions {
-    crate fn should_emit_crate(&self) -> bool {
+    pub(crate) fn should_emit_crate(&self) -> bool {
         self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific)
     }
 }
@@ -310,7 +310,7 @@ impl RenderOptions {
 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.
-    crate fn from_matches(matches: &getopts::Matches) -> Result<Options, i32> {
+    pub(crate) fn from_matches(matches: &getopts::Matches) -> Result<Options, i32> {
         // Check for unstable options.
         nightly_options::check_nightly_options(matches, &opts());
 
@@ -745,7 +745,7 @@ impl Options {
     }
 
     /// Returns `true` if the file given as `self.input` is a Markdown file.
-    crate fn markdown_input(&self) -> bool {
+    pub(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 17644aeed85..53281bfde2e 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -32,70 +32,74 @@ use crate::formats::cache::Cache;
 use crate::passes::collect_intra_doc_links::PreprocessedMarkdownLink;
 use crate::passes::{self, Condition::*};
 
-crate use rustc_session::config::{DebuggingOptions, Input, Options};
+pub(crate) use rustc_session::config::{DebuggingOptions, Input, Options};
 
-crate struct ResolverCaches {
-    crate markdown_links: Option<FxHashMap<String, Vec<PreprocessedMarkdownLink>>>,
-    crate doc_link_resolutions: FxHashMap<(Symbol, Namespace, DefId), Option<Res<NodeId>>>,
+pub(crate) struct ResolverCaches {
+    pub(crate) markdown_links: Option<FxHashMap<String, Vec<PreprocessedMarkdownLink>>>,
+    pub(crate) doc_link_resolutions: FxHashMap<(Symbol, Namespace, DefId), Option<Res<NodeId>>>,
     /// Traits in scope for a given module.
     /// See `collect_intra_doc_links::traits_implemented_by` for more details.
-    crate traits_in_scope: DefIdMap<Vec<TraitCandidate>>,
-    crate all_traits: Option<Vec<DefId>>,
-    crate all_trait_impls: Option<Vec<DefId>>,
-    crate all_macro_rules: FxHashMap<Symbol, Res<NodeId>>,
+    pub(crate) traits_in_scope: DefIdMap<Vec<TraitCandidate>>,
+    pub(crate) all_traits: Option<Vec<DefId>>,
+    pub(crate) all_trait_impls: Option<Vec<DefId>>,
+    pub(crate) all_macro_rules: FxHashMap<Symbol, Res<NodeId>>,
 }
 
-crate struct DocContext<'tcx> {
-    crate tcx: TyCtxt<'tcx>,
+pub(crate) struct DocContext<'tcx> {
+    pub(crate) tcx: TyCtxt<'tcx>,
     /// Name resolver. Used for intra-doc links.
     ///
     /// The `Rc<RefCell<...>>` wrapping is needed because that is what's returned by
     /// [`rustc_interface::Queries::expansion()`].
     // FIXME: see if we can get rid of this RefCell somehow
-    crate resolver: Rc<RefCell<interface::BoxedResolver>>,
-    crate resolver_caches: ResolverCaches,
+    pub(crate) resolver: Rc<RefCell<interface::BoxedResolver>>,
+    pub(crate) resolver_caches: ResolverCaches,
     /// Used for normalization.
     ///
     /// Most of this logic is copied from rustc_lint::late.
-    crate param_env: ParamEnv<'tcx>,
+    pub(crate) param_env: ParamEnv<'tcx>,
     /// Later on moved through `clean::Crate` into `cache`
-    crate external_traits: Rc<RefCell<FxHashMap<DefId, clean::TraitWithExtraInfo>>>,
+    pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, clean::TraitWithExtraInfo>>>,
     /// Used while populating `external_traits` to ensure we don't process the same trait twice at
     /// the same time.
-    crate active_extern_traits: FxHashSet<DefId>,
+    pub(crate) active_extern_traits: FxHashSet<DefId>,
     // The current set of parameter substitutions,
     // for expanding type aliases at the HIR level:
     /// Table `DefId` of type, lifetime, or const parameter -> substituted type, lifetime, or const
-    crate substs: FxHashMap<DefId, clean::SubstParam>,
+    pub(crate) substs: FxHashMap<DefId, clean::SubstParam>,
     /// Table synthetic type parameter for `impl Trait` in argument position -> bounds
-    crate impl_trait_bounds: FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>,
+    pub(crate) impl_trait_bounds: FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>,
     /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`.
     // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set.
-    crate generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>,
-    crate auto_traits: Vec<DefId>,
+    pub(crate) generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>,
+    pub(crate) auto_traits: Vec<DefId>,
     /// The options given to rustdoc that could be relevant to a pass.
-    crate render_options: RenderOptions,
+    pub(crate) render_options: RenderOptions,
     /// This same cache is used throughout rustdoc, including in [`crate::html::render`].
-    crate cache: Cache,
+    pub(crate) cache: Cache,
     /// Used by [`clean::inline`] to tell if an item has already been inlined.
-    crate inlined: FxHashSet<ItemId>,
+    pub(crate) inlined: FxHashSet<ItemId>,
     /// Used by `calculate_doc_coverage`.
-    crate output_format: OutputFormat,
+    pub(crate) output_format: OutputFormat,
 }
 
 impl<'tcx> DocContext<'tcx> {
-    crate fn sess(&self) -> &'tcx Session {
+    pub(crate) fn sess(&self) -> &'tcx Session {
         self.tcx.sess
     }
 
-    crate fn with_param_env<T, F: FnOnce(&mut Self) -> T>(&mut self, def_id: DefId, f: F) -> T {
+    pub(crate) fn with_param_env<T, F: FnOnce(&mut Self) -> T>(
+        &mut self,
+        def_id: DefId,
+        f: F,
+    ) -> T {
         let old_param_env = mem::replace(&mut self.param_env, self.tcx.param_env(def_id));
         let ret = f(self);
         self.param_env = old_param_env;
         ret
     }
 
-    crate fn enter_resolver<F, R>(&self, f: F) -> R
+    pub(crate) fn enter_resolver<F, R>(&self, f: F) -> R
     where
         F: FnOnce(&mut resolve::Resolver<'_>) -> R,
     {
@@ -104,7 +108,11 @@ impl<'tcx> DocContext<'tcx> {
 
     /// Call the closure with the given parameters set as
     /// the substitutions for a type alias' RHS.
-    crate fn enter_alias<F, R>(&mut self, substs: FxHashMap<DefId, clean::SubstParam>, f: F) -> R
+    pub(crate) fn enter_alias<F, R>(
+        &mut self,
+        substs: FxHashMap<DefId, clean::SubstParam>,
+        f: F,
+    ) -> R
     where
         F: FnOnce(&mut Self) -> R,
     {
@@ -116,7 +124,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.)
-    crate fn as_local_hir_id(tcx: TyCtxt<'_>, item_id: ItemId) -> Option<HirId> {
+    pub(crate) fn as_local_hir_id(tcx: TyCtxt<'_>, item_id: ItemId) -> Option<HirId> {
         match item_id {
             ItemId::DefId(real_id) => {
                 real_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
@@ -126,13 +134,13 @@ impl<'tcx> DocContext<'tcx> {
         }
     }
 
-    crate fn with_all_traits(&mut self, f: impl FnOnce(&mut Self, &[DefId])) {
+    pub(crate) fn with_all_traits(&mut self, f: impl FnOnce(&mut Self, &[DefId])) {
         let all_traits = self.resolver_caches.all_traits.take();
         f(self, all_traits.as_ref().expect("`all_traits` are already borrowed"));
         self.resolver_caches.all_traits = all_traits;
     }
 
-    crate fn with_all_trait_impls(&mut self, f: impl FnOnce(&mut Self, &[DefId])) {
+    pub(crate) fn with_all_trait_impls(&mut self, f: impl FnOnce(&mut Self, &[DefId])) {
         let all_trait_impls = self.resolver_caches.all_trait_impls.take();
         f(self, all_trait_impls.as_ref().expect("`all_trait_impls` are already borrowed"));
         self.resolver_caches.all_trait_impls = all_trait_impls;
@@ -143,7 +151,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.
-crate fn new_handler(
+pub(crate) fn new_handler(
     error_format: ErrorOutputType,
     source_map: Option<Lrc<source_map::SourceMap>>,
     debugging_opts: &DebuggingOptions,
@@ -194,7 +202,7 @@ crate fn new_handler(
 }
 
 /// Parse, resolve, and typecheck the given crate.
-crate fn create_config(
+pub(crate) fn create_config(
     RustdocOptions {
         input,
         crate_name,
@@ -311,7 +319,7 @@ crate fn create_config(
     }
 }
 
-crate fn run_global_ctxt(
+pub(crate) fn run_global_ctxt(
     tcx: TyCtxt<'_>,
     resolver: Rc<RefCell<interface::BoxedResolver>>,
     resolver_caches: ResolverCaches,
@@ -535,7 +543,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)]
-crate enum ImplTraitParam {
+pub(crate) enum ImplTraitParam {
     DefId(DefId),
     ParamIndex(u32),
 }
diff --git a/src/librustdoc/docfs.rs b/src/librustdoc/docfs.rs
index 8dd8eb23df2..be066bdafa1 100644
--- a/src/librustdoc/docfs.rs
+++ b/src/librustdoc/docfs.rs
@@ -15,38 +15,38 @@ use std::path::{Path, PathBuf};
 use std::string::ToString;
 use std::sync::mpsc::Sender;
 
-crate trait PathError {
+pub(crate) trait PathError {
     fn new<S, P: AsRef<Path>>(e: S, path: P) -> Self
     where
         S: ToString + Sized;
 }
 
-crate struct DocFS {
+pub(crate) struct DocFS {
     sync_only: bool,
     errors: Option<Sender<String>>,
 }
 
 impl DocFS {
-    crate fn new(errors: Sender<String>) -> DocFS {
+    pub(crate) fn new(errors: Sender<String>) -> DocFS {
         DocFS { sync_only: false, errors: Some(errors) }
     }
 
-    crate fn set_sync_only(&mut self, sync_only: bool) {
+    pub(crate) fn set_sync_only(&mut self, sync_only: bool) {
         self.sync_only = sync_only;
     }
 
-    crate fn close(&mut self) {
+    pub(crate) fn close(&mut self) {
         self.errors = None;
     }
 
-    crate fn create_dir_all<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
+    pub(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)
     }
 
-    crate fn write<E>(
+    pub(crate) fn write<E>(
         &self,
         path: PathBuf,
         contents: impl 'static + Send + AsRef<[u8]>,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 93ccf60a1de..3005bd9e4a4 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -40,14 +40,14 @@ use crate::passes::span_of_attrs;
 
 /// Options that apply to all doctests in a crate or Markdown file (for `rustdoc foo.md`).
 #[derive(Clone, Default)]
-crate struct GlobalTestOptions {
+pub(crate) struct GlobalTestOptions {
     /// Whether to disable the default `extern crate my_crate;` when creating doctests.
-    crate no_crate_inject: bool,
+    pub(crate) no_crate_inject: bool,
     /// Additional crate-level attributes to add to doctests.
-    crate attrs: Vec<String>,
+    pub(crate) attrs: Vec<String>,
 }
 
-crate fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
+pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
     let input = config::Input::File(options.input.clone());
 
     let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name;
@@ -207,7 +207,11 @@ crate fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
     Ok(())
 }
 
-crate fn run_tests(mut test_args: Vec<String>, nocapture: bool, tests: Vec<test::TestDescAndFn>) {
+pub(crate) fn run_tests(
+    mut test_args: Vec<String>,
+    nocapture: bool,
+    tests: Vec<test::TestDescAndFn>,
+) {
     test_args.insert(0, "rustdoctest".to_string());
     if nocapture {
         test_args.push("--nocapture".to_string());
@@ -488,7 +492,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 as well as if the output stream supports colors or not.
-crate fn make_test(
+pub(crate) fn make_test(
     s: &str,
     crate_name: Option<&str>,
     dont_insert_main: bool,
@@ -840,7 +844,7 @@ fn partition_source(s: &str, edition: Edition) -> (String, String, String) {
     (before, after, crates)
 }
 
-crate trait Tester {
+pub(crate) trait Tester {
     fn add_test(&mut self, test: String, config: LangString, line: usize);
     fn get_line(&self) -> usize {
         0
@@ -848,8 +852,8 @@ crate trait Tester {
     fn register_header(&mut self, _name: &str, _level: u32) {}
 }
 
-crate struct Collector {
-    crate tests: Vec<test::TestDescAndFn>,
+pub(crate) struct Collector {
+    pub(crate) tests: Vec<test::TestDescAndFn>,
 
     // The name of the test displayed to the user, separated by `::`.
     //
@@ -887,7 +891,7 @@ crate struct Collector {
 }
 
 impl Collector {
-    crate fn new(
+    pub(crate) fn new(
         crate_name: Symbol,
         rustdoc_options: RustdocOptions,
         use_headers: bool,
@@ -922,7 +926,7 @@ impl Collector {
         format!("{} - {}(line {})", filename.prefer_local(), item_path, line)
     }
 
-    crate fn set_position(&mut self, position: Span) {
+    pub(crate) fn set_position(&mut self, position: Span) {
         self.position = position;
     }
 
diff --git a/src/librustdoc/error.rs b/src/librustdoc/error.rs
index 8eadbf63f33..6ed7eab1aba 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)]
-crate struct Error {
-    crate file: PathBuf,
-    crate error: String,
+pub(crate) struct Error {
+    pub(crate) file: PathBuf,
+    pub(crate) error: String,
 }
 
 impl error::Error for Error {}
diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs
index 4df48cef593..37fd909c933 100644
--- a/src/librustdoc/externalfiles.rs
+++ b/src/librustdoc/externalfiles.rs
@@ -7,20 +7,20 @@ use std::str;
 use serde::Serialize;
 
 #[derive(Clone, Debug, Serialize)]
-crate struct ExternalHtml {
+pub(crate) struct ExternalHtml {
     /// Content that will be included inline in the `<head>` section of a
     /// rendered Markdown file or generated documentation
-    crate in_header: String,
+    pub(crate) in_header: String,
     /// Content that will be included inline between `<body>` and the content of
     /// a rendered Markdown file or generated documentation
-    crate before_content: String,
+    pub(crate) before_content: String,
     /// Content that will be included inline between the content and `</body>` of
     /// a rendered Markdown file or generated documentation
-    crate after_content: String,
+    pub(crate) after_content: String,
 }
 
 impl ExternalHtml {
-    crate fn load(
+    pub(crate) fn load(
         in_header: &[String],
         before_content: &[String],
         after_content: &[String],
@@ -70,12 +70,12 @@ impl ExternalHtml {
     }
 }
 
-crate enum LoadStringError {
+pub(crate) enum LoadStringError {
     ReadFail,
     BadUtf8,
 }
 
-crate fn load_string<P: AsRef<Path>>(
+pub(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 95adc4426b5..f3e075bc12a 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -1,13 +1,13 @@
 use crate::clean::*;
 
-crate fn strip_item(mut item: Item) -> Item {
+pub(crate) fn strip_item(mut item: Item) -> Item {
     if !matches!(*item.kind, StrippedItem(..)) {
         item.kind = box StrippedItem(item.kind);
     }
     item
 }
 
-crate trait DocFolder: Sized {
+pub(crate) trait DocFolder: Sized {
     fn fold_item(&mut self, item: Item) -> Option<Item> {
         Some(self.fold_item_recur(item))
     }
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 28648e25d90..f5c0b5e6762 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -26,25 +26,25 @@ use crate::html::render::IndexItem;
 /// to `Send` so it may be stored in an `Arc` instance and shared among the various
 /// rendering threads.
 #[derive(Default)]
-crate struct Cache {
+pub(crate) struct Cache {
     /// Maps a type ID to all known implementations for that type. This is only
     /// recognized for intra-crate [`clean::Type::Path`]s, 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.
-    crate impls: FxHashMap<DefId, Vec<Impl>>,
+    pub(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.
-    crate paths: FxHashMap<DefId, (Vec<Symbol>, ItemType)>,
+    pub(crate) paths: FxHashMap<DefId, (Vec<Symbol>, ItemType)>,
 
     /// Similar to `paths`, but only holds external paths. This is only used for
     /// generating explicit hyperlinks to other crates.
-    crate external_paths: FxHashMap<DefId, (Vec<Symbol>, ItemType)>,
+    pub(crate) external_paths: FxHashMap<DefId, (Vec<Symbol>, ItemType)>,
 
     /// Maps local `DefId`s of exported types to fully qualified paths.
     /// Unlike 'paths', this mapping ignores any renames that occur
@@ -56,41 +56,41 @@ crate 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.
-    crate exact_paths: FxHashMap<DefId, Vec<Symbol>>,
+    pub(crate) exact_paths: FxHashMap<DefId, Vec<Symbol>>,
 
     /// 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.
-    crate traits: FxHashMap<DefId, clean::TraitWithExtraInfo>,
+    pub(crate) traits: FxHashMap<DefId, clean::TraitWithExtraInfo>,
 
     /// 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
-    crate implementors: FxHashMap<DefId, Vec<Impl>>,
+    pub(crate) implementors: FxHashMap<DefId, Vec<Impl>>,
 
     /// Cache of where external crate documentation can be found.
-    crate extern_locations: FxHashMap<CrateNum, ExternalLocation>,
+    pub(crate) extern_locations: FxHashMap<CrateNum, ExternalLocation>,
 
     /// Cache of where documentation for primitives can be found.
-    crate primitive_locations: FxHashMap<clean::PrimitiveType, DefId>,
+    pub(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.
-    crate access_levels: AccessLevels<DefId>,
+    pub(crate) access_levels: AccessLevels<DefId>,
 
     /// The version of the crate being documented, if given from the `--crate-version` flag.
-    crate crate_version: Option<String>,
+    pub(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.
-    crate document_private: bool,
+    pub(crate) document_private: bool,
 
     /// Crates marked with [`#[doc(masked)]`][doc_masked].
     ///
     /// [doc_masked]: https://doc.rust-lang.org/nightly/unstable-book/language-features/doc-masked.html
-    crate masked_crates: FxHashSet<CrateNum>,
+    pub(crate) masked_crates: FxHashSet<CrateNum>,
 
     // Private fields only used when initially crawling a crate to build a cache
     stack: Vec<Symbol>,
@@ -98,14 +98,14 @@ crate struct Cache {
     parent_is_trait_impl: bool,
     stripped_mod: bool,
 
-    crate search_index: Vec<IndexItem>,
+    pub(crate) search_index: Vec<IndexItem>,
 
     // 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.
-    crate orphan_impl_items: Vec<(DefId, clean::Item)>,
+    pub(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
@@ -119,9 +119,9 @@ crate struct Cache {
     /// All intra-doc links resolved so far.
     ///
     /// Links are indexed by the DefId of the item they document.
-    crate intra_doc_links: FxHashMap<ItemId, Vec<clean::ItemLink>>,
+    pub(crate) intra_doc_links: FxHashMap<ItemId, Vec<clean::ItemLink>>,
     /// Cfg that have been hidden via #![doc(cfg_hide(...))]
-    crate hidden_cfg: FxHashSet<clean::cfg::Cfg>,
+    pub(crate) hidden_cfg: FxHashSet<clean::cfg::Cfg>,
 }
 
 /// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`.
@@ -133,13 +133,13 @@ struct CacheBuilder<'a, 'tcx> {
 }
 
 impl Cache {
-    crate fn new(access_levels: AccessLevels<DefId>, document_private: bool) -> Self {
+    pub(crate) fn new(access_levels: AccessLevels<DefId>, document_private: bool) -> Self {
         Cache { access_levels, document_private, ..Cache::default() }
     }
 
     /// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was
     /// in `krate` due to the data being moved into the `Cache`.
-    crate fn populate(cx: &mut DocContext<'_>, mut krate: clean::Crate) -> clean::Crate {
+    pub(crate) fn populate(cx: &mut DocContext<'_>, mut krate: clean::Crate) -> clean::Crate {
         let tcx = cx.tcx;
 
         // Crawl the crate to build various caches used for the output
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index fb4afb769ad..eca5501cd33 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -21,7 +21,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, Hash, Clone, Debug, PartialOrd, Ord)]
-crate enum ItemType {
+pub(crate) enum ItemType {
     Module = 0,
     ExternCrate = 1,
     Import = 2,
@@ -147,7 +147,7 @@ impl From<DefKind> for ItemType {
 }
 
 impl ItemType {
-    crate fn as_str(&self) -> &'static str {
+    pub(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 3e36318eb71..2367bde0167 100644
--- a/src/librustdoc/formats/mod.rs
+++ b/src/librustdoc/formats/mod.rs
@@ -1,16 +1,16 @@
-crate mod cache;
-crate mod item_type;
-crate mod renderer;
+pub(crate) mod cache;
+pub(crate) mod item_type;
+pub(crate) mod renderer;
 
 use rustc_hir::def_id::DefId;
 
-crate use renderer::{run_format, FormatRenderer};
+pub(crate) use renderer::{run_format, FormatRenderer};
 
 use crate::clean::{self, ItemId};
 
 /// Specifies whether rendering directly implemented trait items or ones from a certain Deref
 /// impl.
-crate enum AssocItemRender<'a> {
+pub(crate) enum AssocItemRender<'a> {
     All,
     DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
 }
@@ -18,26 +18,26 @@ crate 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)]
-crate enum RenderMode {
+pub(crate) enum RenderMode {
     Normal,
     ForDeref { mut_: bool },
 }
 
 /// Metadata about implementations for a type or trait.
 #[derive(Clone, Debug)]
-crate struct Impl {
-    crate impl_item: clean::Item,
+pub(crate) struct Impl {
+    pub(crate) impl_item: clean::Item,
 }
 
 impl Impl {
-    crate fn inner_impl(&self) -> &clean::Impl {
+    pub(crate) fn inner_impl(&self) -> &clean::Impl {
         match *self.impl_item.kind {
             clean::ImplItem(ref impl_) => impl_,
             _ => panic!("non-impl item found in impl"),
         }
     }
 
-    crate fn trait_did(&self) -> Option<DefId> {
+    pub(crate) fn trait_did(&self) -> Option<DefId> {
         self.inner_impl().trait_.as_ref().map(|t| t.def_id())
     }
 
@@ -47,7 +47,7 @@ impl Impl {
     /// with blanket impls).
     ///
     /// It panics if `self` is a `ItemId::Primitive`.
-    crate fn def_id(&self) -> DefId {
+    pub(crate) fn def_id(&self) -> DefId {
         match self.impl_item.item_id {
             ItemId::Blanket { impl_id, .. } => impl_id,
             ItemId::Auto { trait_, .. } => trait_,
diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs
index 2403ff4ebaa..62ba984acc9 100644
--- a/src/librustdoc/formats/renderer.rs
+++ b/src/librustdoc/formats/renderer.rs
@@ -9,7 +9,7 @@ use crate::formats::cache::Cache;
 /// 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.
-crate trait FormatRenderer<'tcx>: Sized {
+pub(crate) trait FormatRenderer<'tcx>: Sized {
     /// Gives a description of the renderer. Used for performance profiling.
     fn descr() -> &'static str;
 
@@ -48,7 +48,7 @@ crate trait FormatRenderer<'tcx>: Sized {
 }
 
 /// Main method for rendering a crate.
-crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
+pub(crate) fn run_format<'tcx, T: FormatRenderer<'tcx>>(
     krate: clean::Crate,
     options: RenderOptions,
     cache: Cache,
diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs
index ce44722a532..4a19d0a44c3 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.
-crate struct Escape<'a>(pub &'a str);
+pub(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 528eb6410cb..3c492f51786 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -33,7 +33,7 @@ use crate::html::render::Context;
 use super::url_parts_builder::estimate_item_path_byte_length;
 use super::url_parts_builder::UrlPartsBuilder;
 
-crate trait Print {
+pub(crate) trait Print {
     fn print(self, buffer: &mut Buffer);
 }
 
@@ -59,7 +59,7 @@ impl Print for &'_ str {
 }
 
 #[derive(Debug, Clone)]
-crate struct Buffer {
+pub(crate) struct Buffer {
     for_html: bool,
     buffer: String,
 }
@@ -82,63 +82,63 @@ impl core::fmt::Write for Buffer {
 }
 
 impl Buffer {
-    crate fn empty_from(v: &Buffer) -> Buffer {
+    pub(crate) fn empty_from(v: &Buffer) -> Buffer {
         Buffer { for_html: v.for_html, buffer: String::new() }
     }
 
-    crate fn html() -> Buffer {
+    pub(crate) fn html() -> Buffer {
         Buffer { for_html: true, buffer: String::new() }
     }
 
-    crate fn new() -> Buffer {
+    pub(crate) fn new() -> Buffer {
         Buffer { for_html: false, buffer: String::new() }
     }
 
-    crate fn is_empty(&self) -> bool {
+    pub(crate) fn is_empty(&self) -> bool {
         self.buffer.is_empty()
     }
 
-    crate fn into_inner(self) -> String {
+    pub(crate) fn into_inner(self) -> String {
         self.buffer
     }
 
-    crate fn insert_str(&mut self, idx: usize, s: &str) {
+    pub(crate) fn insert_str(&mut self, idx: usize, s: &str) {
         self.buffer.insert_str(idx, s);
     }
 
-    crate fn push_str(&mut self, s: &str) {
+    pub(crate) fn push_str(&mut self, s: &str) {
         self.buffer.push_str(s);
     }
 
-    crate fn push_buffer(&mut self, other: Buffer) {
+    pub(crate) fn push_buffer(&mut self, other: Buffer) {
         self.buffer.push_str(&other.buffer);
     }
 
     // Intended for consumption by write! and writeln! (std::fmt) but without
     // the fmt::Result return type imposed by fmt::Write (and avoiding the trait
     // import).
-    crate fn write_str(&mut self, s: &str) {
+    pub(crate) fn write_str(&mut self, s: &str) {
         self.buffer.push_str(s);
     }
 
     // Intended for consumption by write! and writeln! (std::fmt) but without
     // the fmt::Result return type imposed by fmt::Write (and avoiding the trait
     // import).
-    crate fn write_fmt(&mut self, v: fmt::Arguments<'_>) {
+    pub(crate) fn write_fmt(&mut self, v: fmt::Arguments<'_>) {
         use fmt::Write;
         self.buffer.write_fmt(v).unwrap();
     }
 
-    crate fn to_display<T: Print>(mut self, t: T) -> String {
+    pub(crate) fn to_display<T: Print>(mut self, t: T) -> String {
         t.print(&mut self);
         self.into_inner()
     }
 
-    crate fn is_for_html(&self) -> bool {
+    pub(crate) fn is_for_html(&self) -> bool {
         self.for_html
     }
 
-    crate fn reserve(&mut self, additional: usize) {
+    pub(crate) fn reserve(&mut self, additional: usize) {
         self.buffer.reserve(additional)
     }
 }
@@ -158,7 +158,7 @@ fn comma_sep<T: fmt::Display>(
     })
 }
 
-crate fn print_generic_bounds<'a, 'tcx: 'a>(
+pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>(
     bounds: &'a [clean::GenericBound],
     cx: &'a Context<'tcx>,
 ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -176,7 +176,7 @@ crate fn print_generic_bounds<'a, 'tcx: 'a>(
 }
 
 impl clean::GenericParamDef {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -239,7 +239,7 @@ impl clean::GenericParamDef {
 }
 
 impl clean::Generics {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -262,7 +262,7 @@ impl clean::Generics {
 /// * The Generics from which to emit a where-clause.
 /// * The number of spaces to indent each line with.
 /// * Whether the where-clause needs to add a comma and newline after the last bound.
-crate fn print_where_clause<'a, 'tcx: 'a>(
+pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
     gens: &'a clean::Generics,
     cx: &'a Context<'tcx>,
     indent: usize,
@@ -372,13 +372,13 @@ crate fn print_where_clause<'a, 'tcx: 'a>(
 }
 
 impl clean::Lifetime {
-    crate fn print(&self) -> impl fmt::Display + '_ {
+    pub(crate) fn print(&self) -> impl fmt::Display + '_ {
         self.0.as_str()
     }
 }
 
 impl clean::Constant {
-    crate fn print(&self, tcx: TyCtxt<'_>) -> impl fmt::Display + '_ {
+    pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl fmt::Display + '_ {
         let expr = self.expr(tcx);
         display_fn(
             move |f| {
@@ -419,7 +419,7 @@ impl clean::PolyTrait {
 }
 
 impl clean::GenericBound {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -516,7 +516,7 @@ impl clean::GenericArgs {
 }
 
 // Possible errors when computing href link source for a `DefId`
-crate enum HrefError {
+pub(crate) enum HrefError {
     /// This item is known to rustdoc, but from a crate that does not have documentation generated.
     ///
     /// This can only happen for non-local items.
@@ -543,7 +543,7 @@ crate enum HrefError {
 }
 
 // Panics if `syms` is empty.
-crate fn join_with_double_colon(syms: &[Symbol]) -> String {
+pub(crate) fn join_with_double_colon(syms: &[Symbol]) -> String {
     let mut s = String::with_capacity(estimate_item_path_byte_length(syms.len()));
     s.push_str(&syms[0].as_str());
     for sym in &syms[1..] {
@@ -553,7 +553,7 @@ crate fn join_with_double_colon(syms: &[Symbol]) -> String {
     s
 }
 
-crate fn href_with_root_path(
+pub(crate) fn href_with_root_path(
     did: DefId,
     cx: &Context<'_>,
     root_path: Option<&str>,
@@ -633,14 +633,17 @@ crate fn href_with_root_path(
     Ok((url_parts.finish(), shortty, fqp.to_vec()))
 }
 
-crate fn href(did: DefId, cx: &Context<'_>) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
+pub(crate) fn href(
+    did: DefId,
+    cx: &Context<'_>,
+) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
     href_with_root_path(did, cx, None)
 }
 
 /// Both paths should only be modules.
 /// This is because modules get their own directories; that is, `std::vec` and `std::vec::Vec` will
 /// both need `../iter/trait.Iterator.html` to get at the iterator trait.
-crate fn href_relative_parts<'fqp>(
+pub(crate) fn href_relative_parts<'fqp>(
     fqp: &'fqp [Symbol],
     relative_to_fqp: &[Symbol],
 ) -> Box<dyn Iterator<Item = Symbol> + 'fqp> {
@@ -787,7 +790,7 @@ fn tybounds<'a, 'tcx: 'a>(
     })
 }
 
-crate fn anchor<'a, 'cx: 'a>(
+pub(crate) fn anchor<'a, 'cx: 'a>(
     did: DefId,
     text: Symbol,
     cx: &'cx Context<'_>,
@@ -1031,7 +1034,7 @@ fn fmt_type<'cx>(
 }
 
 impl clean::Type {
-    crate fn print<'b, 'a: 'b, 'tcx: 'a>(
+    pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'b + Captures<'tcx> {
@@ -1040,7 +1043,7 @@ impl clean::Type {
 }
 
 impl clean::Path {
-    crate fn print<'b, 'a: 'b, 'tcx: 'a>(
+    pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'b + Captures<'tcx> {
@@ -1049,7 +1052,7 @@ impl clean::Path {
 }
 
 impl clean::Impl {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         use_absolute: bool,
         cx: &'a Context<'tcx>,
@@ -1083,7 +1086,7 @@ impl clean::Impl {
 }
 
 impl clean::Arguments {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -1107,7 +1110,7 @@ impl clean::Arguments {
 }
 
 impl clean::FnRetTy {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -1142,7 +1145,7 @@ impl clean::BareFunctionDecl {
 }
 
 impl clean::FnDecl {
-    crate fn print<'b, 'a: 'b, 'tcx: 'a>(
+    pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'b + Captures<'tcx> {
@@ -1174,7 +1177,7 @@ impl clean::FnDecl {
     /// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
     ///   necessary.
     /// * `asyncness`: Whether the function is async or not.
-    crate fn full_print<'a, 'tcx: 'a>(
+    pub(crate) fn full_print<'a, 'tcx: 'a>(
         &'a self,
         header_len: usize,
         indent: usize,
@@ -1291,7 +1294,7 @@ impl clean::FnDecl {
 }
 
 impl clean::Visibility {
-    crate fn print_with_space<'a, 'tcx: 'a>(
+    pub(crate) fn print_with_space<'a, 'tcx: 'a>(
         self,
         item_did: ItemId,
         cx: &'a Context<'tcx>,
@@ -1339,7 +1342,7 @@ impl clean::Visibility {
     /// This function is the same as print_with_space, except that it renders no links.
     /// It's used for macros' rendered source view, which is syntax highlighted and cannot have
     /// any HTML in it.
-    crate fn to_src_with_space<'a, 'tcx: 'a>(
+    pub(crate) fn to_src_with_space<'a, 'tcx: 'a>(
         self,
         tcx: TyCtxt<'tcx>,
         item_did: DefId,
@@ -1374,7 +1377,7 @@ impl clean::Visibility {
     }
 }
 
-crate trait PrintWithSpace {
+pub(crate) trait PrintWithSpace {
     fn print_with_space(&self) -> &str;
 }
 
@@ -1405,7 +1408,10 @@ impl PrintWithSpace for hir::Mutability {
     }
 }
 
-crate fn print_constness_with_space(c: &hir::Constness, s: Option<ConstStability>) -> &'static str {
+pub(crate) fn print_constness_with_space(
+    c: &hir::Constness,
+    s: Option<ConstStability>,
+) -> &'static str {
     match (c, s) {
         // const stable or when feature(staged_api) is not set
         (
@@ -1419,7 +1425,7 @@ crate fn print_constness_with_space(c: &hir::Constness, s: Option<ConstStability
 }
 
 impl clean::Import {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -1443,7 +1449,7 @@ impl clean::Import {
 }
 
 impl clean::ImportSource {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -1466,7 +1472,7 @@ impl clean::ImportSource {
 }
 
 impl clean::TypeBinding {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -1500,7 +1506,7 @@ impl clean::TypeBinding {
     }
 }
 
-crate fn print_abi_with_space(abi: Abi) -> impl fmt::Display {
+pub(crate) fn print_abi_with_space(abi: Abi) -> impl fmt::Display {
     display_fn(move |f| {
         let quot = if f.alternate() { "\"" } else { "&quot;" };
         match abi {
@@ -1510,12 +1516,12 @@ crate fn print_abi_with_space(abi: Abi) -> impl fmt::Display {
     })
 }
 
-crate fn print_default_space<'a>(v: bool) -> &'a str {
+pub(crate) fn print_default_space<'a>(v: bool) -> &'a str {
     if v { "default " } else { "" }
 }
 
 impl clean::GenericArg {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -1529,7 +1535,7 @@ impl clean::GenericArg {
 }
 
 impl clean::types::Term {
-    crate fn print<'a, 'tcx: 'a>(
+    pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
@@ -1540,7 +1546,9 @@ impl clean::types::Term {
     }
 }
 
-crate fn display_fn(f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Display {
+pub(crate) fn display_fn(
+    f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
+) -> impl fmt::Display {
     struct WithFormatter<F>(Cell<Option<F>>);
 
     impl<F> fmt::Display for WithFormatter<F>
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index a0187bd77f8..480728b1797 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -22,21 +22,21 @@ use super::format::{self, Buffer};
 use super::render::LinkFromSrc;
 
 /// This type is needed in case we want to render links on items to allow to go to their definition.
-crate struct ContextInfo<'a, 'b, 'c> {
-    crate context: &'a Context<'b>,
+pub(crate) struct ContextInfo<'a, 'b, 'c> {
+    pub(crate) context: &'a Context<'b>,
     /// This span contains the current file we're going through.
-    crate file_span: Span,
+    pub(crate) file_span: Span,
     /// This field is used to know "how far" from the top of the directory we are to link to either
     /// documentation pages or other source pages.
-    crate root_path: &'c str,
+    pub(crate) root_path: &'c str,
 }
 
 /// Decorations are represented as a map from CSS class to vector of character ranges.
 /// Each range will be wrapped in a span with that class.
-crate struct DecorationInfo(crate FxHashMap<&'static str, Vec<(u32, u32)>>);
+pub(crate) struct DecorationInfo(pub(crate) FxHashMap<&'static str, Vec<(u32, u32)>>);
 
 /// Highlights `src`, returning the HTML output.
-crate fn render_with_highlighting(
+pub(crate) fn render_with_highlighting(
     src: &str,
     out: &mut Buffer,
     class: Option<&str>,
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 4ca71ea8684..de54347a0f7 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -10,33 +10,33 @@ use crate::html::render::{ensure_trailing_slash, StylePath};
 use askama::Template;
 
 #[derive(Clone)]
-crate struct Layout {
-    crate logo: String,
-    crate favicon: String,
-    crate external_html: ExternalHtml,
-    crate default_settings: FxHashMap<String, String>,
-    crate krate: String,
+pub(crate) struct Layout {
+    pub(crate) logo: String,
+    pub(crate) favicon: String,
+    pub(crate) external_html: ExternalHtml,
+    pub(crate) default_settings: FxHashMap<String, String>,
+    pub(crate) krate: String,
     /// The given user css file which allow to customize the generated
     /// documentation theme.
-    crate css_file_extension: Option<PathBuf>,
+    pub(crate) css_file_extension: Option<PathBuf>,
     /// If true, then scrape-examples.js will be included in the output HTML file
-    crate scrape_examples_extension: bool,
+    pub(crate) scrape_examples_extension: bool,
 }
 
-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(crate) struct Page<'a> {
+    pub(crate) title: &'a str,
+    pub(crate) css_class: &'a str,
+    pub(crate) root_path: &'a str,
+    pub(crate) static_root_path: Option<&'a str>,
+    pub(crate) description: &'a str,
+    pub(crate) keywords: &'a str,
+    pub(crate) resource_suffix: &'a str,
+    pub(crate) extra_scripts: &'a [&'a str],
+    pub(crate) static_extra_scripts: &'a [&'a str],
 }
 
 impl<'a> Page<'a> {
-    crate fn get_static_root_path(&self) -> &str {
+    pub(crate) fn get_static_root_path(&self) -> &str {
         self.static_root_path.unwrap_or(self.root_path)
     }
 }
@@ -51,10 +51,10 @@ struct PageLayout<'a> {
     sidebar: String,
     content: String,
     krate_with_trailing_slash: String,
-    crate rustdoc_version: &'a str,
+    pub(crate) rustdoc_version: &'a str,
 }
 
-crate fn render<T: Print, S: Print>(
+pub(crate) fn render<T: Print, S: Print>(
     layout: &Layout,
     page: &Page<'_>,
     sidebar: S,
@@ -86,7 +86,7 @@ crate fn render<T: Print, S: Print>(
     .unwrap()
 }
 
-crate fn redirect(url: &str) -> String {
+pub(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 5ba3bdc12ed..8877f628332 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -104,23 +104,23 @@ pub struct Markdown<'a> {
     pub heading_offset: HeadingOffset,
 }
 /// A tuple struct like `Markdown` that renders the markdown with a table of contents.
-crate struct MarkdownWithToc<'a>(
-    crate &'a str,
-    crate &'a mut IdMap,
-    crate ErrorCodes,
-    crate Edition,
-    crate &'a Option<Playground>,
+pub(crate) struct MarkdownWithToc<'a>(
+    pub(crate) &'a str,
+    pub(crate) &'a mut IdMap,
+    pub(crate) ErrorCodes,
+    pub(crate) Edition,
+    pub(crate) &'a Option<Playground>,
 );
 /// A tuple struct like `Markdown` that renders the markdown escaping HTML tags.
-crate struct MarkdownHtml<'a>(
-    crate &'a str,
-    crate &'a mut IdMap,
-    crate ErrorCodes,
-    crate Edition,
-    crate &'a Option<Playground>,
+pub(crate) struct MarkdownHtml<'a>(
+    pub(crate) &'a str,
+    pub(crate) &'a mut IdMap,
+    pub(crate) ErrorCodes,
+    pub(crate) Edition,
+    pub(crate) &'a Option<Playground>,
 );
 /// A tuple struct like `Markdown` that renders only the first paragraph.
-crate struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [RenderedLink]);
+pub(crate) struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [RenderedLink]);
 
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum ErrorCodes {
@@ -129,14 +129,14 @@ pub enum ErrorCodes {
 }
 
 impl ErrorCodes {
-    crate fn from(b: bool) -> Self {
+    pub(crate) fn from(b: bool) -> Self {
         match b {
             true => ErrorCodes::Yes,
             false => ErrorCodes::No,
         }
     }
 
-    crate fn as_bool(self) -> bool {
+    pub(crate) fn as_bool(self) -> bool {
         match self {
             ErrorCodes::Yes => true,
             ErrorCodes::No => false,
@@ -716,7 +716,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
     }
 }
 
-crate fn find_testable_code<T: doctest::Tester>(
+pub(crate) fn find_testable_code<T: doctest::Tester>(
     doc: &str,
     tests: &mut T,
     error_codes: ErrorCodes,
@@ -788,7 +788,7 @@ crate fn find_testable_code<T: doctest::Tester>(
     }
 }
 
-crate struct ExtraInfo<'tcx> {
+pub(crate) struct ExtraInfo<'tcx> {
     id: ExtraInfoId,
     sp: Span,
     tcx: TyCtxt<'tcx>,
@@ -800,11 +800,11 @@ enum ExtraInfoId {
 }
 
 impl<'tcx> ExtraInfo<'tcx> {
-    crate fn new(tcx: TyCtxt<'tcx>, hir_id: HirId, sp: Span) -> ExtraInfo<'tcx> {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>, hir_id: HirId, sp: Span) -> ExtraInfo<'tcx> {
         ExtraInfo { id: ExtraInfoId::Hir(hir_id), sp, tcx }
     }
 
-    crate fn new_did(tcx: TyCtxt<'tcx>, did: DefId, sp: Span) -> ExtraInfo<'tcx> {
+    pub(crate) fn new_did(tcx: TyCtxt<'tcx>, did: DefId, sp: Span) -> ExtraInfo<'tcx> {
         ExtraInfo { id: ExtraInfoId::Def(did), sp, tcx }
     }
 
@@ -835,20 +835,20 @@ impl<'tcx> ExtraInfo<'tcx> {
 }
 
 #[derive(Eq, PartialEq, Clone, Debug)]
-crate struct LangString {
+pub(crate) struct LangString {
     original: String,
-    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 edition: Option<Edition>,
+    pub(crate) should_panic: bool,
+    pub(crate) no_run: bool,
+    pub(crate) ignore: Ignore,
+    pub(crate) rust: bool,
+    pub(crate) test_harness: bool,
+    pub(crate) compile_fail: bool,
+    pub(crate) error_codes: Vec<String>,
+    pub(crate) edition: Option<Edition>,
 }
 
 #[derive(Eq, PartialEq, Clone, Debug)]
-crate enum Ignore {
+pub(crate) enum Ignore {
     All,
     None,
     Some(Vec<String>),
@@ -1058,7 +1058,7 @@ impl Markdown<'_> {
 }
 
 impl MarkdownWithToc<'_> {
-    crate fn into_string(self) -> String {
+    pub(crate) fn into_string(self) -> String {
         let MarkdownWithToc(md, mut ids, codes, edition, playground) = self;
 
         let p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
@@ -1080,7 +1080,7 @@ impl MarkdownWithToc<'_> {
 }
 
 impl MarkdownHtml<'_> {
-    crate fn into_string(self) -> String {
+    pub(crate) fn into_string(self) -> String {
         let MarkdownHtml(md, mut ids, codes, edition, playground) = self;
 
         // This is actually common enough to special-case
@@ -1108,7 +1108,7 @@ impl MarkdownHtml<'_> {
 }
 
 impl MarkdownSummaryLine<'_> {
-    crate fn into_string(self) -> String {
+    pub(crate) fn into_string(self) -> String {
         let MarkdownSummaryLine(md, links) = self;
         // This is actually common enough to special-case
         if md.is_empty() {
@@ -1207,7 +1207,7 @@ fn markdown_summary_with_limit(
 /// Will shorten to 59 or 60 characters, including an ellipsis (…) if it was shortened.
 ///
 /// See [`markdown_summary_with_limit`] for details about what is rendered and what is not.
-crate fn short_markdown_summary(markdown: &str, link_names: &[RenderedLink]) -> String {
+pub(crate) fn short_markdown_summary(markdown: &str, link_names: &[RenderedLink]) -> String {
     let (mut s, was_shortened) = markdown_summary_with_limit(markdown, link_names, 59);
 
     if was_shortened {
@@ -1223,7 +1223,7 @@ crate fn short_markdown_summary(markdown: &str, link_names: &[RenderedLink]) ->
 /// - Headings, links, and formatting are stripped.
 /// - Inline code is rendered as-is, surrounded by backticks.
 /// - HTML and code blocks are ignored.
-crate fn plain_text_summary(md: &str) -> String {
+pub(crate) fn plain_text_summary(md: &str) -> String {
     if md.is_empty() {
         return String::new();
     }
@@ -1250,13 +1250,16 @@ crate fn plain_text_summary(md: &str) -> String {
 }
 
 #[derive(Debug)]
-crate struct MarkdownLink {
+pub(crate) struct MarkdownLink {
     pub kind: LinkType,
     pub link: String,
     pub range: Range<usize>,
 }
 
-crate fn markdown_links<R>(md: &str, filter_map: impl Fn(MarkdownLink) -> Option<R>) -> Vec<R> {
+pub(crate) fn markdown_links<R>(
+    md: &str,
+    filter_map: impl Fn(MarkdownLink) -> Option<R>,
+) -> Vec<R> {
     if md.is_empty() {
         return vec![];
     }
@@ -1337,19 +1340,19 @@ crate fn markdown_links<R>(md: &str, filter_map: impl Fn(MarkdownLink) -> Option
 }
 
 #[derive(Debug)]
-crate struct RustCodeBlock {
+pub(crate) struct RustCodeBlock {
     /// The range in the markdown that the code block occupies. Note that this includes the fences
     /// for fenced code blocks.
-    crate range: Range<usize>,
+    pub(crate) range: Range<usize>,
     /// The range in the markdown that the code within the code block occupies.
-    crate code: Range<usize>,
-    crate is_fenced: bool,
-    crate lang_string: LangString,
+    pub(crate) code: Range<usize>,
+    pub(crate) is_fenced: bool,
+    pub(crate) lang_string: LangString,
 }
 
 /// Returns a range of bytes for each code block in the markdown that is tagged as `rust` or
 /// untagged (and assumed to be rust).
-crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec<RustCodeBlock> {
+pub(crate) fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec<RustCodeBlock> {
     let mut code_blocks = vec![];
 
     if md.is_empty() {
@@ -1492,7 +1495,7 @@ impl IdMap {
         IdMap { map: DEFAULT_ID_MAP.clone() }
     }
 
-    crate fn derive<S: AsRef<str> + ToString>(&mut self, candidate: S) -> String {
+    pub(crate) fn derive<S: AsRef<str> + ToString>(&mut self, candidate: S) -> String {
         let id = match self.map.get_mut(candidate.as_ref()) {
             None => candidate.to_string(),
             Some(a) => {
diff --git a/src/librustdoc/html/mod.rs b/src/librustdoc/html/mod.rs
index e1bbc784fd1..481ed16c05f 100644
--- a/src/librustdoc/html/mod.rs
+++ b/src/librustdoc/html/mod.rs
@@ -1,14 +1,14 @@
-crate mod escape;
-crate mod format;
-crate mod highlight;
-crate mod layout;
+pub(crate) mod escape;
+pub(crate) mod format;
+pub(crate) mod highlight;
+pub(crate) mod layout;
 mod length_limit;
 // used by the error-index generator, so it needs to be public
 pub mod markdown;
-crate mod render;
-crate mod sources;
-crate mod static_files;
-crate mod toc;
+pub(crate) mod render;
+pub(crate) mod sources;
+pub(crate) mod static_files;
+pub(crate) mod toc;
 mod url_parts_builder;
 
 #[cfg(test)]
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 81f961992b6..76377c438e8 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -42,13 +42,13 @@ use crate::try_err;
 /// It is intended that this context is a lightweight object which can be fairly
 /// easily cloned because it is cloned per work-job (about once per item in the
 /// rustdoc tree).
-crate struct Context<'tcx> {
+pub(crate) struct Context<'tcx> {
     /// Current hierarchy of components leading down to what's currently being
     /// rendered
     pub(crate) current: Vec<Symbol>,
     /// The current destination folder of where HTML artifacts should be placed.
     /// This changes as the context descends into the module hierarchy.
-    crate dst: PathBuf,
+    pub(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.
@@ -63,11 +63,11 @@ crate struct Context<'tcx> {
     /// Issue for improving the situation: [#82381][]
     ///
     /// [#82381]: https://github.com/rust-lang/rust/issues/82381
-    crate shared: Rc<SharedContext<'tcx>>,
+    pub(crate) shared: Rc<SharedContext<'tcx>>,
     /// This flag indicates whether source links should be generated or not. If
     /// the source files are present in the html rendering, then this will be
     /// `true`.
-    crate include_sources: bool,
+    pub(crate) include_sources: bool,
 }
 
 // `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
@@ -75,16 +75,16 @@ crate struct Context<'tcx> {
 rustc_data_structures::static_assert_size!(Context<'_>, 144);
 
 /// Shared mutable state used in [`Context`] and elsewhere.
-crate struct SharedContext<'tcx> {
-    crate tcx: TyCtxt<'tcx>,
+pub(crate) struct SharedContext<'tcx> {
+    pub(crate) tcx: TyCtxt<'tcx>,
     /// The path to the crate root source minus the file name.
     /// Used for simplifying paths to the highlighted source code files.
-    crate src_root: PathBuf,
+    pub(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).
-    crate layout: layout::Layout,
+    pub(crate) layout: layout::Layout,
     /// The local file sources we've emitted and their respective url-paths.
-    crate local_sources: FxHashMap<PathBuf, String>,
+    pub(crate) local_sources: FxHashMap<PathBuf, String>,
     /// Show the memory layout of types in the docs.
     pub(super) show_type_layout: bool,
     /// The base-URL of the issue tracker for when an item has been tagged with
@@ -97,15 +97,15 @@ crate struct SharedContext<'tcx> {
     /// should be ordered alphabetically or in order of appearance (in the source code).
     pub(super) sort_modules_alphabetically: bool,
     /// Additional CSS files to be added to the generated docs.
-    crate style_files: Vec<StylePath>,
+    pub(crate) style_files: Vec<StylePath>,
     /// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes
     /// "light-v2.css").
-    crate resource_suffix: String,
+    pub(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.
-    crate static_root_path: Option<String>,
+    pub(crate) static_root_path: Option<String>,
     /// The fs handle we are working with.
-    crate fs: DocFS,
+    pub(crate) fs: DocFS,
     pub(super) codes: ErrorCodes,
     pub(super) playground: Option<markdown::Playground>,
     all: RefCell<AllTypes>,
@@ -119,15 +119,15 @@ crate struct SharedContext<'tcx> {
 
     /// Correspondance map used to link types used in the source code pages to allow to click on
     /// links to jump to the type's definition.
-    crate span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
+    pub(crate) span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
     /// The [`Cache`] used during rendering.
-    crate cache: Cache,
+    pub(crate) cache: Cache,
 
-    crate call_locations: AllCallLocations,
+    pub(crate) call_locations: AllCallLocations,
 }
 
 impl SharedContext<'_> {
-    crate fn ensure_dir(&self, dst: &Path) -> Result<(), Error> {
+    pub(crate) fn ensure_dir(&self, dst: &Path) -> Result<(), Error> {
         let mut dirs = self.created_dirs.borrow_mut();
         if !dirs.contains(dst) {
             try_err!(self.fs.create_dir_all(dst), dst);
@@ -137,7 +137,7 @@ impl SharedContext<'_> {
         Ok(())
     }
 
-    crate fn edition(&self) -> Edition {
+    pub(crate) fn edition(&self) -> Edition {
         self.tcx.sess.edition()
     }
 }
@@ -301,7 +301,7 @@ impl<'tcx> Context<'tcx> {
         self.href_from_span(item.span(self.tcx()), true)
     }
 
-    crate fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option<String> {
+    pub(crate) fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option<String> {
         if span.is_dummy() {
             return None;
         }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index c13ae1e431a..0de50c60fac 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -23,7 +23,7 @@
 //! These threads are not parallelized (they haven't been a bottleneck yet), and
 //! both occur before the crate is rendered.
 
-crate mod search_index;
+pub(crate) mod search_index;
 
 #[cfg(test)]
 mod tests;
@@ -33,8 +33,8 @@ mod print_item;
 mod span_map;
 mod write_shared;
 
-crate use self::context::*;
-crate use self::span_map::{collect_spans_and_sources, LinkFromSrc};
+pub(crate) use self::context::*;
+pub(crate) use self::span_map::{collect_spans_and_sources, LinkFromSrc};
 
 use std::collections::VecDeque;
 use std::default::Default;
@@ -81,9 +81,9 @@ use crate::try_none;
 use crate::DOC_RUST_LANG_ORG_CHANNEL;
 
 /// A pair of name and its optional document.
-crate type NameDoc = (String, Option<String>);
+pub(crate) type NameDoc = (String, Option<String>);
 
-crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
+pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
     crate::html::format::display_fn(move |f| {
         if !v.ends_with('/') && !v.is_empty() { write!(f, "{}/", v) } else { f.write_str(v) }
     })
@@ -95,27 +95,27 @@ crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
 /// 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)]
-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>,
-    crate aliases: Box<[Symbol]>,
+pub(crate) struct IndexItem {
+    pub(crate) ty: ItemType,
+    pub(crate) name: String,
+    pub(crate) path: String,
+    pub(crate) desc: String,
+    pub(crate) parent: Option<DefId>,
+    pub(crate) parent_idx: Option<usize>,
+    pub(crate) search_type: Option<IndexItemFunctionType>,
+    pub(crate) aliases: Box<[Symbol]>,
 }
 
 /// A type used for the search index.
 #[derive(Debug)]
-crate struct RenderType {
+pub(crate) struct RenderType {
     name: Option<String>,
     generics: Option<Vec<TypeWithKind>>,
 }
 
 /// Full type of functions/methods in the search index.
 #[derive(Debug)]
-crate struct IndexItemFunctionType {
+pub(crate) struct IndexItemFunctionType {
     inputs: Vec<TypeWithKind>,
     output: Vec<TypeWithKind>,
 }
@@ -143,7 +143,7 @@ impl Serialize for IndexItemFunctionType {
 }
 
 #[derive(Debug)]
-crate struct TypeWithKind {
+pub(crate) struct TypeWithKind {
     ty: RenderType,
     kind: ItemType,
 }
@@ -170,13 +170,13 @@ impl Serialize for TypeWithKind {
 }
 
 #[derive(Debug, Clone)]
-crate struct StylePath {
+pub(crate) struct StylePath {
     /// The path to the theme
-    crate path: PathBuf,
+    pub(crate) path: PathBuf,
 }
 
 impl StylePath {
-    crate fn basename(&self) -> Result<String, Error> {
+    pub(crate) fn basename(&self) -> Result<String, Error> {
         Ok(try_none!(try_none!(self.path.file_stem(), &self.path).to_str(), &self.path).to_string())
     }
 }
@@ -203,7 +203,7 @@ impl ItemEntry {
 }
 
 impl ItemEntry {
-    crate fn print(&self) -> impl fmt::Display + '_ {
+    pub(crate) fn print(&self) -> impl fmt::Display + '_ {
         crate::html::format::display_fn(move |f| {
             write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name))
         })
@@ -2580,7 +2580,7 @@ fn sidebar_foreign_type(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item) {
     }
 }
 
-crate const BASIC_KEYWORDS: &str = "rust, rustlang, rust-lang";
+pub(crate) const BASIC_KEYWORDS: &str = "rust, rustlang, rust-lang";
 
 /// Returns a list of all paths used in the type.
 /// This is used to help deduplicate imported impls
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 4951cd83af2..12e6115e6fe 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -246,14 +246,14 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
     // This call is to remove re-export duplicates in cases such as:
     //
     // ```
-    // crate mod foo {
-    //     crate mod bar {
-    //         crate trait Double { fn foo(); }
+    // pub(crate) mod foo {
+    //     pub(crate) mod bar {
+    //         pub(crate) trait Double { fn foo(); }
     //     }
     // }
     //
-    // crate use foo::bar::*;
-    // crate use foo::*;
+    // pub(crate) use foo::bar::*;
+    // pub(crate) use foo::*;
     // ```
     //
     // `Double` will appear twice in the generated docs.
@@ -1473,7 +1473,7 @@ fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
 }
 
 /// Compare two strings treating multi-digit numbers as single units (i.e. natural sort order).
-crate fn compare_names(mut lhs: &str, mut rhs: &str) -> Ordering {
+pub(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());
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index e1309c03b5c..4e53ba4dc0c 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -15,7 +15,11 @@ use crate::html::markdown::short_markdown_summary;
 use crate::html::render::{IndexItem, IndexItemFunctionType, RenderType, TypeWithKind};
 
 /// Builds the search index from the collected metadata
-crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<'tcx>) -> String {
+pub(crate) fn build_index<'tcx>(
+    krate: &clean::Crate,
+    cache: &mut Cache,
+    tcx: TyCtxt<'tcx>,
+) -> String {
     let mut defid_to_pathid = FxHashMap::default();
     let mut crate_paths = vec![];
 
@@ -185,7 +189,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
     )
 }
 
-crate fn get_function_type_for_search<'tcx>(
+pub(crate) fn get_function_type_for_search<'tcx>(
     item: &clean::Item,
     tcx: TyCtxt<'tcx>,
     cache: &Cache,
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 1ae888d059d..287ce9611d7 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -20,7 +20,7 @@ use std::path::{Path, PathBuf};
 /// Otherwise, we store the definition `DefId` and will generate a link to the documentation page
 /// instead of the source code directly.
 #[derive(Debug)]
-crate enum LinkFromSrc {
+pub(crate) enum LinkFromSrc {
     Local(clean::Span),
     External(DefId),
     Primitive(PrimitiveType),
@@ -36,7 +36,7 @@ crate enum LinkFromSrc {
 /// Note about the `span` correspondance map: the keys are actually `(lo, hi)` of `span`s. We don't
 /// need the `span` context later on, only their position, so instead of keep a whole `Span`, we
 /// only keep the `lo` and `hi`.
-crate fn collect_spans_and_sources(
+pub(crate) fn collect_spans_and_sources(
     tcx: TyCtxt<'_>,
     krate: &clean::Crate,
     src_root: &Path,
@@ -57,8 +57,8 @@ crate fn collect_spans_and_sources(
 }
 
 struct SpanMapVisitor<'tcx> {
-    crate tcx: TyCtxt<'tcx>,
-    crate matches: FxHashMap<Span, LinkFromSrc>,
+    pub(crate) tcx: TyCtxt<'tcx>,
+    pub(crate) matches: FxHashMap<Span, LinkFromSrc>,
 }
 
 impl<'tcx> SpanMapVisitor<'tcx> {
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 9fba6e91162..0bbdc37ea89 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -16,7 +16,7 @@ use std::ffi::OsStr;
 use std::fs;
 use std::path::{Component, Path, PathBuf};
 
-crate fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), Error> {
+pub(crate) fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), Error> {
     info!("emitting source files");
 
     let dst = cx.dst.join("src").join(krate.name(cx.tcx()).as_str());
@@ -27,7 +27,7 @@ crate fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), Error>
     Ok(())
 }
 
-crate fn collect_local_sources<'tcx>(
+pub(crate) fn collect_local_sources<'tcx>(
     tcx: TyCtxt<'tcx>,
     src_root: &Path,
     krate: &clean::Crate,
@@ -231,7 +231,7 @@ impl SourceCollector<'_, '_> {
 /// 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.
-crate fn clean_path<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F)
+pub(crate) fn clean_path<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F)
 where
     F: FnMut(&OsStr),
 {
@@ -253,14 +253,14 @@ where
     }
 }
 
-crate enum SourceContext {
+pub(crate) enum SourceContext {
     Standalone,
     Embedded { offset: usize },
 }
 
 /// Wrapper struct to render the source code of a file. This will do things like
 /// adding line numbers to the left-hand side.
-crate fn print_src(
+pub(crate) fn print_src(
     buf: &mut Buffer,
     s: &str,
     edition: Edition,
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index 85ca8431d90..75f2b7e3570 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -8,131 +8,134 @@
 //! directly written to a `Write` handle.
 
 /// The file contents of the main `rustdoc.css` file, responsible for the core layout of the page.
-crate static RUSTDOC_CSS: &str = include_str!("static/css/rustdoc.css");
+pub(crate) static RUSTDOC_CSS: &str = include_str!("static/css/rustdoc.css");
 
 /// The file contents of `settings.css`, responsible for the items on the settings page.
-crate static SETTINGS_CSS: &str = include_str!("static/css/settings.css");
+pub(crate) static SETTINGS_CSS: &str = include_str!("static/css/settings.css");
 
 /// The file contents of the `noscript.css` file, used in case JS isn't supported or is disabled.
-crate static NOSCRIPT_CSS: &str = include_str!("static/css/noscript.css");
+pub(crate) static NOSCRIPT_CSS: &str = include_str!("static/css/noscript.css");
 
 /// The file contents of `normalize.css`, included to even out standard elements between browser
 /// implementations.
-crate static NORMALIZE_CSS: &str = include_str!("static/css/normalize.css");
+pub(crate) static NORMALIZE_CSS: &str = include_str!("static/css/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.
-crate static MAIN_JS: &str = include_str!("static/js/main.js");
+pub(crate) static MAIN_JS: &str = include_str!("static/js/main.js");
 
 /// The file contents of `search.js`, which contains the search behavior.
-crate static SEARCH_JS: &str = include_str!("static/js/search.js");
+pub(crate) static SEARCH_JS: &str = include_str!("static/js/search.js");
 
 /// The file contents of `settings.js`, which contains the JavaScript used to handle the settings
 /// page.
-crate static SETTINGS_JS: &str = include_str!("static/js/settings.js");
+pub(crate) static SETTINGS_JS: &str = include_str!("static/js/settings.js");
 
 /// The file contents of `storage.js`, which contains functionality related to browser Local
 /// Storage, used to store documentation settings.
-crate static STORAGE_JS: &str = include_str!("static/js/storage.js");
+pub(crate) static STORAGE_JS: &str = include_str!("static/js/storage.js");
 
 /// The file contents of `scraped-examples.js`, which contains functionality related to the
 /// --scrape-examples flag that inserts automatically-found examples of usages of items.
-crate static SCRAPE_EXAMPLES_JS: &str = include_str!("static/js/scrape-examples.js");
+pub(crate) static SCRAPE_EXAMPLES_JS: &str = include_str!("static/js/scrape-examples.js");
 
-crate static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/scrape-examples-help.md");
+pub(crate) static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/scrape-examples-help.md");
 
 /// The file contents of `wheel.svg`, the icon used for the settings button.
-crate static WHEEL_SVG: &[u8] = include_bytes!("static/images/wheel.svg");
+pub(crate) static WHEEL_SVG: &[u8] = include_bytes!("static/images/wheel.svg");
 
 /// The file contents of `clipboard.svg`, the icon used for the "copy path" button.
-crate static CLIPBOARD_SVG: &[u8] = include_bytes!("static/images/clipboard.svg");
+pub(crate) static CLIPBOARD_SVG: &[u8] = include_bytes!("static/images/clipboard.svg");
 
 /// The file contents of `down-arrow.svg`, the icon used for the crate choice combobox.
-crate static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/images/down-arrow.svg");
+pub(crate) static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/images/down-arrow.svg");
 
 /// The file contents of `toggle-minus.svg`, the icon used for opened toggles.
-crate static TOGGLE_MINUS_PNG: &[u8] = include_bytes!("static/images/toggle-minus.svg");
+pub(crate) static TOGGLE_MINUS_PNG: &[u8] = include_bytes!("static/images/toggle-minus.svg");
 
 /// The file contents of `toggle-plus.svg`, the icon used for closed toggles.
-crate static TOGGLE_PLUS_PNG: &[u8] = include_bytes!("static/images/toggle-plus.svg");
+pub(crate) static TOGGLE_PLUS_PNG: &[u8] = include_bytes!("static/images/toggle-plus.svg");
 
 /// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation
 /// output.
-crate static COPYRIGHT: &[u8] = include_bytes!("static/COPYRIGHT.txt");
+pub(crate) static COPYRIGHT: &[u8] = include_bytes!("static/COPYRIGHT.txt");
 
 /// The contents of `LICENSE-APACHE.txt`, the text of the Apache License, version 2.0.
-crate static LICENSE_APACHE: &[u8] = include_bytes!("static/LICENSE-APACHE.txt");
+pub(crate) static LICENSE_APACHE: &[u8] = include_bytes!("static/LICENSE-APACHE.txt");
 
 /// The contents of `LICENSE-MIT.txt`, the text of the MIT License.
-crate static LICENSE_MIT: &[u8] = include_bytes!("static/LICENSE-MIT.txt");
+pub(crate) static LICENSE_MIT: &[u8] = include_bytes!("static/LICENSE-MIT.txt");
 
 /// The contents of `rust-logo.svg`, the default icon of the documentation.
-crate static RUST_LOGO_SVG: &[u8] = include_bytes!("static/images/rust-logo.svg");
+pub(crate) static RUST_LOGO_SVG: &[u8] = include_bytes!("static/images/rust-logo.svg");
 
 /// The default documentation favicons (SVG and PNG fallbacks)
-crate static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/images/favicon.svg");
-crate static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-16x16.png");
-crate static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png");
+pub(crate) static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/images/favicon.svg");
+pub(crate) static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-16x16.png");
+pub(crate) static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png");
 
 /// The built-in themes given to every documentation site.
-crate mod themes {
+pub(crate) mod themes {
     /// The "light" theme, selected by default when no setting is available. Used as the basis for
     /// the `--check-theme` functionality.
-    crate static LIGHT: &str = include_str!("static/css/themes/light.css");
+    pub(crate) static LIGHT: &str = include_str!("static/css/themes/light.css");
 
     /// The "dark" theme.
-    crate static DARK: &str = include_str!("static/css/themes/dark.css");
+    pub(crate) static DARK: &str = include_str!("static/css/themes/dark.css");
 
     /// The "ayu" theme.
-    crate static AYU: &str = include_str!("static/css/themes/ayu.css");
+    pub(crate) static AYU: &str = include_str!("static/css/themes/ayu.css");
 }
 
 /// Files related to the Fira Sans font.
-crate mod fira_sans {
+pub(crate) mod fira_sans {
     /// The file `FiraSans-Regular.woff2`, the Regular variant of the Fira Sans font in woff2.
-    crate static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2");
+    pub(crate) static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2");
 
     /// The file `FiraSans-Medium.woff2`, the Medium variant of the Fira Sans font in woff2.
-    crate static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2");
+    pub(crate) static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2");
 
     /// The file `FiraSans-LICENSE.txt`, the license text for the Fira Sans font.
-    crate static LICENSE: &[u8] = include_bytes!("static/fonts/FiraSans-LICENSE.txt");
+    pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/FiraSans-LICENSE.txt");
 }
 
 /// Files related to the Source Serif 4 font.
-crate mod source_serif_4 {
+pub(crate) mod source_serif_4 {
     /// The file `SourceSerif4-Regular.ttf.woff2`, the Regular variant of the Source Serif 4 font in
     /// woff2.
-    crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2");
+    pub(crate) static REGULAR: &[u8] =
+        include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2");
 
     /// The file `SourceSerif4-Bold.ttf.woff2`, the Bold variant of the Source Serif 4 font in
     /// woff2.
-    crate static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2");
+    pub(crate) static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2");
 
     /// The file `SourceSerif4-It.ttf.woff2`, the Italic variant of the Source Serif 4 font in
     /// woff2.
-    crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2");
+    pub(crate) static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2");
 
     /// The file `SourceSerif4-LICENSE.txt`, the license text for the Source Serif 4 font.
-    crate static LICENSE: &[u8] = include_bytes!("static/fonts/SourceSerif4-LICENSE.md");
+    pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/SourceSerif4-LICENSE.md");
 }
 
 /// Files related to the Source Code Pro font.
-crate mod source_code_pro {
+pub(crate) mod source_code_pro {
     /// The file `SourceCodePro-Regular.ttf.woff2`, the Regular variant of the Source Code Pro font
     /// in woff2.
-    crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2");
+    pub(crate) static REGULAR: &[u8] =
+        include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2");
 
     /// The file `SourceCodePro-Semibold.ttf.woff2`, the Semibold variant of the Source Code Pro
     /// font in woff2.
-    crate static SEMIBOLD: &[u8] = include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2");
+    pub(crate) static SEMIBOLD: &[u8] =
+        include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2");
 
     /// The file `SourceCodePro-It.ttf.woff2`, the Italic variant of the Source Code Pro font in
     /// woff2.
-    crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2");
+    pub(crate) static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2");
 
     /// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font.
-    crate static LICENSE: &[u8] = include_bytes!("static/fonts/SourceCodePro-LICENSE.txt");
+    pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/SourceCodePro-LICENSE.txt");
 }
 
 /// Files related to the Nanum Barun Gothic font.
@@ -150,16 +153,16 @@ crate mod source_code_pro {
 /// --unicodes=U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \
 /// --output-file=NanumBarunGothic.ttf.woff2 --flavor=woff2
 /// ```
-crate mod nanum_barun_gothic {
+pub(crate) mod nanum_barun_gothic {
     /// The file `NanumBarunGothic.ttf.woff2`, the Regular variant of the Nanum Barun Gothic font.
-    crate static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2");
+    pub(crate) static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2");
 
     /// The file `NanumBarunGothic-LICENSE.txt`, the license text of the Nanum Barun Gothic font.
-    crate static LICENSE: &[u8] = include_bytes!("static/fonts/NanumBarunGothic-LICENSE.txt");
+    pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/NanumBarunGothic-LICENSE.txt");
 }
 
 /// Files related to the sidebar in rustdoc sources.
-crate mod sidebar {
+pub(crate) mod sidebar {
     /// File script to handle sidebar.
-    crate static SOURCE_SCRIPT: &str = include_str!("static/js/source-script.js");
+    pub(crate) static SOURCE_SCRIPT: &str = include_str!("static/js/source-script.js");
 }
diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs
index c55f2459a9c..07e33052aa7 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)]
-crate struct Toc {
+pub(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)]
-crate struct TocEntry {
+pub(crate) struct TocEntry {
     level: u32,
     sec_number: String,
     name: String,
@@ -36,7 +36,7 @@ crate struct TocEntry {
 
 /// Progressive construction of a table of contents.
 #[derive(PartialEq)]
-crate struct TocBuilder {
+pub(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 @@ crate struct TocBuilder {
 }
 
 impl TocBuilder {
-    crate fn new() -> TocBuilder {
+    pub(crate) fn new() -> TocBuilder {
         TocBuilder { top_level: Toc { entries: Vec::new() }, chain: Vec::new() }
     }
 
     /// Converts into a true `Toc` struct.
-    crate fn into_toc(mut self) -> Toc {
+    pub(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.
-    crate fn push(&mut self, level: u32, name: String, id: String) -> &str {
+    pub(crate) fn push(&mut self, level: u32, name: String, id: String) -> &str {
         assert!(level >= 1);
 
         // collapse all previous sections into their parents until we
@@ -177,7 +177,7 @@ impl Toc {
         }
         v.push_str("</ul>");
     }
-    crate fn print(&self) -> String {
+    pub(crate) fn print(&self) -> String {
         let mut v = String::new();
         self.print_inner(&mut v);
         v
diff --git a/src/librustdoc/html/url_parts_builder.rs b/src/librustdoc/html/url_parts_builder.rs
index 2bb78aa7dc9..1e6af6af63c 100644
--- a/src/librustdoc/html/url_parts_builder.rs
+++ b/src/librustdoc/html/url_parts_builder.rs
@@ -8,14 +8,14 @@ use rustc_span::Symbol;
 /// This type is a wrapper around the final `String` buffer,
 /// but its API is like that of a `Vec` of URL components.
 #[derive(Debug)]
-crate struct UrlPartsBuilder {
+pub(crate) struct UrlPartsBuilder {
     buf: String,
 }
 
 impl UrlPartsBuilder {
     /// Create an empty buffer.
     #[allow(dead_code)]
-    crate fn new() -> Self {
+    pub(crate) fn new() -> Self {
         Self { buf: String::new() }
     }
 
@@ -43,7 +43,7 @@ impl UrlPartsBuilder {
     /// builder.push_front("nightly");
     /// assert_eq!(builder.finish(), "nightly/core/str");
     /// ```
-    crate fn singleton(part: &str) -> Self {
+    pub(crate) fn singleton(part: &str) -> Self {
         Self { buf: part.to_owned() }
     }
 
@@ -60,7 +60,7 @@ impl UrlPartsBuilder {
     /// builder.push("struct.Bytes.html");
     /// assert_eq!(builder.finish(), "core/str/struct.Bytes.html");
     /// ```
-    crate fn push(&mut self, part: &str) {
+    pub(crate) fn push(&mut self, part: &str) {
         if !self.buf.is_empty() {
             self.buf.push('/');
         }
@@ -80,7 +80,7 @@ impl UrlPartsBuilder {
     /// builder.push_fmt(format_args!("{}.{}.html", "struct", "Bytes"));
     /// assert_eq!(builder.finish(), "core/str/struct.Bytes.html");
     /// ```
-    crate fn push_fmt(&mut self, args: fmt::Arguments<'_>) {
+    pub(crate) fn push_fmt(&mut self, args: fmt::Arguments<'_>) {
         if !self.buf.is_empty() {
             self.buf.push('/');
         }
@@ -101,7 +101,7 @@ impl UrlPartsBuilder {
     /// builder.push("struct.Bytes.html");
     /// assert_eq!(builder.finish(), "nightly/core/str/struct.Bytes.html");
     /// ```
-    crate fn push_front(&mut self, part: &str) {
+    pub(crate) fn push_front(&mut self, part: &str) {
         let is_empty = self.buf.is_empty();
         self.buf.reserve(part.len() + if !is_empty { 1 } else { 0 });
         self.buf.insert_str(0, part);
@@ -111,7 +111,7 @@ impl UrlPartsBuilder {
     }
 
     /// Get the final `String` buffer.
-    crate fn finish(self) -> String {
+    pub(crate) fn finish(self) -> String {
         self.buf
     }
 }
@@ -134,7 +134,7 @@ const AVG_PART_LENGTH: usize = 8;
 ///
 /// **Note:** This is only to be used with, e.g., [`String::with_capacity()`];
 /// the return value is just a rough estimate.
-crate const fn estimate_item_path_byte_length(segment_count: usize) -> usize {
+pub(crate) const fn estimate_item_path_byte_length(segment_count: usize) -> usize {
     AVG_PART_LENGTH * segment_count
 }
 
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 412387313dc..6f6f7e375a4 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -91,11 +91,11 @@ impl JsonRenderer<'_> {
     }
 }
 
-crate trait FromWithTcx<T> {
+pub(crate) trait FromWithTcx<T> {
     fn from_tcx(f: T, tcx: TyCtxt<'_>) -> Self;
 }
 
-crate trait IntoWithTcx<T> {
+pub(crate) trait IntoWithTcx<T> {
     fn into_tcx(self, tcx: TyCtxt<'_>) -> T;
 }
 
@@ -108,7 +108,7 @@ where
     }
 }
 
-crate fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
+pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
     #[rustfmt::skip]
     let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation;
     Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) }
@@ -173,7 +173,7 @@ impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind {
     }
 }
 
-crate fn from_item_id(item_id: ItemId) -> Id {
+pub(crate) fn from_item_id(item_id: ItemId) -> Id {
     struct DisplayDefId(DefId);
 
     impl fmt::Display for DisplayDefId {
@@ -272,7 +272,7 @@ impl FromWithTcx<clean::Union> for Union {
     }
 }
 
-crate fn from_ctor_kind(struct_type: CtorKind) -> StructType {
+pub(crate) fn from_ctor_kind(struct_type: CtorKind) -> StructType {
     match struct_type {
         CtorKind::Fictive => StructType::Plain,
         CtorKind::Fn => StructType::Tuple,
@@ -280,7 +280,7 @@ crate fn from_ctor_kind(struct_type: CtorKind) -> StructType {
     }
 }
 
-crate fn from_fn_header(header: &rustc_hir::FnHeader) -> Header {
+pub(crate) fn from_fn_header(header: &rustc_hir::FnHeader) -> Header {
     Header {
         async_: header.is_async(),
         const_: header.is_const(),
@@ -390,7 +390,9 @@ impl FromWithTcx<clean::GenericBound> for GenericBound {
     }
 }
 
-crate fn from_trait_bound_modifier(modifier: rustc_hir::TraitBoundModifier) -> TraitBoundModifier {
+pub(crate) fn from_trait_bound_modifier(
+    modifier: rustc_hir::TraitBoundModifier,
+) -> TraitBoundModifier {
     use rustc_hir::TraitBoundModifier::*;
     match modifier {
         None => TraitBoundModifier::None,
@@ -554,7 +556,7 @@ impl FromWithTcx<clean::Impl> for Impl {
     }
 }
 
-crate fn from_function(
+pub(crate) fn from_function(
     function: clean::Function,
     header: rustc_hir::FnHeader,
     tcx: TyCtxt<'_>,
@@ -567,7 +569,7 @@ crate fn from_function(
     }
 }
 
-crate fn from_function_method(
+pub(crate) fn from_function_method(
     function: clean::Function,
     has_body: bool,
     header: rustc_hir::FnHeader,
@@ -658,7 +660,7 @@ impl FromWithTcx<clean::ProcMacro> for ProcMacro {
     }
 }
 
-crate fn from_macro_kind(kind: rustc_span::hygiene::MacroKind) -> MacroKind {
+pub(crate) fn from_macro_kind(kind: rustc_span::hygiene::MacroKind) -> MacroKind {
     use rustc_span::hygiene::MacroKind::*;
     match kind {
         Bang => MacroKind::Bang,
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index e6e5bba7f00..08f61056d85 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -29,7 +29,7 @@ use crate::json::conversions::{from_item_id, IntoWithTcx};
 use crate::{clean, try_err};
 
 #[derive(Clone)]
-crate struct JsonRenderer<'tcx> {
+pub(crate) struct JsonRenderer<'tcx> {
     tcx: TyCtxt<'tcx>,
     /// A mapping of IDs that contains all local items for this crate which gets output as a top
     /// level field of the JSON blob.
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index dfc70237821..61acf2de90d 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -13,7 +13,6 @@
 #![feature(let_else)]
 #![feature(nll)]
 #![feature(test)]
-#![feature(crate_visibility_modifier)]
 #![feature(never_type)]
 #![feature(once_cell)]
 #![feature(type_ascription)]
@@ -121,7 +120,7 @@ mod formats;
 // used by the error-index generator, so it needs to be public
 pub mod html;
 mod json;
-crate mod lint;
+pub(crate) mod lint;
 mod markdown;
 mod passes;
 mod scrape_examples;
diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs
index 49d8d7fb7fb..08a1a868521 100644
--- a/src/librustdoc/lint.rs
+++ b/src/librustdoc/lint.rs
@@ -169,7 +169,7 @@ declare_rustdoc_lint! {
    "codeblock could not be parsed as valid Rust or is empty"
 }
 
-crate static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
+pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
     vec![
         BROKEN_INTRA_DOC_LINKS,
         PRIVATE_INTRA_DOC_LINKS,
@@ -183,7 +183,7 @@ crate static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
     ]
 });
 
-crate fn register_lints(_sess: &Session, lint_store: &mut LintStore) {
+pub(crate) fn register_lints(_sess: &Session, lint_store: &mut LintStore) {
     lint_store.register_lints(&**RUSTDOC_LINTS);
     lint_store.register_group(
         true,
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 62e42b783e9..0b557ef244e 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -36,7 +36,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").
-crate fn render<P: AsRef<Path>>(
+pub(crate) fn render<P: AsRef<Path>>(
     input: P,
     options: RenderOptions,
     edition: Edition,
@@ -127,7 +127,7 @@ crate fn render<P: AsRef<Path>>(
 }
 
 /// Runs any tests/code examples in the markdown file `input`.
-crate fn test(options: Options) -> Result<(), String> {
+pub(crate) fn test(options: Options) -> Result<(), String> {
     let input_str = read_to_string(&options.input)
         .map_err(|err| format!("{}: {}", options.input.display(), err))?;
     let mut opts = GlobalTestOptions::default();
diff --git a/src/librustdoc/passes/bare_urls.rs b/src/librustdoc/passes/bare_urls.rs
index 1839a35a8b1..e9e810658ef 100644
--- a/src/librustdoc/passes/bare_urls.rs
+++ b/src/librustdoc/passes/bare_urls.rs
@@ -12,7 +12,7 @@ use rustc_errors::Applicability;
 use std::lazy::SyncLazy;
 use std::mem;
 
-crate const CHECK_BARE_URLS: Pass = Pass {
+pub(crate) const CHECK_BARE_URLS: Pass = Pass {
     name: "check-bare-urls",
     run: check_bare_urls,
     description: "detects URLs that are not hyperlinks",
@@ -54,7 +54,7 @@ impl<'a, 'tcx> BareUrlsLinter<'a, 'tcx> {
     }
 }
 
-crate fn check_bare_urls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
+pub(crate) fn check_bare_urls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
     BareUrlsLinter { cx }.visit_crate(&krate);
     krate
 }
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index 0d40ef4c600..3981d49a8a9 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -16,7 +16,7 @@ use serde::Serialize;
 use std::collections::BTreeMap;
 use std::ops;
 
-crate const CALCULATE_DOC_COVERAGE: Pass = Pass {
+pub(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 23d947c4d72..8a50938f82b 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -14,13 +14,16 @@ use crate::html::markdown::{self, RustCodeBlock};
 use crate::passes::Pass;
 use crate::visit::DocVisitor;
 
-crate const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass {
+pub(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",
 };
 
-crate fn check_code_block_syntax(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
+pub(crate) fn check_code_block_syntax(
+    krate: clean::Crate,
+    cx: &mut DocContext<'_>,
+) -> clean::Crate {
     SyntaxChecker { cx }.visit_crate(&krate);
     krate
 }
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 80a2683fde7..0fb0c7dbdd7 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -17,7 +17,7 @@ use rustc_middle::lint::LintLevelSource;
 use rustc_session::lint;
 use rustc_span::symbol::sym;
 
-crate const CHECK_DOC_TEST_VISIBILITY: Pass = Pass {
+pub(crate) const CHECK_DOC_TEST_VISIBILITY: Pass = Pass {
     name: "check_doc_test_visibility",
     run: check_doc_test_visibility,
     description: "run various visibility-related lints on doctests",
@@ -27,7 +27,7 @@ struct DocTestVisibilityLinter<'a, 'tcx> {
     cx: &'a mut DocContext<'tcx>,
 }
 
-crate fn check_doc_test_visibility(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
+pub(crate) fn check_doc_test_visibility(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
     let mut coll = DocTestVisibilityLinter { cx };
     coll.visit_crate(&krate);
     krate
@@ -55,7 +55,7 @@ impl crate::doctest::Tester for Tests {
     }
 }
 
-crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
+pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
     if !cx.cache.access_levels.is_public(item.item_id.expect_def_id())
         || matches!(
             *item.kind,
@@ -106,7 +106,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo
     level != lint::Level::Allow || matches!(source, LintLevelSource::Default)
 }
 
-crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
+pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
     let Some(hir_id) = DocContext::as_local_hir_id(cx.tcx, item.item_id)
     else {
         // If non-local, no need to check anything.
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 95ba4ce5b06..ea0f5102539 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -33,9 +33,9 @@ use crate::passes::Pass;
 use crate::visit::DocVisitor;
 
 mod early;
-crate use early::early_resolve_intra_doc_links;
+pub(crate) use early::early_resolve_intra_doc_links;
 
-crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
+pub(crate) const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
     name: "collect-intra-doc-links",
     run: collect_intra_doc_links,
     description: "resolves intra-doc links",
@@ -219,14 +219,14 @@ enum MalformedGenerics {
 }
 
 #[derive(Clone, Debug, Hash, PartialEq, Eq)]
-crate enum UrlFragment {
+pub(crate) enum UrlFragment {
     Item(ItemFragment),
     UserWritten(String),
 }
 
 impl UrlFragment {
     /// Render the fragment, including the leading `#`.
-    crate fn render(&self, s: &mut String, tcx: TyCtxt<'_>) -> std::fmt::Result {
+    pub(crate) fn render(&self, s: &mut String, tcx: TyCtxt<'_>) -> std::fmt::Result {
         match self {
             UrlFragment::Item(frag) => frag.render(s, tcx),
             UrlFragment::UserWritten(raw) => write!(s, "#{}", raw),
@@ -235,10 +235,10 @@ impl UrlFragment {
 }
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-crate struct ItemFragment(FragmentKind, DefId);
+pub(crate) struct ItemFragment(FragmentKind, DefId);
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-crate enum FragmentKind {
+pub(crate) enum FragmentKind {
     Method,
     TyMethod,
     AssociatedConstant,
@@ -276,7 +276,7 @@ impl FragmentKind {
 
 impl ItemFragment {
     /// Render the fragment, including the leading `#`.
-    crate fn render(&self, s: &mut String, tcx: TyCtxt<'_>) -> std::fmt::Result {
+    pub(crate) fn render(&self, s: &mut String, tcx: TyCtxt<'_>) -> std::fmt::Result {
         write!(s, "#")?;
         match *self {
             ItemFragment(kind, def_id) => {
@@ -954,7 +954,10 @@ struct PreprocessingInfo {
 }
 
 // Not a typedef to avoid leaking several private structures from this module.
-crate struct PreprocessedMarkdownLink(Result<PreprocessingInfo, PreprocessingError>, MarkdownLink);
+pub(crate) struct PreprocessedMarkdownLink(
+    Result<PreprocessingInfo, PreprocessingError>,
+    MarkdownLink,
+);
 
 /// Returns:
 /// - `None` if the link should be ignored.
diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs
index 6f9912e71c5..a38c44bc888 100644
--- a/src/librustdoc/passes/collect_intra_doc_links/early.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs
@@ -21,7 +21,7 @@ use rustc_span::{Symbol, SyntaxContext};
 use std::collections::hash_map::Entry;
 use std::mem;
 
-crate fn early_resolve_intra_doc_links(
+pub(crate) fn early_resolve_intra_doc_links(
     resolver: &mut Resolver<'_>,
     sess: &Session,
     krate: &ast::Crate,
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 3b7ca7dc3c5..aa7028247be 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -12,13 +12,13 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::ty::DefIdTree;
 use rustc_span::symbol::sym;
 
-crate const COLLECT_TRAIT_IMPLS: Pass = Pass {
+pub(crate) const COLLECT_TRAIT_IMPLS: Pass = Pass {
     name: "collect-trait-impls",
     run: collect_trait_impls,
     description: "retrieves trait impls for items in the crate",
 };
 
-crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate {
+pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate {
     let synth_impls = cx.sess().time("collect_synthetic_impls", || {
         let mut synth = SyntheticImplCollector { cx, impls: Vec::new() };
         synth.visit_crate(&krate);
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index 044f224e788..3012db0cad6 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -11,7 +11,7 @@ use std::iter::Peekable;
 use std::ops::Range;
 use std::str::CharIndices;
 
-crate const CHECK_INVALID_HTML_TAGS: Pass = Pass {
+pub(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",
@@ -21,7 +21,7 @@ struct InvalidHtmlTagsLinter<'a, 'tcx> {
     cx: &'a mut DocContext<'tcx>,
 }
 
-crate fn check_invalid_html_tags(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
+pub(crate) fn check_invalid_html_tags(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
     if cx.tcx.sess.is_nightly_build() {
         let mut coll = InvalidHtmlTagsLinter { cx };
         coll.visit_crate(&krate);
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 97a436c7500..f81b38ea395 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -10,61 +10,61 @@ use crate::clean::{self, DocFragmentKind};
 use crate::core::DocContext;
 
 mod stripper;
-crate use stripper::*;
+pub(crate) use stripper::*;
 
 mod bare_urls;
-crate use self::bare_urls::CHECK_BARE_URLS;
+pub(crate) use self::bare_urls::CHECK_BARE_URLS;
 
 mod strip_hidden;
-crate use self::strip_hidden::STRIP_HIDDEN;
+pub(crate) use self::strip_hidden::STRIP_HIDDEN;
 
 mod strip_private;
-crate use self::strip_private::STRIP_PRIVATE;
+pub(crate) use self::strip_private::STRIP_PRIVATE;
 
 mod strip_priv_imports;
-crate use self::strip_priv_imports::STRIP_PRIV_IMPORTS;
+pub(crate) use self::strip_priv_imports::STRIP_PRIV_IMPORTS;
 
 mod propagate_doc_cfg;
-crate use self::propagate_doc_cfg::PROPAGATE_DOC_CFG;
+pub(crate) use self::propagate_doc_cfg::PROPAGATE_DOC_CFG;
 
-crate mod collect_intra_doc_links;
-crate use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS;
+pub(crate) mod collect_intra_doc_links;
+pub(crate) use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS;
 
 mod check_doc_test_visibility;
-crate use self::check_doc_test_visibility::CHECK_DOC_TEST_VISIBILITY;
+pub(crate) use self::check_doc_test_visibility::CHECK_DOC_TEST_VISIBILITY;
 
 mod collect_trait_impls;
-crate use self::collect_trait_impls::COLLECT_TRAIT_IMPLS;
+pub(crate) use self::collect_trait_impls::COLLECT_TRAIT_IMPLS;
 
 mod check_code_block_syntax;
-crate use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX;
+pub(crate) use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX;
 
 mod calculate_doc_coverage;
-crate use self::calculate_doc_coverage::CALCULATE_DOC_COVERAGE;
+pub(crate) use self::calculate_doc_coverage::CALCULATE_DOC_COVERAGE;
 
 mod html_tags;
-crate use self::html_tags::CHECK_INVALID_HTML_TAGS;
+pub(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)]
-crate struct Pass {
-    crate name: &'static str,
-    crate run: fn(clean::Crate, &mut DocContext<'_>) -> clean::Crate,
-    crate description: &'static str,
+pub(crate) struct Pass {
+    pub(crate) name: &'static str,
+    pub(crate) run: fn(clean::Crate, &mut DocContext<'_>) -> clean::Crate,
+    pub(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)]
-crate struct ConditionalPass {
-    crate pass: Pass,
-    crate condition: Condition,
+pub(crate) struct ConditionalPass {
+    pub(crate) pass: Pass,
+    pub(crate) condition: Condition,
 }
 
 /// How to decide whether to run a conditional pass.
 #[derive(Copy, Clone)]
-crate enum Condition {
+pub(crate) enum Condition {
     Always,
     /// When `--document-private-items` is passed.
     WhenDocumentPrivate,
@@ -75,7 +75,7 @@ crate enum Condition {
 }
 
 /// The full list of passes.
-crate const PASSES: &[Pass] = &[
+pub(crate) const PASSES: &[Pass] = &[
     CHECK_DOC_TEST_VISIBILITY,
     STRIP_HIDDEN,
     STRIP_PRIVATE,
@@ -90,7 +90,7 @@ crate const PASSES: &[Pass] = &[
 ];
 
 /// The list of passes run by default.
-crate const DEFAULT_PASSES: &[ConditionalPass] = &[
+pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[
     ConditionalPass::always(COLLECT_TRAIT_IMPLS),
     ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY),
     ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden),
@@ -104,29 +104,29 @@ crate const DEFAULT_PASSES: &[ConditionalPass] = &[
 ];
 
 /// The list of default passes run when `--doc-coverage` is passed to rustdoc.
-crate const COVERAGE_PASSES: &[ConditionalPass] = &[
+pub(crate) const COVERAGE_PASSES: &[ConditionalPass] = &[
     ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden),
     ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate),
     ConditionalPass::always(CALCULATE_DOC_COVERAGE),
 ];
 
 impl ConditionalPass {
-    crate const fn always(pass: Pass) -> Self {
+    pub(crate) const fn always(pass: Pass) -> Self {
         Self::new(pass, Always)
     }
 
-    crate const fn new(pass: Pass, condition: Condition) -> Self {
+    pub(crate) const fn new(pass: Pass, condition: Condition) -> Self {
         ConditionalPass { pass, condition }
     }
 }
 
 /// Returns the given default set of passes.
-crate fn defaults(show_coverage: bool) -> &'static [ConditionalPass] {
+pub(crate) fn defaults(show_coverage: bool) -> &'static [ConditionalPass] {
     if show_coverage { COVERAGE_PASSES } else { DEFAULT_PASSES }
 }
 
 /// Returns a span encompassing all the given attributes.
-crate fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> {
+pub(crate) fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> {
     if attrs.doc_strings.is_empty() {
         return None;
     }
@@ -143,7 +143,7 @@ crate fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> {
 /// This method will return `None` if we cannot construct a span from the source map or if the
 /// attributes are not all sugared doc comments. It's difficult to calculate the correct span in
 /// that case due to escaping and other source features.
-crate fn source_span_for_markdown_range(
+pub(crate) fn source_span_for_markdown_range(
     tcx: TyCtxt<'_>,
     markdown: &str,
     md_range: &Range<usize>,
diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs
index d3df2d2794b..0c5d8365518 100644
--- a/src/librustdoc/passes/propagate_doc_cfg.rs
+++ b/src/librustdoc/passes/propagate_doc_cfg.rs
@@ -7,13 +7,13 @@ use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::passes::Pass;
 
-crate const PROPAGATE_DOC_CFG: Pass = Pass {
+pub(crate) const PROPAGATE_DOC_CFG: Pass = Pass {
     name: "propagate-doc-cfg",
     run: propagate_doc_cfg,
     description: "propagates `#[doc(cfg(...))]` to child items",
 };
 
-crate fn propagate_doc_cfg(cr: Crate, _: &mut DocContext<'_>) -> Crate {
+pub(crate) fn propagate_doc_cfg(cr: Crate, _: &mut 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 6b052185bbd..ab5526e0612 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::{strip_item, DocFolder};
 use crate::passes::{ImplStripper, Pass};
 
-crate const STRIP_HIDDEN: Pass = Pass {
+pub(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)]`
-crate fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
+pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
     let mut retained = ItemIdSet::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 21ce9ae7a28..85be8fa109a 100644
--- a/src/librustdoc/passes/strip_priv_imports.rs
+++ b/src/librustdoc/passes/strip_priv_imports.rs
@@ -5,12 +5,12 @@ use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::passes::{ImportStripper, Pass};
 
-crate const STRIP_PRIV_IMPORTS: Pass = Pass {
+pub(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",
 };
 
-crate fn strip_priv_imports(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate {
+pub(crate) fn strip_priv_imports(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate {
     ImportStripper.fold_crate(krate)
 }
diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs
index ef7e768a511..6c94912bc53 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};
 
-crate const STRIP_PRIVATE: Pass = Pass {
+pub(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 @@ crate 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.
-crate fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
+pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
     // This stripper collects all *retained* nodes.
     let mut retained = ItemIdSet::default();
 
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 6a522bdacf9..d5db919dc4b 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -7,10 +7,10 @@ use crate::clean::{self, Item, ItemIdSet};
 use crate::fold::{strip_item, DocFolder};
 use crate::formats::cache::Cache;
 
-crate struct Stripper<'a> {
-    crate retained: &'a mut ItemIdSet,
-    crate access_levels: &'a AccessLevels<DefId>,
-    crate update_retained: bool,
+pub(crate) struct Stripper<'a> {
+    pub(crate) retained: &'a mut ItemIdSet,
+    pub(crate) access_levels: &'a AccessLevels<DefId>,
+    pub(crate) update_retained: bool,
 }
 
 impl<'a> DocFolder for Stripper<'a> {
@@ -116,9 +116,9 @@ impl<'a> DocFolder for Stripper<'a> {
 }
 
 /// This stripper discards all impls which reference stripped items
-crate struct ImplStripper<'a> {
-    crate retained: &'a ItemIdSet,
-    crate cache: &'a Cache,
+pub(crate) struct ImplStripper<'a> {
+    pub(crate) retained: &'a ItemIdSet,
+    pub(crate) cache: &'a Cache,
 }
 
 impl<'a> DocFolder for ImplStripper<'a> {
@@ -159,7 +159,7 @@ impl<'a> DocFolder for ImplStripper<'a> {
 }
 
 /// This stripper discards all private import statements (`use`, `extern crate`)
-crate struct ImportStripper;
+pub(crate) struct ImportStripper;
 
 impl DocFolder for ImportStripper {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index e0aed1e1ed4..0fa492af1ad 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -31,14 +31,14 @@ use std::fs;
 use std::path::PathBuf;
 
 #[derive(Debug, Clone)]
-crate struct ScrapeExamplesOptions {
+pub(crate) struct ScrapeExamplesOptions {
     output_path: PathBuf,
     target_crates: Vec<String>,
-    crate scrape_tests: bool,
+    pub(crate) scrape_tests: bool,
 }
 
 impl ScrapeExamplesOptions {
-    crate fn new(
+    pub(crate) fn new(
         matches: &getopts::Matches,
         diag: &rustc_errors::Handler,
     ) -> Result<Option<Self>, i32> {
@@ -65,9 +65,9 @@ impl ScrapeExamplesOptions {
 }
 
 #[derive(Encodable, Decodable, Debug, Clone)]
-crate struct SyntaxRange {
-    crate byte_span: (u32, u32),
-    crate line_span: (usize, usize),
+pub(crate) struct SyntaxRange {
+    pub(crate) byte_span: (u32, u32),
+    pub(crate) line_span: (usize, usize),
 }
 
 impl SyntaxRange {
@@ -83,10 +83,10 @@ impl SyntaxRange {
 }
 
 #[derive(Encodable, Decodable, Debug, Clone)]
-crate struct CallLocation {
-    crate call_expr: SyntaxRange,
-    crate call_ident: SyntaxRange,
-    crate enclosing_item: SyntaxRange,
+pub(crate) struct CallLocation {
+    pub(crate) call_expr: SyntaxRange,
+    pub(crate) call_ident: SyntaxRange,
+    pub(crate) enclosing_item: SyntaxRange,
 }
 
 impl CallLocation {
@@ -105,15 +105,15 @@ impl CallLocation {
 }
 
 #[derive(Encodable, Decodable, Debug, Clone)]
-crate struct CallData {
-    crate locations: Vec<CallLocation>,
-    crate url: String,
-    crate display_name: String,
-    crate edition: Edition,
+pub(crate) struct CallData {
+    pub(crate) locations: Vec<CallLocation>,
+    pub(crate) url: String,
+    pub(crate) display_name: String,
+    pub(crate) edition: Edition,
 }
 
-crate type FnCallLocations = FxHashMap<PathBuf, CallData>;
-crate type AllCallLocations = FxHashMap<DefPathHash, FnCallLocations>;
+pub(crate) type FnCallLocations = FxHashMap<PathBuf, CallData>;
+pub(crate) type AllCallLocations = FxHashMap<DefPathHash, FnCallLocations>;
 
 /// Visitor for traversing a crate and finding instances of function calls.
 struct FindCalls<'a, 'tcx> {
@@ -270,7 +270,7 @@ where
     }
 }
 
-crate fn run(
+pub(crate) fn run(
     krate: clean::Crate,
     mut renderopts: config::RenderOptions,
     cache: formats::cache::Cache,
@@ -328,7 +328,7 @@ crate fn run(
 }
 
 // Note: the Handler must be passed in explicitly because sess isn't available while parsing options
-crate fn load_call_locations(
+pub(crate) fn load_call_locations(
     with_examples: Vec<String>,
     diag: &rustc_errors::Handler,
 ) -> Result<AllCallLocations, i32> {
diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs
index 7c19865b6d7..20258c3b1dc 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)]
-crate struct CssPath {
-    crate name: String,
-    crate children: FxHashSet<CssPath>,
+pub(crate) struct CssPath {
+    pub(crate) name: String,
+    pub(crate) children: FxHashSet<CssPath>,
 }
 
 // This PartialEq implementation IS NOT COMMUTATIVE!!!
@@ -214,7 +214,7 @@ fn inner(v: &[u8], events: &[Events], pos: &mut usize) -> FxHashSet<CssPath> {
     paths.iter().cloned().collect()
 }
 
-crate fn load_css_paths(v: &[u8]) -> CssPath {
+pub(crate) fn load_css_paths(v: &[u8]) -> CssPath {
     let events = load_css_events(v);
     let mut pos = 0;
 
@@ -223,7 +223,7 @@ crate fn load_css_paths(v: &[u8]) -> CssPath {
     parent
 }
 
-crate fn get_differences(against: &CssPath, other: &CssPath, v: &mut Vec<String>) {
+pub(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;
@@ -250,7 +250,7 @@ crate fn get_differences(against: &CssPath, other: &CssPath, v: &mut Vec<String>
     }
 }
 
-crate fn test_theme_against<P: AsRef<Path>>(
+pub(crate) fn test_theme_against<P: AsRef<Path>>(
     f: &P,
     against: &CssPath,
     diag: &Handler,
diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs
index ef502926742..fa8be9a97c5 100644
--- a/src/librustdoc/visit.rs
+++ b/src/librustdoc/visit.rs
@@ -1,6 +1,6 @@
 use crate::clean::*;
 
-crate trait DocVisitor: Sized {
+pub(crate) trait DocVisitor: Sized {
     fn visit_item(&mut self, item: &Item) {
         self.visit_item_recur(item)
     }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 75276d18fe5..519ace7b89a 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -21,22 +21,22 @@ use crate::core;
 /// This module is used to store stuff from Rust's AST in a more convenient
 /// manner (and with prettier names) before cleaning.
 #[derive(Debug)]
-crate struct Module<'hir> {
-    crate name: Symbol,
-    crate where_inner: Span,
-    crate mods: Vec<Module<'hir>>,
-    crate id: hir::HirId,
+pub(crate) struct Module<'hir> {
+    pub(crate) name: Symbol,
+    pub(crate) where_inner: Span,
+    pub(crate) mods: Vec<Module<'hir>>,
+    pub(crate) id: hir::HirId,
     // (item, renamed)
-    crate items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>)>,
-    crate foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
+    pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>)>,
+    pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
 }
 
 impl Module<'_> {
-    crate fn new(name: Symbol, id: hir::HirId, where_inner: Span) -> Self {
+    pub(crate) fn new(name: Symbol, id: hir::HirId, where_inner: Span) -> Self {
         Module { name, id, where_inner, mods: Vec::new(), items: Vec::new(), foreigns: Vec::new() }
     }
 
-    crate fn where_outer(&self, tcx: TyCtxt<'_>) -> Span {
+    pub(crate) fn where_outer(&self, tcx: TyCtxt<'_>) -> Span {
         tcx.hir().span(self.id)
     }
 }
@@ -48,7 +48,7 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec<Symbol> {
     std::iter::once(crate_name).chain(relative).collect()
 }
 
-crate fn inherits_doc_hidden(tcx: TyCtxt<'_>, mut node: hir::HirId) -> bool {
+pub(crate) fn inherits_doc_hidden(tcx: TyCtxt<'_>, mut node: hir::HirId) -> bool {
     while let Some(id) = tcx.hir().get_enclosing_scope(node) {
         node = id;
         if tcx.hir().attrs(node).lists(sym::doc).has_word(sym::hidden) {
@@ -61,7 +61,7 @@ crate fn inherits_doc_hidden(tcx: TyCtxt<'_>, mut node: hir::HirId) -> bool {
 // Also, is there some reason that this doesn't use the 'visit'
 // framework from syntax?.
 
-crate struct RustdocVisitor<'a, 'tcx> {
+pub(crate) struct RustdocVisitor<'a, 'tcx> {
     cx: &'a mut core::DocContext<'tcx>,
     view_item_stack: FxHashSet<hir::HirId>,
     inlining: bool,
@@ -71,7 +71,7 @@ crate struct RustdocVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
-    crate fn new(cx: &'a mut core::DocContext<'tcx>) -> RustdocVisitor<'a, 'tcx> {
+    pub(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);
@@ -89,7 +89,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         self.exact_paths.entry(did).or_insert_with(|| def_id_to_path(tcx, did));
     }
 
-    crate fn visit(mut self) -> Module<'tcx> {
+    pub(crate) fn visit(mut self) -> Module<'tcx> {
         let mut top_level_module = self.visit_mod_contents(
             hir::CRATE_HIR_ID,
             self.cx.tcx.hir().root_module(),
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 9723cdbe334..f01ec38665c 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty::TyCtxt;
 
 /// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
 /// specific rustdoc annotations into account (i.e., `doc(hidden)`)
-crate struct LibEmbargoVisitor<'a, 'tcx> {
+pub(crate) struct LibEmbargoVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     // Accessibility levels for reachable nodes
     access_levels: &'a mut AccessLevels<DefId>,
@@ -19,7 +19,7 @@ crate struct LibEmbargoVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
-    crate fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
+    pub(crate) fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
         LibEmbargoVisitor {
             tcx: cx.tcx,
             access_levels: &mut cx.cache.access_levels,
@@ -28,7 +28,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
         }
     }
 
-    crate fn visit_lib(&mut self, cnum: CrateNum) {
+    pub(crate) fn visit_lib(&mut self, cnum: CrateNum) {
         let did = cnum.as_def_id();
         self.update(did, Some(AccessLevel::Public));
         self.visit_mod(did);
@@ -48,7 +48,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
         }
     }
 
-    crate fn visit_mod(&mut self, def_id: DefId) {
+    pub(crate) fn visit_mod(&mut self, def_id: DefId) {
         if !self.visited_mods.insert(def_id) {
             return;
         }
diff --git a/src/test/rustdoc/visibility.rs b/src/test/rustdoc/visibility.rs
index c573e1b77f9..4099b54f081 100644
--- a/src/test/rustdoc/visibility.rs
+++ b/src/test/rustdoc/visibility.rs
@@ -1,7 +1,5 @@
 // compile-flags: --document-private-items
 
-#![feature(crate_visibility_modifier)]
-
 #![crate_name = "foo"]
 
 // @!has 'foo/index.html' '//a[@href="struct.FooPublic.html"]/..' 'FooPublic 🔒'
@@ -9,7 +7,7 @@
 pub struct FooPublic;
 // @has 'foo/index.html' '//a[@href="struct.FooJustCrate.html"]/..' 'FooJustCrate 🔒'
 // @has 'foo/struct.FooJustCrate.html' '//pre' 'pub(crate) struct FooJustCrate'
-crate struct FooJustCrate;
+pub(crate) struct FooJustCrate;
 // @has 'foo/index.html' '//a[@href="struct.FooPubCrate.html"]/..' 'FooPubCrate 🔒'
 // @has 'foo/struct.FooPubCrate.html' '//pre' 'pub(crate) struct FooPubCrate'
 pub(crate) struct FooPubCrate;
diff --git a/src/test/ui/lint/dead-code/issue-85255.rs b/src/test/ui/lint/dead-code/issue-85255.rs
index 8c4aad66d47..871dde91a3e 100644
--- a/src/test/ui/lint/dead-code/issue-85255.rs
+++ b/src/test/ui/lint/dead-code/issue-85255.rs
@@ -2,7 +2,6 @@
 // check-pass
 
 #![warn(dead_code)]
-#![feature(crate_visibility_modifier)]
 
 struct Foo {
     a: i32, //~ WARNING: field is never read
@@ -28,12 +27,12 @@ impl Bar1 {
     pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function is never used
 }
 
-crate struct Foo2 {
+pub(crate) struct Foo2 {
     a: i32, //~ WARNING: field is never read
     pub b: i32, //~ WARNING: field is never read
 }
 
-crate struct Bar2;
+pub(crate) struct Bar2;
 
 impl Bar2 {
     fn a(&self) -> i32 { 5 } //~ WARNING: associated function is never used
diff --git a/src/test/ui/lint/dead-code/issue-85255.stderr b/src/test/ui/lint/dead-code/issue-85255.stderr
index 736b1a20422..5f786d5a2a8 100644
--- a/src/test/ui/lint/dead-code/issue-85255.stderr
+++ b/src/test/ui/lint/dead-code/issue-85255.stderr
@@ -1,5 +1,5 @@
 warning: field is never read: `a`
-  --> $DIR/issue-85255.rs:8:5
+  --> $DIR/issue-85255.rs:7:5
    |
 LL |     a: i32,
    |     ^^^^^^
@@ -11,67 +11,67 @@ LL | #![warn(dead_code)]
    |         ^^^^^^^^^
 
 warning: field is never read: `b`
-  --> $DIR/issue-85255.rs:9:5
+  --> $DIR/issue-85255.rs:8:5
    |
 LL |     pub b: i32,
    |     ^^^^^^^^^^
 
 warning: associated function is never used: `a`
-  --> $DIR/issue-85255.rs:15:8
+  --> $DIR/issue-85255.rs:14:8
    |
 LL |     fn a(&self) -> i32 { 5 }
    |        ^
 
 warning: associated function is never used: `b`
-  --> $DIR/issue-85255.rs:16:12
+  --> $DIR/issue-85255.rs:15:12
    |
 LL |     pub fn b(&self) -> i32 { 6 }
    |            ^
 
 warning: field is never read: `a`
-  --> $DIR/issue-85255.rs:20:5
+  --> $DIR/issue-85255.rs:19:5
    |
 LL |     a: i32,
    |     ^^^^^^
 
 warning: field is never read: `b`
-  --> $DIR/issue-85255.rs:21:5
+  --> $DIR/issue-85255.rs:20:5
    |
 LL |     pub b: i32,
    |     ^^^^^^^^^^
 
 warning: associated function is never used: `a`
-  --> $DIR/issue-85255.rs:27:8
+  --> $DIR/issue-85255.rs:26:8
    |
 LL |     fn a(&self) -> i32 { 5 }
    |        ^
 
 warning: associated function is never used: `b`
-  --> $DIR/issue-85255.rs:28:12
+  --> $DIR/issue-85255.rs:27:12
    |
 LL |     pub fn b(&self) -> i32 { 6 }
    |            ^
 
 warning: field is never read: `a`
-  --> $DIR/issue-85255.rs:32:5
+  --> $DIR/issue-85255.rs:31:5
    |
 LL |     a: i32,
    |     ^^^^^^
 
 warning: field is never read: `b`
-  --> $DIR/issue-85255.rs:33:5
+  --> $DIR/issue-85255.rs:32:5
    |
 LL |     pub b: i32,
    |     ^^^^^^^^^^
 
 warning: associated function is never used: `a`
-  --> $DIR/issue-85255.rs:39:8
+  --> $DIR/issue-85255.rs:38:8
    |
 LL |     fn a(&self) -> i32 { 5 }
    |        ^
 
 warning: associated function is never used: `b`
-  --> $DIR/issue-85255.rs:40:12
+  --> $DIR/issue-85255.rs:39:12
    |
 LL |     pub fn b(&self) -> i32 { 6 }
    |            ^
diff --git a/src/test/ui/lint/unnecessary-extern-crate.rs b/src/test/ui/lint/unnecessary-extern-crate.rs
index 67eaaf4b6c2..af2bd84bd53 100644
--- a/src/test/ui/lint/unnecessary-extern-crate.rs
+++ b/src/test/ui/lint/unnecessary-extern-crate.rs
@@ -1,7 +1,7 @@
 // edition:2018
 
 #![deny(unused_extern_crates)]
-#![feature(test, rustc_private, crate_visibility_modifier)]
+#![feature(test, rustc_private)]
 
 extern crate libc;
 //~^ ERROR unused extern crate
@@ -21,7 +21,7 @@ pub extern crate alloc;
 
 pub(crate) extern crate alloc as a;
 
-crate extern crate alloc as b;
+pub(crate) extern crate alloc as b;
 
 mod foo {
     pub(in crate::foo) extern crate alloc as c;
diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.rs b/src/test/ui/lint/unreachable_pub-pub_crate.rs
deleted file mode 100644
index 4dc951985ae..00000000000
--- a/src/test/ui/lint/unreachable_pub-pub_crate.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-// This is just like unreachable_pub.rs, but without the
-// `crate_visibility_modifier` feature (so that we can test the suggestions to
-// use `pub(crate)` that are given when that feature is off, as opposed to the
-// suggestions to use `crate` given when it is on). When that feature becomes
-// stable, this test can be deleted.
-
-// check-pass
-
-
-#![warn(unreachable_pub)]
-
-mod private_mod {
-    // non-leaked `pub` items in private module should be linted
-    pub use std::fmt; //~ WARNING unreachable_pub
-    pub use std::env::{Args}; // braced-use has different item spans than unbraced
-    //~^ WARNING unreachable_pub
-
-    pub struct Hydrogen { //~ WARNING unreachable_pub
-        // `pub` struct fields, too
-        pub neutrons: usize, //~ WARNING unreachable_pub
-        // (... but not more-restricted fields)
-        pub(crate) electrons: usize
-    }
-    impl Hydrogen {
-        // impls, too
-        pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub
-        pub(crate) fn count_electrons(&self) -> usize { self.electrons }
-    }
-    impl Clone for Hydrogen {
-        fn clone(&self) -> Hydrogen {
-            Hydrogen { neutrons: self.neutrons, electrons: self.electrons }
-        }
-    }
-
-    pub enum Helium {} //~ WARNING unreachable_pub
-    pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub
-    pub fn beryllium() {} //~ WARNING unreachable_pub
-    pub trait Boron {} //~ WARNING unreachable_pub
-    pub const CARBON: usize = 1; //~ WARNING unreachable_pub
-    pub static NITROGEN: usize = 2; //~ WARNING unreachable_pub
-    pub type Oxygen = bool; //~ WARNING unreachable_pub
-
-    macro_rules! define_empty_struct_with_visibility {
-        ($visibility: vis, $name: ident) => { $visibility struct $name {} }
-        //~^ WARNING unreachable_pub
-    }
-    define_empty_struct_with_visibility!(pub, Fluorine);
-
-    extern "C" {
-        pub fn catalyze() -> bool; //~ WARNING unreachable_pub
-    }
-
-    // items leaked through signatures (see `get_neon` below) are OK
-    pub struct Neon {}
-
-    // crate-visible items are OK
-    pub(crate) struct Sodium {}
-}
-
-pub mod public_mod {
-    // module is public: these are OK, too
-    pub struct Magnesium {}
-    pub(crate) struct Aluminum {}
-}
-
-pub fn get_neon() -> private_mod::Neon {
-    private_mod::Neon {}
-}
-
-fn main() {
-    let _ = get_neon();
-}
diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.stderr b/src/test/ui/lint/unreachable_pub-pub_crate.stderr
deleted file mode 100644
index 6c05a030138..00000000000
--- a/src/test/ui/lint/unreachable_pub-pub_crate.stderr
+++ /dev/null
@@ -1,148 +0,0 @@
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:14:5
-   |
-LL |     pub use std::fmt;
-   |     ---^^^^^^^^^^^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-note: the lint level is defined here
-  --> $DIR/unreachable_pub-pub_crate.rs:10:9
-   |
-LL | #![warn(unreachable_pub)]
-   |         ^^^^^^^^^^^^^^^
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:15:24
-   |
-LL |     pub use std::env::{Args}; // braced-use has different item spans than unbraced
-   |     ---                ^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:18:5
-   |
-LL |     pub struct Hydrogen {
-   |     ---^^^^^^^^^^^^^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` field
-  --> $DIR/unreachable_pub-pub_crate.rs:20:9
-   |
-LL |         pub neutrons: usize,
-   |         ---^^^^^^^^^^^^^^^^
-   |         |
-   |         help: consider restricting its visibility: `pub(crate)`
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:26:9
-   |
-LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
-   |         ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |         |
-   |         help: consider restricting its visibility: `pub(crate)`
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:35:5
-   |
-LL |     pub enum Helium {}
-   |     ---^^^^^^^^^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:36:5
-   |
-LL |     pub union Lithium { c1: usize, c2: u8 }
-   |     ---^^^^^^^^^^^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:37:5
-   |
-LL |     pub fn beryllium() {}
-   |     ---^^^^^^^^^^^^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:38:5
-   |
-LL |     pub trait Boron {}
-   |     ---^^^^^^^^^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:39:5
-   |
-LL |     pub const CARBON: usize = 1;
-   |     ---^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:40:5
-   |
-LL |     pub static NITROGEN: usize = 2;
-   |     ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:41:5
-   |
-LL |     pub type Oxygen = bool;
-   |     ---^^^^^^^^^^^^^^^^^^^^
-   |     |
-   |     help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:44:47
-   |
-LL |         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL |     define_empty_struct_with_visibility!(pub, Fluorine);
-   |     ---------------------------------------------------
-   |     |                                    |
-   |     |                                    help: consider restricting its visibility: `pub(crate)`
-   |     in this macro invocation
-   |
-   = help: or consider exporting it for use by other crates
-   = note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:50:9
-   |
-LL |         pub fn catalyze() -> bool;
-   |         ---^^^^^^^^^^^^^^^^^^^^^^^
-   |         |
-   |         help: consider restricting its visibility: `pub(crate)`
-   |
-   = help: or consider exporting it for use by other crates
-
-warning: 14 warnings emitted
-
diff --git a/src/test/ui/lint/unreachable_pub.rs b/src/test/ui/lint/unreachable_pub.rs
index 39e2b596156..a50467ce82d 100644
--- a/src/test/ui/lint/unreachable_pub.rs
+++ b/src/test/ui/lint/unreachable_pub.rs
@@ -1,7 +1,5 @@
 // check-pass
 
-#![feature(crate_visibility_modifier)]
-
 #![allow(unused)]
 #![warn(unreachable_pub)]
 
@@ -15,12 +13,12 @@ mod private_mod {
         // `pub` struct fields, too
         pub neutrons: usize, //~ WARNING unreachable_pub
         // (... but not more-restricted fields)
-        crate electrons: usize
+        pub(crate) electrons: usize
     }
     impl Hydrogen {
         // impls, too
         pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub
-        crate fn count_electrons(&self) -> usize { self.electrons }
+        pub(crate) fn count_electrons(&self) -> usize { self.electrons }
     }
     impl Clone for Hydrogen {
         fn clone(&self) -> Hydrogen {
@@ -50,13 +48,13 @@ mod private_mod {
     pub struct Neon {}
 
     // crate-visible items are OK
-    crate struct Sodium {}
+    pub(crate) struct Sodium {}
 }
 
 pub mod public_mod {
     // module is public: these are OK, too
     pub struct Magnesium {}
-    crate struct Aluminum {}
+    pub(crate) struct Aluminum {}
 }
 
 pub fn get_neon() -> private_mod::Neon {
diff --git a/src/test/ui/lint/unreachable_pub.stderr b/src/test/ui/lint/unreachable_pub.stderr
index e8e55be5a47..ce22eca1b8c 100644
--- a/src/test/ui/lint/unreachable_pub.stderr
+++ b/src/test/ui/lint/unreachable_pub.stderr
@@ -1,126 +1,126 @@
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:10:5
+  --> $DIR/unreachable_pub.rs:8:5
    |
 LL |     pub use std::fmt;
    |     ---^^^^^^^^^^^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
 note: the lint level is defined here
-  --> $DIR/unreachable_pub.rs:6:9
+  --> $DIR/unreachable_pub.rs:4:9
    |
 LL | #![warn(unreachable_pub)]
    |         ^^^^^^^^^^^^^^^
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:11:24
+  --> $DIR/unreachable_pub.rs:9:24
    |
 LL |     pub use std::env::{Args}; // braced-use has different item spans than unbraced
    |     ---                ^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:14:5
+  --> $DIR/unreachable_pub.rs:12:5
    |
 LL |     pub struct Hydrogen {
    |     ---^^^^^^^^^^^^^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` field
-  --> $DIR/unreachable_pub.rs:16:9
+  --> $DIR/unreachable_pub.rs:14:9
    |
 LL |         pub neutrons: usize,
    |         ---^^^^^^^^^^^^^^^^
    |         |
-   |         help: consider restricting its visibility: `crate`
+   |         help: consider restricting its visibility: `pub(crate)`
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:22:9
+  --> $DIR/unreachable_pub.rs:20:9
    |
 LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
    |         ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |         |
-   |         help: consider restricting its visibility: `crate`
+   |         help: consider restricting its visibility: `pub(crate)`
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:31:5
+  --> $DIR/unreachable_pub.rs:29:5
    |
 LL |     pub enum Helium {}
    |     ---^^^^^^^^^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:32:5
+  --> $DIR/unreachable_pub.rs:30:5
    |
 LL |     pub union Lithium { c1: usize, c2: u8 }
    |     ---^^^^^^^^^^^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:33:5
+  --> $DIR/unreachable_pub.rs:31:5
    |
 LL |     pub fn beryllium() {}
    |     ---^^^^^^^^^^^^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:34:5
+  --> $DIR/unreachable_pub.rs:32:5
    |
 LL |     pub trait Boron {}
    |     ---^^^^^^^^^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:35:5
+  --> $DIR/unreachable_pub.rs:33:5
    |
 LL |     pub const CARBON: usize = 1;
    |     ---^^^^^^^^^^^^^^^^^^^^^^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:36:5
+  --> $DIR/unreachable_pub.rs:34:5
    |
 LL |     pub static NITROGEN: usize = 2;
    |     ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:37:5
+  --> $DIR/unreachable_pub.rs:35:5
    |
 LL |     pub type Oxygen = bool;
    |     ---^^^^^^^^^^^^^^^^^^^^
    |     |
-   |     help: consider restricting its visibility: `crate`
+   |     help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:40:47
+  --> $DIR/unreachable_pub.rs:38:47
    |
 LL |         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -128,19 +128,19 @@ LL |         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
 LL |     define_empty_struct_with_visibility!(pub, Fluorine);
    |     ---------------------------------------------------
    |     |                                    |
-   |     |                                    help: consider restricting its visibility: `crate`
+   |     |                                    help: consider restricting its visibility: `pub(crate)`
    |     in this macro invocation
    |
    = help: or consider exporting it for use by other crates
    = note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:46:9
+  --> $DIR/unreachable_pub.rs:44:9
    |
 LL |         pub fn catalyze() -> bool;
    |         ---^^^^^^^^^^^^^^^^^^^^^^^
    |         |
-   |         help: consider restricting its visibility: `crate`
+   |         help: consider restricting its visibility: `pub(crate)`
    |
    = help: or consider exporting it for use by other crates
 
diff --git a/src/test/ui/macros/macro-pub-matcher.rs b/src/test/ui/macros/macro-pub-matcher.rs
index 174056d6cdf..7b02a70be09 100644
--- a/src/test/ui/macros/macro-pub-matcher.rs
+++ b/src/test/ui/macros/macro-pub-matcher.rs
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code, unused_imports, unused_macro_rules)]
-#![feature(crate_visibility_modifier)]
 
 /**
 Ensure that `:vis` matches can be captured in existing positions, and passed
@@ -56,15 +55,15 @@ mod with_pub_restricted {
 }
 
 mod with_crate {
-    vis_passthru! { crate const A: i32 = 0; }
-    vis_passthru! { crate enum B {} }
-    vis_passthru! { crate extern "C" fn c() {} }
-    vis_passthru! { crate mod d {} }
-    vis_passthru! { crate static E: i32 = 0; }
-    vis_passthru! { crate struct F; }
-    vis_passthru! { crate trait G {} }
-    vis_passthru! { crate type H = i32; }
-    vis_passthru! { crate use A as I; }
+    vis_passthru! { pub(crate) const A: i32 = 0; }
+    vis_passthru! { pub(crate) enum B {} }
+    vis_passthru! { pub(crate) extern "C" fn c() {} }
+    vis_passthru! { pub(crate) mod d {} }
+    vis_passthru! { pub(crate) static E: i32 = 0; }
+    vis_passthru! { pub(crate) struct F; }
+    vis_passthru! { pub(crate) trait G {} }
+    vis_passthru! { pub(crate) type H = i32; }
+    vis_passthru! { pub(crate) use A as I; }
 }
 
 mod garden {
diff --git a/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.rs b/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.rs
index 8f9dc4bc945..6f115e78e14 100644
--- a/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.rs
+++ b/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.rs
@@ -1,5 +1,3 @@
-#![feature(crate_visibility_modifier)]
-
 #[deny(unused_imports)]
 mod rank {
     pub use self::Professor::*;
@@ -31,7 +29,7 @@ mod rank {
         MasterChief
     }
 
-    crate enum Crewman {
+    pub(crate) enum Crewman {
         Recruit,
         Apprentice,
         Full
diff --git a/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.stderr b/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.stderr
index d4d9b31ed83..59b181fab40 100644
--- a/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.stderr
+++ b/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.stderr
@@ -1,47 +1,47 @@
 error[E0364]: `JuniorGrade` is private, and cannot be re-exported
-  --> $DIR/issue-46209-private-enum-variant-reexport.rs:7:32
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:5:32
    |
 LL |     pub use self::Lieutenant::{JuniorGrade, Full};
    |                                ^^^^^^^^^^^
    |
 note: consider marking `JuniorGrade` as `pub` in the imported module
-  --> $DIR/issue-46209-private-enum-variant-reexport.rs:7:32
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:5:32
    |
 LL |     pub use self::Lieutenant::{JuniorGrade, Full};
    |                                ^^^^^^^^^^^
 
 error[E0364]: `Full` is private, and cannot be re-exported
-  --> $DIR/issue-46209-private-enum-variant-reexport.rs:7:45
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:5:45
    |
 LL |     pub use self::Lieutenant::{JuniorGrade, Full};
    |                                             ^^^^
    |
 note: consider marking `Full` as `pub` in the imported module
-  --> $DIR/issue-46209-private-enum-variant-reexport.rs:7:45
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:5:45
    |
 LL |     pub use self::Lieutenant::{JuniorGrade, Full};
    |                                             ^^^^
 
 error: glob import doesn't reexport anything because no candidate is public enough
-  --> $DIR/issue-46209-private-enum-variant-reexport.rs:5:13
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:3:13
    |
 LL |     pub use self::Professor::*;
    |             ^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/issue-46209-private-enum-variant-reexport.rs:3:8
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:1:8
    |
 LL | #[deny(unused_imports)]
    |        ^^^^^^^^^^^^^^
 
 error: glob import doesn't reexport anything because no candidate is public enough
-  --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:8:13
    |
 LL |     pub use self::PettyOfficer::*;
    |             ^^^^^^^^^^^^^^^^^^^^^
 
 error: glob import doesn't reexport anything because no candidate is public enough
-  --> $DIR/issue-46209-private-enum-variant-reexport.rs:12:13
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13
    |
 LL |     pub use self::Crewman::*;
    |             ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/privacy/restricted/auxiliary/pub_restricted.rs b/src/test/ui/privacy/restricted/auxiliary/pub_restricted.rs
index 482d5cdc45d..a4013e6ac60 100644
--- a/src/test/ui/privacy/restricted/auxiliary/pub_restricted.rs
+++ b/src/test/ui/privacy/restricted/auxiliary/pub_restricted.rs
@@ -1,16 +1,14 @@
-#![feature(crate_visibility_modifier)]
-
 pub(crate) struct Crate;
 
 #[derive(Default)]
 pub struct Universe {
     pub x: i32,
     pub(crate) y: i32,
-    crate z: i32,
+    pub(crate) z: i32,
 }
 
 impl Universe {
     pub fn f(&self) {}
     pub(crate) fn g(&self) {}
-    crate fn h(&self) {}
+    pub(crate) fn h(&self) {}
 }
diff --git a/src/test/ui/privacy/restricted/private-in-public.rs b/src/test/ui/privacy/restricted/private-in-public.rs
index 7cae28970d4..1e3dbdf73b9 100644
--- a/src/test/ui/privacy/restricted/private-in-public.rs
+++ b/src/test/ui/privacy/restricted/private-in-public.rs
@@ -1,12 +1,10 @@
-#![feature(crate_visibility_modifier)]
-
 mod foo {
     struct Priv;
     mod bar {
         use foo::Priv;
         pub(super) fn f(_: Priv) {}
         pub(crate) fn g(_: Priv) {} //~ ERROR E0446
-        crate fn h(_: Priv) {} //~ ERROR E0446
+        pub(crate) fn h(_: Priv) {} //~ ERROR E0446
     }
 }
 
diff --git a/src/test/ui/privacy/restricted/private-in-public.stderr b/src/test/ui/privacy/restricted/private-in-public.stderr
index c14382ce290..ee9c031ebff 100644
--- a/src/test/ui/privacy/restricted/private-in-public.stderr
+++ b/src/test/ui/privacy/restricted/private-in-public.stderr
@@ -1,5 +1,5 @@
 error[E0446]: private type `Priv` in public interface
-  --> $DIR/private-in-public.rs:8:9
+  --> $DIR/private-in-public.rs:6:9
    |
 LL |     struct Priv;
    |     ------------ `Priv` declared as private
@@ -8,13 +8,13 @@ LL |         pub(crate) fn g(_: Priv) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
 
 error[E0446]: private type `Priv` in public interface
-  --> $DIR/private-in-public.rs:9:9
+  --> $DIR/private-in-public.rs:7:9
    |
 LL |     struct Priv;
    |     ------------ `Priv` declared as private
 ...
-LL |         crate fn h(_: Priv) {}
-   |         ^^^^^^^^^^^^^^^^^^^ can't leak private type
+LL |         pub(crate) fn h(_: Priv) {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/privacy/restricted/test.stderr b/src/test/ui/privacy/restricted/test.stderr
index 0f6003c4247..5a85aef2b17 100644
--- a/src/test/ui/privacy/restricted/test.stderr
+++ b/src/test/ui/privacy/restricted/test.stderr
@@ -29,7 +29,7 @@ LL |     use pub_restricted::Crate;
    |                         ^^^^^ private struct
    |
 note: the struct `Crate` is defined here
-  --> $DIR/auxiliary/pub_restricted.rs:3:1
+  --> $DIR/auxiliary/pub_restricted.rs:1:1
    |
 LL | pub(crate) struct Crate;
    | ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +88,7 @@ error[E0624]: associated function `g` is private
 LL |     u.g();
    |       ^ private associated function
    |
-  ::: $DIR/auxiliary/pub_restricted.rs:14:5
+  ::: $DIR/auxiliary/pub_restricted.rs:12:5
    |
 LL |     pub(crate) fn g(&self) {}
    |     ---------------------- private associated function defined here
@@ -99,10 +99,10 @@ error[E0624]: associated function `h` is private
 LL |     u.h();
    |       ^ private associated function
    |
-  ::: $DIR/auxiliary/pub_restricted.rs:15:5
+  ::: $DIR/auxiliary/pub_restricted.rs:13:5
    |
-LL |     crate fn h(&self) {}
-   |     ----------------- private associated function defined here
+LL |     pub(crate) fn h(&self) {}
+   |     ---------------------- private associated function defined here
 
 error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/resolve/crate-in-paths.rs b/src/test/ui/resolve/crate-in-paths.rs
index 50ed50cbef0..7ebd259189d 100644
--- a/src/test/ui/resolve/crate-in-paths.rs
+++ b/src/test/ui/resolve/crate-in-paths.rs
@@ -1,9 +1,7 @@
 // edition:2018
 
-#![feature(crate_visibility_modifier)]
-
 mod bar {
-    crate struct Foo;
+    pub(crate) struct Foo;
 }
 
 fn main() {
diff --git a/src/test/ui/resolve/crate-in-paths.stderr b/src/test/ui/resolve/crate-in-paths.stderr
index c3aa135f77d..b7cf4950759 100644
--- a/src/test/ui/resolve/crate-in-paths.stderr
+++ b/src/test/ui/resolve/crate-in-paths.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `Foo` in this scope
-  --> $DIR/crate-in-paths.rs:10:5
+  --> $DIR/crate-in-paths.rs:8:5
    |
 LL |     Foo;
    |     ^^^ not found in this scope
diff --git a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed
index 37847a98ac7..85d106bc11f 100644
--- a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed
+++ b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed
@@ -1,14 +1,14 @@
 // run-rustfix
 
-#![feature(rust_2018_preview, crate_visibility_modifier)]
+#![feature(rust_2018_preview)]
 #![deny(absolute_paths_not_starting_with_crate)]
 
 mod foo {
-    crate trait Foo {
+    pub(crate) trait Foo {
         type Bar;
     }
 
-    crate struct Baz {}
+    pub(crate) struct Baz {}
 
     impl Foo for Baz {
         type Bar = ();
diff --git a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs
index 36efa14601d..9ff3c2e5fcf 100644
--- a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs
+++ b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs
@@ -1,14 +1,14 @@
 // run-rustfix
 
-#![feature(rust_2018_preview, crate_visibility_modifier)]
+#![feature(rust_2018_preview)]
 #![deny(absolute_paths_not_starting_with_crate)]
 
 mod foo {
-    crate trait Foo {
+    pub(crate) trait Foo {
         type Bar;
     }
 
-    crate struct Baz {}
+    pub(crate) struct Baz {}
 
     impl Foo for Baz {
         type Bar = ();
diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed
index 5786ed7b1d5..f25d46ce30d 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed
+++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed
@@ -1,16 +1,16 @@
 // run-rustfix
 
-#![feature(rust_2018_preview, crate_visibility_modifier)]
+#![feature(rust_2018_preview)]
 #![deny(absolute_paths_not_starting_with_crate)]
 #![allow(unused_imports)]
 #![allow(dead_code)]
 
-crate mod foo {
-    crate mod bar {
-        crate mod baz { }
-        crate mod baz1 { }
+pub(crate) mod foo {
+    pub(crate) mod bar {
+        pub(crate) mod baz { }
+        pub(crate) mod baz1 { }
 
-        crate struct XX;
+        pub(crate) struct XX;
     }
 }
 
diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs
index b7c86088c75..9be1680c1ce 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs
+++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs
@@ -1,16 +1,16 @@
 // run-rustfix
 
-#![feature(rust_2018_preview, crate_visibility_modifier)]
+#![feature(rust_2018_preview)]
 #![deny(absolute_paths_not_starting_with_crate)]
 #![allow(unused_imports)]
 #![allow(dead_code)]
 
-crate mod foo {
-    crate mod bar {
-        crate mod baz { }
-        crate mod baz1 { }
+pub(crate) mod foo {
+    pub(crate) mod bar {
+        pub(crate) mod baz { }
+        pub(crate) mod baz1 { }
 
-        crate struct XX;
+        pub(crate) struct XX;
     }
 }
 
diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.fixed b/src/test/ui/rust-2018/edition-lint-nested-paths.fixed
index c4546f8c821..a04937ae8ee 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-paths.fixed
+++ b/src/test/ui/rust-2018/edition-lint-nested-paths.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![feature(rust_2018_preview, crate_visibility_modifier)]
+#![feature(rust_2018_preview)]
 #![deny(absolute_paths_not_starting_with_crate)]
 
 use crate::foo::{a, b};
@@ -10,9 +10,9 @@ use crate::foo::{a, b};
 //~| this is accepted in the current edition
 
 mod foo {
-    crate fn a() {}
-    crate fn b() {}
-    crate fn c() {}
+    pub(crate) fn a() {}
+    pub(crate) fn b() {}
+    pub(crate) fn c() {}
 }
 
 fn main() {
diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.rs b/src/test/ui/rust-2018/edition-lint-nested-paths.rs
index a7e34e407a3..e622a8e24be 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-paths.rs
+++ b/src/test/ui/rust-2018/edition-lint-nested-paths.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![feature(rust_2018_preview, crate_visibility_modifier)]
+#![feature(rust_2018_preview)]
 #![deny(absolute_paths_not_starting_with_crate)]
 
 use foo::{a, b};
@@ -10,9 +10,9 @@ use foo::{a, b};
 //~| this is accepted in the current edition
 
 mod foo {
-    crate fn a() {}
-    crate fn b() {}
-    crate fn c() {}
+    pub(crate) fn a() {}
+    pub(crate) fn b() {}
+    pub(crate) fn c() {}
 }
 
 fn main() {
diff --git a/src/tools/rustfmt/tests/source/fn-simple.rs b/src/tools/rustfmt/tests/source/fn-simple.rs
index 528b9a0292a..12a50c013a9 100644
--- a/src/tools/rustfmt/tests/source/fn-simple.rs
+++ b/src/tools/rustfmt/tests/source/fn-simple.rs
@@ -63,7 +63,7 @@ mod foo {
 // #2082
 pub(crate) fn init() {}
 
-crate fn init() {}
+pub(crate) fn init() {}
 
 // #2630
 fn make_map<T, F: (Fn(&T) -> String)>(records: &Vec<T>, key_fn: F) -> HashMap<String, usize> {}
diff --git a/src/tools/rustfmt/tests/source/pub-restricted.rs b/src/tools/rustfmt/tests/source/pub-restricted.rs
index 30051fa72ee..5683acbf3aa 100644
--- a/src/tools/rustfmt/tests/source/pub-restricted.rs
+++ b/src/tools/rustfmt/tests/source/pub-restricted.rs
@@ -24,19 +24,6 @@ pub(  crate  ) enum WriteState<D> {
     WriteData(Writer<D>),
 }
 
-  crate   enum WriteState<D> {
-    WriteId {
-        id: U64Writer,
-        size: U64Writer,
-        payload: Option<Writer<D>>,
-    },
-    WriteSize {
-        size: U64Writer,
-        payload: Option<Writer<D>>,
-    },
-    WriteData(Writer<D>),
-}
-
 pub(in  ::global::  path :: to::some_mod  ) enum WriteState<D> {
     WriteId {
         id: U64Writer,
diff --git a/src/tools/rustfmt/tests/target/fn-simple.rs b/src/tools/rustfmt/tests/target/fn-simple.rs
index 692739fa6a9..e725269360d 100644
--- a/src/tools/rustfmt/tests/target/fn-simple.rs
+++ b/src/tools/rustfmt/tests/target/fn-simple.rs
@@ -105,7 +105,7 @@ mod foo {
 // #2082
 pub(crate) fn init() {}
 
-crate fn init() {}
+pub(crate) fn init() {}
 
 // #2630
 fn make_map<T, F: (Fn(&T) -> String)>(records: &Vec<T>, key_fn: F) -> HashMap<String, usize> {}
diff --git a/src/tools/rustfmt/tests/target/pub-restricted.rs b/src/tools/rustfmt/tests/target/pub-restricted.rs
index 8cc2ade612a..0e178ef1013 100644
--- a/src/tools/rustfmt/tests/target/pub-restricted.rs
+++ b/src/tools/rustfmt/tests/target/pub-restricted.rs
@@ -24,19 +24,6 @@ pub(crate) enum WriteState<D> {
     WriteData(Writer<D>),
 }
 
-crate enum WriteState<D> {
-    WriteId {
-        id: U64Writer,
-        size: U64Writer,
-        payload: Option<Writer<D>>,
-    },
-    WriteSize {
-        size: U64Writer,
-        payload: Option<Writer<D>>,
-    },
-    WriteData(Writer<D>),
-}
-
 pub(in global::path::to::some_mod) enum WriteState<D> {
     WriteId {
         id: U64Writer,