about summary refs log tree commit diff
diff options
context:
space:
mode:
authorxizheyin <xizheyin@smail.nju.edu.cn>2025-04-20 19:52:26 +0800
committerxizheyin <xizheyin@smail.nju.edu.cn>2025-04-21 18:07:58 +0800
commit6fe881c788ebb4d8126cdd603a89e08ca94b4bdb (patch)
treead59258a3f68384a3294da435c959bd05c7e5cf2
parent4c20d17365e7963a178e053dfb3525f4091cc39b (diff)
downloadrust-6fe881c788ebb4d8126cdd603a89e08ca94b4bdb.tar.gz
rust-6fe881c788ebb4d8126cdd603a89e08ca94b4bdb.zip
Construct OutputType using macro and print [=FILENAME] help info
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
-rw-r--r--compiler/rustc_session/src/config.rs310
-rw-r--r--tests/run-make/metadata-dep-info/dash-separated_something-extra.expected.d4
-rw-r--r--tests/run-make/rustc-help/help-v.diff2
-rw-r--r--tests/run-make/rustc-help/help-v.stdout14
-rw-r--r--tests/run-make/rustc-help/help.stdout14
-rw-r--r--tests/ui/invalid-compile-flags/emit-output-types-without-args.rs1
-rw-r--r--tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr15
7 files changed, 238 insertions, 122 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index ff7ea5bd718..bc92b95ce71 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -568,124 +568,205 @@ impl FromStr for SplitDwarfKind {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, HashStable_Generic)]
-#[derive(Encodable, Decodable)]
-pub enum OutputType {
-    /// This is the optimized bitcode, which could be either pre-LTO or non-LTO bitcode,
-    /// depending on the specific request type.
-    Bitcode,
-    /// This is the summary or index data part of the ThinLTO bitcode.
-    ThinLinkBitcode,
-    Assembly,
-    LlvmAssembly,
-    Mir,
-    Metadata,
-    Object,
-    Exe,
-    DepInfo,
-}
+macro_rules! define_output_types {
+    (
+        $(
+            $(#[doc = $doc:expr])*
+            $Variant:ident => {
+                shorthand: $shorthand:expr,
+                extension: $extension:expr,
+                description: $description:expr,
+                default_filename: $default_filename:expr,
+                is_text: $is_text:expr,
+                compatible_with_cgus_and_single_output: $compatible:expr
+            }
+        ),* $(,)?
+    ) => {
+        #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, HashStable_Generic)]
+        #[derive(Encodable, Decodable)]
+        pub enum OutputType {
+            $(
+                $(#[doc = $doc])*
+                $Variant,
+            )*
+        }
 
-impl StableOrd for OutputType {
-    const CAN_USE_UNSTABLE_SORT: bool = true;
 
-    // Trivial C-Style enums have a stable sort order across compilation sessions.
-    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
-}
+        impl StableOrd for OutputType {
+            const CAN_USE_UNSTABLE_SORT: bool = true;
 
-impl<HCX: HashStableContext> ToStableHashKey<HCX> for OutputType {
-    type KeyType = Self;
+            // Trivial C-Style enums have a stable sort order across compilation sessions.
+            const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
+        }
 
-    fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
-        *self
-    }
-}
+        impl<HCX: HashStableContext> ToStableHashKey<HCX> for OutputType {
+            type KeyType = Self;
 
-impl OutputType {
-    fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
-        match *self {
-            OutputType::Exe | OutputType::DepInfo | OutputType::Metadata => true,
-            OutputType::Bitcode
-            | OutputType::ThinLinkBitcode
-            | OutputType::Assembly
-            | OutputType::LlvmAssembly
-            | OutputType::Mir
-            | OutputType::Object => false,
+            fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
+                *self
+            }
         }
-    }
 
-    pub fn shorthand(&self) -> &'static str {
-        match *self {
-            OutputType::Bitcode => "llvm-bc",
-            OutputType::ThinLinkBitcode => "thin-link-bitcode",
-            OutputType::Assembly => "asm",
-            OutputType::LlvmAssembly => "llvm-ir",
-            OutputType::Mir => "mir",
-            OutputType::Object => "obj",
-            OutputType::Metadata => "metadata",
-            OutputType::Exe => "link",
-            OutputType::DepInfo => "dep-info",
-        }
-    }
-
-    fn from_shorthand(shorthand: &str) -> Option<Self> {
-        Some(match shorthand {
-            "asm" => OutputType::Assembly,
-            "llvm-ir" => OutputType::LlvmAssembly,
-            "mir" => OutputType::Mir,
-            "llvm-bc" => OutputType::Bitcode,
-            "thin-link-bitcode" => OutputType::ThinLinkBitcode,
-            "obj" => OutputType::Object,
-            "metadata" => OutputType::Metadata,
-            "link" => OutputType::Exe,
-            "dep-info" => OutputType::DepInfo,
-            _ => return None,
-        })
-    }
 
-    fn shorthands_display() -> String {
-        format!(
-            "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
-            OutputType::Bitcode.shorthand(),
-            OutputType::ThinLinkBitcode.shorthand(),
-            OutputType::Assembly.shorthand(),
-            OutputType::LlvmAssembly.shorthand(),
-            OutputType::Mir.shorthand(),
-            OutputType::Object.shorthand(),
-            OutputType::Metadata.shorthand(),
-            OutputType::Exe.shorthand(),
-            OutputType::DepInfo.shorthand(),
-        )
-    }
+        impl OutputType {
+            pub fn iter_all() -> impl Iterator<Item = OutputType> {
+                static ALL_VARIANTS: &[OutputType] = &[
+                    $(
+                        OutputType::$Variant,
+                    )*
+                ];
+                ALL_VARIANTS.iter().copied()
+            }
+
+            fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
+                match *self {
+                    $(
+                        OutputType::$Variant => $compatible,
+                    )*
+                }
+            }
+
+            pub fn shorthand(&self) -> &'static str {
+                match *self {
+                    $(
+                        OutputType::$Variant => $shorthand,
+                    )*
+                }
+            }
+
+            fn from_shorthand(shorthand: &str) -> Option<Self> {
+                match shorthand {
+                    $(
+                        s if s == $shorthand => Some(OutputType::$Variant),
+                    )*
+                    _ => None,
+                }
+            }
+
+            fn shorthands_display() -> String {
+                let shorthands = vec![
+                    $(
+                        format!("`{}`", $shorthand),
+                    )*
+                ];
+                shorthands.join(", ")
+            }
+
+            pub fn extension(&self) -> &'static str {
+                match *self {
+                    $(
+                        OutputType::$Variant => $extension,
+                    )*
+                }
+            }
+
+            pub fn is_text_output(&self) -> bool {
+                match *self {
+                    $(
+                        OutputType::$Variant => $is_text,
+                    )*
+                }
+            }
+
+            pub fn description(&self) -> &'static str {
+                match *self {
+                    $(
+                        OutputType::$Variant => $description,
+                    )*
+                }
+            }
+
+            pub fn default_filename(&self) -> &'static str {
+                match *self {
+                    $(
+                        OutputType::$Variant => $default_filename,
+                    )*
+                }
+            }
 
