Rollup merge of #111068 - Urgau:check-cfg-improvements, r=petrochenkov

Improve check-cfg implementation

This PR makes multiple improvements into the implementation of check-cfg, it is a prerequisite to a follow-up PR that will introduce a simpler and more explicit syntax.

The 2 main area of improvements are:
 1. Internal representation of expected values:
    - now uses `FxHashSet<Option<Symbol>>` instead of `FxHashSet<Symbol>`, it made the no value expected case only possible when no values where in the `HashSet` which is now represented as `None` (same as cfg represent-it).
    - a enum with `Some` and `Any` makes it now clear if some values are expected or not, necessary for `feature` and `target_feature`.
 2. Diagnostics: Improve the diagnostics in multiple case and fix case where a missing value could have had a new name suggestion instead of the value diagnostic; and some drive by improvements

I highly recommend reviewing commit by commit.

r? `@petrochenkov`
This commit is contained in:
Dylan DPC 2023-05-05 18:40:35 +05:30 committed by GitHub
commit ded0a9e15f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 421 additions and 237 deletions

View file

@ -5,6 +5,7 @@ use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedM
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
use rustc_macros::HashStable_Generic; use rustc_macros::HashStable_Generic;
use rustc_session::config::ExpectedValues;
use rustc_session::lint::builtin::UNEXPECTED_CFGS; use rustc_session::lint::builtin::UNEXPECTED_CFGS;
use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::parse::{feature_err, ParseSess}; use rustc_session::parse::{feature_err, ParseSess};
@ -581,32 +582,32 @@ pub fn cfg_matches(
) -> bool { ) -> bool {
eval_condition(cfg, sess, features, &mut |cfg| { eval_condition(cfg, sess, features, &mut |cfg| {
try_gate_cfg(cfg.name, cfg.span, sess, features); try_gate_cfg(cfg.name, cfg.span, sess, features);
if let Some(names_valid) = &sess.check_config.names_valid { match sess.check_config.expecteds.get(&cfg.name) {
if !names_valid.contains(&cfg.name) { Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => {
sess.buffer_lint_with_diagnostic(
UNEXPECTED_CFGS,
cfg.span,
lint_node_id,
"unexpected `cfg` condition value",
BuiltinLintDiagnostics::UnexpectedCfgValue(
(cfg.name, cfg.name_span),
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
),
);
}
None if sess.check_config.exhaustive_names => {
sess.buffer_lint_with_diagnostic( sess.buffer_lint_with_diagnostic(
UNEXPECTED_CFGS, UNEXPECTED_CFGS,
cfg.span, cfg.span,
lint_node_id, lint_node_id,
"unexpected `cfg` condition name", "unexpected `cfg` condition name",
BuiltinLintDiagnostics::UnexpectedCfg((cfg.name, cfg.name_span), None), BuiltinLintDiagnostics::UnexpectedCfgName(
(cfg.name, cfg.name_span),
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
),
); );
} }
} _ => { /* not unexpected */ }
if let Some(value) = cfg.value {
if let Some(values) = &sess.check_config.values_valid.get(&cfg.name) {
if !values.contains(&value) {
sess.buffer_lint_with_diagnostic(
UNEXPECTED_CFGS,
cfg.span,
lint_node_id,
"unexpected `cfg` condition value",
BuiltinLintDiagnostics::UnexpectedCfg(
(cfg.name, cfg.name_span),
cfg.value_span.map(|vs| (value, vs)),
),
);
}
}
} }
sess.config.contains(&(cfg.name, cfg.value)) sess.config.contains(&(cfg.name, cfg.value))
}) })

View file

@ -9,11 +9,12 @@ use rustc_data_structures::OnDrop;
use rustc_errors::registry::Registry; use rustc_errors::registry::Registry;
use rustc_errors::{ErrorGuaranteed, Handler}; use rustc_errors::{ErrorGuaranteed, Handler};
use rustc_lint::LintStore; use rustc_lint::LintStore;
use rustc_middle::ty; use rustc_middle::{bug, ty};
use rustc_parse::maybe_new_parser_from_source_str; use rustc_parse::maybe_new_parser_from_source_str;
use rustc_query_impl::QueryCtxt; use rustc_query_impl::QueryCtxt;
use rustc_query_system::query::print_query_stack; use rustc_query_system::query::print_query_stack;
use rustc_session::config::{self, CheckCfg, ErrorOutputType, Input, OutputFilenames}; use rustc_session::config::{self, ErrorOutputType, Input, OutputFilenames};
use rustc_session::config::{CheckCfg, ExpectedValues};
use rustc_session::lint; use rustc_session::lint;
use rustc_session::parse::{CrateConfig, ParseSess}; use rustc_session::parse::{CrateConfig, ParseSess};
use rustc_session::Session; use rustc_session::Session;
@ -121,9 +122,9 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
/// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`. /// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg { pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
rustc_span::create_default_session_if_not_set_then(move |_| { rustc_span::create_default_session_if_not_set_then(move |_| {
let mut cfg = CheckCfg::default(); let mut check_cfg = CheckCfg::default();
'specs: for s in specs { for s in specs {
let sess = ParseSess::with_silent_emitter(Some(format!( let sess = ParseSess::with_silent_emitter(Some(format!(
"this error occurred on the command line: `--check-cfg={s}`" "this error occurred on the command line: `--check-cfg={s}`"
))); )));
@ -137,40 +138,54 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"), concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"),
s s
), ),
); )
}; };
} }
let expected_error = || {
error!(
"expected `names(name1, name2, ... nameN)` or \
`values(name, \"value1\", \"value2\", ... \"valueN\")`"
)
};
match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) { match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) {
Ok(mut parser) => match parser.parse_meta_item() { Ok(mut parser) => match parser.parse_meta_item() {
Ok(meta_item) if parser.token == token::Eof => { Ok(meta_item) if parser.token == token::Eof => {
if let Some(args) = meta_item.meta_item_list() { if let Some(args) = meta_item.meta_item_list() {
if meta_item.has_name(sym::names) { if meta_item.has_name(sym::names) {
let names_valid = check_cfg.exhaustive_names = true;
cfg.names_valid.get_or_insert_with(|| FxHashSet::default());
for arg in args { for arg in args {
if arg.is_word() && arg.ident().is_some() { if arg.is_word() && arg.ident().is_some() {
let ident = arg.ident().expect("multi-segment cfg key"); let ident = arg.ident().expect("multi-segment cfg key");
names_valid.insert(ident.name.to_string()); check_cfg
.expecteds
.entry(ident.name.to_string())
.or_insert(ExpectedValues::Any);
} else { } else {
error!("`names()` arguments must be simple identifiers"); error!("`names()` arguments must be simple identifiers");
} }
} }
continue 'specs;
} else if meta_item.has_name(sym::values) { } else if meta_item.has_name(sym::values) {
if let Some((name, values)) = args.split_first() { if let Some((name, values)) = args.split_first() {
if name.is_word() && name.ident().is_some() { if name.is_word() && name.ident().is_some() {
let ident = name.ident().expect("multi-segment cfg key"); let ident = name.ident().expect("multi-segment cfg key");
let ident_values = cfg let expected_values = check_cfg
.values_valid .expecteds
.entry(ident.name.to_string()) .entry(ident.name.to_string())
.or_insert_with(|| FxHashSet::default()); .or_insert_with(|| {
ExpectedValues::Some(FxHashSet::default())
});
let ExpectedValues::Some(expected_values) = expected_values else {
bug!("shoudn't be possible")
};
for val in values { for val in values {
if let Some(LitKind::Str(s, _)) = if let Some(LitKind::Str(s, _)) =
val.lit().map(|lit| &lit.kind) val.lit().map(|lit| &lit.kind)
{ {
ident_values.insert(s.to_string()); expected_values.insert(Some(s.to_string()));
} else { } else {
error!( error!(
"`values()` arguments must be string literals" "`values()` arguments must be string literals"
@ -178,35 +193,40 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
} }
} }
continue 'specs; if values.is_empty() {
expected_values.insert(None);
}
} else { } else {
error!( error!(
"`values()` first argument must be a simple identifier" "`values()` first argument must be a simple identifier"
); );
} }
} else if args.is_empty() { } else if args.is_empty() {
cfg.well_known_values = true; check_cfg.exhaustive_values = true;
continue 'specs; } else {
expected_error();
} }
} else {
expected_error();
} }
} else {
expected_error();
} }
} }
Ok(..) => {} Ok(..) => expected_error(),
Err(err) => err.cancel(), Err(err) => {
err.cancel();
expected_error();
}
}, },
Err(errs) => drop(errs), Err(errs) => {
drop(errs);
expected_error();
}
} }
error!(
"expected `names(name1, name2, ... nameN)` or \
`values(name, \"value1\", \"value2\", ... \"valueN\")`"
);
} }
if let Some(names_valid) = &mut cfg.names_valid { check_cfg
names_valid.extend(cfg.values_valid.keys().cloned());
}
cfg
}) })
} }

