Rollup merge of #130507 - Urgau:check-cfg-raw-keywords, r=jieyouxu

Improve handling of raw-idents in check-cfg

This PR improves the handling of raw-idents in the check-cfg diagnostics.

In particular the list of expected names and the suggestion now correctly take into account the "keyword-ness" of the ident, and correctly prefix the ident with `r#` when necessary.

`@rustbot` labels +F-check-cfg
This commit is contained in:
Matthias Krüger 2024-09-18 17:49:44 +02:00 committed by GitHub
commit 00c4be3df8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 133 additions and 4 deletions

View File

@ -2,6 +2,7 @@ use rustc_middle::bug;
use rustc_session::config::ExpectedValues; use rustc_session::config::ExpectedValues;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::symbol::Ident;
use rustc_span::{sym, Span, Symbol}; use rustc_span::{sym, Span, Symbol};
use crate::lints; use crate::lints;
@ -30,7 +31,7 @@ enum EscapeQuotes {
No, No,
} }
fn to_check_cfg_arg(name: Symbol, value: Option<Symbol>, quotes: EscapeQuotes) -> String { fn to_check_cfg_arg(name: Ident, value: Option<Symbol>, quotes: EscapeQuotes) -> String {
if let Some(value) = value { if let Some(value) = value {
let value = str::escape_debug(value.as_str()).to_string(); let value = str::escape_debug(value.as_str()).to_string();
let values = match quotes { let values = match quotes {
@ -110,6 +111,7 @@ pub(super) fn unexpected_cfg_name(
} }
}; };
let best_match = Ident::new(best_match, name_span);
if let Some((value, value_span)) = value { if let Some((value, value_span)) = value {
if best_match_values.contains(&Some(value)) { if best_match_values.contains(&Some(value)) {
lints::unexpected_cfg_name::CodeSuggestion::SimilarNameAndValue { lints::unexpected_cfg_name::CodeSuggestion::SimilarNameAndValue {
@ -163,6 +165,8 @@ pub(super) fn unexpected_cfg_name(
}; };
let expected_names = if !possibilities.is_empty() { let expected_names = if !possibilities.is_empty() {
let (possibilities, and_more) = sort_and_truncate_possibilities(sess, possibilities); let (possibilities, and_more) = sort_and_truncate_possibilities(sess, possibilities);
let possibilities: Vec<_> =
possibilities.into_iter().map(|s| Ident::new(s, name_span)).collect();
Some(lints::unexpected_cfg_name::ExpectedNames { Some(lints::unexpected_cfg_name::ExpectedNames {
possibilities: possibilities.into(), possibilities: possibilities.into(),
and_more, and_more,
@ -176,7 +180,9 @@ pub(super) fn unexpected_cfg_name(
} }
}; };
let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes); let inst = |escape_quotes| {
to_check_cfg_arg(Ident::new(name, name_span), value.map(|(v, _s)| v), escape_quotes)
};
let invocation_help = if is_from_cargo { let invocation_help = if is_from_cargo {
let sub = if !is_feature_cfg { Some(cargo_help_sub(sess, &inst)) } else { None }; let sub = if !is_feature_cfg { Some(cargo_help_sub(sess, &inst)) } else { None };
@ -273,7 +279,9 @@ pub(super) fn unexpected_cfg_value(
|| (matches!(sess.psess.unstable_features, rustc_feature::UnstableFeatures::Cheat) || (matches!(sess.psess.unstable_features, rustc_feature::UnstableFeatures::Cheat)
&& !sess.opts.unstable_opts.ui_testing); && !sess.opts.unstable_opts.ui_testing);
let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes); let inst = |escape_quotes| {
to_check_cfg_arg(Ident::new(name, name_span), value.map(|(v, _s)| v), escape_quotes)
};
let invocation_help = if is_from_cargo { let invocation_help = if is_from_cargo {
let help = if name == sym::feature { let help = if name == sym::feature {

View File

@ -2180,6 +2180,7 @@ pub(crate) struct UnexpectedCfgName {
pub(crate) mod unexpected_cfg_name { pub(crate) mod unexpected_cfg_name {
use rustc_errors::DiagSymbolList; use rustc_errors::DiagSymbolList;
use rustc_macros::Subdiagnostic; use rustc_macros::Subdiagnostic;
use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol}; use rustc_span::{Span, Symbol};
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
@ -2260,7 +2261,7 @@ pub(crate) mod unexpected_cfg_name {
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
#[help_once(lint_unexpected_cfg_name_expected_names)] #[help_once(lint_unexpected_cfg_name_expected_names)]
pub(crate) struct ExpectedNames { pub(crate) struct ExpectedNames {
pub possibilities: DiagSymbolList, pub possibilities: DiagSymbolList<Ident>,
pub and_more: usize, pub and_more: usize,
} }

View File

@ -0,0 +1,40 @@
warning: unexpected `cfg` condition name: `tru`
--> $DIR/raw-keywords.rs:14:7
|
LL | #[cfg(tru)]
| ^^^ help: there is a config with a similar name: `r#true`
|
= help: to expect this configuration use `--check-cfg=cfg(tru)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition name: `r#false`
--> $DIR/raw-keywords.rs:19:7
|
LL | #[cfg(r#false)]
| ^^^^^^^
|
= help: expected names are: `async`, `clippy`, `debug_assertions`, `doc`, `doctest`, `edition2015`, `edition2021`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `r#true`, `ub_checks`, `unix`, and `windows`
= help: to expect this configuration use `--check-cfg=cfg(r#false)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition name: `await`
--> $DIR/raw-keywords.rs:27:29
|
LL | #[cfg_attr(edition2015, cfg(await))]
| ^^^^^
|
= help: to expect this configuration use `--check-cfg=cfg(await)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition name: `raw`
--> $DIR/raw-keywords.rs:33:7
|
LL | #[cfg(r#raw)]
| ^^^^^
|
= help: to expect this configuration use `--check-cfg=cfg(raw)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: 4 warnings emitted

View File

@ -0,0 +1,40 @@
warning: unexpected `cfg` condition name: `tru`
--> $DIR/raw-keywords.rs:14:7
|
LL | #[cfg(tru)]
| ^^^ help: there is a config with a similar name: `r#true`
|
= help: to expect this configuration use `--check-cfg=cfg(tru)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition name: `r#false`
--> $DIR/raw-keywords.rs:19:7
|
LL | #[cfg(r#false)]
| ^^^^^^^
|
= help: expected names are: `r#async`, `clippy`, `debug_assertions`, `doc`, `doctest`, `edition2015`, `edition2021`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `r#true`, `ub_checks`, `unix`, and `windows`
= help: to expect this configuration use `--check-cfg=cfg(r#false)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition name: `r#await`
--> $DIR/raw-keywords.rs:28:29
|
LL | #[cfg_attr(edition2021, cfg(r#await))]
| ^^^^^^^
|
= help: to expect this configuration use `--check-cfg=cfg(r#await)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition name: `raw`
--> $DIR/raw-keywords.rs:33:7
|
LL | #[cfg(r#raw)]
| ^^^^^
|
= help: to expect this configuration use `--check-cfg=cfg(raw)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: 4 warnings emitted

View File

@ -0,0 +1,40 @@
// This test check that using raw keywords works with --cfg and --check-cfg
// and that the diagnostics suggestions are coherent
//
//@ check-pass
//@ no-auto-check-cfg
//@ compile-flags: --cfg=true --cfg=async --check-cfg=cfg(r#true,r#async,edition2015,edition2021)
//
//@ revisions: edition2015 edition2021
//@ [edition2021] compile-flags: --edition 2021
#[cfg(r#true)]
fn foo() {}
#[cfg(tru)]
//~^ WARNING unexpected `cfg` condition name: `tru`
//~^^ SUGGESTION r#true
fn foo() {}
#[cfg(r#false)]
//~^ WARNING unexpected `cfg` condition name: `r#false`
fn foo() {}
#[cfg_attr(edition2015, cfg(async))]
#[cfg_attr(edition2021, cfg(r#async))]
fn bar() {}
#[cfg_attr(edition2015, cfg(await))]
#[cfg_attr(edition2021, cfg(r#await))]
//[edition2015]~^^ WARNING unexpected `cfg` condition name: `await`
//[edition2021]~^^ WARNING unexpected `cfg` condition name: `r#await`
fn zoo() {}
#[cfg(r#raw)]
//~^ WARNING unexpected `cfg` condition name: `raw`
fn foo() {}
fn main() {
foo();
bar();
}