about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorThe Miri Conjob Bot <miri@cron.bot>2023-10-23 05:37:15 +0000
committerThe Miri Conjob Bot <miri@cron.bot>2023-10-23 05:37:15 +0000
commit624f68da16c2f105dd2d7b4e16bc476d0c53c2b9 (patch)
treef4ab0ea057effbad3f343739705e55948a25ca60 /src
parenta80b5c00b64a6ec8175a3153b174f59a237434a7 (diff)
parentf1a1ef68c7a6d588ba9faa20f3b2ecac4ef607c5 (diff)
downloadrust-624f68da16c2f105dd2d7b4e16bc476d0c53c2b9.tar.gz
rust-624f68da16c2f105dd2d7b4e16bc476d0c53c2b9.zip
Merge from rustc
Diffstat (limited to 'src')
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile50
-rw-r--r--src/ci/github-actions/ci.yml5
-rw-r--r--src/doc/rustdoc/src/write-documentation/what-to-include.md2
-rw-r--r--src/etc/gdb_providers.py307
-rw-r--r--src/librustdoc/clean/inline.rs6
-rw-r--r--src/librustdoc/clean/mod.rs30
-rw-r--r--src/librustdoc/clean/types.rs11
-rw-r--r--src/librustdoc/html/format.rs77
-rw-r--r--src/librustdoc/json/conversions.rs6
m---------src/tools/cargo0
-rw-r--r--src/tools/opt-dist/src/main.rs4
-rw-r--r--src/tools/opt-dist/src/tests.rs9
14 files changed, 302 insertions, 213 deletions
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index c04121a8bee..9a2fcb0ce0a 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -57,9 +57,9 @@ COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/
 RUN ./build-clang.sh
 ENV CC=clang CXX=clang++
 
-# rustc-perf version from 2023-05-30
+# rustc-perf version from 2023-10-22
 # Should also be changed in the opt-dist tool for other environments.
-ENV PERF_COMMIT 8b2ac3042e1ff2c0074455a0a3618adef97156b1
+ENV PERF_COMMIT 4f313add609f43e928e98132358e8426ed3969ae
 RUN curl -LS -o perf.zip https://ci-mirrors.rust-lang.org/rustc/rustc-perf-$PERF_COMMIT.zip && \
     unzip perf.zip && \
     mv rustc-perf-$PERF_COMMIT rustc-perf && \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile
index 1e2b802e64e..c177e7387fc 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile
@@ -38,6 +38,10 @@ RUN sh /scripts/sccache.sh
 # LLVM, rather than the typical src/llvm-project LLVM.
 ENV NO_DOWNLOAD_CI_LLVM 1
 
+# This is not the latest LLVM version, so some components required by tests may
+# be missing.
+ENV IS_NOT_LATEST_LLVM 1
+
 # Using llvm-link-shared due to libffi issues -- see #34486
 ENV RUST_CONFIGURE_ARGS \
       --build=x86_64-unknown-linux-gnu \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile
