diff options
| author | bors <bors@rust-lang.org> | 2024-05-06 07:46:27 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-05-06 07:46:27 +0000 |
| commit | 69f53f5e5583381267298ac182eb02c7f1b5c1cd (patch) | |
| tree | a9cdceb56a7aa73c2c853b6ea965e46a7c8c97e0 /compiler/rustc_interface/src/interface.rs | |
| parent | d287f3e4eeaf680e8fe875f1ec75cca68f357d30 (diff) | |
| parent | 228496e4f5f7b94d69ec7e5bc858370ce9540fca (diff) | |
| download | rust-69f53f5e5583381267298ac182eb02c7f1b5c1cd.tar.gz rust-69f53f5e5583381267298ac182eb02c7f1b5c1cd.zip | |
Auto merge of #124679 - Urgau:check-cfg-structured-cli-errors, r=nnethercote
Improve check-cfg CLI errors with more structured diagnostics This PR improve check-cfg CLI errors with more structured diagnostics. In particular it now shows the statement where the error occurred, what kind lit it is, as well as pointing users to the doc for more details. `@rustbot` label +F-check-cfg
Diffstat (limited to 'compiler/rustc_interface/src/interface.rs')
| -rw-r--r-- | compiler/rustc_interface/src/interface.rs | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index c5b81dbd679..55304bbbd92 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -120,14 +120,45 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg { ); let filename = FileName::cfg_spec_source_code(&s); + const VISIT: &str = + "visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details"; + macro_rules! error { ($reason:expr) => { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - dcx.fatal(format!( - concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"), - s - )) + { + let mut diag = + dcx.struct_fatal(format!("invalid `--check-cfg` argument: `{s}`")); + diag.note($reason); + diag.note(VISIT); + diag.emit() + } + }; + (in $arg:expr, $reason:expr) => { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + { + let mut diag = + dcx.struct_fatal(format!("invalid `--check-cfg` argument: `{s}`")); + + let pparg = rustc_ast_pretty::pprust::meta_list_item_to_string($arg); + if let Some(lit) = $arg.lit() { + let (lit_kind_article, lit_kind_descr) = { + let lit_kind = lit.as_token_lit().kind; + (lit_kind.article(), lit_kind.descr()) + }; + diag.note(format!( + "`{pparg}` is {lit_kind_article} {lit_kind_descr} literal" + )); + } else { + diag.note(format!("`{pparg}` is invalid")); + } + + diag.note($reason); + diag.note(VISIT); + diag.emit() + } }; } @@ -183,7 +214,7 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg { } any_specified = true; if !args.is_empty() { - error!("`any()` must be empty"); + error!(in arg, "`any()` takes no argument"); } } else if arg.has_name(sym::values) && let Some(args) = arg.meta_item_list() @@ -202,25 +233,25 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg { && let Some(args) = arg.meta_item_list() { if values_any_specified { - error!("`any()` in `values()` cannot be specified multiple times"); + error!(in arg, "`any()` in `values()` cannot be specified multiple times"); } values_any_specified = true; if !args.is_empty() { - error!("`any()` must be empty"); + error!(in arg, "`any()` in `values()` takes no argument"); } } else if arg.has_name(sym::none) && let Some(args) = arg.meta_item_list() { values.insert(None); if !args.is_empty() { - error!("`none()` must be empty"); + error!(in arg, "`none()` in `values()` takes no argument"); } } else { - error!("`values()` arguments must be string literals, `none()` or `any()`"); + error!(in arg, "`values()` arguments must be string literals, `none()` or `any()`"); } } } else { - error!("`cfg()` arguments must be simple identifiers, `any()` or `values(...)`"); + error!(in arg, "`cfg()` arguments must be simple identifiers, `any()` or `values(...)`"); } } |