-    pub fn extension(&self) -> &'static str {
-        match *self {
-            OutputType::Bitcode => "bc",
-            OutputType::ThinLinkBitcode => "indexing.o",
-            OutputType::Assembly => "s",
-            OutputType::LlvmAssembly => "ll",
-            OutputType::Mir => "mir",
-            OutputType::Object => "o",
-            OutputType::Metadata => "rmeta",
-            OutputType::DepInfo => "d",
-            OutputType::Exe => "",
-        }
-    }
 
-    pub fn is_text_output(&self) -> bool {
-        match *self {
-            OutputType::Assembly
-            | OutputType::LlvmAssembly
-            | OutputType::Mir
-            | OutputType::DepInfo => true,
-            OutputType::Bitcode
-            | OutputType::ThinLinkBitcode
-            | OutputType::Object
-            | OutputType::Metadata
-            | OutputType::Exe => false,
         }
     }
 }
 
+define_output_types! {
+    Assembly => {
+        shorthand: "asm",
+        extension: "s",
+        description: "Generates a file with the crate's assembly code",
+        default_filename: "CRATE_NAME.s",
+        is_text: true,
+        compatible_with_cgus_and_single_output: false
+    },
+    #[doc = "This is the optimized bitcode, which could be either pre-LTO or non-LTO bitcode,"]
+    #[doc = "depending on the specific request type."]
+    Bitcode => {
+        shorthand: "llvm-bc",
+        extension: "bc",
+        description: "Generates a binary file containing the LLVM bitcode",
+        default_filename: "CRATE_NAME.bc",
+        is_text: false,
+        compatible_with_cgus_and_single_output: false
+    },
+    DepInfo => {
+        shorthand: "dep-info",
+        extension: "d",
+        description: "Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate",
+        default_filename: "CRATE_NAME.d",
+        is_text: true,
+        compatible_with_cgus_and_single_output: true
+    },
+    Exe => {
+        shorthand: "link",
+        extension: "",
+        description: "Generates the crates specified by --crate-type. This is the default if --emit is not specified",
+        default_filename: "(platform and crate-type dependent)",
+        is_text: false,
+        compatible_with_cgus_and_single_output: true
+    },
+    LlvmAssembly => {
+        shorthand: "llvm-ir",
+        extension: "ll",
+        description: "Generates a file containing LLVM IR",
+        default_filename: "CRATE_NAME.ll",
+        is_text: true,
+        compatible_with_cgus_and_single_output: false
+    },
+    Metadata => {
+        shorthand: "metadata",
+        extension: "rmeta",
+        description: "Generates a file containing metadata about the crate",
+        default_filename: "libCRATE_NAME.rmeta",
+        is_text: false,
+        compatible_with_cgus_and_single_output: true
+    },
+    Mir => {
+        shorthand: "mir",
+        extension: "mir",
+        description: "Generates a file containing rustc's mid-level intermediate representation",
+        default_filename: "CRATE_NAME.mir",
+        is_text: true,
+        compatible_with_cgus_and_single_output: false
+    },
+    Object => {
+        shorthand: "obj",
+        extension: "o",
+        description: "Generates a native object file",
+        default_filename: "CRATE_NAME.o",
+        is_text: false,
+        compatible_with_cgus_and_single_output: false
+    },
+    #[doc = "This is the summary or index data part of the ThinLTO bitcode."]
+    ThinLinkBitcode => {
+        shorthand: "thin-link-bitcode",
+        extension: "indexing.o",
+        description: "Generates the ThinLTO summary as bitcode",
+        default_filename: "CRATE_NAME.indexing.o",
+        is_text: false,
+        compatible_with_cgus_and_single_output: false
+    },
+}
+
 /// The type of diagnostics output to generate.
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
 pub enum ErrorOutputType {
@@ -1570,6 +1651,18 @@ static PRINT_HELP: LazyLock<String> = LazyLock::new(|| {
     )
 });
 
