diff options
| author | Urgau <urgau@numericable.fr> | 2024-03-16 23:33:54 +0100 |
|---|---|---|
| committer | Urgau <urgau@numericable.fr> | 2024-03-16 23:33:54 +0100 |
| commit | bf8715e6eedcbb64c86c6357c5adeb059f322d35 (patch) | |
| tree | 7c0dbaac4867942e0074a711723be38890f24279 /compiler/rustc_lint/src/context/diagnostics.rs | |
| parent | fe6157522848604562f83084154274c545fe3a27 (diff) | |
| download | rust-bf8715e6eedcbb64c86c6357c5adeb059f322d35.tar.gz rust-bf8715e6eedcbb64c86c6357c5adeb059f322d35.zip | |
Move check-cfg diagnostic logic into it's own module
Diffstat (limited to 'compiler/rustc_lint/src/context/diagnostics.rs')
| -rw-r--r-- | compiler/rustc_lint/src/context/diagnostics.rs | 279 |
1 files changed, 5 insertions, 274 deletions
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index a0be1c09c9a..e2010ab3830 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -5,49 +5,11 @@ use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_errors::{add_elided_lifetime_in_path_suggestion, Diag}; use rustc_errors::{Applicability, SuggestionStyle}; use rustc_middle::middle::stability; -use rustc_session::config::ExpectedValues; use rustc_session::lint::BuiltinLintDiag; use rustc_session::Session; -use rustc_span::edit_distance::find_best_match_for_name; -use rustc_span::symbol::{sym, Symbol}; use rustc_span::BytePos; -const MAX_CHECK_CFG_NAMES_OR_VALUES: usize = 35; - -fn check_cfg_expected_note( - sess: &Session, - possibilities: &[Symbol], - type_: &str, - name: Option<Symbol>, - suffix: &str, -) -> String { - use std::fmt::Write; - - let n_possibilities = if sess.opts.unstable_opts.check_cfg_all_expected { - possibilities.len() - } else { - std::cmp::min(possibilities.len(), MAX_CHECK_CFG_NAMES_OR_VALUES) - }; - - let mut possibilities = possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>(); - possibilities.sort(); - - let and_more = possibilities.len().saturating_sub(n_possibilities); - let possibilities = possibilities[..n_possibilities].join("`, `"); - - let mut note = String::with_capacity(50 + possibilities.len()); - - write!(&mut note, "expected {type_}").unwrap(); - if let Some(name) = name { - write!(&mut note, " for `{name}`").unwrap(); - } - write!(&mut note, " are: {suffix}`{possibilities}`").unwrap(); - if and_more > 0 { - write!(&mut note, " and {and_more} more").unwrap(); - } - - note -} +mod check_cfg; pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) { match diagnostic { @@ -219,242 +181,11 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di diag.help(help); diag.note("see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information"); } - BuiltinLintDiag::UnexpectedCfgName((name, name_span), value) => { - #[allow(rustc::potential_query_instability)] - let possibilities: Vec<Symbol> = - sess.psess.check_config.expecteds.keys().copied().collect(); - - let mut names_possibilities: Vec<_> = if value.is_none() { - // We later sort and display all the possibilities, so the order here does not matter. - #[allow(rustc::potential_query_instability)] - sess.psess - .check_config - .expecteds - .iter() - .filter_map(|(k, v)| match v { - ExpectedValues::Some(v) if v.contains(&Some(name)) => Some(k), - _ => None, - }) - .collect() - } else { - Vec::new() - }; - - let is_from_cargo = rustc_session::utils::was_invoked_from_cargo(); - let mut is_feature_cfg = name == sym::feature; - - if is_feature_cfg && is_from_cargo { - diag.help("consider defining some features in `Cargo.toml`"); - // Suggest the most probable if we found one - } else if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) { - if let Some(ExpectedValues::Some(best_match_values)) = - sess.psess.check_config.expecteds.get(&best_match) - { - // We will soon sort, so the initial order does not matter. - #[allow(rustc::potential_query_instability)] - let mut possibilities = - best_match_values.iter().flatten().map(Symbol::as_str).collect::<Vec<_>>(); - possibilities.sort(); - - let mut should_print_possibilities = true; - if let Some((value, value_span)) = value { - if best_match_values.contains(&Some(value)) { - diag.span_suggestion( - name_span, - "there is a config with a similar name and value", - best_match, - Applicability::MaybeIncorrect, - ); - should_print_possibilities = false; - } else if best_match_values.contains(&None) { - diag.span_suggestion( - name_span.to(value_span), - "there is a config with a similar name and no value", - best_match, - Applicability::MaybeIncorrect, - ); - should_print_possibilities = false; - } else if let Some(first_value) = possibilities.first() { - diag.span_suggestion( - name_span.to(value_span), - "there is a config with a similar name and different values", - format!("{best_match} = \"{first_value}\""), - Applicability::MaybeIncorrect, - ); - } else { - diag.span_suggestion( - name_span.to(value_span), - "there is a config with a similar name and different values", - best_match, - Applicability::MaybeIncorrect, - ); - }; - } else { - diag.span_suggestion( - name_span, - "there is a config with a similar name", - best_match, - Applicability::MaybeIncorrect, - ); - } - - if !possibilities.is_empty() && should_print_possibilities { - let possibilities = possibilities.join("`, `"); - diag.help(format!( - "expected values for `{best_match}` are: `{possibilities}`" - )); - } - } else { - diag.span_suggestion( - name_span, - "there is a config with a similar name", - best_match, - Applicability::MaybeIncorrect, - ); - } - - is_feature_cfg |= best_match == sym::feature; - } else { - if !names_possibilities.is_empty() && names_possibilities.len() <= 3 { - names_possibilities.sort(); - for cfg_name in names_possibilities.iter() { - diag.span_suggestion( - name_span, - "found config with similar value", - format!("{cfg_name} = \"{name}\""), - Applicability::MaybeIncorrect, - ); - } - } - if !possibilities.is_empty() { - diag.help_once(check_cfg_expected_note( - sess, - &possibilities, - "names", - None, - "", - )); - } - } - - let inst = if let Some((value, _value_span)) = value { - let pre = if is_from_cargo { "\\" } else { "" }; - format!("cfg({name}, values({pre}\"{value}{pre}\"))") - } else { - format!("cfg({name})") - }; - - if is_from_cargo { - if !is_feature_cfg { - diag.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`")); - } - diag.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration"); - } else { - diag.help(format!("to expect this configuration use `--check-cfg={inst}`")); - diag.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration"); - } + BuiltinLintDiag::UnexpectedCfgName(name, value) => { + check_cfg::unexpected_cfg_name(sess, diag, name, value) } - BuiltinLintDiag::UnexpectedCfgValue((name, name_span), value) => { - let Some(ExpectedValues::Some(values)) = &sess.psess.check_config.expecteds.get(&name) - else { - bug!( - "it shouldn't be possible to have a diagnostic on a value whose name is not in values" - ); - }; - let mut have_none_possibility = false; - // We later sort possibilities if it is not empty, so the - // order here does not matter. - #[allow(rustc::potential_query_instability)] - let possibilities: Vec<Symbol> = values - .iter() - .inspect(|a| have_none_possibility |= a.is_none()) - .copied() - .flatten() - .collect(); - let is_from_cargo = rustc_session::utils::was_invoked_from_cargo(); - - // Show the full list if all possible values for a given name, but don't do it - // for names as the possibilities could be very long - if !possibilities.is_empty() { - diag.note(check_cfg_expected_note( - sess, - &possibilities, - "values", - Some(name), - if have_none_possibility { "(none), " } else { "" }, - )); - - if let Some((value, value_span)) = value { - // Suggest the most probable if we found one - if let Some(best_match) = find_best_match_for_name(&possibilities, value, None) - { - diag.span_suggestion( - value_span, - "there is a expected value with a similar name", - format!("\"{best_match}\""), - Applicability::MaybeIncorrect, - ); - } - } else if let &[first_possibility] = &possibilities[..] { - diag.span_suggestion( - name_span.shrink_to_hi(), - "specify a config value", - format!(" = \"{first_possibility}\""), - Applicability::MaybeIncorrect, - ); - } - } else if have_none_possibility { - diag.note(format!("no expected value for `{name}`")); - if let Some((_value, value_span)) = value { - diag.span_suggestion( - name_span.shrink_to_hi().to(value_span), - "remove the value", - "", - Applicability::MaybeIncorrect, - ); - } - } else { - diag.note(format!("no expected values for `{name}`")); - - let sp = if let Some((_value, value_span)) = value { - name_span.to(value_span) - } else { - name_span - }; - diag.span_suggestion(sp, "remove the condition", "", Applicability::MaybeIncorrect); - } - - // We don't want to suggest adding values to well known names - // since those are defined by rustc it-self. Users can still - // do it if they want, but should not encourage them. - let is_cfg_a_well_know_name = sess.psess.check_config.well_known_names.contains(&name); - - let inst = if let Some((value, _value_span)) = value { - let pre = if is_from_cargo { "\\" } else { "" }; - format!("cfg({name}, values({pre}\"{value}{pre}\"))") - } else { - format!("cfg({name})") - }; - - if is_from_cargo { - if name == sym::feature { - if let Some((value, _value_span)) = value { - diag.help(format!( - "consider adding `{value}` as a feature in `Cargo.toml`" - )); - } else { - diag.help("consider defining some features in `Cargo.toml`"); - } - } else if !is_cfg_a_well_know_name { - diag.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`")); - } - diag.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration"); - } else { - if !is_cfg_a_well_know_name { - diag.help(format!("to expect this configuration use `--check-cfg={inst}`")); - } - diag.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration"); - } + BuiltinLintDiag::UnexpectedCfgValue(name, value) => { + check_cfg::unexpected_cfg_value(sess, diag, name, value) } BuiltinLintDiag::DeprecatedWhereclauseLocation(sugg) => { let left_sp = diag.span.primary_span().unwrap(); |
