about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs14
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs1
-rw-r--r--library/core/src/ptr/const_ptr.rs92
-rw-r--r--library/core/src/ptr/mut_ptr.rs92
m---------src/doc/book0
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/librustdoc/html/escape.rs12
-rw-r--r--src/librustdoc/html/escape/tests.rs4
-rw-r--r--src/tools/run-make-support/src/macros.rs24
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt1
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--tests/codegen/function-return.rs6
-rw-r--r--tests/codegen/option-as-slice.rs8
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.rs1
-rw-r--r--tests/run-make/emit-to-stdout/Makefile51
-rw-r--r--tests/run-make/emit-to-stdout/rmake.rs73
-rw-r--r--tests/ui/consts/large-zst-array-77062.rs (renamed from tests/ui/consts/issue-77062-large-zst-array.rs)1
-rw-r--r--tests/ui/traits/assoc-type-hrtb-normalization-30472.rs32
-rw-r--r--tests/ui/traits/fn-pointer/hrtb-assoc-fn-traits-28994.rs22
-rw-r--r--tests/ui/traits/hrtb-related-type-params-30867.rs14
-rw-r--r--tests/ui/utf8-bom.rs4
-rw-r--r--triagebot.toml1
28 files changed, 392 insertions, 64 deletions
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 2b8912d1db2..81b82840472 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -19,7 +19,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::Session;
 use rustc_session::config::{
-    BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, PAuthKey, PacRet,
+    BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, FunctionReturn, PAuthKey, PacRet,
 };
 use rustc_span::source_map::Spanned;
 use rustc_span::{DUMMY_SP, Span};
@@ -378,6 +378,18 @@ pub(crate) unsafe fn create_module<'ll>(
         }
     }
 