+static EMIT_HELP: LazyLock<String> = LazyLock::new(|| {
+    let mut result =
+        String::from("Comma separated list of types of output for the compiler to emit.\n");
+    result.push_str("Each TYPE has the default FILE name:\n");
+
+    for output in OutputType::iter_all() {
+        result.push_str(&format!("*  {} - {}\n", output.shorthand(), output.default_filename()));
+    }
+
+    result
+});
+
 /// Returns all rustc command line options, including metadata for
 /// each option, such as whether the option is stable.
 pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
@@ -1616,14 +1709,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
         make_crate_type_option(),
         opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "NAME"),
         opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
-        opt(
-            Stable,
-            Multi,
-            "",
-            "emit",
-            "Comma separated list of types of output for the compiler to emit",
-            "[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
-        ),
+        opt(Stable, Multi, "", "emit", &EMIT_HELP, "TYPE[=FILE]"),
         opt(Stable, Multi, "", "print", &PRINT_HELP, "INFO[=FILE]"),
         opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
         opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
diff --git a/tests/run-make/metadata-dep-info/dash-separated_something-extra.expected.d b/tests/run-make/metadata-dep-info/dash-separated_something-extra.expected.d
index 497d76b4ea1..43e8f9185a3 100644
--- a/tests/run-make/metadata-dep-info/dash-separated_something-extra.expected.d
+++ b/tests/run-make/metadata-dep-info/dash-separated_something-extra.expected.d
@@ -1,5 +1,5 @@
-libdash_separated_something-extra.rmeta: dash-separated.rs
-
 dash-separated_something-extra.d: dash-separated.rs
 