View file

@ -63,6 +63,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOf};
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef};
use rustc_session::config::ExpectedValues;
use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason}; use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason};
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
@ -3306,16 +3307,15 @@ impl EarlyLintPass for UnexpectedCfgs {
let cfg = &cx.sess().parse_sess.config; let cfg = &cx.sess().parse_sess.config;
let check_cfg = &cx.sess().parse_sess.check_config; let check_cfg = &cx.sess().parse_sess.check_config;
for &(name, value) in cfg { for &(name, value) in cfg {
if let Some(names_valid) = &check_cfg.names_valid && !names_valid.contains(&name){ match check_cfg.expecteds.get(&name) {
cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigName { Some(ExpectedValues::Some(values)) if !values.contains(&value) => {
name, let value = value.unwrap_or(kw::Empty);
}); cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigValue { name, value });
} }
if let Some(value) = value && let Some(values) = check_cfg.values_valid.get(&name) && !values.contains(&value) { None if check_cfg.exhaustive_names => {
cx.emit_lint( cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigName { name });
UNEXPECTED_CFGS, }
BuiltinUnexpectedCliConfigValue { name, value }, _ => { /* expected */ }
);
} }
} }
} }

View file

@ -36,6 +36,7 @@ use rustc_middle::middle::stability;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, print::Printer, subst::GenericArg, RegisteredTools, Ty, TyCtxt}; use rustc_middle::ty::{self, print::Printer, subst::GenericArg, RegisteredTools, Ty, TyCtxt};
use rustc_session::config::ExpectedValues;
use rustc_session::lint::{BuiltinLintDiagnostics, LintExpectationId}; use rustc_session::lint::{BuiltinLintDiagnostics, LintExpectationId};
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
use rustc_session::Session; use rustc_session::Session;
@ -768,22 +769,52 @@ pub trait LintContext: Sized {
db.help(help); db.help(help);
db.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"); db.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");
}, },
BuiltinLintDiagnostics::UnexpectedCfg((name, name_span), None) => { BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => {
let Some(names_valid) = &sess.parse_sess.check_config.names_valid else { let possibilities: Vec<Symbol> = sess.parse_sess.check_config.expecteds.keys().map(|s| *s).collect();
bug!("it shouldn't be possible to have a diagnostic on a name if name checking is not enabled");
};
let possibilities: Vec<Symbol> = names_valid.iter().map(|s| *s).collect();
// Suggest the most probable if we found one // Suggest the most probable if we found one
if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) { if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) {
db.span_suggestion(name_span, "did you mean", best_match, Applicability::MaybeIncorrect); if let Some(ExpectedValues::Some(best_match_values)) =
sess.parse_sess.check_config.expecteds.get(&best_match) {
let mut possibilities = best_match_values.iter()
.flatten()
.map(Symbol::as_str)
.collect::<Vec<_>>();
possibilities.sort();
if let Some((value, value_span)) = value {
if best_match_values.contains(&Some(value)) {
db.span_suggestion(name_span, "there is a config with a similar name and value", best_match, Applicability::MaybeIncorrect);
} else if best_match_values.contains(&None) {
db.span_suggestion(name_span.to(value_span), "there is a config with a similar name and no value", best_match, Applicability::MaybeIncorrect);
} else if let Some(first_value) = possibilities.first() {
db.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 {
db.span_suggestion(name_span.to(value_span), "there is a config with a similar name and different values", best_match, Applicability::MaybeIncorrect);
};
} else {
db.span_suggestion(name_span, "there is a config with a similar name", best_match, Applicability::MaybeIncorrect);
}
if !possibilities.is_empty() {
let possibilities = possibilities.join("`, `");
db.help(format!("expected values for `{best_match}` are: `{possibilities}`"));
}
} else {
db.span_suggestion(name_span, "there is a config with a similar name", best_match, Applicability::MaybeIncorrect);
}
} }
}, },
BuiltinLintDiagnostics::UnexpectedCfg((name, name_span), Some((value, value_span))) => { BuiltinLintDiagnostics::UnexpectedCfgValue((name, name_span), value) => {
let Some(values) = &sess.parse_sess.check_config.values_valid.get(&name) else { let Some(ExpectedValues::Some(values)) = &sess.parse_sess.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"); bug!("it shouldn't be possible to have a diagnostic on a value whose name is not in values");
}; };
let possibilities: Vec<Symbol> = values.iter().map(|&s| s).collect(); let mut have_none_possibility = false;
let possibilities: Vec<Symbol> = values.iter()
.inspect(|a| have_none_possibility |= a.is_none())
.copied()
.flatten()
.collect();
// Show the full list if all possible values for a given name, but don't do it // 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 // for names as the possibilities could be very long
@ -792,17 +823,24 @@ pub trait LintContext: Sized {
let mut possibilities = possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>(); let mut possibilities = possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>();
possibilities.sort(); possibilities.sort();
let possibilities = possibilities.join(", "); let possibilities = possibilities.join("`, `");
db.note(format!("expected values for `{name}` are: {possibilities}")); let none = if have_none_possibility { "(none), " } else { "" };
db.note(format!("expected values for `{name}` are: {none}`{possibilities}`"));
} }
// Suggest the most probable if we found one if let Some((value, value_span)) = value {
if let Some(best_match) = find_best_match_for_name(&possibilities, value, None) { // Suggest the most probable if we found one
db.span_suggestion(value_span, "did you mean", format!("\"{best_match}\""), Applicability::MaybeIncorrect); if let Some(best_match) = find_best_match_for_name(&possibilities, value, None) {
db.span_suggestion(value_span, "there is a expected value with a similar name", format!("\"{best_match}\""), Applicability::MaybeIncorrect);
}
} else if let &[first_possibility] = &possibilities[..] {
db.span_suggestion(name_span.shrink_to_hi(), "specify a config value", format!(" = \"{first_possibility}\""), Applicability::MaybeIncorrect);
} }
} else { } else if have_none_possibility {
db.note(format!("no expected value for `{name}`")); db.note(format!("no expected value for `{name}`"));
if name != sym::feature { if let Some((_value, value_span)) = value {
db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", "", Applicability::MaybeIncorrect); db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", "", Applicability::MaybeIncorrect);
} }
} }

