about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-22 23:59:01 +0000
committerbors <bors@rust-lang.org>2025-03-22 23:59:01 +0000
commit756bff97ea7f8f1a99f3db6a212dd9155a9c238e (patch)
tree6658d5165b2f46e241a0fc2ca263d086c90b2f14
parentb48576b4db5a595f453891f0b7243ef75d8c0afa (diff)
parent3f59916a3025f949c0cdfbfa3d8d373092caee4d (diff)
downloadrust-756bff97ea7f8f1a99f3db6a212dd9155a9c238e.tar.gz
rust-756bff97ea7f8f1a99f3db6a212dd9155a9c238e.zip
Auto merge of #138841 - matthiaskrgr:rollup-bfkls57, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #138018 (rustdoc: Use own logic to print `#[repr(..)]` attributes in JSON output.)
 - #138294 (Mark some std tests as requiring `panic = "unwind"`)
 - #138468 (rustdoc js: add nonnull helper and typecheck src-script.js)
 - #138675 (Add release notes for 1.85.1)
 - #138765 (Fix Thread::set_name on cygwin)
 - #138786 (Move some driver code around)
 - #138793 (target spec check: better error when llvm-floatabi is missing)
 - #138822 (De-Stabilize `file_lock`)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--RELEASES.md11
-rw-r--r--compiler/rustc_driver_impl/messages.ftl2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs27
-rw-r--r--compiler/rustc_driver_impl/src/session_diagnostics.rs6
-rw-r--r--compiler/rustc_interface/messages.ftl3
-rw-r--r--compiler/rustc_interface/src/errors.rs6
-rw-r--r--compiler/rustc_interface/src/passes.rs24
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs2
-rw-r--r--compiler/rustc_passes/src/errors.rs4
-rw-r--r--compiler/rustc_target/src/spec/mod.rs5
-rw-r--r--library/std/src/fs.rs15
-rw-r--r--library/std/src/sys/pal/unix/thread.rs5
-rw-r--r--library/std/src/thread/tests.rs5
-rw-r--r--library/std/tests/sync/mutex.rs10
-rw-r--r--library/std/tests/sync/once.rs4
-rw-r--r--library/std/tests/sync/once_lock.rs6
-rw-r--r--library/std/tests/sync/rwlock.rs16
-rw-r--r--src/librustdoc/clean/types.rs25
-rw-r--r--src/librustdoc/html/static/js/rustdoc.d.ts29
-rw-r--r--src/librustdoc/html/static/js/src-script.js28
-rw-r--r--src/librustdoc/html/static/js/storage.js22
-rw-r--r--src/rustdoc-json-types/lib.rs22
-rw-r--r--tests/rustdoc-json/attrs/repr_align.rs2
-rw-r--r--tests/rustdoc-json/attrs/repr_c.rs6
-rw-r--r--tests/rustdoc-json/attrs/repr_combination.rs23
-rw-r--r--tests/rustdoc-json/attrs/repr_int_enum.rs6
-rw-r--r--tests/rustdoc-json/attrs/repr_packed.rs8
-rw-r--r--tests/rustdoc-json/attrs/repr_transparent.rs29
-rw-r--r--tests/rustdoc-json/enums/discriminant/struct.rs2
-rw-r--r--tests/rustdoc-json/enums/discriminant/tuple.rs2
-rw-r--r--tests/ui/lint/linker-warning.stderr2
32 files changed, 256 insertions, 105 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 381b9ebc952..755e73a34c6 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,14 @@
+Version 1.85.1 (2025-03-18)
+==========================
+
+<a id="1.85.1"></a>
+
+- [Fix the doctest-merging feature of the 2024 Edition.](https://github.com/rust-lang/rust/pull/137899/)
+- [Relax some `target_feature` checks when generating docs.](https://github.com/rust-lang/rust/pull/137632/)
+- [Fix errors in `std::fs::rename` on Windows 10, version 1607.](https://github.com/rust-lang/rust/pull/137528/)
+- [Downgrade bootstrap `cc` to fix custom targets.](https://github.com/rust-lang/rust/pull/137460/)
+- [Skip submodule updates when building Rust from a source tarball.](https://github.com/rust-lang/rust/pull/137338/)
+
 Version 1.85.0 (2025-02-20)
 ==========================
 
diff --git a/compiler/rustc_driver_impl/messages.ftl b/compiler/rustc_driver_impl/messages.ftl
index 05e11c4527f..2c6a0291ac2 100644
--- a/compiler/rustc_driver_impl/messages.ftl
+++ b/compiler/rustc_driver_impl/messages.ftl
@@ -1,3 +1,5 @@
+driver_impl_cant_emit_mir = could not emit MIR: {$error}
+
 driver_impl_ice = the compiler unexpectedly panicked. this is a bug.
 driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url}
 driver_impl_ice_bug_report_internal_feature = using internal features is not supported and expected to cause internal compiler errors when used incorrectly
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 8ede6e41336..4ba076c64e1 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -108,7 +108,7 @@ mod signal_handler {
 }
 
 use crate::session_diagnostics::{
-    RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch,
+    CantEmitMIR, RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch,
     RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead, UnstableFeatureUsage,
 };
 
@@ -243,12 +243,17 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
         return;
     }
 
+    let input = make_input(&default_early_dcx, &matches.free);
+    let has_input = input.is_some();
     let (odir, ofile) = make_output(&matches);
+
+    drop(default_early_dcx);
+
     let mut config = interface::Config {
         opts: sopts,
         crate_cfg: matches.opt_strs("cfg"),
         crate_check_cfg: matches.opt_strs("check-cfg"),
-        input: Input::File(PathBuf::new()),
+        input: input.unwrap_or(Input::File(PathBuf::new())),
         output_file: ofile,
         output_dir: odir,
         ice_file,
@@ -265,16 +270,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
         expanded_args: args,
     };
 
-    let has_input = match make_input(&default_early_dcx, &matches.free) {
-        Some(input) => {
-            config.input = input;
-            true // has input: normal compilation
-        }
-        None => false, // no input: we will exit early
-    };
-
-    drop(default_early_dcx);
-
     callbacks.config(&mut config);
 
     let registered_lints = config.register_lints.is_some();
@@ -379,6 +374,12 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
                 return early_exit();
             }
 
+            if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
+                if let Err(error) = rustc_mir_transform::dump_mir::emit_mir(tcx) {
+                    tcx.dcx().emit_fatal(CantEmitMIR { error });
+                }
+            }
+
             Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend))
         });
 