+    match sess.opts.unstable_opts.function_return {
+        FunctionReturn::Keep => {}
+        FunctionReturn::ThunkExtern => unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                c"function_return_thunk_extern".as_ptr(),
+                1,
+            )
+        },
+    }
+
     match (sess.opts.unstable_opts.small_data_threshold, sess.target.small_data_threshold_support())
     {
         // Set up the small-data optimization limit for architectures that use
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs
index 51960dbec4a..254ae54db21 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs
@@ -15,6 +15,7 @@ pub(crate) fn target() -> Target {
         },
 
         options: TargetOptions {
+            vendor: "espressif".into(),
             cpu: "esp32".into(),
             linker: Some("xtensa-esp32-elf-gcc".into()),
             max_atomic_width: Some(32),
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs
index 21330615a87..34d8383a604 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs
@@ -15,6 +15,7 @@ pub(crate) fn target() -> Target {
         },
 
         options: TargetOptions {
+            vendor: "espressif".into(),
             cpu: "esp32-s2".into(),
             linker: Some("xtensa-esp32s2-elf-gcc".into()),
             max_atomic_width: Some(32),
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs
index fca47b4bdb1..023a67f2871 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs
@@ -15,6 +15,7 @@ pub(crate) fn target() -> Target {
         },
 
         options: TargetOptions {
+            vendor: "espressif".into(),
             cpu: "esp32-s3".into(),
             linker: Some("xtensa-esp32s3-elf-gcc".into()),
             max_atomic_width: Some(32),
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 332c5e904d7..c9af7f13e46 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -395,6 +395,36 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
+        #[inline]
+        const fn runtime_offset_nowrap(this: *const (), count: isize, size: usize) -> bool {
+            #[inline]
+            fn runtime(this: *const (), count: isize, size: usize) -> bool {
+                // We know `size <= isize::MAX` so the `as` cast here is not lossy.
+                let Some(byte_offset) = count.checked_mul(size as isize) else {
+                    return false;
+                };
+                let (_, overflow) = this.addr().overflowing_add_signed(byte_offset);
+                !overflow
+            }
+
+            const fn comptime(_: *const (), _: isize, _: usize) -> bool {
+                true
+            }
+
+            // We can use const_eval_select here because this is only for UB checks.
+            intrinsics::const_eval_select((this, count, size), comptime, runtime)
+        }
+
+        ub_checks::assert_unsafe_precondition!(
+            check_language_ub,
+            "ptr::offset requires the address calculation to not overflow",
+            (
+                this: *const () = self as *const (),
+                count: isize = count,
+                size: usize = size_of::<T>(),
+            ) => runtime_offset_nowrap(this, count, size)
+        );
+
         // SAFETY: the caller must uphold the safety contract for `offset`.
         unsafe { intrinsics::offset(self, count) }
     }
@@ -726,7 +756,6 @@ impl<T: ?Sized> *const T {
                 true
             }
 
-            #[allow(unused_unsafe)]
             intrinsics::const_eval_select((this, origin), comptime, runtime)
         }
 
@@ -858,6 +887,36 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
+        #[cfg(debug_assertions)]
+        #[inline]
+        const fn runtime_add_nowrap(this: *const (), count: usize, size: usize) -> bool {
+            #[inline]
+            fn runtime(this: *const (), count: usize, size: usize) -> bool {
+                let Some(byte_offset) = count.checked_mul(size) else {
+                    return false;
+                };
+                let (_, overflow) = this.addr().overflowing_add(byte_offset);
+                byte_offset <= (isize::MAX as usize) && !overflow
+            }
+
+            const fn comptime(_: *const (), _: usize, _: usize) -> bool {
+                true
+            }
+
+            intrinsics::const_eval_select((this, count, size), comptime, runtime)
+        }
+
+        #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild.
+        ub_checks::assert_unsafe_precondition!(
+            check_language_ub,
+            "ptr::add requires that the address calculation does not overflow",
+            (
+                this: *const () = self as *const (),
+                count: usize = count,
+                size: usize = size_of::<T>(),
+            ) => runtime_add_nowrap(this, count, size)
+        );
+
         // SAFETY: the caller must uphold the safety contract for `offset`.
         unsafe { intrinsics::offset(self, count) }
     }
@@ -936,6 +995,35 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
+        #[cfg(debug_assertions)]
+        #[inline]
+        const fn runtime_sub_nowrap(this: *const (), count: usize, size: usize) -> bool {
+            #[inline]
+            fn runtime(this: *const (), count: usize, size: usize) -> bool {
+                let Some(byte_offset) = count.checked_mul(size) else {
+                    return false;
+                };
+                byte_offset <= (isize::MAX as usize) && this.addr() >= byte_offset
+            }
+
+            const fn comptime(_: *const (), _: usize, _: usize) -> bool {
+                true
+            }
+
+            intrinsics::const_eval_select((this, count, size), comptime, runtime)
+        }
+
+        #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild.
+        ub_checks::assert_unsafe_precondition!(
+            check_language_ub,
+            "ptr::sub requires that the address calculation does not overflow",
+            (
+                this: *const () = self as *const (),
+                count: usize = count,
+                size: usize = size_of::<T>(),
+            ) => runtime_sub_nowrap(this, count, size)
+        );
+
         if T::IS_ZST {
             // Pointer arithmetic does nothing when the pointee is a ZST.
             self
@@ -943,7 +1031,7 @@ impl<T: ?Sized> *const T {
             // SAFETY: the caller must uphold the safety contract for `offset`.
             // Because the pointee is *not* a ZST, that means that `count` is
             // at most `isize::MAX`, and thus the negation cannot overflow.
-            unsafe { self.offset((count as isize).unchecked_neg()) }
+            unsafe { intrinsics::offset(self, intrinsics::unchecked_sub(0, count as isize)) }
         }
     }
 
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 287073497f8..e458bb4642f 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -393,6 +393,37 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
+        #[inline]
+        const fn runtime_offset_nowrap(this: *const (), count: isize, size: usize) -> bool {
+            #[inline]
+            fn runtime(this: *const (), count: isize, size: usize) -> bool {
+                // `size` is the size of a Rust type, so we know that
+                // `size <= isize::MAX` and thus `as` cast here is not lossy.
+                let Some(byte_offset) = count.checked_mul(size as isize) else {
+                    return false;
+                };
+                let (_, overflow) = this.addr().overflowing_add_signed(byte_offset);
+                !overflow
+            }
+
+            const fn comptime(_: *const (), _: isize, _: usize) -> bool {
+                true
+            }
+
+            // We can use const_eval_select here because this is only for UB checks.
+            intrinsics::const_eval_select((this, count, size), comptime, runtime)
+        }
+
+        ub_checks::assert_unsafe_precondition!(
+            check_language_ub,
+            "ptr::offset requires the address calculation to not overflow",
+            (
+                this: *const () = self as *const (),
+                count: isize = count,
+                size: usize = size_of::<T>(),
+            ) => runtime_offset_nowrap(this, count, size)
+        );
+
         // SAFETY: the caller must uphold the safety contract for `offset`.
         // The obtained pointer is valid for writes since the caller must
         // guarantee that it points to the same allocated object as `self`.
@@ -940,6 +971,36 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
+        #[cfg(debug_assertions)]
+        #[inline]
+        const fn runtime_add_nowrap(this: *const (), count: usize, size: usize) -> bool {
+            #[inline]
+            fn runtime(this: *const (), count: usize, size: usize) -> bool {
+                let Some(byte_offset) = count.checked_mul(size) else {
+                    return false;
+                };
+                let (_, overflow) = this.addr().overflowing_add(byte_offset);
+                byte_offset <= (isize::MAX as usize) && !overflow
+            }
+
+            const fn comptime(_: *const (), _: usize, _: usize) -> bool {
+                true
+            }
+
+            intrinsics::const_eval_select((this, count, size), comptime, runtime)
+        }
+
+        #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild.
+        ub_checks::assert_unsafe_precondition!(
+            check_language_ub,
+            "ptr::add requires that the address calculation does not overflow",
+            (
+                this: *const () = self as *const (),
+                count: usize = count,
+                size: usize = size_of::<T>(),
+            ) => runtime_add_nowrap(this, count, size)
+        );
+
         // SAFETY: the caller must uphold the safety contract for `offset`.
         unsafe { intrinsics::offset(self, count) }
     }
