Rollup merge of #138552 - jieyouxu:print-request-cleanups, r=Urgau

Misc print request handling cleanups + a centralized test for print request stability gating

I was working on implementing `--print=supported-crate-types`, then I noticed some things that were mildly annoying me, so I pulled out these changes. In this PR:

- First commit adds a centralized test `tests/ui/print/stability.rs` that is responsible for exercising stability gating of the print requests.
    - AFAICT we didn't have any test that systematically checks this.
    - I coalesced `tests/ui/feature-gates/feature-gate-print-check-cfg.rs` (for `--print=check-cfg`) into this test too, since `--print=check-cfg` is only `-Z unstable-options`-gated like other unstable print requests, and is not additionally feature-gated. cc ``@Urgau`` in case you have any concerns.
- Second commit alphabetically sorts the `PrintKind` enum for consistency because the `PRINT_KINDS` list (using the enum) is *already* alphabetically sorted.
- Third commit pulls out two helpers:
    1. A helper `check_print_request_stability` for checking stability of print requests and the diagnostics for using unstable print requests without `-Z unstable-options`, to avoid repeating the same logic over and over.
    2. A helper `emit_unknown_print_request_help` for the unknown print request diagnostics to make print request collection control flow more obvious.
- Fourth commit renames `PrintKind::{TargetSpec,AllTargetSpecs}` to `PrintKind::{TargetSpecJson,AllTargetSpecsJson}` to better reflect their actual print names, `--print={target-spec-json,all-target-specs-json}`.

r? ``@nnethercote`` (or compiler/reroll)
This commit is contained in:
Jacob Pratt 2025-03-16 21:47:44 -04:00 committed by GitHub
commit 6da26f7cfe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 160 additions and 68 deletions

View file

