Repository: rust-lang/rust
Pull request: rustdoc: add missing {os,target,target_env} values for cfg pretty printer

<!-- homu-ignore:start -->
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.

This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using

    r? <reviewer name>
-->
the title says everything. i don't know if these big match arms should be a method of `Os`, `Arch` and `Env`. happy to change my code if necessary :)
<!-- homu-ignore:end -->


Changed files:
filename: src/librustdoc/clean/cfg.rs
patch: @@ -3,6 +3,7 @@
 // FIXME: Once the portability lint RFC is implemented (see tracking issue #41619),
 // switch to use those structures instead.
 
+use std::str::FromStr;
 use std::sync::Arc;
 use std::{fmt, mem, ops};
 
@@ -15,6 +16,7 @@ use rustc_hir::attrs::{self, AttributeKind, CfgEntry, CfgHideShow, HideOrShow};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::{Symbol, sym};
 use rustc_span::{DUMMY_SP, Span};
+use rustc_target::spec;
 
 use crate::display::{Joined as _, MaybeDisplay, Wrapped};
 use crate::html::escape::Escape;
@@ -421,70 +423,20 @@ impl fmt::Display for Display<'_> {
                     (sym::unix, None) => "Unix",
                     (sym::windows, None) => "Windows",
                     (sym::debug_assertions, None) => "debug-assertions enabled",
-                    (sym::target_os, Some(os)) => match os.as_str() {
-                        "android" => "Android",
-                        "cygwin" => "Cygwin",
-                        "dragonfly" => "DragonFly BSD",
-                        "emscripten" => "Emscripten",
-                        "freebsd" => "FreeBSD",
-                        "fuchsia" => "Fuchsia",
-                        "haiku" => "Haiku",
-                        "hermit" => "Hermit",
-                        "illumos" => "illumos",
-                        "ios" => "iOS",
-                        "l4re" => "L4Re",
-                        "linux" => "Linux",
-                        "macos" => "macOS",
-                        "netbsd" => "NetBSD",
-                        "openbsd" => "OpenBSD",
-                        "redox" => "Redox",
-                        "solaris" => "Solaris",
-                        "tvos" => "tvOS",
-                        "wasi" => "WASI",
-                        "watchos" => "watchOS",
-                        "windows" => "Windows",
-                        "visionos" => "visionOS",
-                        _ => "",
-                    },
-                    (sym::target_arch, Some(arch)) => match arch.as_str() {
-                        "aarch64" => "AArch64",
-                        "arm" => "ARM",
-                        "loongarch32" => "LoongArch LA32",
-                        "loongarch64" => "LoongArch LA64",
-                        "m68k" => "M68k",
-                        "csky" => "CSKY",
-                        "mips" => "MIPS",
-                        "mips32r6" => "MIPS Release 6",
-                        "mips64" => "MIPS-64",
-                        "mips64r6" => "MIPS-64 Release 6",
-                        "msp430" => "MSP430",
-                        "powerpc" => "PowerPC",
-                        "powerpc64" => "PowerPC-64",
-                        "riscv32" => "RISC-V RV32",
-                        "riscv64" => "RISC-V RV64",
-                        "s390x" => "s390x",
-                        "sparc64" => "SPARC64",
-                        "wasm32" | "wasm64" => "WebAssembly",
-                        "x86" => "x86",
-                        "x86_64" => "x86-64",
-                        _ => "",
-                    },
+                    (sym::target_os, Some(os)) => human_readable_target_os(*os).unwrap_or_default(),
+                    (sym::target_arch, Some(arch)) => {
+                        human_readable_target_arch(*arch).unwrap_or_default()
+                    }
                     (sym::target_vendor, Some(vendor)) => match vendor.as_str() {
                         "apple" => "Apple",
                         "pc" => "PC",
                         "sun" => "Sun",
                         "fortanix" => "Fortanix",
                         _ => "",
                     },