new file mode 100644
index 00000000000..76846f1fed7
--- /dev/null
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile
@@ -0,0 +1,50 @@
+FROM ubuntu:23.10
+
+ARG DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+  g++ \
+  gcc-multilib \
+  make \
+  ninja-build \
+  file \
+  curl \
+  ca-certificates \
+  python3 \
+  git \
+  cmake \
+  sudo \
+  gdb \
+  llvm-17-tools \
+  llvm-17-dev \
+  libedit-dev \
+  libssl-dev \
+  pkg-config \
+  zlib1g-dev \
+  xz-utils \
+  nodejs \
+  mingw-w64 \
+  && rm -rf /var/lib/apt/lists/*
+
+# Install powershell (universal package) so we can test x.ps1 on Linux
+RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \
+    dpkg -i powershell.deb && \
+    rm -f powershell.deb
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+# We are disabling CI LLVM since this builder is intentionally using a host
+# LLVM, rather than the typical src/llvm-project LLVM.
+ENV NO_DOWNLOAD_CI_LLVM 1
+
+# Using llvm-link-shared due to libffi issues -- see #34486
+ENV RUST_CONFIGURE_ARGS \
+      --build=x86_64-unknown-linux-gnu \
+      --llvm-root=/usr/lib/llvm-17 \
+      --enable-llvm-link-shared \
+      --set rust.thin-lto-import-instr-limit=10
+
+COPY host-x86_64/x86_64-gnu-llvm-15/script.sh /tmp/
+
+ENV SCRIPT /tmp/script.sh
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 5136aec9896..2577682c57c 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -463,6 +463,11 @@ jobs:
           - name: x86_64-gnu-distcheck
             <<: *job-linux-8c
 
+          - name: x86_64-gnu-llvm-17
+            env:
+              RUST_BACKTRACE: 1
+            <<: *job-linux-8c
+
           - name: x86_64-gnu-llvm-16
             env:
               RUST_BACKTRACE: 1
diff --git a/src/doc/rustdoc/src/write-documentation/what-to-include.md b/src/doc/rustdoc/src/write-documentation/what-to-include.md
index 4bcae4d222c..75d3b7dae61 100644
--- a/src/doc/rustdoc/src/write-documentation/what-to-include.md
+++ b/src/doc/rustdoc/src/write-documentation/what-to-include.md
@@ -73,7 +73,7 @@ and your test suite, this example needs some additional code:
 ``````text
 /// Example
 /// ```rust
-/// # main() -> Result<(), std::num::ParseIntError> {
+/// # fn main() -> Result<(), std::num::ParseIntError> {
 /// let fortytwo = "42".parse::<u32>()?;
 /// println!("{} + 10 = {}", fortytwo, fortytwo+10);
 /// #     Ok(())
diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py
index 32b8d8e24c6..e851aa62634 100644
--- a/src/etc/gdb_providers.py
+++ b/src/etc/gdb_providers.py
@@ -18,70 +18,79 @@ def unwrap_unique_or_non_null(unique_or_nonnull):
     return ptr if ptr.type.code == gdb.TYPE_CODE_PTR else ptr[ptr.type.fields()[0]]
 
 
-class EnumProvider:
+# GDB 14 has a tag class that indicates that extension methods are ok
+# to call.  Use of this tag only requires that printers hide local
+# attributes and methods by prefixing them with "_".
+if hasattr(gdb, 'ValuePrinter'):
+    printer_base = gdb.ValuePrinter
+else:
+    printer_base = object
+
+
+class EnumProvider(printer_base):
     def __init__(self, valobj):
         content = valobj[valobj.type.fields()[0]]
         fields = content.type.fields()
-        self.empty = len(fields) == 0
-        if not self.empty:
+        self._empty = len(fields) == 0
+        if not self._empty:
             if len(fields) == 1:
                 discriminant = 0
             else:
                 discriminant = int(content[fields[0]]) + 1
-            self.active_variant = content[fields[discriminant]]
-            self.name = fields[discriminant].name
-            self.full_name = "{}::{}".format(valobj.type.name, self.name)
+            self._active_variant = content[fields[discriminant]]
+            self._name = fields[discriminant].name
+            self._full_name = "{}::{}".format(valobj.type.name, self._name)
         else:
-            self.full_name = valobj.type.name
+            self._full_name = valobj.type.name
 
     def to_string(self):
-        return self.full_name
+        return self._full_name
 
     def children(self):
-        if not self.empty:
-            yield self.name, self.active_variant
+        if not self._empty:
+            yield self._name, self._active_variant
 
 
-class StdStringProvider:
+class StdStringProvider(printer_base):
     def __init__(self, valobj):
-        self.valobj = valobj
+        self._valobj = valobj
         vec = valobj["vec"]
-        self.length = int(vec["len"])
-        self.data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
+        self._length = int(vec["len"])
+        self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
 
     def to_string(self):
-        return self.data_ptr.lazy_string(encoding="utf-8", length=self.length)
+        return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)
 
     @staticmethod
     def display_hint():
         return "string"
 
 
-class StdOsStringProvider:
+class StdOsStringProvider(printer_base):
     def __init__(self, valobj):
-        self.valobj = valobj
-        buf = self.valobj["inner"]["inner"]
+        self._valobj = valobj
+        buf = self._valobj["inner"]["inner"]
         is_windows = "Wtf8Buf" in buf.type.name
         vec = buf[ZERO_FIELD] if is_windows else buf
 
-        self.length = int(vec["len"])
-        self.data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
+        self._length = int(vec["len"])
+        self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
 
     def to_string(self):
-        return self.data_ptr.lazy_string(encoding="utf-8", length=self.length)
+        return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)
 
     def display_hint(self):
         return "string"
 
 
-class StdStrProvider:
+class StdStrProvider(printer_base):
     def __init__(self, valobj):
-        self.valobj = valobj
-        self.length = int(valobj["length"])
-        self.data_ptr = valobj["data_ptr"]
+        self._valobj = valobj
+        self._length = int(valobj["length"])
+        self._data_ptr = valobj["data_ptr"]
 
     def to_string(self):
-        return self.data_ptr.lazy_string(encoding="utf-8", length=self.length)
+        return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)
 
     @staticmethod
     def display_hint():
@@ -103,36 +112,36 @@ def _enumerate_array_elements(element_ptrs):
 
         yield key, element
 
-class StdSliceProvider:
+class StdSliceProvider(printer_base):
     def __init__(self, valobj):
-        self.valobj = valobj
-        self.length = int(valobj["length"])
-        self.data_ptr = valobj["data_ptr"]
+        self._valobj = valobj
+        self._length = int(valobj["length"])
+        self._data_ptr = valobj["data_ptr"]
 
     def to_string(self):
-        return "{}(size={})".format(self.valobj.type, self.length)
+        return "{}(size={})".format(self._valobj.type, self._length)
 
     def children(self):
         return _enumerate_array_elements(
-            self.data_ptr + index for index in xrange(self.length)
+            self._data_ptr + index for index in xrange(self._length)
         )
 
     @staticmethod
     def display_hint():
         return "array"
 
-class StdVecProvider:
+class StdVecProvider(printer_base):
     def __init__(self, valobj):
-        self.valobj = valobj
-        self.length = int(valobj["len"])
-        self.data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
+        self._valobj = valobj
+        self._length = int(valobj["len"])
+        self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
 
     def to_string(self):
-        return "Vec(size={})".format(self.length)
+        return "Vec(size={})".format(self._length)
 
     def children(self):
         return _enumerate_array_elements(
-            self.data_ptr + index for index in xrange(self.length)
+            self._data_ptr + index for index in xrange(self._length)
         )
 
     @staticmethod
@@ -140,20 +149,20 @@ class StdVecProvider:
         return "array"
 
 
-class StdVecDequeProvider:
+class StdVecDequeProvider(printer_base):
     def __init__(self, valobj):
-        self.valobj = valobj
-        self.head = int(valobj["head"])
-        self.size = int(valobj["len"])
-        self.cap = int(valobj["buf"]["cap"])
-        self.data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
+        self._valobj = valobj
+        self._head = int(valobj["head"])
+        self._size = int(valobj["len"])
+        self._cap = int(valobj["buf"]["cap"])
+        self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
 
     def to_string(self):
-        return "VecDeque(size={})".format(self.size)
+        return "VecDeque(size={})".format(self._size)
 
     def children(self):
         return _enumerate_array_elements(
-            (self.data_ptr + ((self.head + index) % self.cap)) for index in xrange(self.size)
+            (self._data_ptr + ((self._head + index) % self._cap)) for index in xrange(self._size)
         )
 
     @staticmethod
@@ -161,81 +170,81 @@ class StdVecDequeProvider:
         return "array"
 
 
-class StdRcProvider:
+class StdRcProvider(printer_base):
     def __init__(self, valobj, is_atomic=False):
-        self.valobj = valobj
-        self.is_atomic = is_atomic
-        self.ptr = unwrap_unique_or_non_null(valobj["ptr"])
-        self.value = self.ptr["data" if is_atomic else "value"]
-        self.strong = self.ptr["strong"]["v" if is_atomic else "value"]["value"]
-        self.weak = self.ptr["weak"]["v" if is_atomic else "value"]["value"] - 1
+        self._valobj = valobj
+        self._is_atomic = is_atomic
+        self._ptr = unwrap_unique_or_non_null(valobj["ptr"])
+        self._value = self._ptr["data" if is_atomic else "value"]
+        self._strong = self._ptr["strong"]["v" if is_atomic else "value"]["value"]
+        self._weak = self._ptr["weak"]["v" if is_atomic else "value"]["value"] - 1
 
     def to_string(self):
-        if self.is_atomic:
-            return "Arc(strong={}, weak={})".format(int(self.strong), int(self.weak))
+        if self._is_atomic:
+            return "Arc(strong={}, weak={})".format(int(self._strong), int(self._weak))
         else:
-            return "Rc(strong={}, weak={})".format(int(self.strong), int(self.weak))
+            return "Rc(strong={}, weak={})".format(int(self._strong), int(self._weak))
 
     def children(self):
-        yield "value", self.value
-        yield "strong", self.strong
-        yield "weak", self.weak
+        yield "value", self._value
+        yield "strong", self._strong
+        yield "weak", self._weak
 
 
-class StdCellProvider:
+class StdCellProvider(printer_base):
     def __init__(self, valobj):
-        self.value = valobj["value"]["value"]
+        self._value = valobj["value"]["value"]
 
     def to_string(self):
         return "Cell"
 
     def children(self):
-        yield "value", self.value
+        yield "value", self._value
 
 
-class StdRefProvider:
+class StdRefProvider(printer_base):
     def __init__(self, valobj):
-        self.value = valobj["value"].dereference()
-        self.borrow = valobj["borrow"]["borrow"]["value"]["value"]
+        self._value = valobj["value"].dereference()
+        self._borrow = valobj["borrow"]["borrow"]["value"]["value"]
 
     def to_string(self):
-        borrow = int(self.borrow)
+        borrow = int(self._borrow)
         if borrow >= 0:
             return "Ref(borrow={})".format(borrow)
         else:
             return "Ref(borrow_mut={})".format(-borrow)
 
     def children(self):
-        yield "*value", self.value
-        yield "borrow", self.borrow
+        yield "*value", self._value
+        yield "borrow", self._borrow
 
 
-class StdRefCellProvider:
+class StdRefCellProvider(printer_base):
     def __init__(self, valobj):
-        self.value = valobj["value"]["value"]
-        self.borrow = valobj["borrow"]["value"]["value"]
+        self._value = valobj["value"]["value"]
+        self._borrow = valobj["borrow"]["value"]["value"]
 
     def to_string(self):
-        borrow = int(self.borrow)
+        borrow = int(self._borrow)
         if borrow >= 0:
             return "RefCell(borrow={})".format(borrow)
         else:
             return "RefCell(borrow_mut={})".format(-borrow)
 
     def children(self):
-        yield "value", self.value
-        yield "borrow", self.borrow
+        yield "value", self._value
+        yield "borrow", self._borrow
 
 
-class StdNonZeroNumberProvider:
+class StdNonZeroNumberProvider(printer_base):
     def __init__(self, valobj):
         fields = valobj.type.fields()
         assert len(fields) == 1
         field = list(fields)[0]
-        self.value = str(valobj[field.name])
+        self._value = str(valobj[field.name])
 
     def to_string(self):
-        return self.value
+        return self._value
 
 
 # Yields children (in a provider's sense of the word) for a BTreeMap.
@@ -280,15 +289,15 @@ def children_of_btree_map(map):
             yield child
 
 
-class StdBTreeSetProvider:
+class StdBTreeSetProvider(printer_base):
     def __init__(self, valobj):
-        self.valobj = valobj
+        self._valobj = valobj
 
     def to_string(self):
-        return "BTreeSet(size={})".format(self.valobj["map"]["length"])
+        return "BTreeSet(size={})".format(self._valobj["map"]["length"])
 
     def children(self):
-        inner_map = self.valobj["map"]
+        inner_map = self._valobj["map"]
         for i, (child, _) in enumerate(children_of_btree_map(inner_map)):
             yield "[{}]".format(i), child
 
@@ -297,15 +306,15 @@ class StdBTreeSetProvider:
         return "array"
 
 
-class StdBTreeMapProvider:
+class StdBTreeMapProvider(printer_base):
     def __init__(self, valobj):
-        self.valobj = valobj
+        self._valobj = valobj
 
     def to_string(self):
-        return "BTreeMap(size={})".format(self.valobj["length"])
+        return "BTreeMap(size={})".format(self._valobj["length"])
 
     def children(self):
-        for i, (key, val) in enumerate(children_of_btree_map(self.valobj)):
+        for i, (key, val) in enumerate(children_of_btree_map(self._valobj)):
             yield "key{}".format(i), key
             yield "val{}".format(i), val
 
@@ -315,124 +324,124 @@ class StdBTreeMapProvider:
 
 
 # BACKCOMPAT: rust 1.35
-class StdOldHashMapProvider:
+class StdOldHashMapProvider(printer_base):
     def __init__(self, valobj, show_values=True):
-        self.valobj = valobj
-        self.show_values = show_values
-
-        self.table = self.valobj["table"]
-        self.size = int(self.table["size"])
-        self.hashes = self.table["hashes"]
-        self.hash_uint_type = self.hashes.type
-        self.hash_uint_size = self.hashes.type.sizeof
-        self.modulo = 2 ** self.hash_uint_size
-        self.data_ptr = self.hashes[ZERO_FIELD]["pointer"]
-
-        self.capacity_mask = int(self.table["capacity_mask"])
-        self.capacity = (self.capacity_mask + 1) % self.modulo
-
-        marker = self.table["marker"].type
-        self.pair_type = marker.template_argument(0)
-        self.pair_type_size = self.pair_type.sizeof
-
-        self.valid_indices = []
-        for idx in range(self.capacity):
-            data_ptr = self.data_ptr.cast(self.hash_uint_type.pointer())
+        self._valobj = valobj
+        self._show_values = show_values
+
+        self._table = self._valobj["table"]
+        self._size = int(self._table["size"])
+        self._hashes = self._table["hashes"]
+        self._hash_uint_type = self._hashes.type
+        self._hash_uint_size = self._hashes.type.sizeof
+        self._modulo = 2 ** self._hash_uint_size
+        self._data_ptr = self._hashes[ZERO_FIELD]["pointer"]
+
+        self._capacity_mask = int(self._table["capacity_mask"])
+        self._capacity = (self._capacity_mask + 1) % self._modulo
+
+        marker = self._table["marker"].type
+        self._pair_type = marker.template_argument(0)
+        self._pair_type_size = self._pair_type.sizeof
+
+        self._valid_indices = []
+        for idx in range(self._capacity):
+            data_ptr = self._data_ptr.cast(self._hash_uint_type.pointer())
             address = data_ptr + idx
             hash_uint = address.dereference()
             hash_ptr = hash_uint[ZERO_FIELD]["pointer"]
             if int(hash_ptr) != 0:
-                self.valid_indices.append(idx)
+                self._valid_indices.append(idx)
 
     def to_string(self):
-        if self.show_values:
-            return "HashMap(size={})".format(self.size)
+        if self._show_values:
+            return "HashMap(size={})".format(self._size)
         else:
-            return "HashSet(size={})".format(self.size)
+            return "HashSet(size={})".format(self._size)
 
     def children(self):
-        start = int(self.data_ptr) & ~1
+        start = int(self._data_ptr) & ~1
 
-        hashes = self.hash_uint_size * self.capacity
-        align = self.pair_type_size
-        len_rounded_up = (((((hashes + align) % self.modulo - 1) % self.modulo) & ~(
-                (align - 1) % self.modulo)) % self.modulo - hashes) % self.modulo
+        hashes = self._hash_uint_size * self._capacity
+        align = self._pair_type_size
+        len_rounded_up = (((((hashes + align) % self._modulo - 1) % self._modulo) & ~(
+                (align - 1) % self._modulo)) % self._modulo - hashes) % self._modulo
 
         pairs_offset = hashes + len_rounded_up
-        pairs_start = gdb.Value(start + pairs_offset).cast(self.pair_type.pointer())
+        pairs_start = gdb.Value(start + pairs_offset).cast(self._pair_type.pointer())
 
-        for index in range(self.size):
-            table_index = self.valid_indices[index]
-            idx = table_index & self.capacity_mask
+        for index in range(self._size):
+            table_index = self._valid_indices[index]
+            idx = table_index & self._capacity_mask
             element = (pairs_start + idx).dereference()
-            if self.show_values:
+            if self._show_values:
                 yield "key{}".format(index), element[ZERO_FIELD]
                 yield "val{}".format(index), element[FIRST_FIELD]
             else:
                 yield "[{}]".format(index), element[ZERO_FIELD]
 
     def display_hint(self):
-        return "map" if self.show_values else "array"
+        return "map" if self._show_values else "array"
 
 
-class StdHashMapProvider:
+class StdHashMapProvider(printer_base):
     def __init__(self, valobj, show_values=True):
-        self.valobj = valobj
-        self.show_values = show_values
+        self._valobj = valobj
+        self._show_values = show_values
 
-        table = self.table()
+        table = self._table()
         table_inner = table["table"]
         capacity = int(table_inner["bucket_mask"]) + 1
         ctrl = table_inner["ctrl"]["pointer"]
 
-        self.size = int(table_inner["items"])
-        self.pair_type = table.type.template_argument(0).strip_typedefs()
+        self._size = int(table_inner["items"])
+        self._pair_type = table.type.template_argument(0).strip_typedefs()
 
-        self.new_layout = not table_inner.type.has_key("data")
-        if self.new_layout:
-            self.data_ptr = ctrl.cast(self.pair_type.pointer())
+        self._new_layout = not table_inner.type.has_key("data")
+        if self._new_layout:
+            self._data_ptr = ctrl.cast(self._pair_type.pointer())
         else:
-            self.data_ptr = table_inner["data"]["pointer"]
+            self._data_ptr = table_inner["data"]["pointer"]
 
-        self.valid_indices = []
+        self._valid_indices = []
         for idx in range(capacity):
             address = ctrl + idx
             value = address.dereference()
             is_presented = value & 128 == 0
             if is_presented:
-                self.valid_indices.append(idx)
+                self._valid_indices.append(idx)
 
-    def table(self):
-        if self.show_values:
-            hashbrown_hashmap = self.valobj["base"]
-        elif self.valobj.type.fields()[0].name == "map":
+    def _table(self):
+        if self._show_values:
+            hashbrown_hashmap = self._valobj["base"]
+        elif self._valobj.type.fields()[0].name == "map":
             # BACKCOMPAT: rust 1.47
             # HashSet wraps std::collections::HashMap, which wraps hashbrown::HashMap
-            hashbrown_hashmap = self.valobj["map"]["base"]
+            hashbrown_hashmap = self._valobj["map"]["base"]
         else:
             # HashSet wraps hashbrown::HashSet, which wraps hashbrown::HashMap
-            hashbrown_hashmap = self.valobj["base"]["map"]
+            hashbrown_hashmap = self._valobj["base"]["map"]
         return hashbrown_hashmap["table"]
 
     def to_string(self):
-        if self.show_values:
-            return "HashMap(size={})".format(self.size)
+        if self._show_values:
+            return "HashMap(size={})".format(self._size)
         else:
-            return "HashSet(size={})".format(self.size)
+            return "HashSet(size={})".format(self._size)
 
     def children(self):
-        pairs_start = self.data_ptr
+        pairs_start = self._data_ptr
 
-        for index in range(self.size):
-            idx = self.valid_indices[index]
-            if self.new_layout:
+        for index in range(self._size):
+            idx = self._valid_indices[index]
+            if self._new_layout:
                 idx = -(idx + 1)
             element = (pairs_start + idx).dereference()
-            if self.show_values:
+            if self._show_values:
                 yield "key{}".format(index), element[ZERO_FIELD]
                 yield "val{}".format(index), element[FIRST_FIELD]
             else:
                 yield "[{}]".format(index), element[ZERO_FIELD]
 
     def display_hint(self):
-        return "map" if self.show_values else "array"
+        return "map" if self._show_values else "array"
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index eb18ecf662c..89796761126 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -641,13 +641,13 @@ fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant {
     clean::simplify::move_bounds_to_generic_parameters(&mut generics);
 
     clean::Constant {
-        type_: clean_middle_ty(
+        type_: Box::new(clean_middle_ty(
             ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()),
             cx,
             Some(def_id),
             None,
-        ),
-        generics: Box::new(generics),
+        )),
+        generics,
         kind: clean::ConstantKind::Extern { def_id },
     }
 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 7becc156142..125b1fecf18 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -259,13 +259,13 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) ->
 pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant {
     let def_id = cx.tcx.hir().body_owner_def_id(constant.value.body).to_def_id();
     Constant {
-        type_: clean_middle_ty(
+        type_: Box::new(clean_middle_ty(
             ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()),
             cx,
             Some(def_id),
             None,
-        ),
-        generics: Box::new(Generics::default()),
+        )),
+        generics: Generics::default(),
         kind: ConstantKind::Anonymous { body: constant.value.body },
     }
 }
@@ -276,8 +276,8 @@ pub(crate) fn clean_middle_const<'tcx>(
 ) -> Constant {
     // FIXME: instead of storing the stringified expression, store `self` directly instead.
     Constant {
-        type_: clean_middle_ty(constant.map_bound(|c| c.ty()), cx, None, None),
-        generics: Box::new(Generics::default()),
+        type_: Box::new(clean_middle_ty(constant.map_bound(|c| c.ty()), cx, None, None)),
+        generics: Generics::default(),
         kind: ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() },
     }
 }
@@ -1216,14 +1216,14 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
             hir::TraitItemKind::Const(ty, Some(default)) => {
                 let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
                 AssocConstItem(
-                    Box::new(generics),
-                    clean_ty(ty, cx),
+                    generics,
+                    Box::new(clean_ty(ty, cx)),
                     ConstantKind::Local { def_id: local_did, body: default },
                 )
             }
             hir::TraitItemKind::Const(ty, None) => {
                 let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
-                TyAssocConstItem(Box::new(generics), clean_ty(ty, cx))
+                TyAssocConstItem(generics, Box::new(clean_ty(ty, cx)))
             }
             hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
                 let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body));
@@ -1272,7 +1272,7 @@ pub(crate) fn clean_impl_item<'tcx>(
             hir::ImplItemKind::Const(ty, expr) => {
                 let generics = clean_generics(impl_.generics, cx);
                 let default = ConstantKind::Local { def_id: local_did, body: expr };
-                AssocConstItem(Box::new(generics), clean_ty(ty, cx), default)
+                AssocConstItem(generics, Box::new(clean_ty(ty, cx)), default)
             }
             hir::ImplItemKind::Fn(ref sig, body) => {
                 let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body));
@@ -1311,18 +1311,18 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
     let tcx = cx.tcx;
     let kind = match assoc_item.kind {
         ty::AssocKind::Const => {
-            let ty = clean_middle_ty(
+            let ty = Box::new(clean_middle_ty(
                 ty::Binder::dummy(tcx.type_of(assoc_item.def_id).instantiate_identity()),
                 cx,
                 Some(assoc_item.def_id),
                 None,
-            );
+            ));
 
-            let mut generics = Box::new(clean_ty_generics(
+            let mut generics = clean_ty_generics(
                 cx,
                 tcx.generics_of(assoc_item.def_id),
                 tcx.explicit_predicates_of(assoc_item.def_id),
-            ));
+            );
             simplify::move_bounds_to_generic_parameters(&mut generics);
 
             let provided = match assoc_item.container {
@@ -2718,8 +2718,8 @@ fn clean_maybe_renamed_item<'tcx>(
                 StaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: Some(body_id) })
             }
             ItemKind::Const(ty, generics, body_id) => ConstantItem(Constant {
-                type_: clean_ty(ty, cx),
-                generics: Box::new(clean_generics(generics, cx)),
+                type_: Box::new(clean_ty(ty, cx)),
+                generics: clean_generics(generics, cx),
                 kind: ConstantKind::Local { body: body_id, def_id },
             }),
             ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 2a54266676d..6a7410144fd 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -852,9 +852,9 @@ pub(crate) enum ItemKind {
     ProcMacroItem(ProcMacro),
     PrimitiveItem(PrimitiveType),
     /// A required associated constant in a trait declaration.
-    TyAssocConstItem(Box<Generics>, Type),
+    TyAssocConstItem(Generics, Box<Type>),
     /// An associated constant in a trait impl or a provided one in a trait declaration.
-    AssocConstItem(Box<Generics>, Type, ConstantKind),
+    AssocConstItem(Generics, Box<Type>, ConstantKind),
     /// A required associated type in a trait declaration.
     ///
     /// The bounds may be non-empty if there is a `where` clause.
@@ -2282,8 +2282,8 @@ pub(crate) struct Static {
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub(crate) struct Constant {
-    pub(crate) type_: Type,
-    pub(crate) generics: Box<Generics>,
+    pub(crate) type_: Box<Type>,
+    pub(crate) generics: Generics,
     pub(crate) kind: ConstantKind,
 }
 
@@ -2524,8 +2524,7 @@ mod size_asserts {
     static_assert_size!(GenericParamDef, 56);
     static_assert_size!(Generics, 16);
     static_assert_size!(Item, 56);
-    // FIXME(generic_const_items): Further reduce the size.
-    static_assert_size!(ItemKind, 72);
+    static_assert_size!(ItemKind, 56);
     static_assert_size!(PathSegment, 40);
     static_assert_size!(Type, 32);
     // tidy-alphabetical-end
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index aa3f7184b4e..29fd880af50 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -847,7 +847,7 @@ fn resolved_path<'cx>(
 fn primitive_link(
     f: &mut fmt::Formatter<'_>,
     prim: clean::PrimitiveType,
-    name: &str,
+    name: fmt::Arguments<'_>,
     cx: &Context<'_>,
 ) -> fmt::Result {
     primitive_link_fragment(f, prim, name, "", cx)
@@ -856,7 +856,7 @@ fn primitive_link(
 fn primitive_link_fragment(
     f: &mut fmt::Formatter<'_>,
     prim: clean::PrimitiveType,
-    name: &str,
+    name: fmt::Arguments<'_>,
     fragment: &str,
     cx: &Context<'_>,
 ) -> fmt::Result {
@@ -907,7 +907,7 @@ fn primitive_link_fragment(
             None => {}
         }
     }
-    f.write_str(name)?;
+    std::fmt::Display::fmt(&name, f)?;
     if needs_termination {
         write!(f, "</a>")?;
     }
@@ -977,9 +977,11 @@ fn fmt_type<'cx>(
         }
         clean::Infer => write!(f, "_"),
         clean::Primitive(clean::PrimitiveType::Never) => {
-            primitive_link(f, PrimitiveType::Never, "!", cx)
+            primitive_link(f, PrimitiveType::Never, format_args!("!"), cx)
+        }
+        clean::Primitive(prim) => {
+            primitive_link(f, prim, format_args!("{}", prim.as_sym().as_str()), cx)
         }
-        clean::Primitive(prim) => primitive_link(f, prim, prim.as_sym().as_str(), cx),
         clean::BareFunction(ref decl) => {
             if f.alternate() {
                 write!(
@@ -998,16 +1000,16 @@ fn fmt_type<'cx>(
                     decl.unsafety.print_with_space(),
                     print_abi_with_space(decl.abi)
                 )?;
-                primitive_link(f, PrimitiveType::Fn, "fn", cx)?;
+                primitive_link(f, PrimitiveType::Fn, format_args!("fn"), cx)?;
                 write!(f, "{}", decl.decl.print(cx))
             }
         }
         clean::Tuple(ref typs) => {
             match &typs[..] {
-                &[] => primitive_link(f, PrimitiveType::Unit, "()", cx),
+                &[] => primitive_link(f, PrimitiveType::Unit, format_args!("()"), cx),
                 [one] => {
                     if let clean::Generic(name) = one {
-                        primitive_link(f, PrimitiveType::Tuple, &format!("({name},)"), cx)
+                        primitive_link(f, PrimitiveType::Tuple, format_args!("({name},)"), cx)
                     } else {
                         write!(f, "(")?;
                         // Carry `f.alternate()` into this display w/o branching manually.
@@ -1028,7 +1030,10 @@ fn fmt_type<'cx>(
                         primitive_link(
                             f,
                             PrimitiveType::Tuple,
-                            &format!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")),
+                            format_args!(
+                                "({})",
+                                generic_names.iter().map(|s| s.as_str()).join(", ")
+                            ),
                             cx,
                         )
                     } else {
@@ -1047,7 +1052,7 @@ fn fmt_type<'cx>(
         }
         clean::Slice(ref t) => match **t {
             clean::Generic(name) => {
-                primitive_link(f, PrimitiveType::Slice, &format!("[{name}]"), cx)
+                primitive_link(f, PrimitiveType::Slice, format_args!("[{name}]"), cx)
             }
             _ => {
                 write!(f, "[")?;
@@ -1059,7 +1064,7 @@ fn fmt_type<'cx>(
             clean::Generic(name) if !f.alternate() => primitive_link(
                 f,
                 PrimitiveType::Array,
-                &format!("[{name}; {n}]", n = Escape(n)),
+                format_args!("[{name}; {n}]", n = Escape(n)),
                 cx,
             ),
             _ => {
@@ -1069,7 +1074,12 @@ fn fmt_type<'cx>(
                     write!(f, "; {n}")?;
                 } else {
                     write!(f, "; ")?;
-                    primitive_link(f, PrimitiveType::Array, &format!("{n}", n = Escape(n)), cx)?;
+                    primitive_link(
+                        f,
+                        PrimitiveType::Array,
+                        format_args!("{n}", n = Escape(n)),
+                        cx,
+                    )?;
                 }
                 write!(f, "]")
             }
@@ -1081,22 +1091,32 @@ fn fmt_type<'cx>(
             };
 
             if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
-                let text = if f.alternate() {
-                    format!("*{m} {ty:#}", ty = t.print(cx))
+                let ty = t.print(cx);
+                if f.alternate() {
+                    primitive_link(
+                        f,
+                        clean::PrimitiveType::RawPointer,
+                        format_args!("*{m} {ty:#}"),
+                        cx,
+                    )
                 } else {
-                    format!("*{m} {ty}", ty = t.print(cx))
-                };
-                primitive_link(f, clean::PrimitiveType::RawPointer, &text, cx)
+                    primitive_link(
+                        f,
+                        clean::PrimitiveType::RawPointer,
+                        format_args!("*{m} {ty}"),
+                        cx,
+                    )
+                }
             } else {
-                primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{m} "), cx)?;
+                primitive_link(f, clean::PrimitiveType::RawPointer, format_args!("*{m} "), cx)?;
                 fmt::Display::fmt(&t.print(cx), f)
             }
         }
         clean::BorrowedRef { lifetime: ref l, mutability, type_: ref ty } => {
-            let lt = match l {
-                Some(l) => format!("{} ", l.print()),
-                _ => String::new(),
-            };
+            let lt = display_fn(|f| match l {
+                Some(l) => write!(f, "{} ", l.print()),
+                _ => Ok(()),
+            });
             let m = mutability.print_with_space();
             let amp = if f.alternate() { "&" } else { "&amp;" };
 
@@ -1104,7 +1124,7 @@ fn fmt_type<'cx>(
                 return primitive_link(
                     f,
                     PrimitiveType::Reference,
-                    &format!("{amp}{lt}{m}{name}"),
+                    format_args!("{amp}{lt}{m}{name}"),
                     cx,
                 );
             }
@@ -1254,7 +1274,7 @@ impl clean::Impl {
             {
                 // Hardcoded anchor library/core/src/primitive_docs.rs
                 // Link should match `# Trait implementations`
-                primitive_link_fragment(f, PrimitiveType::Tuple, &format!("({name}₁, {name}₂, …, {name}ₙ)"), "#trait-implementations-1", cx)?;
+                primitive_link_fragment(f, PrimitiveType::Tuple, format_args!("({name}₁, {name}₂, …, {name}ₙ)"), "#trait-implementations-1", cx)?;
             } else if let clean::BareFunction(bare_fn) = &self.for_ &&
                 let [clean::Argument { type_: clean::Type::Generic(name), .. }] = &bare_fn.decl.inputs.values[..] &&
                 (self.kind.is_fake_variadic() || self.kind.is_auto())
@@ -1281,7 +1301,7 @@ impl clean::Impl {
                 } else {
                     ""
                 };
-                primitive_link_fragment(f, PrimitiveType::Tuple, &format!("fn ({name}₁, {name}₂, …, {name}ₙ{ellipsis})"), "#trait-implementations-1", cx)?;
+                primitive_link_fragment(f, PrimitiveType::Tuple, format_args!("fn ({name}₁, {name}₂, …, {name}ₙ{ellipsis})"), "#trait-implementations-1", cx)?;
                 // Write output.
                 if !bare_fn.decl.output.is_unit() {
                     write!(f, " -> ")?;
@@ -1665,7 +1685,12 @@ impl clean::ImportSource {
                 }
                 let name = self.path.last();
                 if let hir::def::Res::PrimTy(p) = self.path.res {
-                    primitive_link(f, PrimitiveType::from(p), name.as_str(), cx)?;
+                    primitive_link(
+                        f,
+                        PrimitiveType::from(p),
+                        format_args!("{}", name.as_str()),
+                        cx,
+                    )?;
                 } else {
                     f.write_str(name.as_str())?;
                 }
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 17e2172a270..563e0cffddd 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -177,7 +177,7 @@ impl FromWithTcx<clean::Constant> for Constant {
         let expr = constant.expr(tcx);
         let value = constant.value(tcx);
         let is_literal = constant.is_literal(tcx);
-        Constant { type_: constant.type_.into_tcx(tcx), expr, value, is_literal }
+        Constant { type_: (*constant.type_).into_tcx(tcx), expr, value, is_literal }
     }
 }
 
@@ -325,11 +325,11 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
         }
         // FIXME(generic_const_items): Add support for generic associated consts.
         TyAssocConstItem(_generics, ty) => {
-            ItemEnum::AssocConst { type_: ty.into_tcx(tcx), default: None }
+            ItemEnum::AssocConst { type_: (*ty).into_tcx(tcx), default: None }
         }
         // FIXME(generic_const_items): Add support for generic associated consts.
         AssocConstItem(_generics, ty, default) => {
-            ItemEnum::AssocConst { type_: ty.into_tcx(tcx), default: Some(default.expr(tcx)) }
+            ItemEnum::AssocConst { type_: (*ty).into_tcx(tcx), default: Some(default.expr(tcx)) }
         }
         TyAssocTypeItem(g, b) => ItemEnum::AssocType {
             generics: g.into_tcx(tcx),
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 8eb8acbb116e7923ea2ce33a50109933ed5ab37
+Subproject d2f6a048529eb8e9ebc55d793abd63456c98fac
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index 9cdff84676e..f9ff1a0a486 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -408,8 +408,8 @@ fn download_rustc_perf(env: &Environment) -> anyhow::Result<()> {
 
     // FIXME: add some mechanism for synchronization of this commit SHA with
     // Linux (which builds rustc-perf in a Dockerfile)
-    // rustc-perf version from 2023-05-30
-    const PERF_COMMIT: &str = "8b2ac3042e1ff2c0074455a0a3618adef97156b1";
+    // rustc-perf version from 2023-10-22
+    const PERF_COMMIT: &str = "4f313add609f43e928e98132358e8426ed3969ae";
 
     let url = format!("https://ci-mirrors.rust-lang.org/rustc/rustc-perf-{PERF_COMMIT}.zip");
     let client = reqwest::blocking::Client::builder()
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index 8000c9e7fdd..3c33cfe985d 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -24,11 +24,10 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> {
     let host_triple = env.host_triple();
     let version = find_dist_version(&dist_dir)?;
 
-    // Extract rustc, libstd, cargo and src archives to create the optimized sysroot
+    // Extract rustc, libstd and src archives to create the optimized sysroot
     let rustc_dir = extract_dist_dir(&format!("rustc-{version}-{host_triple}"))?.join("rustc");
     let libstd_dir = extract_dist_dir(&format!("rust-std-{version}-{host_triple}"))?
         .join(format!("rust-std-{host_triple}"));
-    let cargo_dir = extract_dist_dir(&format!("cargo-{version}-{host_triple}"))?.join("cargo");
     let extracted_src_dir = extract_dist_dir(&format!("rust-src-{version}"))?.join("rust-src");
 
     // We need to manually copy libstd to the extracted rustc sysroot
@@ -47,8 +46,6 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> {
 
     let rustc_path = rustc_dir.join("bin").join(format!("rustc{}", executable_extension()));
     assert!(rustc_path.is_file());
-    let cargo_path = cargo_dir.join("bin").join(format!("cargo{}", executable_extension()));
-    assert!(cargo_path.is_file());
 
     // Specify path to a LLVM config so that LLVM is not rebuilt.
     // It doesn't really matter which LLVM config we choose, because no sysroot will be compiled.
@@ -65,13 +62,11 @@ change-id = 115898
 
 [build]
 rustc = "{rustc}"
-cargo = "{cargo}"
 
 [target.{host_triple}]
 llvm-config = "{llvm_config}"
 "#,
         rustc = rustc_path.to_string().replace('\\', "/"),
-        cargo = cargo_path.to_string().replace('\\', "/"),
         llvm_config = llvm_config.to_string().replace('\\', "/")
     );
     log::info!("Using following `config.toml` for running tests:\n{config_content}");
@@ -84,6 +79,8 @@ llvm-config = "{llvm_config}"
         env.python_binary(),
         x_py.as_str(),
         "test",
+        "--build",
+        env.host_triple(),
         "--stage",
         "0",
         "tests/assembly",