@@ -1018,6 +1079,35 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
+        #[cfg(debug_assertions)]
+        #[inline]
+        const fn runtime_sub_nowrap(this: *const (), count: usize, size: usize) -> bool {
+            #[inline]
+            fn runtime(this: *const (), count: usize, size: usize) -> bool {
+                let Some(byte_offset) = count.checked_mul(size) else {
+                    return false;
+                };
+                byte_offset <= (isize::MAX as usize) && this.addr() >= byte_offset
+            }
+
+            const fn comptime(_: *const (), _: usize, _: usize) -> bool {
+                true
+            }
+
+            intrinsics::const_eval_select((this, count, size), comptime, runtime)
+        }
+
+        #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild.
+        ub_checks::assert_unsafe_precondition!(
+            check_language_ub,
+            "ptr::sub requires that the address calculation does not overflow",
+            (
+                this: *const () = self as *const (),
+                count: usize = count,
+                size: usize = size_of::<T>(),
+            ) => runtime_sub_nowrap(this, count, size)
+        );
+
         if T::IS_ZST {
             // Pointer arithmetic does nothing when the pointee is a ZST.
             self
@@ -1025,7 +1115,7 @@ impl<T: ?Sized> *mut T {
             // SAFETY: the caller must uphold the safety contract for `offset`.
             // Because the pointee is *not* a ZST, that means that `count` is
             // at most `isize::MAX`, and thus the negation cannot overflow.
-            unsafe { self.offset((count as isize).unchecked_neg()) }
+            unsafe { intrinsics::offset(self, intrinsics::unchecked_sub(0, count as isize)) }
         }
     }
 