+libdash_separated_something-extra.rmeta: dash-separated.rs
+
 dash-separated.rs:
diff --git a/tests/run-make/rustc-help/help-v.diff b/tests/run-make/rustc-help/help-v.diff
index 30703f6424e..0ea79f3e557 100644
--- a/tests/run-make/rustc-help/help-v.diff
+++ b/tests/run-make/rustc-help/help-v.diff
@@ -1,4 +1,4 @@
-@@ -53,10 +53,27 @@
+@@ -63,10 +63,27 @@
                          Set a codegen option
      -V, --version       Print version info and exit
      -v, --verbose       Use verbose output
diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout
index 13af6e21060..744453d6e85 100644
--- a/tests/run-make/rustc-help/help-v.stdout
+++ b/tests/run-make/rustc-help/help-v.stdout
@@ -26,9 +26,19 @@ Options:
                         Specify which edition of the compiler to use when
                         compiling code. The default is 2015 and the latest
                         stable edition is 2024.
-        --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
+        --emit TYPE[=FILE]
                         Comma separated list of types of output for the
-                        compiler to emit
+                        compiler to emit.
+                        Each TYPE has the default FILE name:
+                        * asm - CRATE_NAME.s
+                        * llvm-bc - CRATE_NAME.bc
+                        * dep-info - CRATE_NAME.d
+                        * link - (platform and crate-type dependent)
+                        * llvm-ir - CRATE_NAME.ll
+                        * metadata - libCRATE_NAME.rmeta
+                        * mir - CRATE_NAME.mir
+                        * obj - CRATE_NAME.o
+                        * thin-link-bitcode - CRATE_NAME.indexing.o
         --print INFO[=FILE]
                         Compiler information to print on stdout (or to a file)
                         INFO may be one of
diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout
index 62757d989eb..3043755207a 100644
--- a/tests/run-make/rustc-help/help.stdout
+++ b/tests/run-make/rustc-help/help.stdout
@@ -26,9 +26,19 @@ Options:
                         Specify which edition of the compiler to use when
                         compiling code. The default is 2015 and the latest
                         stable edition is 2024.
-        --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
+        --emit TYPE[=FILE]
                         Comma separated list of types of output for the
-                        compiler to emit
+                        compiler to emit.
+                        Each TYPE has the default FILE name:
+                        * asm - CRATE_NAME.s
+                        * llvm-bc - CRATE_NAME.bc
+                        * dep-info - CRATE_NAME.d
+                        * link - (platform and crate-type dependent)
+                        * llvm-ir - CRATE_NAME.ll
+                        * metadata - libCRATE_NAME.rmeta
+                        * mir - CRATE_NAME.mir
+                        * obj - CRATE_NAME.o
+                        * thin-link-bitcode - CRATE_NAME.indexing.o
         --print INFO[=FILE]
                         Compiler information to print on stdout (or to a file)
                         INFO may be one of
diff --git a/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs b/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs
index 793931e99d9..a96eeb0a5ce 100644
--- a/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs
+++ b/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs
@@ -1 +1,2 @@
 //@ compile-flags: --emit
+//@ error-pattern: Argument to option 'emit' missing
diff --git a/tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr b/tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr
index dad81dcb13c..669913b5765 100644
--- a/tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr
+++ b/tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr
@@ -1,6 +1,15 @@
 error: Argument to option 'emit' missing
        Usage:
-           --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
-                               Comma separated list of types of output for the
-                               compiler to emit
+           --emit TYPE[=FILE]  Comma separated list of types of output for the
+                               compiler to emit.
+                               Each TYPE has the default FILE name:
+                               * asm - CRATE_NAME.s
+                               * llvm-bc - CRATE_NAME.bc
+                               * dep-info - CRATE_NAME.d
+                               * link - (platform and crate-type dependent)
+                               * llvm-ir - CRATE_NAME.ll
+                               * metadata - libCRATE_NAME.rmeta
+                               * mir - CRATE_NAME.mir
+                               * obj - CRATE_NAME.o
+                               * thin-link-bitcode - CRATE_NAME.indexing.o