@ -649,10 +649,10 @@ fn print_crate_info(
HostTuple => println_info!("{}", rustc_session::config::host_tuple()),
Sysroot => println_info!("{}", sess.sysroot.display()),
TargetLibdir => println_info!("{}", sess.target_tlib_path.dir.display()),
TargetSpec => {
TargetSpecJson => {
println_info!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
}
AllTargetSpecs => {
AllTargetSpecsJson => {
let mut targets = BTreeMap::new();
for name in rustc_target::spec::TARGETS {
let triple = TargetTuple::from_tuple(name);

View file

@ -44,7 +44,7 @@ pub mod sigpipe;
pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
// tidy-alphabetical-start
("all-target-specs-json", PrintKind::AllTargetSpecs),
("all-target-specs-json", PrintKind::AllTargetSpecsJson),
("calling-conventions", PrintKind::CallingConventions),
("cfg", PrintKind::Cfg),
("check-cfg", PrintKind::CheckCfg),
@ -63,7 +63,7 @@ pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
("target-features", PrintKind::TargetFeatures),
("target-libdir", PrintKind::TargetLibdir),
("target-list", PrintKind::TargetList),
("target-spec-json", PrintKind::TargetSpec),
("target-spec-json", PrintKind::TargetSpecJson),
("tls-models", PrintKind::TlsModels),
// tidy-alphabetical-end
];
@ -873,27 +873,29 @@ pub struct PrintRequest {
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum PrintKind {
FileNames,
HostTuple,
Sysroot,
TargetLibdir,
CrateName,
// tidy-alphabetical-start
AllTargetSpecsJson,
CallingConventions,
Cfg,
CheckCfg,
CallingConventions,
TargetList,
CodeModels,
CrateName,
DeploymentTarget,
FileNames,
HostTuple,
LinkArgs,
NativeStaticLibs,
RelocationModels,
SplitDebuginfo,
StackProtectorStrategies,
Sysroot,
TargetCPUs,
TargetFeatures,
RelocationModels,
CodeModels,
TargetLibdir,
TargetList,
TargetSpecJson,
TlsModels,
TargetSpec,
AllTargetSpecs,
NativeStaticLibs,
StackProtectorStrategies,
LinkArgs,
SplitDebuginfo,
DeploymentTarget,
// tidy-alphabetical-end
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)]
@ -2030,49 +2032,13 @@ fn collect_print_requests(
prints.extend(matches.opt_strs("print").into_iter().map(|req| {
let (req, out) = split_out_file_name(&req);
let kind = match PRINT_KINDS.iter().find(|&&(name, _)| name == req) {
Some((_, PrintKind::TargetSpec)) => {
if unstable_opts.unstable_options {
PrintKind::TargetSpec
} else {
early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \
enable the target-spec-json print option",
);
}
}
Some((_, PrintKind::AllTargetSpecs)) => {
if unstable_opts.unstable_options {
PrintKind::AllTargetSpecs
} else {
early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \
enable the all-target-specs-json print option",
);
}
}
Some((_, PrintKind::CheckCfg)) => {
if unstable_opts.unstable_options {
PrintKind::CheckCfg
} else {
early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \
enable the check-cfg print option",
);
}
}
Some(&(_, print_kind)) => print_kind,
None => {
let prints =
PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
let prints = prints.join(", ");
let mut diag =
early_dcx.early_struct_fatal(format!("unknown print request: `{req}`"));
#[allow(rustc::diagnostic_outside_of_impl)]
diag.help(format!("valid print requests are: {prints}"));
diag.emit()
}
let kind = if let Some((print_name, print_kind)) =
PRINT_KINDS.iter().find(|&&(name, _)| name == req)
{
check_print_request_stability(early_dcx, unstable_opts, (print_name, *print_kind));
*print_kind
} else {
emit_unknown_print_request_help(early_dcx, req)
};
let out = out.unwrap_or(OutFileName::Stdout);
@ -2091,6 +2057,34 @@ fn collect_print_requests(
prints
}
fn check_print_request_stability(
early_dcx: &EarlyDiagCtxt,
unstable_opts: &UnstableOptions,
(print_name, print_kind): (&str, PrintKind),
) {
match print_kind {
PrintKind::AllTargetSpecsJson | PrintKind::CheckCfg | PrintKind::TargetSpecJson
if !unstable_opts.unstable_options =>
{
early_dcx.early_fatal(format!(
"the `-Z unstable-options` flag must also be passed to enable the `{print_name}` \
print option"
));
}
_ => {}
}
}
fn emit_unknown_print_request_help(early_dcx: &EarlyDiagCtxt, req: &str) -> ! {
let prints = PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
let prints = prints.join(", ");
let mut diag = early_dcx.early_struct_fatal(format!("unknown print request: `{req}`"));
#[allow(rustc::diagnostic_outside_of_impl)]
diag.help(format!("valid print requests are: {prints}"));
diag.emit()
}
pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
match matches.opt_str("target") {
Some(target) if target.ends_with(".json") => {

View file

@ -1,3 +0,0 @@
//@ compile-flags: --print=check-cfg
fn main() {}

View file

@ -1,2 +0,0 @@
error: the `-Z unstable-options` flag must also be passed to enable the check-cfg print option

View file

@ -0,0 +1,103 @@
//! Check that we properly gate unstable print requests (`--print=KIND`) and require the user to
//! specify `-Z unstable-options` to use unstable print requests.
// We don't care about the exact *stdout* output (i.e. what the print requests actually give back)
// for the purposes of this test.
//@ dont-check-compiler-stdout
// We want to check for the core error message of the unstable print requests being `-Z
// unstable-options`-gated and not the help because the help can change with addition of a new print
// request, which is not important for the purposes of this test.
//@ dont-check-compiler-stderr
// =======================
// Unstable print requests
// =======================
//@ revisions: all_target_specs_json
//@[all_target_specs_json] compile-flags: --print=all-target-specs-json
//@[all_target_specs_json] error-pattern: the `-Z unstable-options` flag must also be passed
//@ revisions: check_cfg
//@[check_cfg] compile-flags: --print=check-cfg
//@[check_cfg] error-pattern: the `-Z unstable-options` flag must also be passed
//@ revisions: target_spec_json
//@[target_spec_json] compile-flags: --print=target-spec-json
//@[target_spec_json] error-pattern: the `-Z unstable-options` flag must also be passed
// =======================
// Stable print requests
// =======================
//@ revisions: calling_conventions
//@[calling_conventions] compile-flags: --print=calling-conventions
//@[calling_conventions] check-pass
//@ revisions: cfg
//@[cfg] compile-flags: --print=cfg
//@[cfg] check-pass
//@ revisions: code_models
//@[code_models] compile-flags: --print=code-models
//@[code_models] check-pass
//@ revisions: crate_name
//@[crate_name] compile-flags: --print=crate-name
//@[crate_name] check-pass
// Note: `--print=deployment_target` is only accepted on Apple targets.
//@ revisions: deployment_target
//@[deployment_target] only-apple
//@[deployment_target] compile-flags: --print=deployment-target
//@[deployment_target] check-pass
//@ revisions: file_names
//@[file_names] compile-flags: --print=file-names
//@[file_names] check-pass
//@ revisions: host_tuple
//@[host_tuple] compile-flags: --print=host-tuple
//@[host_tuple] check-pass
//@ revisions: link_args
//@[link_args] compile-flags: --print=link-args
//@[link_args] check-pass
//@ revisions: native_static_libs
//@[native_static_libs] compile-flags: --print=native-static-libs
//@[native_static_libs] check-pass
//@ revisions: relocation_models
//@[relocation_models] compile-flags: --print=relocation-models
//@[relocation_models] check-pass
//@ revisions: split_debuginfo
//@[split_debuginfo] compile-flags: --print=split-debuginfo
//@[split_debuginfo] check-pass
//@ revisions: stack_protector_strategies
//@[stack_protector_strategies] compile-flags: --print=stack-protector-strategies
//@[stack_protector_strategies] check-pass
//@ revisions: target_cpus
//@[target_cpus] compile-flags: --print=target-cpus
//@[target_cpus] check-pass
//@ revisions: target_features
//@[target_features] compile-flags: --print=target-features
//@[target_features] check-pass
//@ revisions: target_libdir
//@[target_libdir] compile-flags: --print=target-libdir
//@[target_libdir] check-pass
//@ revisions: target_list
//@[target_list] compile-flags: --print=target-list
//@[target_list] check-pass
//@ revisions: tls_models
//@[tls_models] compile-flags: --print=tls-models
//@[tls_models] check-pass
fn main() {}