diff --git a/src/doc/book b/src/doc/book
-Subproject 99cf75a5414fa8adbe3974bd0836661ca901708
+Subproject f38ce8baef98cb20229e56f1be2d50e345f1179
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject dbae36bf3f8410aa4313b3bad42e374735d48a9
+Subproject f40a8b420ec4b4505d9489965e261f1d5c28ba2
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 14649f15d232d509478206ee9ed5105641aa60d
+Subproject 456b904f791751892b01282fd2757904993c4c2
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 24fb2687cdbc54fa18ae4acf5d879cfceca77b2
+Subproject c64e52a3d306eac0129f3ad6c6d8806ab99ae2e
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject c79ec345f08a1e94494cdc8c999709a90203fd8
+Subproject 8bede1b919a81ab7d0c961f6bbf68d3efa297bd
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 555f3de2fa0d61c4294b74d245f1cbad6fcbf58
+Subproject 07bc9ca9eb1cd6d9fbbf758c2753b748804a134
diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs
index 691f86847b5..31a2701f06a 100644
--- a/src/librustdoc/html/escape.rs
+++ b/src/librustdoc/html/escape.rs
@@ -108,7 +108,17 @@ impl<'a> fmt::Display for EscapeBodyTextWithWbr<'a> {
                 || pk.map_or(true, |(_, t)| t.chars().any(|c| c.is_uppercase()));
             let next_is_underscore = || pk.map_or(true, |(_, t)| t.contains('_'));
             let next_is_colon = || pk.map_or(true, |(_, t)| t.contains(':'));
-            if i - last > 3 && is_uppercase() && !next_is_uppercase() {
+            // Check for CamelCase.
+            //
+            // `i - last > 3` avoids turning FmRadio into Fm<wbr>Radio, which is technically
+            // correct, but needlessly bloated.
+            //
+            // is_uppercase && !next_is_uppercase checks for camelCase. HTTPSProxy,
+            // for example, should become HTTPS<wbr>Proxy.
+            //
+            // !next_is_underscore avoids turning TEST_RUN into TEST<wbr>_<wbr>RUN, which is also
+            // needlessly bloated.
+            if i - last > 3 && is_uppercase() && !next_is_uppercase() && !next_is_underscore() {
                 EscapeBodyText(&text[last..i]).fmt(fmt)?;
                 fmt.write_str("<wbr>")?;
                 last = i;
diff --git a/src/librustdoc/html/escape/tests.rs b/src/librustdoc/html/escape/tests.rs
index a09649e9e18..de702e16063 100644
--- a/src/librustdoc/html/escape/tests.rs
+++ b/src/librustdoc/html/escape/tests.rs
@@ -24,6 +24,10 @@ fn escape_body_text_with_wbr() {
     assert_eq!(&E("first:second").to_string(), "first:<wbr>second");
     assert_eq!(&E("first::second").to_string(), "first::<wbr>second");
     assert_eq!(&E("MY_CONSTANT").to_string(), "MY_<wbr>CONSTANT");
+    assert_eq!(
+        &E("_SIDD_MASKED_NEGATIVE_POLARITY").to_string(),
+        "_SIDD_<wbr>MASKED_<wbr>NEGATIVE_<wbr>POLARITY"
+    );
     // a string won't get wrapped if it's less than 8 bytes
     assert_eq!(&E("HashSet").to_string(), "HashSet");
     // an individual word won't get wrapped if it's less than 4 bytes
diff --git a/src/tools/run-make-support/src/macros.rs b/src/tools/run-make-support/src/macros.rs
index f7fe4f54223..cc3d1281d0a 100644
--- a/src/tools/run-make-support/src/macros.rs
+++ b/src/tools/run-make-support/src/macros.rs
@@ -70,6 +70,30 @@ macro_rules! impl_common_helpers {
                 self
             }
 
+            /// Configuration for the child process’s standard input (stdin) handle.
+            ///
+            /// See [`std::process::Command::stdin`].
+            pub fn stdin<T: Into<::std::process::Stdio>>(&mut self, cfg: T) -> &mut Self {
+                self.cmd.stdin(cfg);
+                self
+            }
+
+            /// Configuration for the child process’s standard output (stdout) handle.
+            ///
+            /// See [`std::process::Command::stdout`].
+            pub fn stdout<T: Into<::std::process::Stdio>>(&mut self, cfg: T) -> &mut Self {
+                self.cmd.stdout(cfg);
+                self
+            }
+
+            /// Configuration for the child process’s standard error (stderr) handle.
+            ///
+            /// See [`std::process::Command::stderr`].
+            pub fn stderr<T: Into<::std::process::Stdio>>(&mut self, cfg: T) -> &mut Self {
+                self.cmd.stderr(cfg);
+                self
+            }
+
             /// Inspect what the underlying [`Command`] is up to the
             /// current construction.
             pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 50d21c7ed4c..7a0f98d59f0 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -1,6 +1,5 @@
 run-make/branch-protection-check-IBT/Makefile
 run-make/cat-and-grep-sanity-check/Makefile
-run-make/emit-to-stdout/Makefile
 run-make/extern-fn-reachable/Makefile
 run-make/incr-add-rust-src-component/Makefile
 run-make/issue-84395-lto-embed-bitcode/Makefile
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 86cae849b97..8dc1ee38ffd 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -802,7 +802,6 @@ ui/consts/issue-70942-trait-vs-impl-mismatch.rs
 ui/consts/issue-73976-monomorphic.rs
 ui/consts/issue-73976-polymorphic.rs
 ui/consts/issue-76064.rs
-ui/consts/issue-77062-large-zst-array.rs
 ui/consts/issue-78655.rs
 ui/consts/issue-79137-monomorphic.rs
 ui/consts/issue-79137-toogeneric.rs
diff --git a/tests/codegen/function-return.rs b/tests/codegen/function-return.rs
index 0ca1a41ee86..2b9de4e1478 100644
--- a/tests/codegen/function-return.rs
+++ b/tests/codegen/function-return.rs
@@ -26,3 +26,9 @@ pub fn foo() {
     // keep-thunk-extern: attributes #0 = { {{.*}}fn_ret_thunk_extern{{.*}} }
     // thunk-extern-keep-NOT: fn_ret_thunk_extern
 }
+
+// unset-NOT: !{{[0-9]+}} = !{i32 4, !"function_return_thunk_extern", i32 1}
+// keep-NOT: !{{[0-9]+}} = !{i32 4, !"function_return_thunk_extern", i32 1}
+// thunk-extern: !{{[0-9]+}} = !{i32 4, !"function_return_thunk_extern", i32 1}
+// keep-thunk-extern: !{{[0-9]+}} = !{i32 4, !"function_return_thunk_extern", i32 1}
+// thunk-extern-keep-NOT: !{{[0-9]+}} = !{i32 4, !"function_return_thunk_extern", i32 1}
diff --git a/tests/codegen/option-as-slice.rs b/tests/codegen/option-as-slice.rs
index cfa479aa4b2..0edbbac1176 100644
--- a/tests/codegen/option-as-slice.rs
+++ b/tests/codegen/option-as-slice.rs
@@ -14,7 +14,9 @@ pub fn u64_opt_as_slice(o: &Option<u64>) -> &[u64] {
     // CHECK-NOT: br
     // CHECK-NOT: switch
     // CHECK-NOT: icmp
-    // CHECK: %[[LEN:.+]] = load i64,{{.+}} !range ![[META_U64:.+]], !noundef
+    // CHECK: %[[LEN:.+]] = load i64
+    // CHECK-SAME: !range ![[META_U64:[0-9]+]],
+    // CHECK-SAME: !noundef
     // CHECK-NOT: select
     // CHECK-NOT: br
     // CHECK-NOT: switch
@@ -51,7 +53,9 @@ pub fn u8_opt_as_slice(o: &Option<u8>) -> &[u8] {
     // CHECK-NOT: br
     // CHECK-NOT: switch
     // CHECK-NOT: icmp
-    // CHECK: %[[TAG:.+]] = load i8,{{.+}} !range ![[META_U8:.+]], !noundef
+    // CHECK: %[[TAG:.+]] = load i8
+    // CHECK-SAME: !range ![[META_U8:[0-9]+]],
+    // CHECK-SAME: !noundef
     // CHECK: %[[LEN:.+]] = zext{{.*}} i8 %[[TAG]] to i64
     // CHECK-NOT: select
     // CHECK-NOT: br
diff --git a/tests/mir-opt/pre-codegen/slice_iter.rs b/tests/mir-opt/pre-codegen/slice_iter.rs
index 3f89ab0e6f3..fee4214982d 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.rs
+++ b/tests/mir-opt/pre-codegen/slice_iter.rs
@@ -1,6 +1,7 @@
 // skip-filecheck
 //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
 //@ only-64bit (constants for `None::<&T>` show in the output)
+//@ ignore-debug: precondition checks on ptr::add are under cfg(debug_assertions)
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
 #![crate_type = "lib"]
diff --git a/tests/run-make/emit-to-stdout/Makefile b/tests/run-make/emit-to-stdout/Makefile
deleted file mode 100644
index 80e9b6a4ded..00000000000
--- a/tests/run-make/emit-to-stdout/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-include ../tools.mk
-
-SRC=test.rs
-OUT=$(TMPDIR)/out
-
-all: asm llvm-ir dep-info mir llvm-bc obj metadata link multiple-types multiple-types-option-o
-
-asm: $(OUT)
-	$(RUSTC) --emit asm=$(OUT)/$@ $(SRC)
-	$(RUSTC) --emit asm=- $(SRC) | diff - $(OUT)/$@
-llvm-ir: $(OUT)
-	$(RUSTC) --emit llvm-ir=$(OUT)/$@ $(SRC)
-	$(RUSTC) --emit llvm-ir=- $(SRC) | diff - $(OUT)/$@
-dep-info: $(OUT)
-	$(RUSTC) -Z dep-info-omit-d-target=yes --emit dep-info=$(OUT)/$@ $(SRC)
-	$(RUSTC) --emit dep-info=- $(SRC) | diff - $(OUT)/$@
-mir: $(OUT)
-	$(RUSTC) --emit mir=$(OUT)/$@ $(SRC)
-	$(RUSTC) --emit mir=- $(SRC) | diff - $(OUT)/$@
-
-llvm-bc: $(OUT)
-	$(RUSTC) --emit llvm-bc=- $(SRC) 1>/dev/ptmx 2>$(OUT)/$@ || true
-	diff $(OUT)/$@ emit-llvm-bc.stderr
-obj: $(OUT)
-	$(RUSTC) --emit obj=- $(SRC) 1>/dev/ptmx 2>$(OUT)/$@ || true
-	diff $(OUT)/$@ emit-obj.stderr
-
-# For metadata output, a temporary directory will be created to hold the temporary
-# metadata file. But when output is stdout, the temporary directory will be located
-# in the same place as $(SRC), which is mounted as read-only in the tests. Thus as
-# a workaround, $(SRC) is copied to the test output directory $(OUT) and we compile
-# it there.
-metadata: $(OUT)
-	cp $(SRC) $(OUT)
-	(cd $(OUT); $(RUSTC) --emit metadata=- $(SRC) 1>/dev/ptmx 2>$(OUT)/$@ || true)
-	diff $(OUT)/$@ emit-metadata.stderr
-
-link: $(OUT)
-	$(RUSTC) --emit link=- $(SRC) 1>/dev/ptmx 2>$(OUT)/$@ || true
-	diff $(OUT)/$@ emit-link.stderr
-
-multiple-types: $(OUT)
-	$(RUSTC) --emit asm=- --emit llvm-ir=- --emit dep-info=- --emit mir=- $(SRC) 2>$(OUT)/$@ || true
-	diff $(OUT)/$@ emit-multiple-types.stderr
-
-multiple-types-option-o: $(OUT)
-	$(RUSTC) -o - --emit asm,llvm-ir,dep-info,mir $(SRC) 2>$(OUT)/$@ || true
-	diff $(OUT)/$@ emit-multiple-types.stderr
-
-$(OUT):
-	mkdir -p $(OUT)
diff --git a/tests/run-make/emit-to-stdout/rmake.rs b/tests/run-make/emit-to-stdout/rmake.rs
new file mode 100644
index 00000000000..a9a3796731b
--- /dev/null
+++ b/tests/run-make/emit-to-stdout/rmake.rs
@@ -0,0 +1,73 @@
+//! If `-o -` or `--emit KIND=-` is provided, output should be written to stdout
+//! instead. Binary output (`obj`, `llvm-bc`, `link` and `metadata`)
+//! being written this way will result in an error if stdout is a tty.
+//! Multiple output types going to stdout will trigger an error too,
+//! as they would all be mixed together.
+//!
+//! See <https://github.com/rust-lang/rust/pull/111626>.
+
+use std::fs::File;
+
+use run_make_support::{diff, run_in_tmpdir, rustc};
+
+// Test emitting text outputs to stdout works correctly
+fn run_diff(name: &str, file_args: &[&str]) {
+    rustc().emit(format!("{name}={name}")).input("test.rs").args(file_args).run();
+    let out = rustc().emit(format!("{name}=-")).input("test.rs").run().stdout_utf8();
+    diff().expected_file(name).actual_text("stdout", &out).run();
+}
+
+// Test that emitting binary formats to a terminal gives the correct error
+fn run_terminal_err_diff(name: &str) {
+    #[cfg(not(windows))]
+    let terminal = File::create("/dev/ptmx").unwrap();
+    // FIXME: If this test fails and the compiler does print to the console,
+    // then this will produce a lot of output.
+    // We should spawn a new console instead to print stdout.
+    #[cfg(windows)]
+    let terminal = File::options().read(true).write(true).open(r"\\.\CONOUT$").unwrap();
+
+    let err = File::create(name).unwrap();
+    rustc().emit(format!("{name}=-")).input("test.rs").stdout(terminal).stderr(err).run_fail();
+    diff().expected_file(format!("emit-{name}.stderr")).actual_file(name).run();
+}
+
+fn main() {
+    run_in_tmpdir(|| {
+        run_diff("asm", &[]);
+        run_diff("llvm-ir", &[]);
+        run_diff("dep-info", &["-Zdep-info-omit-d-target=yes"]);
+        run_diff("mir", &[]);
+
+        run_terminal_err_diff("llvm-bc");
+        run_terminal_err_diff("obj");
+        run_terminal_err_diff("metadata");
+        run_terminal_err_diff("link");
+
+        // Test error for emitting multiple types to stdout
+        rustc()
+            .input("test.rs")
+            .emit("asm=-")
+            .emit("llvm-ir=-")
+            .emit("dep-info=-")
+            .emit("mir=-")
+            .stderr(File::create("multiple-types").unwrap())
+            .run_fail();
+        diff().expected_file("emit-multiple-types.stderr").actual_file("multiple-types").run();
+
+        // Same as above, but using `-o`
+        rustc()
+            .input("test.rs")
+            .output("-")
+            .emit("asm,llvm-ir,dep-info,mir")
+            .stderr(File::create("multiple-types-option-o").unwrap())
+            .run_fail();
+        diff()
+            .expected_file("emit-multiple-types.stderr")
+            .actual_file("multiple-types-option-o")
+            .run();
+
+        // Test that `-o -` redirected to a file works correctly (#26719)
+        rustc().input("test.rs").output("-").stdout(File::create("out-stdout").unwrap()).run();
+    });
+}
diff --git a/tests/ui/consts/issue-77062-large-zst-array.rs b/tests/ui/consts/large-zst-array-77062.rs
index ef5178fba95..089353d0885 100644
--- a/tests/ui/consts/issue-77062-large-zst-array.rs
+++ b/tests/ui/consts/large-zst-array-77062.rs
@@ -1,4 +1,5 @@
 //@ build-pass
+pub static FOO: [(); usize::MAX] = [(); usize::MAX];
 
 fn main() {
     let _ = &[(); usize::MAX];
diff --git a/tests/ui/traits/assoc-type-hrtb-normalization-30472.rs b/tests/ui/traits/assoc-type-hrtb-normalization-30472.rs
new file mode 100644
index 00000000000..4ce3b9b3b77
--- /dev/null
+++ b/tests/ui/traits/assoc-type-hrtb-normalization-30472.rs
@@ -0,0 +1,32 @@
+//@ check-pass
+//! Tests that associated type projections normalize properly in the presence of HRTBs.
+//! Original issue: <https://github.com/rust-lang/rust/issues/30472>
+
+
+pub trait MyFrom<T> {}
+impl<T> MyFrom<T> for T {}
+
+pub trait MyInto<T> {}
+impl<T, U> MyInto<U> for T where U: MyFrom<T> {}
+
+
+pub trait A<'self_> {
+    type T;
+}
+pub trait B: for<'self_> A<'self_> {
+    // Originally caused the `type U = usize` example below to fail with a type mismatch error
+    type U: for<'self_> MyFrom<<Self as A<'self_>>::T>;
+}
+
+
+pub struct M;
+impl<'self_> A<'self_> for M {
+    type T = usize;
+}
+
+impl B for M {
+    type U = usize;
+}
+
+
+fn main() {}
diff --git a/tests/ui/traits/fn-pointer/hrtb-assoc-fn-traits-28994.rs b/tests/ui/traits/fn-pointer/hrtb-assoc-fn-traits-28994.rs
new file mode 100644
index 00000000000..e2f02053f95
--- /dev/null
+++ b/tests/ui/traits/fn-pointer/hrtb-assoc-fn-traits-28994.rs
@@ -0,0 +1,22 @@
+//@ check-pass
+//! Tests that a HRTB + FnOnce bound involving an associated type don't prevent
+//! a function pointer from implementing `Fn` traits.
+//! Test for <https://github.com/rust-lang/rust/issues/28994>
+
+trait LifetimeToType<'a> {
+    type Out;
+}
+
+impl<'a> LifetimeToType<'a> for () {
+    type Out = &'a ();
+}
+
+fn id<'a>(val: &'a ()) -> <() as LifetimeToType<'a>>::Out {
+    val
+}
+
+fn assert_fn<F: for<'a> FnOnce(&'a ()) -> <() as LifetimeToType<'a>>::Out>(_func: F) { }
+
+fn main() {
+    assert_fn(id);
+}
diff --git a/tests/ui/traits/hrtb-related-type-params-30867.rs b/tests/ui/traits/hrtb-related-type-params-30867.rs
new file mode 100644
index 00000000000..ec1e3355bfb
--- /dev/null
+++ b/tests/ui/traits/hrtb-related-type-params-30867.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+//! Tests that HRTB impl selection covers type parameters not directly related
+//! to the trait.
+//! Test for <https://github.com/rust-lang/rust/issues/30867>
+
+#![crate_type = "lib"]
+
+trait Unary<T> {}
+impl<T, U, F: Fn(T) -> U> Unary<T> for F {}
+fn unary<F: for<'a> Unary<&'a T>, T>() {}
+
+pub fn test<F: for<'a> Fn(&'a i32) -> &'a i32>() {
+    unary::<F, i32>()
+}
diff --git a/tests/ui/utf8-bom.rs b/tests/ui/utf8-bom.rs
index e2e4ccd63c1..5b9e27fb7b9 100644
--- a/tests/ui/utf8-bom.rs
+++ b/tests/ui/utf8-bom.rs
@@ -1,6 +1,4 @@
+// This file has utf-8 BOM, it should be compiled normally without error.
 //@ run-pass
-//
-
-// This file has utf-8 BOM, it should be compiled normally without error.
 
 pub fn main() {}
diff --git a/triagebot.toml b/triagebot.toml
index 0172a80b3a5..d3e4af9b718 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -926,7 +926,6 @@ users_on_vacation = [
     "jhpratt",
     "jyn514",
     "oli-obk",
-    "jieyouxu",
 ]
 
 [assign.adhoc_groups]