View file

@ -496,7 +496,8 @@ pub enum BuiltinLintDiagnostics {
BreakWithLabelAndLoop(Span), BreakWithLabelAndLoop(Span),
NamedAsmLabel(String), NamedAsmLabel(String),
UnicodeTextFlow(Span, String), UnicodeTextFlow(Span, String),
UnexpectedCfg((Symbol, Span), Option<(Symbol, Span)>), UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>),
UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>),
DeprecatedWhereclauseLocation(Span, String), DeprecatedWhereclauseLocation(Span, String),
SingleUseLifetime { SingleUseLifetime {
/// Span of the parameter which declares this lifetime. /// Span of the parameter which declares this lifetime.

View file

@ -1064,37 +1064,76 @@ pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig
/// The parsed `--check-cfg` options /// The parsed `--check-cfg` options
pub struct CheckCfg<T = String> { pub struct CheckCfg<T = String> {
/// The set of all `names()`, if None no name checking is performed /// Is well known names activated
pub names_valid: Option<FxHashSet<T>>, pub exhaustive_names: bool,
/// Is well known values activated /// Is well known values activated
pub well_known_values: bool, pub exhaustive_values: bool,
/// The set of all `values()` /// All the expected values for a config name
pub values_valid: FxHashMap<T, FxHashSet<T>>, pub expecteds: FxHashMap<T, ExpectedValues<T>>,
} }
impl<T> Default for CheckCfg<T> { impl<T> Default for CheckCfg<T> {
fn default() -> Self { fn default() -> Self {
CheckCfg { CheckCfg {
names_valid: Default::default(), exhaustive_names: false,
values_valid: Default::default(), exhaustive_values: false,
well_known_values: false, expecteds: FxHashMap::default(),
} }
} }
} }
impl<T> CheckCfg<T> { impl<T> CheckCfg<T> {
fn map_data<O: Eq + Hash>(&self, f: impl Fn(&T) -> O) -> CheckCfg<O> { fn map_data<O: Eq + Hash>(self, f: impl Fn(T) -> O) -> CheckCfg<O> {
CheckCfg { CheckCfg {
names_valid: self exhaustive_names: self.exhaustive_names,
.names_valid exhaustive_values: self.exhaustive_values,
.as_ref() expecteds: self
.map(|names_valid| names_valid.iter().map(|a| f(a)).collect()), .expecteds
values_valid: self .into_iter()
.values_valid .map(|(name, values)| {
.iter() (
.map(|(a, b)| (f(a), b.iter().map(|b| f(b)).collect())) f(name),
match values {
ExpectedValues::Some(values) => ExpectedValues::Some(
values.into_iter().map(|b| b.map(|b| f(b))).collect(),
),
ExpectedValues::Any => ExpectedValues::Any,
},
)
})
.collect(), .collect(),
well_known_values: self.well_known_values, }
}
}
pub enum ExpectedValues<T> {
Some(FxHashSet<Option<T>>),
Any,
}
impl<T: Eq + Hash> ExpectedValues<T> {
fn insert(&mut self, value: T) -> bool {
match self {
ExpectedValues::Some(expecteds) => expecteds.insert(Some(value)),
ExpectedValues::Any => false,
}
}
}
impl<T: Eq + Hash> Extend<T> for ExpectedValues<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
match self {
ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(Some)),
ExpectedValues::Any => {}
}
}
}
impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
match self {
ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(|a| Some(*a))),
ExpectedValues::Any => {}
} }
} }
} }
@ -1103,58 +1142,27 @@ impl<T> CheckCfg<T> {
/// `rustc_interface::interface::Config` accepts this in the compiler configuration, /// `rustc_interface::interface::Config` accepts this in the compiler configuration,
/// but the symbol interner is not yet set up then, so we must convert it later. /// but the symbol interner is not yet set up then, so we must convert it later.
pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig { pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig {
cfg.map_data(|s| Symbol::intern(s)) cfg.map_data(|s| Symbol::intern(&s))
} }
impl CrateCheckConfig { impl CrateCheckConfig {
/// Fills a `CrateCheckConfig` with well-known configuration names. pub fn fill_well_known(&mut self, current_target: &Target) {
fn fill_well_known_names(&mut self) { if !self.exhaustive_values && !self.exhaustive_names {
// NOTE: This should be kept in sync with `default_configuration` and
// `fill_well_known_values`
const WELL_KNOWN_NAMES: &[Symbol] = &[
// rustc
sym::unix,
sym::windows,
sym::target_os,
sym::target_family,
sym::target_arch,
sym::target_endian,
sym::target_pointer_width,
sym::target_env,
sym::target_abi,
sym::target_vendor,
sym::target_thread_local,
sym::target_has_atomic_load_store,
sym::target_has_atomic,
sym::target_has_atomic_equal_alignment,
sym::target_feature,
sym::panic,
sym::sanitize,
sym::debug_assertions,
sym::proc_macro,
sym::test,
sym::feature,
// rustdoc
sym::doc,
sym::doctest,
// miri
sym::miri,
];
// We only insert well-known names if `names()` was activated
if let Some(names_valid) = &mut self.names_valid {
names_valid.extend(WELL_KNOWN_NAMES);
}
}
/// Fills a `CrateCheckConfig` with well-known configuration values.
fn fill_well_known_values(&mut self, current_target: &Target) {
if !self.well_known_values {
return; return;
} }
// NOTE: This should be kept in sync with `default_configuration` and let no_values = || {
// `fill_well_known_names` let mut values = FxHashSet::default();
values.insert(None);
ExpectedValues::Some(values)
};
let empty_values = || {
let values = FxHashSet::default();
ExpectedValues::Some(values)
};
// NOTE: This should be kept in sync with `default_configuration`
let panic_values = &PanicStrategy::all(); let panic_values = &PanicStrategy::all();
@ -1174,6 +1182,9 @@ impl CrateCheckConfig {
// Unknown possible values: // Unknown possible values:
// - `feature` // - `feature`
// - `target_feature` // - `target_feature`
for name in [sym::feature, sym::target_feature] {
self.expecteds.entry(name).or_insert(ExpectedValues::Any);
}
// No-values // No-values
for name in [ for name in [
@ -1187,20 +1198,23 @@ impl CrateCheckConfig {
sym::debug_assertions, sym::debug_assertions,
sym::target_thread_local, sym::target_thread_local,
] { ] {
self.values_valid.entry(name).or_default(); self.expecteds.entry(name).or_insert_with(no_values);
} }
// Pre-defined values // Pre-defined values
self.values_valid.entry(sym::panic).or_default().extend(panic_values); self.expecteds.entry(sym::panic).or_insert_with(empty_values).extend(panic_values);
self.values_valid.entry(sym::sanitize).or_default().extend(sanitize_values); self.expecteds.entry(sym::sanitize).or_insert_with(empty_values).extend(sanitize_values);
self.values_valid.entry(sym::target_has_atomic).or_default().extend(atomic_values); self.expecteds
self.values_valid .entry(sym::target_has_atomic)
.entry(sym::target_has_atomic_load_store) .or_insert_with(no_values)
.or_default()
.extend(atomic_values); .extend(atomic_values);
self.values_valid self.expecteds
.entry(sym::target_has_atomic_load_store)
.or_insert_with(no_values)
.extend(atomic_values);
self.expecteds
.entry(sym::target_has_atomic_equal_alignment) .entry(sym::target_has_atomic_equal_alignment)
.or_default() .or_insert_with(no_values)
.extend(atomic_values); .extend(atomic_values);
// Target specific values // Target specific values
@ -1218,47 +1232,50 @@ impl CrateCheckConfig {
// Initialize (if not already initialized) // Initialize (if not already initialized)
for &e in VALUES { for &e in VALUES {
self.values_valid.entry(e).or_default(); let entry = self.expecteds.entry(e);
if !self.exhaustive_values {
entry.or_insert(ExpectedValues::Any);
} else {
entry.or_insert_with(empty_values);
}
} }
// Get all values map at once otherwise it would be costly. if self.exhaustive_values {
// (8 values * 220 targets ~= 1760 times, at the time of writing this comment). // Get all values map at once otherwise it would be costly.
let [ // (8 values * 220 targets ~= 1760 times, at the time of writing this comment).
values_target_os, let [
values_target_family, values_target_os,
values_target_arch, values_target_family,
values_target_endian, values_target_arch,
values_target_env, values_target_endian,
values_target_abi, values_target_env,
values_target_vendor, values_target_abi,
values_target_pointer_width, values_target_vendor,
] = self values_target_pointer_width,
.values_valid ] = self
.get_many_mut(VALUES) .expecteds
.expect("unable to get all the check-cfg values buckets"); .get_many_mut(VALUES)
.expect("unable to get all the check-cfg values buckets");
for target in TARGETS for target in TARGETS
.iter() .iter()
.map(|target| Target::expect_builtin(&TargetTriple::from_triple(target))) .map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
.chain(iter::once(current_target.clone())) .chain(iter::once(current_target.clone()))
{ {
values_target_os.insert(Symbol::intern(&target.options.os)); values_target_os.insert(Symbol::intern(&target.options.os));
values_target_family values_target_family.extend(
.extend(target.options.families.iter().map(|family| Symbol::intern(family))); target.options.families.iter().map(|family| Symbol::intern(family)),
values_target_arch.insert(Symbol::intern(&target.arch)); );
values_target_endian.insert(Symbol::intern(target.options.endian.as_str())); values_target_arch.insert(Symbol::intern(&target.arch));
values_target_env.insert(Symbol::intern(&target.options.env)); values_target_endian.insert(Symbol::intern(target.options.endian.as_str()));
values_target_abi.insert(Symbol::intern(&target.options.abi)); values_target_env.insert(Symbol::intern(&target.options.env));
values_target_vendor.insert(Symbol::intern(&target.options.vendor)); values_target_abi.insert(Symbol::intern(&target.options.abi));
values_target_pointer_width.insert(sym::integer(target.pointer_width)); values_target_vendor.insert(Symbol::intern(&target.options.vendor));
values_target_pointer_width.insert(sym::integer(target.pointer_width));
}
} }
} }
} }
pub fn fill_well_known(&mut self, current_target: &Target) {
self.fill_well_known_names();
self.fill_well_known_values(current_target);
}
} }
pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateConfig { pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateConfig {

View file

@ -2,7 +2,7 @@ warning: unexpected `cfg` condition name
--> $DIR/check-cfg.rs:5:7 --> $DIR/check-cfg.rs:5:7
| |
LL | #[cfg(uniz)] LL | #[cfg(uniz)]
| ^^^^ help: did you mean: `unix` | ^^^^ help: there is a config with a similar name: `unix`
| |
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default

View file

@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value
LL | #[cfg(feature = "invalid")] LL | #[cfg(feature = "invalid")]
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: test = note: expected values for `feature` are: `test`
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default
warning: 1 warning emitted warning: 1 warning emitted

View file

@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value
LL | #[cfg(target(os = "linux", arch = "X"))] LL | #[cfg(target(os = "linux", arch = "X"))]
| ^^^^^^^^^^ | ^^^^^^^^^^
| |
= note: expected values for `target_arch` are: aarch64, arm, avr, bpf, hexagon, loongarch64, m68k, mips, mips64, msp430, nvptx64, powerpc, powerpc64, riscv32, riscv64, s390x, sparc, sparc64, wasm32, wasm64, x86, x86_64 = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips64`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default
warning: 1 warning emitted warning: 1 warning emitted

View file

@ -0,0 +1,31 @@
// check-pass
// compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") --check-cfg=values(no_values) -Z unstable-options
#[cfg(featur)]
//~^ WARNING unexpected `cfg` condition name
fn feature() {}
#[cfg(featur = "foo")]
//~^ WARNING unexpected `cfg` condition name
fn feature() {}
#[cfg(featur = "fo")]
//~^ WARNING unexpected `cfg` condition name
fn feature() {}
#[cfg(feature = "foo")]
fn feature() {}
#[cfg(no_value)]
//~^ WARNING unexpected `cfg` condition name
fn no_values() {}
#[cfg(no_value = "foo")]
//~^ WARNING unexpected `cfg` condition name
fn no_values() {}
#[cfg(no_values = "bar")]
//~^ WARNING unexpected `cfg` condition value
fn no_values() {}
fn main() {}

View file

@ -0,0 +1,62 @@
warning: unexpected `cfg` condition name
--> $DIR/diagnotics.rs:4:7
|
LL | #[cfg(featur)]
| ^^^^^^ help: there is a config with a similar name: `feature`
|
= help: expected values for `feature` are: `foo`
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition name
--> $DIR/diagnotics.rs:8:7
|
LL | #[cfg(featur = "foo")]
| ^^^^^^^^^^^^^^
|
= help: expected values for `feature` are: `foo`
help: there is a config with a similar name and value
|
LL | #[cfg(feature = "foo")]
| ~~~~~~~
warning: unexpected `cfg` condition name
--> $DIR/diagnotics.rs:12:7
|
LL | #[cfg(featur = "fo")]
| ^^^^^^^^^^^^^
|
= help: expected values for `feature` are: `foo`
help: there is a config with a similar name and different values
|
LL | #[cfg(feature = "foo")]
| ~~~~~~~~~~~~~~~
warning: unexpected `cfg` condition name
--> $DIR/diagnotics.rs:19:7
|
LL | #[cfg(no_value)]
| ^^^^^^^^ help: there is a config with a similar name: `no_values`
warning: unexpected `cfg` condition name
--> $DIR/diagnotics.rs:23:7
|
LL | #[cfg(no_value = "foo")]
| ^^^^^^^^^^^^^^^^
|
help: there is a config with a similar name and no value
|
LL | #[cfg(no_values)]
| ~~~~~~~~~
warning: unexpected `cfg` condition value
--> $DIR/diagnotics.rs:27:7
|
LL | #[cfg(no_values = "bar")]
| ^^^^^^^^^--------
| |
| help: remove the value
|
= note: no expected value for `no_values`
warning: 6 warnings emitted

View file

@ -2,7 +2,7 @@ warning: unexpected `cfg` condition name
--> $DIR/invalid-cfg-name.rs:7:7 --> $DIR/invalid-cfg-name.rs:7:7
| |
LL | #[cfg(widnows)] LL | #[cfg(widnows)]
| ^^^^^^^ help: did you mean: `windows` | ^^^^^^^ help: there is a config with a similar name: `windows`
| |
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default

View file

@ -4,9 +4,9 @@ warning: unexpected `cfg` condition value
LL | #[cfg(feature = "sedre")] LL | #[cfg(feature = "sedre")]
| ^^^^^^^^^^------- | ^^^^^^^^^^-------
| | | |
| help: did you mean: `"serde"` | help: there is a expected value with a similar name: `"serde"`
| |
= note: expected values for `feature` are: full, serde = note: expected values for `feature` are: `full`, `serde`
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value
LL | #[cfg(feature = "rand")] LL | #[cfg(feature = "rand")]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: full, serde = note: expected values for `feature` are: `full`, `serde`
warning: unexpected condition value `rand` for condition name `feature` warning: unexpected condition value `rand` for condition name `feature`
| |

View file

@ -12,6 +12,10 @@ fn do_windows_stuff() {}
//~^ WARNING unexpected `cfg` condition name //~^ WARNING unexpected `cfg` condition name
fn do_windows_stuff() {} fn do_windows_stuff() {}
#[cfg(feature)]
//~^ WARNING unexpected `cfg` condition value
fn no_feature() {}
#[cfg(feature = "foo")] #[cfg(feature = "foo")]
fn use_foo() {} fn use_foo() {}

View file

@ -2,28 +2,36 @@ warning: unexpected `cfg` condition name
--> $DIR/mix.rs:11:7 --> $DIR/mix.rs:11:7
| |
LL | #[cfg(widnows)] LL | #[cfg(widnows)]
| ^^^^^^^ help: did you mean: `windows` | ^^^^^^^ help: there is a config with a similar name: `windows`
| |
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:18:7 --> $DIR/mix.rs:15:7
| |
LL | #[cfg(feature = "bar")] LL | #[cfg(feature)]
| ^^^^^^^^^^^^^^^ | ^^^^^^^- help: specify a config value: `= "foo"`
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:22:7 --> $DIR/mix.rs:22:7
| |
LL | #[cfg(feature = "bar")]
| ^^^^^^^^^^^^^^^
|
= note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition value
--> $DIR/mix.rs:26:7
|
LL | #[cfg(feature = "zebra")] LL | #[cfg(feature = "zebra")]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:26:12 --> $DIR/mix.rs:30:12
| |
LL | #[cfg_attr(uu, test)] LL | #[cfg_attr(uu, test)]
| ^^ | ^^
@ -37,146 +45,146 @@ warning: unexpected `unknown_name` as condition name
= help: was set with `--cfg` but isn't in the `--check-cfg` expected names = help: was set with `--cfg` but isn't in the `--check-cfg` expected names
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:35:10 --> $DIR/mix.rs:39:10
| |
LL | cfg!(widnows); LL | cfg!(widnows);
| ^^^^^^^ help: did you mean: `windows` | ^^^^^^^ help: there is a config with a similar name: `windows`
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:38:10 --> $DIR/mix.rs:42:10
| |
LL | cfg!(feature = "bar"); LL | cfg!(feature = "bar");
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:40:10 --> $DIR/mix.rs:44:10
| |
LL | cfg!(feature = "zebra"); LL | cfg!(feature = "zebra");
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:42:10 --> $DIR/mix.rs:46:10
| |
LL | cfg!(xxx = "foo"); LL | cfg!(xxx = "foo");
| ^^^^^^^^^^^ | ^^^^^^^^^^^
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:44:10 --> $DIR/mix.rs:48:10
| |
LL | cfg!(xxx); LL | cfg!(xxx);
| ^^^ | ^^^
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:46:14 --> $DIR/mix.rs:50:14
| |
LL | cfg!(any(xxx, windows)); LL | cfg!(any(xxx, windows));
| ^^^ | ^^^
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:48:14 --> $DIR/mix.rs:52:14
| |
LL | cfg!(any(feature = "bad", windows)); LL | cfg!(any(feature = "bad", windows));
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:50:23 --> $DIR/mix.rs:54:23
| |
LL | cfg!(any(windows, xxx)); LL | cfg!(any(windows, xxx));
| ^^^ | ^^^
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:52:20 --> $DIR/mix.rs:56:20
| |
LL | cfg!(all(unix, xxx)); LL | cfg!(all(unix, xxx));
| ^^^ | ^^^
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:54:14 --> $DIR/mix.rs:58:14
| |
LL | cfg!(all(aa, bb)); LL | cfg!(all(aa, bb));
| ^^ | ^^
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:54:18 --> $DIR/mix.rs:58:18
| |
LL | cfg!(all(aa, bb)); LL | cfg!(all(aa, bb));
| ^^ | ^^
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:57:14 --> $DIR/mix.rs:61:14
| |
LL | cfg!(any(aa, bb)); LL | cfg!(any(aa, bb));
| ^^ | ^^
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:57:18 --> $DIR/mix.rs:61:18
| |
LL | cfg!(any(aa, bb)); LL | cfg!(any(aa, bb));
| ^^ | ^^
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:60:20 --> $DIR/mix.rs:64:20
| |
LL | cfg!(any(unix, feature = "zebra")); LL | cfg!(any(unix, feature = "zebra"));
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:62:14 --> $DIR/mix.rs:66:14
| |
LL | cfg!(any(xxx, feature = "zebra")); LL | cfg!(any(xxx, feature = "zebra"));
| ^^^ | ^^^
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:62:19 --> $DIR/mix.rs:66:19
| |
LL | cfg!(any(xxx, feature = "zebra")); LL | cfg!(any(xxx, feature = "zebra"));
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:65:14 --> $DIR/mix.rs:69:14
| |
LL | cfg!(any(xxx, unix, xxx)); LL | cfg!(any(xxx, unix, xxx));
| ^^^ | ^^^
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/mix.rs:65:25 --> $DIR/mix.rs:69:25
| |
LL | cfg!(any(xxx, unix, xxx)); LL | cfg!(any(xxx, unix, xxx));
| ^^^ | ^^^
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:68:14 --> $DIR/mix.rs:72:14
| |
LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:68:33 --> $DIR/mix.rs:72:33
| |
LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/mix.rs:68:52 --> $DIR/mix.rs:72:52
| |
LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra"));
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= note: expected values for `feature` are: foo = note: expected values for `feature` are: `foo`
warning: 27 warnings emitted warning: 28 warnings emitted

View file

@ -2,7 +2,9 @@ warning: unexpected `cfg` condition value
--> $DIR/no-values.rs:6:7 --> $DIR/no-values.rs:6:7
| |
LL | #[cfg(feature = "foo")] LL | #[cfg(feature = "foo")]
| ^^^^^^^^^^^^^^^ | ^^^^^^^--------
| |
| help: remove the value
| |
= note: no expected value for `feature` = note: no expected value for `feature`
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default

View file

@ -4,9 +4,9 @@ warning: unexpected `cfg` condition value
LL | #[cfg(target_os = "linuz")] LL | #[cfg(target_os = "linuz")]
| ^^^^^^^^^^^^------- | ^^^^^^^^^^^^-------
| | | |
| help: did you mean: `"linux"` | help: there is a expected value with a similar name: `"linux"`
| |
= note: expected values for `target_os` are: aix, android, cuda, dragonfly, emscripten, ericos, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vita, vxworks, wasi, watchos, windows, xous = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `ericos`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default
warning: 1 warning emitted warning: 1 warning emitted

View file

@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name
LL | #[cfg(target_oz = "linux")] LL | #[cfg(target_oz = "linux")]
| ---------^^^^^^^^^^ | ---------^^^^^^^^^^
| | | |
| help: did you mean: `target_os` | help: there is a config with a similar name: `target_os`
| |
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default
@ -14,13 +14,13 @@ warning: unexpected `cfg` condition name
LL | #[cfg(features = "foo")] LL | #[cfg(features = "foo")]
| --------^^^^^^^^ | --------^^^^^^^^
| | | |
| help: did you mean: `feature` | help: there is a config with a similar name: `feature`
warning: unexpected `cfg` condition name warning: unexpected `cfg` condition name
--> $DIR/well-known-names.rs:20:7 --> $DIR/well-known-names.rs:20:7
| |
LL | #[cfg(uniw)] LL | #[cfg(uniw)]
| ^^^^ help: did you mean: `unix` | ^^^^ help: there is a config with a similar name: `unix`
warning: 3 warnings emitted warning: 3 warnings emitted

View file

@ -4,9 +4,9 @@ warning: unexpected `cfg` condition value
LL | #[cfg(target_os = "linuz")] LL | #[cfg(target_os = "linuz")]
| ^^^^^^^^^^^^------- | ^^^^^^^^^^^^-------
| | | |
| help: did you mean: `"linux"` | help: there is a expected value with a similar name: `"linux"`
| |
= note: expected values for `target_os` are: aix, android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vita, vxworks, wasi, watchos, windows, xous = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
= note: `#[warn(unexpected_cfgs)]` on by default = note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
@ -15,9 +15,9 @@ warning: unexpected `cfg` condition value
LL | #[cfg(target_has_atomic = "0")] LL | #[cfg(target_has_atomic = "0")]
| ^^^^^^^^^^^^^^^^^^^^--- | ^^^^^^^^^^^^^^^^^^^^---
| | | |
| help: did you mean: `"8"` | help: there is a expected value with a similar name: `"8"`
| |
= note: expected values for `target_has_atomic` are: 128, 16, 32, 64, 8, ptr = note: expected values for `target_has_atomic` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr`
warning: unexpected `cfg` condition value warning: unexpected `cfg` condition value
--> $DIR/well-known-values.rs:21:7 --> $DIR/well-known-values.rs:21:7