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,122 +568,203 @@ 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 ToStableHashKey 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 ToStableHashKey for OutputType { + type KeyType = Self; + + fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType { + *self + } + } + + + impl OutputType { + pub fn iter_all() -> impl Iterator { + 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 { + 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, + )* + } + } + + + } } } -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, - } - } - - 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 { - 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(), - ) - } - - 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. @@ -1570,6 +1651,18 @@ static PRINT_HELP: LazyLock = LazyLock::new(|| { ) }); +static EMIT_HELP: LazyLock = 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 { @@ -1616,14 +1709,7 @@ pub fn rustc_optgroups() -> Vec { 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 new file mode 100644 index 00000000000..a96eeb0a5ce --- /dev/null +++ b/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs @@ -0,0 +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 new file mode 100644 index 00000000000..669913b5765 --- /dev/null +++ b/tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr @@ -0,0 +1,15 @@ +error: Argument to option 'emit' missing + Usage: + --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 +