about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-08-06 08:12:07 +0000
committerbors <bors@rust-lang.org>2024-08-06 08:12:07 +0000
commit5b2cdc1f65285f39ba871fb7d47b60f07f51002c (patch)
tree8cd5865bacfa8c796f818acf8bde7ce95a724f38 /src
parentf6edc8a07c831a423e367049f39a96eb10137320 (diff)
parentac3e3491101a021e79ce79399b4d6803fc79bf8f (diff)
downloadrust-5b2cdc1f65285f39ba871fb7d47b60f07f51002c.tar.gz
rust-5b2cdc1f65285f39ba871fb7d47b60f07f51002c.zip
Auto merge of #3791 - rust-lang:rustup-2024-08-06, r=RalfJung
Automatic Rustup
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs14
-rw-r--r--src/bootstrap/src/utils/helpers.rs3
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile14
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md47
-rw-r--r--src/librustdoc/clean/inline.rs16
-rw-r--r--src/librustdoc/clean/mod.rs11
-rw-r--r--src/librustdoc/clean/simplify.rs1
-rw-r--r--src/librustdoc/clean/types.rs37
-rw-r--r--src/librustdoc/clean/utils.rs2
-rw-r--r--src/librustdoc/formats/cache.rs38
-rw-r--r--src/librustdoc/html/format.rs30
-rw-r--r--src/librustdoc/html/render/mod.rs15
-rw-r--r--src/librustdoc/html/render/search_index.rs483
-rw-r--r--src/librustdoc/json/conversions.rs4
-rw-r--r--src/librustdoc/json/mod.rs6
-rw-r--r--src/tools/build-manifest/src/main.rs1
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs2
-rw-r--r--src/tools/run-make-support/src/external_deps/c_build.rs4
-rw-r--r--src/tools/run-make-support/src/external_deps/cc.rs10
-rw-r--r--src/tools/run-make-support/src/external_deps/cygpath.rs35
-rw-r--r--src/tools/run-make-support/src/external_deps/llvm.rs3
-rw-r--r--src/tools/run-make-support/src/external_deps/mod.rs3
-rw-r--r--src/tools/run-make-support/src/fs.rs26
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt2
27 files changed, 413 insertions, 399 deletions
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 1541396bfdd..2cd5db706c2 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -599,6 +599,16 @@ impl Step for Std {
     fn run(self, builder: &Builder<'_>) {
         let stage = self.stage;
         let target = self.target;
+        let crates = if self.crates.is_empty() {
+            builder
+                .in_tree_crates("sysroot", Some(target))
+                .iter()
+                .map(|c| c.name.to_string())
+                .collect()
+        } else {
+            self.crates
+        };
+
         let out = match self.format {
             DocumentationFormat::Html => builder.doc_out(target),
             DocumentationFormat::Json => builder.json_doc_out(target),
@@ -627,7 +637,7 @@ impl Step for Std {
             extra_args.push("--disable-minification");
         }
 
-        doc_std(builder, self.format, stage, target, &out, &extra_args, &self.crates);
+        doc_std(builder, self.format, stage, target, &out, &extra_args, &crates);
 
         // Don't open if the format is json
         if let DocumentationFormat::Json = self.format {
@@ -639,7 +649,7 @@ impl Step for Std {
             let index = out.join("std").join("index.html");
             builder.open_in_browser(index);
         } else {
-            for requested_crate in &*self.crates {
+            for requested_crate in crates {
                 if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
                     let index = out.join(requested_crate).join("index.html");
                     builder.open_in_browser(index);
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 16959ce7e82..65e75f114bb 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -536,8 +536,7 @@ pub fn get_closest_merge_base_commit(
 
     let merge_base = get_git_merge_base(config, source_dir).unwrap_or_else(|_| "HEAD".into());
 
-    git.arg(Path::new("rev-list"));
-    git.args([&format!("--author={author}"), "-n1", "--first-parent", &merge_base]);
+    git.args(["rev-list", &format!("--author={author}"), "-n1", "--first-parent", &merge_base]);
 
     if !target_paths.is_empty() {
         git.arg("--").args(target_paths);
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index 2621e9a6031..1b98d541693 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -24,7 +24,8 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no
   # Needed for apt-key to work:
   dirmngr \
   gpg-agent \
-  g++-9-arm-linux-gnueabi
+  g++-9-arm-linux-gnueabi \
+  g++-11-riscv64-linux-gnu
 
 RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7924C5513486
 RUN add-apt-repository -y 'deb https://apt.dilos.org/dilos dilos2 main'
@@ -73,6 +74,10 @@ RUN env \
     CC=arm-linux-gnueabi-gcc-9 CFLAGS="-march=armv7-a" \
     CXX=arm-linux-gnueabi-g++-9 CXXFLAGS="-march=armv7-a" \
     bash musl.sh armv7 && \
+    env \
+    CC=riscv64-linux-gnu-gcc-11 \
+    CXX=riscv64-linux-gnu-g++-11 \
+    bash musl.sh riscv64gc && \
     rm -rf /build/*
 
 WORKDIR /tmp
@@ -125,6 +130,7 @@ ENV TARGETS=$TARGETS,x86_64-unknown-none
 ENV TARGETS=$TARGETS,aarch64-unknown-uefi
 ENV TARGETS=$TARGETS,i686-unknown-uefi
 ENV TARGETS=$TARGETS,x86_64-unknown-uefi
+ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-musl
 
 # As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211
 # we need asm in the search path for gcc-9 (for gnux32) but not in the search path of the
@@ -132,7 +138,11 @@ ENV TARGETS=$TARGETS,x86_64-unknown-uefi
 # Luckily one of the folders is /usr/local/include so symlink /usr/include/x86_64-linux-gnu/asm there
 RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm
 
+# musl-gcc can't find libgcc_s.so.1 since it doesn't use the standard search paths.
+RUN ln -s /usr/riscv64-linux-gnu/lib/libgcc_s.so.1 /usr/lib/gcc-cross/riscv64-linux-gnu/11/
+
 ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \
-  --musl-root-armv7=/musl-armv7
+  --musl-root-armv7=/musl-armv7 \
+  --musl-root-riscv64gc=/musl-riscv64gc
 
 ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index d5141591b97..467fd6f43e4 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -66,6 +66,7 @@
     - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
     - [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
     - [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md)
+    - [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md)
     - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
     - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
     - [\*-nto-qnx-\*](platform-support/nto-qnx.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index f3b49a65aad..7fd1808a1f0 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -98,6 +98,7 @@ target | notes
 `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17)
 `powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17)
 [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29)
+[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3)
 `s390x-unknown-linux-gnu` | S390x Linux (kernel 3.2, glibc 2.17)
 `x86_64-unknown-freebsd` | 64-bit FreeBSD
 `x86_64-unknown-illumos` | illumos
@@ -354,7 +355,6 @@ target | std | host | notes
 [`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ |   | RISC-V Hermit
 `riscv64gc-unknown-freebsd` |   |   | RISC-V FreeBSD
 `riscv64gc-unknown-fuchsia` |   |   | RISC-V Fuchsia
-`riscv64gc-unknown-linux-musl` |   |   | RISC-V Linux (kernel 4.20, musl 1.2.3)
 [`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD
 [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
 [`riscv64-linux-android`](platform-support/android.md) |   |   | RISC-V 64-bit Android
diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md
new file mode 100644
index 00000000000..5b3dc683038
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md
@@ -0,0 +1,47 @@
+# riscv64gc-unknown-linux-musl
+
+**Tier: 2**
+
+Target for RISC-V Linux programs using musl libc.
+
+## Target maintainers
+
+- [@Amanieu](https://github.com/Amanieu)
+- [@kraj](https://github.com/kraj)
+
+## Requirements
+
+Building the target itself requires a RISC-V compiler that is supported by `cc-rs`.
+
+## Building the target
+
+The target can be built by enabling it for a `rustc` build.
+
+```toml
+[build]
+target = ["riscv64gc-unknown-linux-musl"]
+```
+
+Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`:
+
+```toml
+[target.riscv64gc-unknown-linux-musl]
+cc = "riscv64-linux-gnu-gcc"
+cxx = "riscv64-linux-gnu-g++"
+ar = "riscv64-linux-gnu-ar"
+linker = "riscv64-linux-gnu-gcc"
+```
+
+## Building Rust programs
+
+This target are distributed through `rustup`, and otherwise require no
+special configuration.
+
+## Cross-compilation
+
+This target can be cross-compiled from any host.
+
+## Testing
+
+This target can be tested as normal with `x.py` on a RISC-V host or via QEMU
+emulation.
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index d92bc845664..f8953f0ebcf 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -12,7 +12,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::hygiene::MacroKind;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{sym, Symbol};
 use thin_vec::{thin_vec, ThinVec};
 use {rustc_ast as ast, rustc_hir as hir};
 
@@ -792,11 +792,7 @@ fn build_macro(
 fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
     for pred in &mut g.where_predicates {
         match *pred {
-            clean::WherePredicate::BoundPredicate {
-                ty: clean::Generic(ref s),
-                ref mut bounds,
-                ..
-            } if *s == kw::SelfUpper => {
+            clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref mut bounds, .. } => {
                 bounds.retain(|bound| match bound {
                     clean::GenericBound::TraitBound(clean::PolyTrait { trait_, .. }, _) => {
                         trait_.def_id() != trait_did
@@ -812,13 +808,13 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
         clean::WherePredicate::BoundPredicate {
             ty:
                 clean::QPath(box clean::QPathData {
-                    self_type: clean::Generic(ref s),
+                    self_type: clean::Generic(_),
                     trait_: Some(trait_),
                     ..
                 }),
             bounds,
             ..
-        } => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
+        } => !bounds.is_empty() && trait_.def_id() != trait_did,
         _ => true,
     });
     g
@@ -832,9 +828,7 @@ fn separate_supertrait_bounds(
 ) -> (clean::Generics, Vec<clean::GenericBound>) {
     let mut ty_bounds = Vec::new();
     g.where_predicates.retain(|pred| match *pred {
-        clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds, .. }
-            if *s == kw::SelfUpper =>
-        {
+        clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref bounds, .. } => {
             ty_bounds.extend(bounds.iter().cloned());
             false
         }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 324b633e8ea..cffadc7c10a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1351,11 +1351,11 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
                 let self_arg_ty =
                     tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder();
                 if self_arg_ty == self_ty {
-                    item.decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
+                    item.decl.inputs.values[0].type_ = SelfTy;
                 } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
                     if ty == self_ty {
                         match item.decl.inputs.values[0].type_ {
-                            BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper),
+                            BorrowedRef { ref mut type_, .. } => **type_ = SelfTy,
                             _ => unreachable!(),
                         }
                     }
@@ -1439,9 +1439,8 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
                         if trait_.def_id() != assoc_item.container_id(tcx) {
                             return true;
                         }
-                        match *self_type {
-                            Generic(ref s) if *s == kw::SelfUpper => {}
-                            _ => return true,
+                        if *self_type != SelfTy {
+                            return true;
                         }
                         match &assoc.args {
                             GenericArgs::AngleBracketed { args, constraints } => {
@@ -2228,6 +2227,8 @@ pub(crate) fn clean_middle_ty<'tcx>(
         ty::Param(ref p) => {
             if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
                 ImplTrait(bounds)
+            } else if p.name == kw::SelfUpper {
+                SelfTy
             } else {
                 Generic(p.name)
             }
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 739f6eb8cc8..1d81ae3eb8b 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -145,7 +145,6 @@ pub(crate) fn sized_bounds(cx: &mut DocContext<'_>, generics: &mut clean::Generi
     // should be handled when cleaning associated types.
     generics.where_predicates.retain(|pred| {
         if let WP::BoundPredicate { ty: clean::Generic(param), bounds, .. } = pred
-            && *param != rustc_span::symbol::kw::SelfUpper
             && bounds.iter().any(|b| b.is_sized_bound(cx))
         {
             sized_params.insert(*param);
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 7d5a16bc7e3..4850500a1bf 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -34,10 +34,9 @@ use thin_vec::ThinVec;
 use {rustc_ast as ast, rustc_hir as hir};
 
 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,
+    RawPointer, SelfTy, Slice, Tuple,
 };
 use crate::clean::cfg::Cfg;
 use crate::clean::clean_middle_path;
@@ -1384,8 +1383,8 @@ pub(crate) struct FnDecl {
 }
 
 impl FnDecl {
-    pub(crate) fn self_type(&self) -> Option<SelfTy> {
-        self.inputs.values.get(0).and_then(|v| v.to_self())
+    pub(crate) fn receiver_type(&self) -> Option<&Type> {
+        self.inputs.values.get(0).and_then(|v| v.to_receiver())
     }
 }
 
@@ -1403,27 +1402,9 @@ pub(crate) struct Argument {
     pub(crate) is_const: bool,
 }
 
-#[derive(Clone, PartialEq, Debug)]
-pub(crate) enum SelfTy {
-    SelfValue,
-    SelfBorrowed(Option<Lifetime>, Mutability),
-    SelfExplicit(Type),
-}
-
 impl Argument {
-    pub(crate) fn to_self(&self) -> Option<SelfTy> {
-        if self.name != kw::SelfLower {
-            return None;
-        }
-        if self.type_.is_self_type() {
-            return Some(SelfValue);
-        }
-        match self.type_ {
-            BorrowedRef { ref lifetime, mutability, ref type_ } if type_.is_self_type() => {
-                Some(SelfBorrowed(lifetime.clone(), mutability))
-            }
-            _ => Some(SelfExplicit(self.type_.clone())),
-        }
+    pub(crate) fn to_receiver(&self) -> Option<&Type> {
+        if self.name == kw::SelfLower { Some(&self.type_) } else { None }
     }
 }
 
@@ -1477,6 +1458,8 @@ pub(crate) enum Type {
     DynTrait(Vec<PolyTrait>, Option<Lifetime>),
     /// A type parameter.
     Generic(Symbol),
+    /// The `Self` type.
+    SelfTy,
     /// A primitive (aka, builtin) type.
     Primitive(PrimitiveType),
     /// A function pointer: `extern "ABI" fn(...) -> ...`
@@ -1571,6 +1554,8 @@ impl Type {
             // If both sides are generic, this returns true.
             (_, Type::Generic(_)) => true,
             (Type::Generic(_), _) => false,
+            // `Self` only matches itself.
+            (Type::SelfTy, Type::SelfTy) => true,
             // Paths account for both the path itself and its generics.
             (Type::Path { path: a }, Type::Path { path: b }) => {
                 a.def_id() == b.def_id()
@@ -1642,7 +1627,7 @@ impl Type {
 
     pub(crate) fn is_self_type(&self) -> bool {
         match *self {
-            Generic(name) => name == kw::SelfUpper,
+            SelfTy => true,
             _ => false,
         }
     }
@@ -1700,7 +1685,7 @@ impl Type {
             Type::Pat(..) => PrimitiveType::Pat,
             RawPointer(..) => PrimitiveType::RawPointer,
             QPath(box QPathData { ref self_type, .. }) => return self_type.def_id(cache),
-            Generic(_) | Infer | ImplTrait(_) => return None,
+            Generic(_) | SelfTy | Infer | ImplTrait(_) => return None,
         };
         Primitive(t).def_id(cache)
     }
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 2dd3041ab4c..68266f3506a 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -468,7 +468,7 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
     match path.res {
         Res::PrimTy(p) => Primitive(PrimitiveType::from(p)),
         Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } if path.segments.len() == 1 => {
-            Generic(kw::SelfUpper)
+            Type::SelfTy
         }
         Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => Generic(path.segments[0].name),
         _ => {
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 2769bce1eed..947bae99305 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -310,16 +310,16 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                     // `public_items` map, so we can skip inserting into the
                     // paths map if there was already an entry present and we're
                     // not a public item.
-                    if !self.cache.paths.contains_key(&item.item_id.expect_def_id())
+                    let item_def_id = item.item_id.expect_def_id();
+                    if !self.cache.paths.contains_key(&item_def_id)
                         || self
                             .cache
                             .effective_visibilities
-                            .is_directly_public(self.tcx, item.item_id.expect_def_id())
+                            .is_directly_public(self.tcx, item_def_id)
                     {
-                        self.cache.paths.insert(
-                            item.item_id.expect_def_id(),
-                            (self.cache.stack.clone(), item.type_()),
-                        );
+                        self.cache
+                            .paths
+                            .insert(item_def_id, (self.cache.stack.clone(), item.type_()));
                     }
                 }
             }
@@ -381,9 +381,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                         && adt.is_fundamental()
                     {
                         for ty in generics {
-                            if let Some(did) = ty.def_id(self.cache) {
-                                dids.insert(did);
-                            }
+                            dids.extend(ty.def_id(self.cache));
                         }
                     }
                 }
@@ -396,32 +394,26 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                         .primitive_type()
                         .and_then(|t| self.cache.primitive_locations.get(&t).cloned());
 
-                    if let Some(did) = did {
-                        dids.insert(did);
-                    }
+                    dids.extend(did);
                 }
             }
 
             if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) {
                 for bound in generics {
-                    if let Some(did) = bound.def_id(self.cache) {
-                        dids.insert(did);
-                    }
+                    dids.extend(bound.def_id(self.cache));
                 }
             }
             let impl_item = Impl { impl_item: item };
-            if impl_item.trait_did().map_or(true, |d| self.cache.traits.contains_key(&d)) {
+            let impl_did = impl_item.def_id();
+            let trait_did = impl_item.trait_did();
+            if trait_did.map_or(true, |d| self.cache.traits.contains_key(&d)) {
                 for did in dids {
-                    if self.impl_ids.entry(did).or_default().insert(impl_item.def_id()) {
-                        self.cache
-                            .impls
-                            .entry(did)
-                            .or_insert_with(Vec::new)
-                            .push(impl_item.clone());
+                    if self.impl_ids.entry(did).or_default().insert(impl_did) {
+                        self.cache.impls.entry(did).or_default().push(impl_item.clone());
                     }
                 }
             } else {
-                let trait_did = impl_item.trait_did().expect("no trait did");
+                let trait_did = trait_did.expect("no trait did");
                 self.cache.orphan_trait_impls.push((trait_did, dids, impl_item));
             }
             None
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index bb5ac303ffd..b5ab6a35fdb 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1006,6 +1006,7 @@ fn fmt_type<'cx>(
 
     match *t {
         clean::Generic(name) => f.write_str(name.as_str()),
+        clean::SelfTy => f.write_str("Self"),
         clean::Type::Path { ref path } => {
             // Paths like `T::Output` and `Self::Output` should be rendered with all segments.
             let did = path.def_id();
@@ -1452,29 +1453,22 @@ impl clean::FnDecl {
 
         let last_input_index = self.inputs.values.len().checked_sub(1);
         for (i, input) in self.inputs.values.iter().enumerate() {
-            if let Some(selfty) = input.to_self() {
+            if let Some(selfty) = input.to_receiver() {
                 match selfty {
-                    clean::SelfValue => {
+                    clean::SelfTy => {
                         write!(f, "self")?;
                     }
-                    clean::SelfBorrowed(Some(ref lt), mutability) => {
-                        write!(
-                            f,
-                            "{amp}{lifetime} {mutability}self",
-                            lifetime = lt.print(),
-                            mutability = mutability.print_with_space(),
-                        )?;
-                    }
-                    clean::SelfBorrowed(None, mutability) => {
-                        write!(
-                            f,
-                            "{amp}{mutability}self",
-                            mutability = mutability.print_with_space(),
-                        )?;
+                    clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
+                        write!(f, "{amp}")?;
+                        match lifetime {
+                            Some(lt) => write!(f, "{lt} ", lt = lt.print())?,
+                            None => {}
+                        }
+                        write!(f, "{mutability}self", mutability = mutability.print_with_space())?;
                     }
-                    clean::SelfExplicit(ref typ) => {
+                    _ => {
                         write!(f, "self: ")?;
-                        typ.print(cx).fmt(f)?;
+                        selfty.print(cx).fmt(f)?;
                     }
                 }
             } else {
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 9617f0d9a1f..9074e40a536 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -58,7 +58,7 @@ use serde::{Serialize, Serializer};
 
 pub(crate) use self::context::*;
 pub(crate) use self::span_map::{collect_spans_and_sources, LinkFromSrc};
-use crate::clean::{self, ItemId, RenderedLink, SelfTy};
+use crate::clean::{self, ItemId, RenderedLink};
 use crate::error::Error;
 use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
@@ -1372,21 +1372,20 @@ fn render_deref_methods(
 
 fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool {
     let self_type_opt = match *item.kind {
-        clean::MethodItem(ref method, _) => method.decl.self_type(),
-        clean::TyMethodItem(ref method) => method.decl.self_type(),
+        clean::MethodItem(ref method, _) => method.decl.receiver_type(),
+        clean::TyMethodItem(ref method) => method.decl.receiver_type(),
         _ => None,
     };
 
     if let Some(self_ty) = self_type_opt {
-        let (by_mut_ref, by_box, by_value) = match self_ty {
-            SelfTy::SelfBorrowed(_, mutability)
-            | SelfTy::SelfExplicit(clean::BorrowedRef { mutability, .. }) => {
+        let (by_mut_ref, by_box, by_value) = match *self_ty {
+            clean::Type::BorrowedRef { mutability, .. } => {
                 (mutability == Mutability::Mut, false, false)
             }
-            SelfTy::SelfExplicit(clean::Type::Path { path }) => {
+            clean::Type::Path { ref path } => {
                 (false, Some(path.def_id()) == tcx.lang_items().owned_box(), false)
             }
-            SelfTy::SelfValue => (false, false, true),
+            clean::Type::SelfTy => (false, false, true),
             _ => (false, false, false),
         };
 
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index b3f4d82e054..8a2f31f7413 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -797,7 +797,11 @@ fn get_index_type_id(
             }
         }
         // Not supported yet
-        clean::Type::Pat(..) | clean::Generic(_) | clean::ImplTrait(_) | clean::Infer => None,
+        clean::Type::Pat(..)
+        | clean::Generic(_)
+        | clean::SelfTy
+        | clean::ImplTrait(_)
+        | clean::Infer => None,
     }
 }
 
@@ -850,34 +854,70 @@ fn simplify_fn_type<'tcx, 'a>(
 
     // If this argument is a type parameter and not a trait bound or a type, we need to look
     // for its bounds.
-    if let Type::Generic(arg_s) = *arg {
-        // First we check if the bounds are in a `where` predicate...
-        let mut type_bounds = Vec::new();
-        for where_pred in generics.where_predicates.iter().filter(|g| match g {
-            WherePredicate::BoundPredicate { ty: Type::Generic(ty_s), .. } => *ty_s == arg_s,
-            _ => false,
-        }) {
-            let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]);
-            for bound in bounds.iter() {
-                if let Some(path) = bound.get_trait_path() {
-                    let ty = Type::Path { path };
-                    simplify_fn_type(
-                        self_,
-                        generics,
-                        &ty,
-                        tcx,
-                        recurse + 1,
-                        &mut type_bounds,
-                        rgen,
-                        is_return,
-                        cache,
-                    );
+    match *arg {
+        Type::Generic(arg_s) => {
+            // First we check if the bounds are in a `where` predicate...
+            let mut type_bounds = Vec::new();
+            for where_pred in generics.where_predicates.iter().filter(|g| match g {
+                WherePredicate::BoundPredicate { ty, .. } => *ty == *arg,
+                _ => false,
+            }) {
+                let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]);
+                for bound in bounds.iter() {
+                    if let Some(path) = bound.get_trait_path() {
+                        let ty = Type::Path { path };
+                        simplify_fn_type(
+                            self_,
+                            generics,
+                            &ty,
+                            tcx,
+                            recurse + 1,
+                            &mut type_bounds,
+                            rgen,
+                            is_return,
+                            cache,
+                        );
+                    }
+                }
+            }
+            // Otherwise we check if the trait bounds are "inlined" like `T: Option<u32>`...
+            if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
+                for bound in bound.get_bounds().unwrap_or(&[]) {
+                    if let Some(path) = bound.get_trait_path() {
+                        let ty = Type::Path { path };
+                        simplify_fn_type(
+                            self_,
+                            generics,
+                            &ty,
+                            tcx,
+                            recurse + 1,
+                            &mut type_bounds,
+                            rgen,
+                            is_return,
+                            cache,
+                        );
+                    }
                 }
             }
+            if let Some((idx, _)) = rgen.get(&SimplifiedParam::Symbol(arg_s)) {
+                res.push(RenderType {
+                    id: Some(RenderTypeId::Index(*idx)),
+                    generics: None,
+                    bindings: None,
+                });
+            } else {
+                let idx = -isize::try_from(rgen.len() + 1).unwrap();
+                rgen.insert(SimplifiedParam::Symbol(arg_s), (idx, type_bounds));
+                res.push(RenderType {
+                    id: Some(RenderTypeId::Index(idx)),
+                    generics: None,
+                    bindings: None,
+                });
+            }
         }
-        // Otherwise we check if the trait bounds are "inlined" like `T: Option<u32>`...
-        if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
-            for bound in bound.get_bounds().unwrap_or(&[]) {
+        Type::ImplTrait(ref bounds) => {
+            let mut type_bounds = Vec::new();
+            for bound in bounds {
                 if let Some(path) = bound.get_trait_path() {
                     let ty = Type::Path { path };
                     simplify_fn_type(
@@ -893,84 +933,22 @@ fn simplify_fn_type<'tcx, 'a>(
                     );
                 }
             }
-        }
-        if let Some((idx, _)) = rgen.get(&SimplifiedParam::Symbol(arg_s)) {
-            res.push(RenderType {
-                id: Some(RenderTypeId::Index(*idx)),
-                generics: None,
-                bindings: None,
-            });
-        } else {
-            let idx = -isize::try_from(rgen.len() + 1).unwrap();
-            rgen.insert(SimplifiedParam::Symbol(arg_s), (idx, type_bounds));
-            res.push(RenderType {
-                id: Some(RenderTypeId::Index(idx)),
-                generics: None,
-                bindings: None,
-            });
-        }
-    } else if let Type::ImplTrait(ref bounds) = *arg {
-        let mut type_bounds = Vec::new();
-        for bound in bounds {
-            if let Some(path) = bound.get_trait_path() {
-                let ty = Type::Path { path };
-                simplify_fn_type(
-                    self_,
-                    generics,
-                    &ty,
-                    tcx,
-                    recurse + 1,
-                    &mut type_bounds,
-                    rgen,
-                    is_return,
-                    cache,
-                );
+            if is_return && !type_bounds.is_empty() {
+                // In return position, `impl Trait` is a unique thing.
+                res.push(RenderType { id: None, generics: Some(type_bounds), bindings: None });
+            } else {
+                // In parameter position, `impl Trait` is the same as an unnamed generic parameter.
+                let idx = -isize::try_from(rgen.len() + 1).unwrap();
+                rgen.insert(SimplifiedParam::Anonymous(idx), (idx, type_bounds));
+                res.push(RenderType {
+                    id: Some(RenderTypeId::Index(idx)),
+                    generics: None,
+                    bindings: None,
+                });
             }
         }
-        if is_return && !type_bounds.is_empty() {
-            // In parameter position, `impl Trait` is a unique thing.
-            res.push(RenderType { id: None, generics: Some(type_bounds), bindings: None });
-        } else {
-            // In parameter position, `impl Trait` is the same as an unnamed generic parameter.
-            let idx = -isize::try_from(rgen.len() + 1).unwrap();
-            rgen.insert(SimplifiedParam::Anonymous(idx), (idx, type_bounds));
-            res.push(RenderType {
-                id: Some(RenderTypeId::Index(idx)),
-                generics: None,
-                bindings: None,
-            });
-        }
-    } else if let Type::Slice(ref ty) = *arg {
-        let mut ty_generics = Vec::new();
-        simplify_fn_type(
-            self_,
-            generics,
-            &ty,
-            tcx,
-            recurse + 1,
-            &mut ty_generics,
-            rgen,
-            is_return,
-            cache,
-        );
-        res.push(get_index_type(arg, ty_generics, rgen));
-    } else if let Type::Array(ref ty, _) = *arg {
-        let mut ty_generics = Vec::new();
-        simplify_fn_type(
-            self_,
-            generics,
-            &ty,
-            tcx,
-            recurse + 1,
-            &mut ty_generics,
-            rgen,
-            is_return,
-            cache,
-        );
-        res.push(get_index_type(arg, ty_generics, rgen));
-    } else if let Type::Tuple(ref tys) = *arg {
-        let mut ty_generics = Vec::new();
-        for ty in tys {
+        Type::Slice(ref ty) => {
+            let mut ty_generics = Vec::new();
             simplify_fn_type(
                 self_,
                 generics,
@@ -982,15 +960,14 @@ fn simplify_fn_type<'tcx, 'a>(
                 is_return,
                 cache,
             );
+            res.push(get_index_type(arg, ty_generics, rgen));
         }
-        res.push(get_index_type(arg, ty_generics, rgen));
-    } else if let Type::BareFunction(ref bf) = *arg {
-        let mut ty_generics = Vec::new();
-        for ty in bf.decl.inputs.values.iter().map(|arg| &arg.type_) {
+        Type::Array(ref ty, _) => {
+            let mut ty_generics = Vec::new();
             simplify_fn_type(
                 self_,
                 generics,
-                ty,
+                &ty,
                 tcx,
                 recurse + 1,
                 &mut ty_generics,
@@ -998,62 +975,11 @@ fn simplify_fn_type<'tcx, 'a>(
                 is_return,
                 cache,
             );
+            res.push(get_index_type(arg, ty_generics, rgen));
         }
-        // The search index, for simplicity's sake, represents fn pointers and closures
-        // the same way: as a tuple for the parameters, and an associated type for the
-        // return type.
-        let mut ty_output = Vec::new();
-        simplify_fn_type(
-            self_,
-            generics,
-            &bf.decl.output,
-            tcx,
-            recurse + 1,
-            &mut ty_output,
-            rgen,
-            is_return,
-            cache,
-        );
-        let ty_bindings = vec![(RenderTypeId::AssociatedType(sym::Output), ty_output)];
-        res.push(RenderType {
-            id: get_index_type_id(&arg, rgen),
-            bindings: Some(ty_bindings),
-            generics: Some(ty_generics),
-        });
-    } else if let Type::BorrowedRef { lifetime: _, mutability, ref type_ } = *arg {
-        let mut ty_generics = Vec::new();
-        if mutability.is_mut() {
-            ty_generics.push(RenderType {
-                id: Some(RenderTypeId::Mut),
-                generics: None,
-                bindings: None,
-            });
-        }
-        simplify_fn_type(
-            self_,
-            generics,
-            &type_,
-            tcx,
-            recurse + 1,
-            &mut ty_generics,
-            rgen,
-            is_return,
-            cache,
-        );
-        res.push(get_index_type(arg, ty_generics, rgen));
-    } else {
-        // This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
-        // looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't.
-        //
-        // So in here, we can add it directly and look for its own type parameters (so for `Option`,
-        // we will look for them but not for `T`).
-        let mut ty_generics = Vec::new();
-        let mut ty_constraints = Vec::new();
-        if let Some(arg_generics) = arg.generic_args() {
-            for ty in arg_generics.into_iter().filter_map(|param| match param {
-                clean::GenericArg::Type(ty) => Some(ty),
-                _ => None,
-            }) {
+        Type::Tuple(ref tys) => {
+            let mut ty_generics = Vec::new();
+            for ty in tys {
                 simplify_fn_type(
                     self_,
                     generics,
@@ -1066,94 +992,181 @@ fn simplify_fn_type<'tcx, 'a>(
                     cache,
                 );
             }
-            for constraint in arg_generics.constraints() {
-                simplify_fn_constraint(
+            res.push(get_index_type(arg, ty_generics, rgen));
+        }
+        Type::BareFunction(ref bf) => {
+            let mut ty_generics = Vec::new();
+            for ty in bf.decl.inputs.values.iter().map(|arg| &arg.type_) {
+                simplify_fn_type(
                     self_,
                     generics,
-                    &constraint,
+                    ty,
                     tcx,
                     recurse + 1,
-                    &mut ty_constraints,
+                    &mut ty_generics,
                     rgen,
                     is_return,
                     cache,
                 );
             }
+            // The search index, for simplicity's sake, represents fn pointers and closures
+            // the same way: as a tuple for the parameters, and an associated type for the
+            // return type.
+            let mut ty_output = Vec::new();
+            simplify_fn_type(
+                self_,
+                generics,
+                &bf.decl.output,
+                tcx,
+                recurse + 1,
+                &mut ty_output,
+                rgen,
+                is_return,
+                cache,
+            );
+            let ty_bindings = vec![(RenderTypeId::AssociatedType(sym::Output), ty_output)];
+            res.push(RenderType {
+                id: get_index_type_id(&arg, rgen),
+                bindings: Some(ty_bindings),
+                generics: Some(ty_generics),
+            });
         }
-        // Every trait associated type on self gets assigned to a type parameter index
-        // this same one is used later for any appearances of these types
-        //
-        // for example, Iterator::next is:
-        //
-        //     trait Iterator {
-        //         fn next(&mut self) -> Option<Self::Item>
-        //     }
-        //
-        // Self is technically just Iterator, but we want to pretend it's more like this:
-        //
-        //     fn next<T>(self: Iterator<Item=T>) -> Option<T>
-        if is_self
-            && let Type::Path { path } = arg
-            && let def_id = path.def_id()
-            && let Some(trait_) = cache.traits.get(&def_id)
-            && trait_.items.iter().any(|at| at.is_ty_associated_type())
-        {
-            for assoc_ty in &trait_.items {
-                if let clean::ItemKind::TyAssocTypeItem(_generics, bounds) = &*assoc_ty.kind
-                    && let Some(name) = assoc_ty.name
-                {
-                    let idx = -isize::try_from(rgen.len() + 1).unwrap();
-                    let (idx, stored_bounds) = rgen
-                        .entry(SimplifiedParam::AssociatedType(def_id, name))
-                        .or_insert_with(|| (idx, Vec::new()));
-                    let idx = *idx;
-                    if stored_bounds.is_empty() {
-                        // Can't just pass stored_bounds to simplify_fn_type,
-                        // because it also accepts rgen as a parameter.
-                        // Instead, have it fill in this local, then copy it into the map afterward.
-                        let mut type_bounds = Vec::new();
-                        for bound in bounds {
-                            if let Some(path) = bound.get_trait_path() {
-                                let ty = Type::Path { path };
-                                simplify_fn_type(
-                                    self_,
-                                    generics,
-                                    &ty,
-                                    tcx,
-                                    recurse + 1,
-                                    &mut type_bounds,
-                                    rgen,
-                                    is_return,
-                                    cache,
-                                );
-                            }
-                        }
-                        let stored_bounds = &mut rgen
-                            .get_mut(&SimplifiedParam::AssociatedType(def_id, name))
-                            .unwrap()
-                            .1;
+        Type::BorrowedRef { lifetime: _, mutability, ref type_ } => {
+            let mut ty_generics = Vec::new();
+            if mutability.is_mut() {
+                ty_generics.push(RenderType {
+                    id: Some(RenderTypeId::Mut),
+                    generics: None,
+                    bindings: None,
+                });
+            }
+            simplify_fn_type(
+                self_,
+                generics,
+                &type_,
+                tcx,
+                recurse + 1,
+                &mut ty_generics,
+                rgen,
+                is_return,
+                cache,
+            );
+            res.push(get_index_type(arg, ty_generics, rgen));
+        }
+        _ => {
+            // This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
+            // looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't.
+            //
+            // So in here, we can add it directly and look for its own type parameters (so for `Option`,
+            // we will look for them but not for `T`).
+            let mut ty_generics = Vec::new();
+            let mut ty_constraints = Vec::new();
+            if let Some(arg_generics) = arg.generic_args() {
+                for ty in arg_generics.into_iter().filter_map(|param| match param {
+                    clean::GenericArg::Type(ty) => Some(ty),
+                    _ => None,
+                }) {
+                    simplify_fn_type(
+                        self_,
+                        generics,
+                        &ty,
+                        tcx,
+                        recurse + 1,
+                        &mut ty_generics,
+                        rgen,
+                        is_return,
+                        cache,
+                    );
+                }
+                for constraint in arg_generics.constraints() {
+                    simplify_fn_constraint(
+                        self_,
+                        generics,
+                        &constraint,
+                        tcx,
+                        recurse + 1,
+                        &mut ty_constraints,
+                        rgen,
+                        is_return,
+                        cache,
+                    );
+                }
+            }
+            // Every trait associated type on self gets assigned to a type parameter index
+            // this same one is used later for any appearances of these types
+            //
+            // for example, Iterator::next is:
+            //
+            //     trait Iterator {
+            //         fn next(&mut self) -> Option<Self::Item>
+            //     }
+            //
+            // Self is technically just Iterator, but we want to pretend it's more like this:
+            //
+            //     fn next<T>(self: Iterator<Item=T>) -> Option<T>
+            if is_self
+                && let Type::Path { path } = arg
+                && let def_id = path.def_id()
+                && let Some(trait_) = cache.traits.get(&def_id)
+                && trait_.items.iter().any(|at| at.is_ty_associated_type())
+            {
+                for assoc_ty in &trait_.items {
+                    if let clean::ItemKind::TyAssocTypeItem(_generics, bounds) = &*assoc_ty.kind
+                        && let Some(name) = assoc_ty.name
+                    {
+                        let idx = -isize::try_from(rgen.len() + 1).unwrap();
+                        let (idx, stored_bounds) = rgen
+                            .entry(SimplifiedParam::AssociatedType(def_id, name))
+                            .or_insert_with(|| (idx, Vec::new()));
+                        let idx = *idx;
                         if stored_bounds.is_empty() {
-                            *stored_bounds = type_bounds;
+                            // Can't just pass stored_bounds to simplify_fn_type,
+                            // because it also accepts rgen as a parameter.
+                            // Instead, have it fill in this local, then copy it into the map afterward.
+                            let mut type_bounds = Vec::new();
+                            for bound in bounds {
+                                if let Some(path) = bound.get_trait_path() {
+                                    let ty = Type::Path { path };
+                                    simplify_fn_type(
+                                        self_,
+                                        generics,
+                                        &ty,
+                                        tcx,
+                                        recurse + 1,
+                                        &mut type_bounds,
+                                        rgen,
+                                        is_return,
+                                        cache,
+                                    );
+                                }
+                            }
+                            let stored_bounds = &mut rgen
+                                .get_mut(&SimplifiedParam::AssociatedType(def_id, name))
+                                .unwrap()
+                                .1;
+                            if stored_bounds.is_empty() {
+                                *stored_bounds = type_bounds;
+                            }
                         }
+                        ty_constraints.push((
+                            RenderTypeId::AssociatedType(name),
+                            vec![RenderType {
+                                id: Some(RenderTypeId::Index(idx)),
+                                generics: None,
+                                bindings: None,
+                            }],
+                        ))
                     }
-                    ty_constraints.push((
-                        RenderTypeId::AssociatedType(name),
-                        vec![RenderType {
-                            id: Some(RenderTypeId::Index(idx)),
-                            generics: None,
-                            bindings: None,
-                        }],
-                    ))
                 }
             }
-        }
-        let id = get_index_type_id(&arg, rgen);
-        if id.is_some() || !ty_generics.is_empty() {
-            res.push(RenderType {
-                id,
-                bindings: if ty_constraints.is_empty() { None } else { Some(ty_constraints) },
-                generics: if ty_generics.is_empty() { None } else { Some(ty_generics) },
-            });
+            let id = get_index_type_id(&arg, rgen);
+            if id.is_some() || !ty_generics.is_empty() {
+                res.push(RenderType {
+                    id,
+                    bindings: if ty_constraints.is_empty() { None } else { Some(ty_constraints) },
+                    generics: if ty_generics.is_empty() { None } else { Some(ty_generics) },
+                });
+            }
         }
     }
 }
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index b56244f2d3b..b97d710c007 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -578,7 +578,7 @@ impl FromWithTcx<clean::Type> for Type {
     fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
         use clean::Type::{
             Array, BareFunction, BorrowedRef, Generic, ImplTrait, Infer, Primitive, QPath,
-            RawPointer, Slice, Tuple,
+            RawPointer, SelfTy, Slice, Tuple,
         };
 
         match ty {
@@ -588,6 +588,8 @@ impl FromWithTcx<clean::Type> for Type {
                 traits: bounds.into_tcx(tcx),
             }),
             Generic(s) => Type::Generic(s.to_string()),
+            // FIXME: add dedicated variant to json Type?
+            SelfTy => Type::Generic("Self".to_owned()),
             Primitive(p) => Type::Primitive(p.as_sym().to_string()),
             BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
             Tuple(t) => Type::Tuple(t.into_tcx(tcx)),
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index dd516c4cbd7..ea191dc89cf 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -216,13 +216,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
     fn after_krate(&mut self) -> Result<(), Error> {
         debug!("Done with crate");
 
-        debug!("Adding Primitive impls");
-        for primitive in Rc::clone(&self.cache).primitive_locations.values() {
-            self.get_impls(*primitive);
-        }
-
         let e = ExternalCrate { crate_num: LOCAL_CRATE };
-
         let index = (*self.index).clone().into_inner();
 
         debug!("Constructing Output");
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index ff475b9571b..2b263f848e8 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -141,6 +141,7 @@ static TARGETS: &[&str] = &[
     "riscv64gc-unknown-hermit",
     "riscv64gc-unknown-none-elf",
     "riscv64gc-unknown-linux-gnu",
+    "riscv64gc-unknown-linux-musl",
     "s390x-unknown-linux-gnu",
     "sparc64-unknown-linux-gnu",
     "sparcv9-sun-solaris",
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index b74f9759ebe..f6fbc9844f8 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-29e924841f06bb181d87494eba2783761bc1ddec
+c9687a95a602091777e28703aa5abf20f1ce1797
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index d60119e75f1..18b22827bdb 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -33,7 +33,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let this = self.eval_context_mut();
 
         // See if the core engine can handle this intrinsic.
-        if this.emulate_intrinsic(instance, args, dest, ret)? {
+        if this.eval_intrinsic(instance, args, dest, ret)? {
             return Ok(None);
         }
         let intrinsic_name = this.tcx.item_name(instance.def_id());
diff --git a/src/tools/run-make-support/src/external_deps/c_build.rs b/src/tools/run-make-support/src/external_deps/c_build.rs
index 15e02d04393..fb22780eaa0 100644
--- a/src/tools/run-make-support/src/external_deps/c_build.rs
+++ b/src/tools/run-make-support/src/external_deps/c_build.rs
@@ -1,6 +1,5 @@
 use std::path::PathBuf;
 
-use super::cygpath::get_windows_path;
 use crate::artifact_names::{dynamic_lib_name, static_lib_name};
 use crate::external_deps::cc::{cc, cxx};
 use crate::external_deps::llvm::llvm_ar;
@@ -44,8 +43,7 @@ pub fn build_native_dynamic_lib(lib_name: &str) -> PathBuf {
     };
     let obj_file = if is_msvc() { format!("{lib_name}.obj") } else { format!("{lib_name}.o") };
     if is_msvc() {
-        let mut out_arg = "-out:".to_owned();
-        out_arg.push_str(&get_windows_path(&lib_path));
+        let out_arg = format!("-out:{lib_path}");
         cc().input(&obj_file).args(&["-link", "-dll", &out_arg]).run();
     } else if is_darwin() {
         cc().out_exe(&lib_path).input(&obj_file).args(&["-dynamiclib", "-Wl,-dylib"]).run();
diff --git a/src/tools/run-make-support/src/external_deps/cc.rs b/src/tools/run-make-support/src/external_deps/cc.rs
index 39ac3efef39..36cef15781f 100644
--- a/src/tools/run-make-support/src/external_deps/cc.rs
+++ b/src/tools/run-make-support/src/external_deps/cc.rs
@@ -1,7 +1,5 @@
 use std::path::Path;
 
-// FIXME(jieyouxu): can we get rid of the `cygpath` external dependency?
-use super::cygpath::get_windows_path;
 use crate::command::Command;
 use crate::{env_var, is_msvc, is_windows, uname};
 
@@ -97,12 +95,12 @@ impl Cc {
 
         if is_msvc() {
             path.set_extension("exe");
-            let fe_path = get_windows_path(&path);
+            let fe_path = path.clone();
             path.set_extension("");
             path.set_extension("obj");
-            let fo_path = get_windows_path(path);
-            self.cmd.arg(format!("-Fe:{fe_path}"));
-            self.cmd.arg(format!("-Fo:{fo_path}"));
+            let fo_path = path;
+            self.cmd.arg(format!("-Fe:{}", fe_path.to_str().unwrap()));
+            self.cmd.arg(format!("-Fo:{}", fo_path.to_str().unwrap()));
         } else {
             self.cmd.arg("-o");
             self.cmd.arg(name);
diff --git a/src/tools/run-make-support/src/external_deps/cygpath.rs b/src/tools/run-make-support/src/external_deps/cygpath.rs
deleted file mode 100644
index 07d8e840a63..00000000000
--- a/src/tools/run-make-support/src/external_deps/cygpath.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-use std::panic;
-use std::path::Path;
-
-use crate::command::Command;
-use crate::util::handle_failed_output;
-
-/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
-/// available on the platform!
-///
-/// # FIXME
-///
-/// FIXME(jieyouxu): we should consider not depending on `cygpath`.
-///
-/// > The cygpath program is a utility that converts Windows native filenames to Cygwin POSIX-style
-/// > pathnames and vice versa.
-/// >
-/// > [irrelevant entries omitted...]
-/// >
-/// > `-w, --windows         print Windows form of NAMEs (C:\WINNT)`
-/// >
-/// > -- *from [cygpath documentation](https://cygwin.com/cygwin-ug-net/cygpath.html)*.
-#[track_caller]
-#[must_use]
-pub fn get_windows_path<P: AsRef<Path>>(path: P) -> String {
-    let caller = panic::Location::caller();
-    let mut cygpath = Command::new("cygpath");
-    cygpath.arg("-w");
-    cygpath.arg(path.as_ref());
-    let output = cygpath.run();
-    if !output.status().success() {
-        handle_failed_output(&cygpath, output, caller.line());
-    }
-    // cygpath -w can attach a newline
-    output.stdout_utf8().trim().to_string()
-}
diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs
index 56021cec269..dc651fdd820 100644
--- a/src/tools/run-make-support/src/external_deps/llvm.rs
+++ b/src/tools/run-make-support/src/external_deps/llvm.rs
@@ -151,7 +151,8 @@ impl LlvmReadobj {
         self
     }
 
-    /// Pass `--symbols` to display the symbol.
+    /// Pass `--symbols` to display the symbol table, including both local
+    /// and global symbols.
     pub fn symbols(&mut self) -> &mut Self {
         self.cmd.arg("--symbols");
         self
diff --git a/src/tools/run-make-support/src/external_deps/mod.rs b/src/tools/run-make-support/src/external_deps/mod.rs
index a2dc426f3f2..f7c84724d0e 100644
--- a/src/tools/run-make-support/src/external_deps/mod.rs
+++ b/src/tools/run-make-support/src/external_deps/mod.rs
@@ -9,6 +9,3 @@ pub mod llvm;
 pub mod python;
 pub mod rustc;
 pub mod rustdoc;
-
-// Library-internal external dependency.
-mod cygpath;
diff --git a/src/tools/run-make-support/src/fs.rs b/src/tools/run-make-support/src/fs.rs
index 0a796161633..2c35ba52a62 100644
--- a/src/tools/run-make-support/src/fs.rs
+++ b/src/tools/run-make-support/src/fs.rs
@@ -9,11 +9,19 @@ pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
     if link.as_ref().exists() {
         std::fs::remove_dir(link.as_ref()).unwrap();
     }
-    std::os::windows::fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
-        "failed to create symlink {:?} for {:?}",
-        link.as_ref().display(),
-        original.as_ref().display(),
-    ));
+    if original.as_ref().is_file() {
+        std::os::windows::fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
+            "failed to create symlink {:?} for {:?}",
+            link.as_ref().display(),
+            original.as_ref().display(),
+        ));
+    } else {
+        std::os::windows::fs::symlink_dir(original.as_ref(), link.as_ref()).expect(&format!(
+            "failed to create symlink {:?} for {:?}",
+            link.as_ref().display(),
+            original.as_ref().display(),
+        ));
+    }
 }
 
 /// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
@@ -41,6 +49,8 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
             let ty = entry.file_type()?;
             if ty.is_dir() {
                 copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
+            } else if ty.is_symlink() {
+                copy_symlink(entry.path(), dst.join(entry.file_name()))?;
             } else {
                 std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
             }
@@ -59,6 +69,12 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
     }
 }
 
+fn copy_symlink<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
+    let target_path = std::fs::read_link(from).unwrap();
+    create_symlink(target_path, to);
+    Ok(())
+}
+
 /// Helper for reading entries in a given directory.
 pub fn read_dir_entries<P: AsRef<Path>, F: FnMut(&Path)>(dir: P, mut callback: F) {
     for entry in read_dir(dir) {
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 088d5ba0c2b..38880e5e95f 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -27,12 +27,10 @@ run-make/raw-dylib-alt-calling-convention/Makefile
 run-make/raw-dylib-c/Makefile
 run-make/redundant-libs/Makefile
 run-make/remap-path-prefix-dwarf/Makefile
-run-make/reproducible-build-2/Makefile
 run-make/reproducible-build/Makefile
 run-make/rlib-format-packed-bundled-libs/Makefile
 run-make/simd-ffi/Makefile
 run-make/split-debuginfo/Makefile
-run-make/stable-symbol-names/Makefile
 run-make/staticlib-dylib-linkage/Makefile
 run-make/symbol-mangling-hashed/Makefile
 run-make/sysroot-crates-are-unstable/Makefile