-                    (sym::target_env, Some(env)) => match env.as_str() {
-                        "gnu" => "GNU",
-                        "msvc" => "MSVC",
-                        "musl" => "musl",
-                        "newlib" => "Newlib",
-                        "uclibc" => "uClibc",
-                        "sgx" => "SGX",
-                        _ => "",
-                    },
+                    (sym::target_env, Some(env)) => {
+                        human_readable_target_env(*env).unwrap_or_default()
+                    }
                     (sym::target_endian, Some(endian)) => {
                         return write!(fmt, "{endian}-endian");
                     }
@@ -527,6 +479,135 @@ impl fmt::Display for Display<'_> {
     }
 }
 
+fn human_readable_target_os(os: Symbol) -> Option<&'static str> {
+    let os = spec::Os::from_str(os.as_str()).ok()?;
+
+    use spec::Os::*;
+    Some(match os {
+        // tidy-alphabetical-start
+        Aix => "AIX",
+        AmdHsa => "AMD HSA",
+        Android => "Android",
+        Cuda => "CUDA",
+        Cygwin => "Cygwin",
+        Dragonfly => "DragonFly BSD",
+        Emscripten => "Emscripten",
+        EspIdf => "ESP-IDF",
+        FreeBsd => "FreeBSD",
+        Fuchsia => "Fuchsia",
+        Haiku => "Haiku",
+        HelenOs => "HelenOS",
+        Hermit => "Hermit",
+        Horizon => "Horizon",
+        Hurd => "GNU/Hurd",
+        IOs => "iOS",
+        Illumos => "illumos",
+        L4Re => "L4Re",
+        Linux => "Linux",
+        LynxOs178 => "LynxOS-178",
+        MacOs => "macOS",
+        Managarm => "Managarm",
+        Motor => "Motor OS",
+        NetBsd => "NetBSD",
+        None => "bare-metal", // FIXME(scrabsha): is this appropriate?
+        Nto => "QNX Neutrino",
+        NuttX => "NuttX",
+        OpenBsd => "OpenBSD",
+        Psp => "Play Station Portable",
+        Psx => "Play Station 1",
+        Qurt => "QuRT",
+        Redox => "Redox OS",
+        Rtems => "RTEMS OS",
+        Solaris => "Solaris",
+        SolidAsp3 => "SOLID ASP3",
+        TeeOs => "TEEOS",
+        Trusty => "Trusty",
+        TvOs => "tvOS",
+        Uefi => "UEFI",
+        VexOs => "VEXos",
+        VisionOs => "visionOS",
+        Vita => "Play Station Vita",
+        VxWorks => "VxWorks",
+        Wasi => "WASI",
+        WatchOs => "watchOS",
+        Windows => "Windows",
+        Xous => "Xous",
+        Zkvm => "zero knowledge Virtual Machine",
+        // tidy-alphabetical-end
+        Unknown | Other(_) => return Option::None,
+    })
+}
+
+fn human_readable_target_arch(os: Symbol) -> Option<&'static str> {
+    let arch = spec::Arch::from_str(os.as_str()).ok()?;
+
+    use spec::Arch::*;
+    Some(match arch {
+        // tidy-alphabetical-start
+        AArch64 => "AArch64",
+        AmdGpu => "AMG GPU",
+        Arm => "ARM",
+        Arm64EC => "ARM64EC",
+        Avr => "AVR",
+        Bpf => "BPF",
+        CSky => "C-SKY",
+        Hexagon => "Hexagon",
+        LoongArch32 => "LoongArch64",
+        LoongArch64 => "LoongArch32",
+        M68k => "Motorola 680x0",
+        Mips => "MIPS",
+        Mips32r6 => "MIPS release 6",
+        Mips64 => "MIPS-64",
+        Mips64r6 => "MIPS-64 release 6",
+        Msp430 => "MSP430",
+        Nvptx64 => "NVidia GPU",
+        PowerPC => "PowerPC",
+        PowerPC64 => "PowerPC64",
+        RiscV32 => "RISC-V RV32",
+        RiscV64 => "RISC-V RV64",
+        S390x => "s390x",
+        Sparc => "SPARC",
+        Sparc64 => "SPARC-64",
+        SpirV => "SPIR-V",
+        Wasm32 | Wasm64 => "WebAssembly",
+        X86 => "x86",
+        X86_64 => "x86-64",
+        Xtensa => "Xtensa",
+        // tidy-alphabetical-end
+        Other(_) => return None,
+    })
+}
+
+fn human_readable_target_env(env: Symbol) -> Option<&'static str> {
+    let env = spec::Env::from_str(env.as_str()).ok()?;
+
+    use spec::Env::*;
+    Some(match env {
+        // tidy-alphabetical-start
+        Gnu => "GNU",
+        MacAbi => "Catalyst",
+        Mlibc => "mac ABI",
+        Msvc => "MSVC",
+        Musl => "musl",
+        Newlib => "Newlib",
+        Nto70 => "Neutrino 7.0",
+        Nto71 => "Neutrino 7.1",
+        Nto71IoSock => "Neutrino 7.1 with io-sock",
+        Nto80 => "Neutrino 8.0",
+        Ohos => "OpenHarmony",
+        P1 => "WASIp1",
+        P2 => "WASIp2",
+        P3 => "WASIp3",
+        Relibc => "relibc",
+        Sgx => "SGX",
+        Sim => "Simulator",
+        Uclibc => "uClibc",
+        V5 => "V5",
+        // tidy-alphabetical-end
+        Unspecified | Other(_) => return None,
+    })
+}
+
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 struct NameValueCfg {
     name: Symbol,

filename: tests/rustdoc-gui/item-info-overflow.goml
patch: @@ -8,7 +8,7 @@ assert-property: (".item-info", {"scrollWidth": "940"})
 // Just to be sure we're comparing the correct "item-info":
 assert-text: (
     ".item-info",
-    "Available on Android or Linux or Emscripten or DragonFly BSD",
+    "Available on Android or Linux or Emscripten or DragonFly BSD or FreeBSD or NetBSD or OpenBSD",
     STARTS_WITH,
 )
 
@@ -26,6 +26,6 @@ assert-property: (
 // Just to be sure we're comparing the correct "item-info":
 assert-text: (
     "#impl-SimpleTrait-for-LongItemInfo2 .item-info",
-    "Available on Android or Linux or Emscripten or DragonFly BSD",
+    "Available on Android or Linux or Emscripten or DragonFly BSD or FreeBSD or NetBSD or OpenBSD",
     STARTS_WITH,
 )

filename: tests/rustdoc-html/doc-cfg/all-targets.rs
patch: @@ -0,0 +1,139 @@
+#![feature(doc_cfg)]
+
+//@ has all_targets/fn.foo.html \
+//  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
+//  'Available on GNU or Catalyst or mac ABI or MSVC or musl or Newlib or \
+//  Neutrino 7.0 or Neutrino 7.1 or Neutrino 7.1 with io-sock or Neutrino 8.0 or \
+//  OpenHarmony or relibc or SGX or Simulator or WASIp1 or WASIp2 or WASIp3 or \
+//  uClibc or V5 or target_env=fake_env only.'
+#[doc(cfg(any(
+    target_env = "gnu",
+    target_env = "macabi",
+    target_env = "mlibc",
+    target_env = "msvc",
+    target_env = "musl",
+    target_env = "newlib",
+    target_env = "nto70",
+    target_env = "nto71",
+    target_env = "nto71_iosock",
+    target_env = "nto80",
+    target_env = "ohos",
+    target_env = "relibc",
+    target_env = "sgx",
+    target_env = "sim",
+    target_env = "p1",
+    target_env = "p2",
+    target_env = "p3",
+    target_env = "uclibc",
+    target_env = "v5",
+    target_env = "fake_env",
+)))]
+pub fn foo() {}
+
+//@ has all_targets/fn.bar.html \
+//  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
+//  'Available on AArch64 or AMG GPU or ARM or ARM64EC or AVR or BPF or C-SKY or \
+//  Hexagon or LoongArch64 or LoongArch32 or Motorola 680x0 or MIPS or MIPS release \
+//  6 or MIPS-64 or MIPS-64 release 6 or MSP430 or NVidia GPU or PowerPC or \
+//  PowerPC64 or RISC-V RV32 or RISC-V RV64 or s390x or SPARC or SPARC-64 or SPIR-V \
+//  or WebAssembly or WebAssembly or x86 or x86-64 or Xtensa or \
+//  target_arch=fake_arch only.'
+#[doc(cfg(any(
+    target_arch = "aarch64",
+    target_arch = "amdgpu",
+    target_arch = "arm",
+    target_arch = "arm64ec",
+    target_arch = "avr",
+    target_arch = "bpf",
+    target_arch = "csky",
+    target_arch = "hexagon",
+    target_arch = "loongarch32",
+    target_arch = "loongarch64",
+    target_arch = "m68k",
+    target_arch = "mips",
+    target_arch = "mips32r6",
+    target_arch = "mips64",
+    target_arch = "mips64r6",
+    target_arch = "msp430",
+    target_arch = "nvptx64",
+    target_arch = "powerpc",
+    target_arch = "powerpc64",
+    target_arch = "riscv32",
+    target_arch = "riscv64",
+    target_arch = "s390x",
+    target_arch = "sparc",
+    target_arch = "sparc64",
+    target_arch = "spirv",
+    target_arch = "wasm32",
+    target_arch = "wasm64",
+    target_arch = "x86",
+    target_arch = "x86_64",
+    target_arch = "xtensa",
+    target_arch = "fake_arch",
+)))]
+pub fn bar() {}
+
+//@ has all_targets/fn.baz.html \
+//  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
+//  'Available on AIX and AMD HSA and Android and CUDA and Cygwin and DragonFly \
+//  BSD and Emscripten and ESP-IDF and FreeBSD and Fuchsia and Haiku and HelenOS \
+//  and Hermit and Horizon and GNU/Hurd and illumos and iOS and L4Re and Linux \
+//  and LynxOS-178 and macOS and Managarm and Motor OS and NetBSD and bare-metal \
+//  and QNX Neutrino and NuttX and OpenBSD and Play Station Portable and Play \
+//  Station 1 and QuRT and Redox OS and RTEMS OS and Solaris and SOLID ASP3 and \
+//  TEEOS and Trusty and tvOS and UEFI and VEXos and visionOS and Play Station \
+//  Vita and VxWorks and WASI and watchOS and Windows and Xous and zero knowledge \
+//  Virtual Machine and target_os=unknown and target_os=fake_os only.'
+#[doc(cfg(all(
+    target_os = "aix",
+    target_os = "amdhsa",
+    target_os = "android",
+    target_os = "cuda",
+    target_os = "cygwin",
+    target_os = "dragonfly",
+    target_os = "emscripten",
+    target_os = "espidf",
+    target_os = "freebsd",
+    target_os = "fuchsia",
+    target_os = "haiku",
+    target_os = "helenos",
+    target_os = "hermit",
+    target_os = "horizon",
+    target_os = "hurd",
+    target_os = "illumos",
+    target_os = "ios",
+    target_os = "l4re",
+    target_os = "linux",
+    target_os = "lynxos178",
+    target_os = "macos",
+    target_os = "managarm",
+    target_os = "motor",
+    target_os = "netbsd",
+    target_os = "none",
+    target_os = "nto",
+    target_os = "nuttx",
+    target_os = "openbsd",
+    target_os = "psp",
+    target_os = "psx",
+    target_os = "qurt",
+    target_os = "redox",
+    target_os = "rtems",
+    target_os = "solaris",
+    target_os = "solid_asp3",
+    target_os = "teeos",
+    target_os = "trusty",
+    target_os = "tvos",
+    target_os = "uefi",
+    target_os = "vexos",
+    target_os = "visionos",
+    target_os = "vita",
+    target_os = "vxworks",
+    target_os = "wasi",
+    target_os = "watchos",
+    target_os = "windows",
+    target_os = "xous",
+    target_os = "zkvm",
+    target_os = "unknown",
+    target_os = "fake_os",
+)))]
+pub fn baz() {}