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 | |
| 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')
| -rw-r--r-- | compiler/rustc_ast/src/token.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_interface/Cargo.toml | 1 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/interface.rs | 51 |
3 files changed, 43 insertions, 11 deletions
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 6e946530749..72f89737f99 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -167,7 +167,7 @@ impl LitKind { pub fn descr(self) -> &'static str { match self { - Bool => panic!("literal token contains `Lit::Bool`"), + Bool => "boolean", Byte => "byte", Char => "char", Integer => "integer", diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 0e90836145e..4b3b0728f38 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -10,6 +10,7 @@ rustc-rayon-core = { version = "0.5.0", optional = true } rustc_ast = { path = "../rustc_ast" } rustc_ast_lowering = { path = "../rustc_ast_lowering" } rustc_ast_passes = { path = "../rustc_ast_passes" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } rustc_borrowck = { path = "../rustc_borrowck" } rustc_builtin_macros = { path = "../rustc_builtin_macros" } 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(...)`"); } } |