@@ -407,7 +408,7 @@ fn dump_feature_usage_metrics(tcxt: TyCtxt<'_>, metrics_dir: &Path) {
     }
 }
 
-// Extract output directory and file from matches.
+/// Extract output directory and file from matches.
 fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<OutFileName>) {
     let odir = matches.opt_str("out-dir").map(|o| PathBuf::from(&o));
     let ofile = matches.opt_str("o").map(|o| match o.as_str() {
diff --git a/compiler/rustc_driver_impl/src/session_diagnostics.rs b/compiler/rustc_driver_impl/src/session_diagnostics.rs
index e06c56539d1..774221fd396 100644
--- a/compiler/rustc_driver_impl/src/session_diagnostics.rs
+++ b/compiler/rustc_driver_impl/src/session_diagnostics.rs
@@ -3,6 +3,12 @@ use std::error::Error;
 use rustc_macros::{Diagnostic, Subdiagnostic};
 
 #[derive(Diagnostic)]
+#[diag(driver_impl_cant_emit_mir)]
+pub struct CantEmitMIR {
+    pub error: std::io::Error,
+}
+
+#[derive(Diagnostic)]
 #[diag(driver_impl_rlink_unable_to_read)]
 pub(crate) struct RlinkUnableToRead {
     pub err: std::io::Error,
diff --git a/compiler/rustc_interface/messages.ftl b/compiler/rustc_interface/messages.ftl
index adc7ed54e14..ffbe708ba8d 100644
--- a/compiler/rustc_interface/messages.ftl
+++ b/compiler/rustc_interface/messages.ftl
@@ -3,9 +3,6 @@ interface_abi_required_feature =
     .note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 interface_abi_required_feature_issue = for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
 
-interface_cant_emit_mir =
-    could not emit MIR: {$error}
-
 interface_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$crate_name}` != `{$attr_crate_name}`
 
 interface_crate_name_invalid = crate names cannot start with a `-`, but `{$crate_name}` has a leading hyphen
diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs
index eed729a1777..ef0235b5577 100644
--- a/compiler/rustc_interface/src/errors.rs
+++ b/compiler/rustc_interface/src/errors.rs
@@ -74,12 +74,6 @@ pub struct TempsDirError;
 pub struct OutDirError;
 
 #[derive(Diagnostic)]
-#[diag(interface_cant_emit_mir)]
-pub struct CantEmitMIR {
-    pub error: io::Error,
-}
-
-#[derive(Diagnostic)]
 #[diag(interface_rustc_error_fatal)]
 pub struct RustcErrorFatal {
     #[primary_span]
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index e47385d0899..3d6b6a594a2 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -1078,6 +1078,15 @@ pub(crate) fn start_codegen<'tcx>(
     codegen_backend: &dyn CodegenBackend,
     tcx: TyCtxt<'tcx>,
 ) -> Box<dyn Any> {
+    // Hook for UI tests.
+    check_for_rustc_errors_attr(tcx);
+
+    // Don't run this test assertions when not doing codegen. Compiletest tries to build
+    // build-fail tests in check mode first and expects it to not give an error in that case.
+    if tcx.sess.opts.output_types.should_codegen() {
+        rustc_symbol_mangling::test::report_symbol_names(tcx);
+    }
+
     // Don't do code generation if there were any errors. Likewise if
     // there were any delayed bugs, because codegen will likely cause
     // more ICEs, obscuring the original problem.
@@ -1085,9 +1094,6 @@ pub(crate) fn start_codegen<'tcx>(
         guar.raise_fatal();
     }
 
-    // Hook for UI tests.
-    check_for_rustc_errors_attr(tcx);
-
     info!("Pre-codegen\n{:?}", tcx.debug_stats());
 
     let (metadata, need_metadata_module) = rustc_metadata::fs::encode_and_write_metadata(tcx);
@@ -1096,20 +1102,8 @@ pub(crate) fn start_codegen<'tcx>(
         codegen_backend.codegen_crate(tcx, metadata, need_metadata_module)
     });
 
-    // Don't run this test assertions when not doing codegen. Compiletest tries to build
-    // build-fail tests in check mode first and expects it to not give an error in that case.
-    if tcx.sess.opts.output_types.should_codegen() {
-        rustc_symbol_mangling::test::report_symbol_names(tcx);
-    }
-
     info!("Post-codegen\n{:?}", tcx.debug_stats());
 
-    if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
-        if let Err(error) = rustc_mir_transform::dump_mir::emit_mir(tcx) {
-            tcx.dcx().emit_fatal(errors::CantEmitMIR { error });
-        }
-    }
-
     // This must run after monomorphization so that all generic types
     // have been instantiated.
     if tcx.sess.opts.unstable_opts.print_type_sizes {
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index ed498d9d344..06398dd4f72 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -811,8 +811,8 @@ passes_unused_duplicate =
 passes_unused_empty_lints_note =
     attribute `{$name}` with an empty list has no effect
 
-passes_unused_linker_warnings_note =
-    the `linker_warnings` lint can only be controlled at the root of a crate that needs to be linked
+passes_unused_linker_messages_note =
+    the `linker_messages` lint can only be controlled at the root of a crate that needs to be linked
 
 passes_unused_multiple =
     multiple `{$name}` attributes
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 1ace98c91e6..9238c73cdb1 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -2402,7 +2402,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     .iter()
                     .all(|kind| matches!(kind, CrateType::Rlib | CrateType::Staticlib));
                 if never_needs_link {
-                    errors::UnusedNote::LinkerWarningsBinaryCrateOnly
+                    errors::UnusedNote::LinkerMessagesBinaryCrateOnly
                 } else {
                     return;
                 }
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index b8359c27e53..a72f40cd843 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -770,8 +770,8 @@ pub(crate) enum UnusedNote {
     NoLints { name: Symbol },
     #[note(passes_unused_default_method_body_const_note)]
     DefaultMethodBodyConst,
-    #[note(passes_unused_linker_warnings_note)]
-    LinkerWarningsBinaryCrateOnly,
+    #[note(passes_unused_linker_messages_note)]
+    LinkerMessagesBinaryCrateOnly,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 1887134c575..263646d8347 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -3342,7 +3342,10 @@ impl Target {
                 );
             }
             "arm" => {
-                check!(self.llvm_floatabi.is_some(), "ARM targets must specify their float ABI",)
+                check!(
+                    self.llvm_floatabi.is_some(),
+                    "ARM targets must set `llvm-floatabi` to `hard` or `soft`",
+                )
             }
             _ => {}
         }
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 7fc010d2ec3..fa98db69306 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -665,6 +665,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -673,7 +674,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn lock(&self) -> io::Result<()> {
         self.inner.lock()
     }
@@ -717,6 +718,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -725,7 +727,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn lock_shared(&self) -> io::Result<()> {
         self.inner.lock_shared()
     }
@@ -774,6 +776,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -782,7 +785,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn try_lock(&self) -> io::Result<bool> {
         self.inner.try_lock()
     }
@@ -830,6 +833,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -838,7 +842,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn try_lock_shared(&self) -> io::Result<bool> {
         self.inner.try_lock_shared()
     }
@@ -866,6 +870,7 @@ impl File {
     /// # Examples
     ///
     /// ```no_run
+    /// #![feature(file_lock)]
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
@@ -875,7 +880,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
+    #[unstable(feature = "file_lock", issue = "130994")]
     pub fn unlock(&self) -> io::Result<()> {
         self.inner.unlock()
     }
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index bffe2536299..bb34c2fabe5 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -143,8 +143,8 @@ impl Thread {
     pub fn set_name(name: &CStr) {
         unsafe {
             cfg_if::cfg_if! {
-                if #[cfg(target_os = "linux")] {
-                    // Linux limits the allowed length of the name.
+                if #[cfg(any(target_os = "linux", target_os = "cygwin"))] {
+                    // Linux and Cygwin limits the allowed length of the name.
                     const TASK_COMM_LEN: usize = 16;
                     let name = truncate_cstr::<{ TASK_COMM_LEN }>(name);
                 } else {
@@ -346,6 +346,7 @@ impl Drop for Thread {
     target_os = "solaris",
     target_os = "illumos",
     target_os = "vxworks",
+    target_os = "cygwin",
     target_vendor = "apple",
 ))]
 fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] {
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 06c347af181..59ec48a57d1 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -108,6 +108,7 @@ fn test_is_finished() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_join_panic() {
     match thread::spawn(move || panic!()).join() {
         result::Result::Err(_) => (),
@@ -210,6 +211,7 @@ fn test_simple_newsched_spawn() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_try_panic_message_string_literal() {
     match thread::spawn(move || {
         panic!("static string");
@@ -226,6 +228,7 @@ fn test_try_panic_message_string_literal() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_try_panic_any_message_owned_str() {
     match thread::spawn(move || {
         panic_any("owned string".to_string());
@@ -242,6 +245,7 @@ fn test_try_panic_any_message_owned_str() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_try_panic_any_message_any() {
     match thread::spawn(move || {
         panic_any(Box::new(413u16) as Box<dyn Any + Send>);
@@ -260,6 +264,7 @@ fn test_try_panic_any_message_any() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_try_panic_any_message_unit_struct() {
     struct Juju;
 
diff --git a/library/std/tests/sync/mutex.rs b/library/std/tests/sync/mutex.rs
index 74c62720107..88fb448d1eb 100644
--- a/library/std/tests/sync/mutex.rs
+++ b/library/std/tests/sync/mutex.rs
@@ -118,6 +118,7 @@ fn test_into_inner_drop() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_into_inner_poison() {
     let m = new_poisoned_mutex(NonCopy(10));
 
@@ -135,6 +136,7 @@ fn test_get_cloned() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_get_cloned_poison() {
     let m = new_poisoned_mutex(Cloneable(10));
 
@@ -152,6 +154,7 @@ fn test_get_mut() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_get_mut_poison() {
     let mut m = new_poisoned_mutex(NonCopy(10));
 
@@ -179,6 +182,7 @@ fn test_set() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_set_poison() {
     fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
     where
@@ -217,6 +221,7 @@ fn test_replace() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_replace_poison() {
     fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
     where
@@ -261,6 +266,7 @@ fn test_mutex_arc_condvar() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_arc_condvar_poison() {
     let packet = Packet(Arc::new((Mutex::new(1), Condvar::new())));
     let packet2 = Packet(packet.0.clone());
@@ -290,6 +296,7 @@ fn test_arc_condvar_poison() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_mutex_arc_poison() {
     let arc = Arc::new(Mutex::new(1));
     assert!(!arc.is_poisoned());
@@ -304,6 +311,7 @@ fn test_mutex_arc_poison() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_mutex_arc_poison_mapped() {
     let arc = Arc::new(Mutex::new(1));
     assert!(!arc.is_poisoned());
@@ -335,6 +343,7 @@ fn test_mutex_arc_nested() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_mutex_arc_access_in_unwind() {
     let arc = Arc::new(Mutex::new(1));
     let arc2 = arc.clone();
@@ -381,6 +390,7 @@ fn test_mapping_mapped_guard() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn panic_while_mapping_unlocked_poison() {
     let lock = Mutex::new(());
 
diff --git a/library/std/tests/sync/once.rs b/library/std/tests/sync/once.rs
index a3ffc73fe06..1b43831df3a 100644
--- a/library/std/tests/sync/once.rs
+++ b/library/std/tests/sync/once.rs
@@ -52,6 +52,7 @@ fn stampede_once() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn poison_bad() {
     static O: Once = Once::new();
 
@@ -80,6 +81,7 @@ fn poison_bad() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn wait_for_force_to_finish() {
     static O: Once = Once::new();
 
@@ -137,6 +139,7 @@ fn wait() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn wait_on_poisoned() {
     let once = Once::new();
 
@@ -145,6 +148,7 @@ fn wait_on_poisoned() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn wait_force_on_poisoned() {
     let once = Once::new();
 
diff --git a/library/std/tests/sync/once_lock.rs b/library/std/tests/sync/once_lock.rs
index ac9aaa8892e..922fd7da3d4 100644
--- a/library/std/tests/sync/once_lock.rs
+++ b/library/std/tests/sync/once_lock.rs
@@ -77,8 +77,10 @@ fn get_or_try_init() {
     let cell: OnceLock<String> = OnceLock::new();
     assert!(cell.get().is_none());
 
-    let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
-    assert!(res.is_err());
+    if cfg!(panic = "unwind") {
+        let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
+        assert!(res.is_err());
+    }
     assert!(cell.get().is_none());
 
     assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
diff --git a/library/std/tests/sync/rwlock.rs b/library/std/tests/sync/rwlock.rs
index 49f260648c6..d2c784aefcf 100644
--- a/library/std/tests/sync/rwlock.rs
+++ b/library/std/tests/sync/rwlock.rs
@@ -73,6 +73,7 @@ fn frob() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_rw_arc_poison_wr() {
     let arc = Arc::new(RwLock::new(1));
     let arc2 = arc.clone();
@@ -85,6 +86,7 @@ fn test_rw_arc_poison_wr() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_rw_arc_poison_mapped_w_r() {
     let arc = Arc::new(RwLock::new(1));
     let arc2 = arc.clone();
@@ -98,6 +100,7 @@ fn test_rw_arc_poison_mapped_w_r() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_rw_arc_poison_ww() {
     let arc = Arc::new(RwLock::new(1));
     assert!(!arc.is_poisoned());
@@ -112,6 +115,7 @@ fn test_rw_arc_poison_ww() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_rw_arc_poison_mapped_w_w() {
     let arc = Arc::new(RwLock::new(1));
     let arc2 = arc.clone();
@@ -126,6 +130,7 @@ fn test_rw_arc_poison_mapped_w_w() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_rw_arc_no_poison_rr() {
     let arc = Arc::new(RwLock::new(1));
     let arc2 = arc.clone();
@@ -139,6 +144,7 @@ fn test_rw_arc_no_poison_rr() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_rw_arc_no_poison_mapped_r_r() {
     let arc = Arc::new(RwLock::new(1));
     let arc2 = arc.clone();
@@ -153,6 +159,7 @@ fn test_rw_arc_no_poison_mapped_r_r() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_rw_arc_no_poison_rw() {
     let arc = Arc::new(RwLock::new(1));
     let arc2 = arc.clone();
@@ -166,6 +173,7 @@ fn test_rw_arc_no_poison_rw() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_rw_arc_no_poison_mapped_r_w() {
     let arc = Arc::new(RwLock::new(1));
     let arc2 = arc.clone();
@@ -218,6 +226,7 @@ fn test_rw_arc() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_rw_arc_access_in_unwind() {
     let arc = Arc::new(RwLock::new(1));
     let arc2 = arc.clone();
@@ -316,6 +325,7 @@ fn test_into_inner_drop() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_into_inner_poison() {
     let m = new_poisoned_rwlock(NonCopy(10));
 
@@ -333,6 +343,7 @@ fn test_get_cloned() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_get_cloned_poison() {
     let m = new_poisoned_rwlock(Cloneable(10));
 
@@ -350,6 +361,7 @@ fn test_get_mut() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_get_mut_poison() {
     let mut m = new_poisoned_rwlock(NonCopy(10));
 
@@ -377,6 +389,7 @@ fn test_set() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_set_poison() {
     fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
     where
@@ -415,6 +428,7 @@ fn test_replace() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_replace_poison() {
     fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
     where
@@ -482,6 +496,7 @@ fn test_mapping_mapped_guard() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn panic_while_mapping_read_unlocked_no_poison() {
     let lock = RwLock::new(());
 
@@ -551,6 +566,7 @@ fn panic_while_mapping_read_unlocked_no_poison() {
 }
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn panic_while_mapping_write_unlocked_poison() {
     let lock = RwLock::new(());
 
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 3b2dcb3db81..1207f2f0360 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -768,12 +768,22 @@ impl Item {
             .iter()
             .filter_map(|attr| {
                 if is_json {
-                    if matches!(attr, hir::Attribute::Parsed(AttributeKind::Deprecation { .. })) {
-                        // rustdoc-json stores this in `Item::deprecation`, so we
-                        // don't want it it `Item::attrs`.
-                        None
-                    } else {
-                        Some(rustc_hir_pretty::attribute_to_string(&tcx, attr))
+                    match attr {
+                        hir::Attribute::Parsed(AttributeKind::Deprecation { .. }) => {
+                            // rustdoc-json stores this in `Item::deprecation`, so we
+                            // don't want it it `Item::attrs`.
+                            None
+                        }
+                        rustc_hir::Attribute::Parsed(rustc_attr_parsing::AttributeKind::Repr(
+                            ..,
+                        )) => {
+                            // We have separate pretty-printing logic for `#[repr(..)]` attributes.
+                            // For example, there are circumstances where `#[repr(transparent)]`
+                            // is applied but should not be publicly shown in rustdoc
+                            // because it isn't public API.
+                            None
+                        }
+                        _ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)),
                     }
                 } else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
                     Some(
@@ -789,8 +799,7 @@ impl Item {
             .collect();
 
         // Add #[repr(...)]
-        if !is_json
-            && let Some(def_id) = self.def_id()
+        if let Some(def_id) = self.def_id()
             && let ItemType::Struct | ItemType::Enum | ItemType::Union = self.type_()
         {
             let adt = tcx.adt_def(def_id);
diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts
index 4b43c00730d..e94c6beabea 100644
--- a/src/librustdoc/html/static/js/rustdoc.d.ts
+++ b/src/librustdoc/html/static/js/rustdoc.d.ts
@@ -4,6 +4,10 @@
 
 /* eslint-disable */
 declare global {
+    /** Map from crate name to directory structure, for source view */
+    declare var srcIndex: Map<string, rustdoc.Dir>;
+    /** Defined and documented in `main.js` */
+    declare function nonnull(x: T|null, msg: string|undefined);
     interface Window {
         /** Make the current theme easy to find */
         currentTheme: HTMLLinkElement|null;
@@ -41,6 +45,23 @@ declare global {
          */
         rustdocShowSourceSidebar: function(),
         /**
+         * Close the sidebar in source code view
+         */
+        rustdocCloseSourceSidebar?: function(),
+        /**
+         * Shows the sidebar in source code view
+         */
+        rustdocShowSourceSidebar?: function(),
+        /**
+         * Toggles the sidebar in source code view
+         */
+        rustdocToggleSrcSidebar?: function(),
+        /**
+         * create's the sidebar in source code view.
+         * called in generated `src-files.js`.
+         */
+        createSrcSidebar?: function(),
+        /**
          * Set up event listeners for a scraped source example.
          */
         updateScrapedExample?: function(HTMLElement, HTMLElement),
@@ -438,4 +459,12 @@ declare namespace rustdoc {
     type TypeImpls = {
         [cratename: string]: Array<Array<string|0>>
     }
+
+    /**
+     * Directory structure for source code view,
+     * defined in generated `src-files.js`.
+     *
+     * is a tuple of (filename, subdirs, filenames).
+     */
+    type Dir = [string, rustdoc.Dir[], string[]]
 }
diff --git a/src/librustdoc/html/static/js/src-script.js b/src/librustdoc/html/static/js/src-script.js
index fc27241334b..b9ab6e85603 100644
--- a/src/librustdoc/html/static/js/src-script.js
+++ b/src/librustdoc/html/static/js/src-script.js
@@ -3,10 +3,8 @@
 
 // Local js definitions:
 /* global addClass, onEachLazy, removeClass, browserSupportsHistoryApi */
-/* global updateLocalStorage, getVar */
+/* global updateLocalStorage, getVar, nonnull */
 
-// Eventually fix this.
-// @ts-nocheck
 
 "use strict";
 
@@ -29,6 +27,14 @@ function closeSidebarIfMobile() {
     }
 }
 
+/**
+ * @param {rustdoc.Dir} elem
+ * @param {HTMLElement} parent
+ * @param {string} fullPath
+ * @param {boolean} hasFoundFile
+ *
+ * @returns {boolean} - new value for hasFoundFile
+ */
 function createDirEntry(elem, parent, fullPath, hasFoundFile) {
     const dirEntry = document.createElement("details");
     const summary = document.createElement("summary");
@@ -95,7 +101,7 @@ window.rustdocToggleSrcSidebar = () => {
 // This function is called from "src-files.js", generated in `html/render/write_shared.rs`.
 // eslint-disable-next-line no-unused-vars
 function createSrcSidebar() {
-    const container = document.querySelector("nav.sidebar");
+    const container = nonnull(document.querySelector("nav.sidebar"));
 
     const sidebar = document.createElement("div");
     sidebar.id = "src-sidebar";
@@ -111,6 +117,7 @@ function createSrcSidebar() {
     // Focus on the current file in the source files sidebar.
     const selected_elem = sidebar.getElementsByClassName("selected")[0];
     if (typeof selected_elem !== "undefined") {
+        // @ts-expect-error
         selected_elem.focus();
     }
 }
@@ -130,11 +137,12 @@ function highlightSrcLines() {
         to = from;
         from = tmp;
     }
-    let elem = document.getElementById(from);
+    const from_s = "" + from;
+    let elem = document.getElementById(from_s);
     if (!elem) {
         return;
     }
-    const x = document.getElementById(from);
+    const x = document.getElementById(from_s);
     if (x) {
         x.scrollIntoView();
     }
@@ -142,7 +150,7 @@ function highlightSrcLines() {
         removeClass(e, "line-highlighted");
     });
     for (let i = from; i <= to; ++i) {
-        elem = document.getElementById(i);
+        elem = document.getElementById("" + i);
         if (!elem) {
             break;
         }
@@ -153,11 +161,12 @@ function highlightSrcLines() {
 const handleSrcHighlight = (function() {
     let prev_line_id = 0;
 
+    /** @type {function(string): void} */
     const set_fragment = name => {
         const x = window.scrollX,
             y = window.scrollY;
         if (browserSupportsHistoryApi()) {
-            history.replaceState(null, null, "#" + name);
+            history.replaceState(null, "", "#" + name);
             highlightSrcLines();
         } else {
             location.replace("#" + name);
@@ -166,6 +175,7 @@ const handleSrcHighlight = (function() {
         window.scrollTo(x, y);
     };
 
+    // @ts-expect-error
     return ev => {
         let cur_line_id = parseInt(ev.target.id, 10);
         // This event handler is attached to the entire line number column, but it should only
@@ -191,7 +201,7 @@ const handleSrcHighlight = (function() {
         } else {
             prev_line_id = cur_line_id;
 
-            set_fragment(cur_line_id);
+            set_fragment("" + cur_line_id);
         }
     };
 }());
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 425b915b5f9..748d2ef33c3 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -22,6 +22,28 @@ const settingsDataset = (function() {
 })();
 
 /**
+ * Assert that the passed value is nonnull, then return it.
+ *
+ * Takes an optional error message argument.
+ *
+ * Must be defined in this file, as it is loaded before all others.
+ *
+ * @template T
+ * @param {T|null} x
+ * @param {string=} msg
+ * @returns T
+ */
+// used in other files, not yet used in this one.
+// eslint-disable-next-line no-unused-vars
+function nonnull(x, msg) {
+    if (x === null) {
+        throw (msg || "unexpected null value!");
+    } else {
+        return x;
+    }
+}
+
+/**
  * Get a configuration value. If it's not set, get the default.
  *
  * @param {string} settingName
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 44e82c7d8b1..137fe4c4c35 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
 /// This integer is incremented with every breaking change to the API,
 /// and is returned along with the JSON blob as [`Crate::format_version`].
 /// Consuming code should assert that this value matches the format version(s) that it supports.
-pub const FORMAT_VERSION: u32 = 42;
+pub const FORMAT_VERSION: u32 = 43;
 
 /// The root of the emitted JSON blob.
 ///
@@ -120,9 +120,23 @@ pub struct Item {
     pub docs: Option<String>,
     /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs
     pub links: HashMap<String, Id>,
-    /// Stringified versions of parsed attributes on this item.
-    /// Essentially debug printed (e.g. `#[inline]` becomes something similar to `#[attr="Inline(Hint)"]`).
-    /// Equivalent to the hir pretty-printing of attributes.
+    /// Attributes on this item.
+    ///
+    /// Does not include `#[deprecated]` attributes: see the [`Self::deprecation`] field instead.
+    ///
+    /// Some attributes appear in pretty-printed Rust form, regardless of their formatting
+    /// in the original source code. For example:
+    /// - `#[non_exhaustive]` and `#[must_use]` are represented as themselves.
+    /// - `#[no_mangle]` and `#[export_name]` are also represented as themselves.
+    /// - `#[repr(C)]` and other reprs also appear as themselves,
+    ///   though potentially with a different order: e.g. `repr(i8, C)` may become `repr(C, i8)`.
+    ///   Multiple repr attributes on the same item may be combined into an equivalent single attr.
+    ///
+    /// Other attributes may appear debug-printed. For example:
+    /// - `#[inline]` becomes something similar to `#[attr="Inline(Hint)"]`.
+    ///
+    /// As an internal implementation detail subject to change, this debug-printing format
+    /// is currently equivalent to the HIR pretty-printing of parsed attributes.
     pub attrs: Vec<String>,
     /// Information about the item’s deprecation, if present.
     pub deprecation: Option<Deprecation>,
diff --git a/tests/rustdoc-json/attrs/repr_align.rs b/tests/rustdoc-json/attrs/repr_align.rs
index 83506737b21..c6debda7f1c 100644
--- a/tests/rustdoc-json/attrs/repr_align.rs
+++ b/tests/rustdoc-json/attrs/repr_align.rs
@@ -1,6 +1,6 @@
 #![no_std]
 
-//@ is "$.index[?(@.name=='Aligned')].attrs" '["#[attr = Repr([ReprAlign(Align(4 bytes))])]\n"]'
+//@ is "$.index[?(@.name=='Aligned')].attrs" '["#[repr(align(4))]"]'
 #[repr(align(4))]
 pub struct Aligned {
     a: i8,
diff --git a/tests/rustdoc-json/attrs/repr_c.rs b/tests/rustdoc-json/attrs/repr_c.rs
index 018086b3c1f..e6219413f30 100644
--- a/tests/rustdoc-json/attrs/repr_c.rs
+++ b/tests/rustdoc-json/attrs/repr_c.rs
@@ -1,16 +1,16 @@
 #![no_std]
 
-//@ is "$.index[?(@.name=='ReprCStruct')].attrs" '["#[attr = Repr([ReprC])]\n"]'
+//@ is "$.index[?(@.name=='ReprCStruct')].attrs" '["#[repr(C)]"]'
 #[repr(C)]
 pub struct ReprCStruct(pub i64);
 
-//@ is "$.index[?(@.name=='ReprCEnum')].attrs" '["#[attr = Repr([ReprC])]\n"]'
+//@ is "$.index[?(@.name=='ReprCEnum')].attrs" '["#[repr(C)]"]'
 #[repr(C)]
 pub enum ReprCEnum {
     First,
 }
 
-//@ is "$.index[?(@.name=='ReprCUnion')].attrs" '["#[attr = Repr([ReprC])]\n"]'
+//@ is "$.index[?(@.name=='ReprCUnion')].attrs" '["#[repr(C)]"]'
 #[repr(C)]
 pub union ReprCUnion {
     pub left: i64,
diff --git a/tests/rustdoc-json/attrs/repr_combination.rs b/tests/rustdoc-json/attrs/repr_combination.rs
index c3ef8becb77..0e8e2ef0d83 100644
--- a/tests/rustdoc-json/attrs/repr_combination.rs
+++ b/tests/rustdoc-json/attrs/repr_combination.rs
@@ -1,34 +1,35 @@
 #![no_std]
 
 // Combinations of `#[repr(..)]` attributes.
+// Rustdoc JSON emits normalized output, regardless of the original source.
 
-//@ is "$.index[?(@.name=='ReprCI8')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I8))])]\n"]'
+//@ is "$.index[?(@.name=='ReprCI8')].attrs" '["#[repr(C, i8)]"]'
 #[repr(C, i8)]
 pub enum ReprCI8 {
     First,
 }
 
-//@ is "$.index[?(@.name=='SeparateReprCI16')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I16))])]\n"]'
+//@ is "$.index[?(@.name=='SeparateReprCI16')].attrs" '["#[repr(C, i16)]"]'
 #[repr(C)]
 #[repr(i16)]
 pub enum SeparateReprCI16 {
     First,
 }
 
-//@ is "$.index[?(@.name=='ReversedReprCUsize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize)), ReprC])]\n"]'
+//@ is "$.index[?(@.name=='ReversedReprCUsize')].attrs" '["#[repr(C, usize)]"]'
 #[repr(usize, C)]
 pub enum ReversedReprCUsize {
     First,
 }
 
-//@ is "$.index[?(@.name=='ReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(1 bytes))])]\n"]'
+//@ is "$.index[?(@.name=='ReprCPacked')].attrs" '["#[repr(C, packed(1))]"]'
 #[repr(C, packed)]
 pub struct ReprCPacked {
     a: i8,
     b: i64,
 }
 
-//@ is "$.index[?(@.name=='SeparateReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(2 bytes))])]\n"]'
+//@ is "$.index[?(@.name=='SeparateReprCPacked')].attrs" '["#[repr(C, packed(2))]"]'
 #[repr(C)]
 #[repr(packed(2))]
 pub struct SeparateReprCPacked {
@@ -36,21 +37,21 @@ pub struct SeparateReprCPacked {
     b: i64,
 }
 
-//@ is "$.index[?(@.name=='ReversedReprCPacked')].attrs" '["#[attr = Repr([ReprPacked(Align(2 bytes)), ReprC])]\n"]'
+//@ is "$.index[?(@.name=='ReversedReprCPacked')].attrs" '["#[repr(C, packed(2))]"]'
 #[repr(packed(2), C)]
 pub struct ReversedReprCPacked {
     a: i8,
     b: i64,
 }
 
-//@ is "$.index[?(@.name=='ReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes))])]\n"]'
+//@ is "$.index[?(@.name=='ReprCAlign')].attrs" '["#[repr(C, align(16))]"]'
 #[repr(C, align(16))]
 pub struct ReprCAlign {
     a: i8,
     b: i64,
 }
 
-//@ is "$.index[?(@.name=='SeparateReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(2 bytes))])]\n"]'
+//@ is "$.index[?(@.name=='SeparateReprCAlign')].attrs" '["#[repr(C, align(2))]"]'
 #[repr(C)]
 #[repr(align(2))]
 pub struct SeparateReprCAlign {
@@ -58,20 +59,20 @@ pub struct SeparateReprCAlign {
     b: i64,
 }
 
-//@ is "$.index[?(@.name=='ReversedReprCAlign')].attrs" '["#[attr = Repr([ReprAlign(Align(2 bytes)), ReprC])]\n"]'
+//@ is "$.index[?(@.name=='ReversedReprCAlign')].attrs" '["#[repr(C, align(2))]"]'
 #[repr(align(2), C)]
 pub struct ReversedReprCAlign {
     a: i8,
     b: i64,
 }
 
-//@ is "$.index[?(@.name=='AlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes)), ReprInt(SignedInt(Isize))])]\n"]'
+//@ is "$.index[?(@.name=='AlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]'
 #[repr(C, align(16), isize)]
 pub enum AlignedExplicitRepr {
     First,
 }
 
-//@ is "$.index[?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprInt(SignedInt(Isize)), ReprC, ReprAlign(Align(16 bytes))])]\n"]'
+//@ is "$.index[?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]'
 #[repr(isize, C, align(16))]
 pub enum ReorderedAlignedExplicitRepr {
     First,
diff --git a/tests/rustdoc-json/attrs/repr_int_enum.rs b/tests/rustdoc-json/attrs/repr_int_enum.rs
index 206cb7835f5..9b09f341d4f 100644
--- a/tests/rustdoc-json/attrs/repr_int_enum.rs
+++ b/tests/rustdoc-json/attrs/repr_int_enum.rs
@@ -1,18 +1,18 @@
 #![no_std]
 
-//@ is "$.index[?(@.name=='I8')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I8))])]\n"]'
+//@ is "$.index[?(@.name=='I8')].attrs" '["#[repr(i8)]"]'
 #[repr(i8)]
 pub enum I8 {
     First,
 }
 
-//@ is "$.index[?(@.name=='I32')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]'
+//@ is "$.index[?(@.name=='I32')].attrs" '["#[repr(i32)]"]'
 #[repr(i32)]
 pub enum I32 {
     First,
 }
 
-//@ is "$.index[?(@.name=='Usize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize))])]\n"]'
+//@ is "$.index[?(@.name=='Usize')].attrs" '["#[repr(usize)]"]'
 #[repr(usize)]
 pub enum Usize {
     First,
diff --git a/tests/rustdoc-json/attrs/repr_packed.rs b/tests/rustdoc-json/attrs/repr_packed.rs
index d4c400f72f8..9f3fd86c4b0 100644
--- a/tests/rustdoc-json/attrs/repr_packed.rs
+++ b/tests/rustdoc-json/attrs/repr_packed.rs
@@ -1,16 +1,16 @@
 #![no_std]
 
 // Note the normalization:
-// `#[repr(packed)]` in has the implict "1" in rustdoc JSON.
-
-//@ is "$.index[?(@.name=='Packed')].attrs" '["#[attr = Repr([ReprPacked(Align(1 bytes))])]\n"]'
+// `#[repr(packed)]` in source becomes `#[repr(packed(1))]` in rustdoc JSON.
+//
+//@ is "$.index[?(@.name=='Packed')].attrs" '["#[repr(packed(1))]"]'
 #[repr(packed)]
 pub struct Packed {
     a: i8,
     b: i64,
 }
 
-//@ is "$.index[?(@.name=='PackedAligned')].attrs" '["#[attr = Repr([ReprPacked(Align(4 bytes))])]\n"]'
+//@ is "$.index[?(@.name=='PackedAligned')].attrs" '["#[repr(packed(4))]"]'
 #[repr(packed(4))]
 pub struct PackedAligned {
     a: i8,
diff --git a/tests/rustdoc-json/attrs/repr_transparent.rs b/tests/rustdoc-json/attrs/repr_transparent.rs
index 3f57b21dcc5..1e634ca901d 100644
--- a/tests/rustdoc-json/attrs/repr_transparent.rs
+++ b/tests/rustdoc-json/attrs/repr_transparent.rs
@@ -1,22 +1,37 @@
 #![no_std]
 
-// Rustdoc JSON currently includes `#[repr(transparent)]`
-// even if the transparency is not part of the public API
+// Rustdoc JSON *only* includes `#[repr(transparent)]`
+// if the transparency is public API:
+// - if a non-1-ZST field exists, it has to be public
+// - otherwise, all fields are 1-ZST and at least one of them is public
 //
-// https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
+// More info: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
 
-//@ is "$.index[?(@.name=='Transparent')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
+// Here, the non-1-ZST field is public.
+// We expect `#[repr(transparent)]` in the attributes.
+//
+//@ is "$.index[?(@.name=='Transparent')].attrs" '["#[repr(transparent)]"]'
 #[repr(transparent)]
 pub struct Transparent(pub i64);
 
-//@ is "$.index[?(@.name=='TransparentNonPub')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
+// Here the non-1-ZST field isn't public, so the attribute isn't included.
+//
+//@ has "$.index[?(@.name=='TransparentNonPub')]"
+//@ is "$.index[?(@.name=='TransparentNonPub')].attrs" '[]'
 #[repr(transparent)]
 pub struct TransparentNonPub(i64);
 
-//@ is "$.index[?(@.name=='AllZst')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
+// Only 1-ZST fields here, and one of them is public.
+// We expect `#[repr(transparent)]` in the attributes.
+//
+//@ is "$.index[?(@.name=='AllZst')].attrs" '["#[repr(transparent)]"]'
 #[repr(transparent)]
 pub struct AllZst<'a>(pub core::marker::PhantomData<&'a ()>, ());
 
-//@ is "$.index[?(@.name=='AllZstNotPublic')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]'
+// Only 1-ZST fields here but none of them are public.
+// The attribute isn't included.
+//
+//@ has "$.index[?(@.name=='AllZstNotPublic')]"
+//@ is "$.index[?(@.name=='AllZstNotPublic')].attrs" '[]'
 #[repr(transparent)]
 pub struct AllZstNotPublic<'a>(core::marker::PhantomData<&'a ()>, ());
diff --git a/tests/rustdoc-json/enums/discriminant/struct.rs b/tests/rustdoc-json/enums/discriminant/struct.rs
index 08fb80540fa..ea669e6a0b3 100644
--- a/tests/rustdoc-json/enums/discriminant/struct.rs
+++ b/tests/rustdoc-json/enums/discriminant/struct.rs
@@ -1,5 +1,5 @@
 #[repr(i32)]
-//@ is "$.index[?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]'
+//@ is "$.index[?(@.name=='Foo')].attrs" '["#[repr(i32)]"]'
 pub enum Foo {
     //@ is    "$.index[?(@.name=='Struct')].inner.variant.discriminant" null
     //@ count "$.index[?(@.name=='Struct')].inner.variant.kind.struct.fields[*]" 0
diff --git a/tests/rustdoc-json/enums/discriminant/tuple.rs b/tests/rustdoc-json/enums/discriminant/tuple.rs
index c74e9a2c58d..1b8e791eb23 100644
--- a/tests/rustdoc-json/enums/discriminant/tuple.rs
+++ b/tests/rustdoc-json/enums/discriminant/tuple.rs
@@ -1,5 +1,5 @@
 #[repr(u32)]
-//@ is "$.index[?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(U32))])]\n"]'
+//@ is "$.index[?(@.name=='Foo')].attrs" '["#[repr(u32)]"]'
 pub enum Foo {
     //@ is    "$.index[?(@.name=='Tuple')].inner.variant.discriminant" null
     //@ count "$.index[?(@.name=='Tuple')].inner.variant.kind.tuple[*]" 0
diff --git a/tests/ui/lint/linker-warning.stderr b/tests/ui/lint/linker-warning.stderr
index 3a2c392fd03..c678562ab54 100644
--- a/tests/ui/lint/linker-warning.stderr
+++ b/tests/ui/lint/linker-warning.stderr
@@ -16,7 +16,7 @@ warning: unused attribute
 LL | #![allow(linker_messages)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
    |
-   = note: the `linker_warnings` lint can only be controlled at the root of a crate that needs to be linked
+   = note: the `linker_messages` lint can only be controlled at the root of a crate that needs to be linked
 
 warning: 2 warnings emitted