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:
commit
ded0a9e15f
19 changed files with 421 additions and 237 deletions
|
@ -5,6 +5,7 @@ use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedM
|
|||
use rustc_ast_pretty::pprust;
|
||||
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_session::config::ExpectedValues;
|
||||
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
|
||||
use rustc_session::lint::BuiltinLintDiagnostics;
|
||||
use rustc_session::parse::{feature_err, ParseSess};
|
||||
|
@ -581,32 +582,32 @@ pub fn cfg_matches(
|
|||
) -> bool {
|
||||
eval_condition(cfg, sess, features, &mut |cfg| {
|
||||
try_gate_cfg(cfg.name, cfg.span, sess, features);
|
||||
if let Some(names_valid) = &sess.check_config.names_valid {
|
||||
if !names_valid.contains(&cfg.name) {
|
||||
match sess.check_config.expecteds.get(&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(
|
||||
UNEXPECTED_CFGS,
|
||||
cfg.span,
|
||||
lint_node_id,
|
||||
"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())),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
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)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => { /* not unexpected */ }
|
||||
}
|
||||
sess.config.contains(&(cfg.name, cfg.value))
|
||||
})
|
||||
|
|
|
@ -9,11 +9,12 @@ use rustc_data_structures::OnDrop;
|
|||
use rustc_errors::registry::Registry;
|
||||
use rustc_errors::{ErrorGuaranteed, Handler};
|
||||
use rustc_lint::LintStore;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::{bug, ty};
|
||||
use rustc_parse::maybe_new_parser_from_source_str;
|
||||
use rustc_query_impl::QueryCtxt;
|
||||
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::parse::{CrateConfig, ParseSess};
|
||||
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`.
|
||||
pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
|
||||
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!(
|
||||
"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, ")"),
|
||||
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()) {
|
||||
Ok(mut parser) => match parser.parse_meta_item() {
|
||||
Ok(meta_item) if parser.token == token::Eof => {
|
||||
if let Some(args) = meta_item.meta_item_list() {
|
||||
if meta_item.has_name(sym::names) {
|
||||
let names_valid =
|
||||
cfg.names_valid.get_or_insert_with(|| FxHashSet::default());
|
||||
check_cfg.exhaustive_names = true;
|
||||
for arg in args {
|
||||
if arg.is_word() && arg.ident().is_some() {
|
||||
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 {
|
||||
error!("`names()` arguments must be simple identifiers");
|
||||
}
|
||||
}
|
||||
continue 'specs;
|
||||
} else if meta_item.has_name(sym::values) {
|
||||
if let Some((name, values)) = args.split_first() {
|
||||
if name.is_word() && name.ident().is_some() {
|
||||
let ident = name.ident().expect("multi-segment cfg key");
|
||||
let ident_values = cfg
|
||||
.values_valid
|
||||
let expected_values = check_cfg
|
||||
.expecteds
|
||||
.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 {
|
||||
if let Some(LitKind::Str(s, _)) =
|
||||
val.lit().map(|lit| &lit.kind)
|
||||
{
|
||||
ident_values.insert(s.to_string());
|
||||
expected_values.insert(Some(s.to_string()));
|
||||
} else {
|
||||
error!(
|
||||
"`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 {
|
||||
error!(
|
||||
"`values()` first argument must be a simple identifier"
|
||||
);
|
||||
}
|
||||
} else if args.is_empty() {
|
||||
cfg.well_known_values = true;
|
||||
continue 'specs;
|
||||
check_cfg.exhaustive_values = true;
|
||||
} else {
|
||||
expected_error();
|
||||
}
|
||||
} else {
|
||||
expected_error();
|
||||
}
|
||||
} else {
|
||||
expected_error();
|
||||
}
|
||||
}
|
||||
Ok(..) => {}
|
||||
Err(err) => err.cancel(),
|
||||
Ok(..) => expected_error(),
|
||||
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 {
|
||||
names_valid.extend(cfg.values_valid.keys().cloned());
|
||||
}
|
||||
cfg
|
||||
check_cfg
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOf};
|
|||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef};
|
||||
use rustc_session::config::ExpectedValues;
|
||||
use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
@ -3306,16 +3307,15 @@ impl EarlyLintPass for UnexpectedCfgs {
|
|||
let cfg = &cx.sess().parse_sess.config;
|
||||
let check_cfg = &cx.sess().parse_sess.check_config;
|
||||
for &(name, value) in cfg {
|
||||
if let Some(names_valid) = &check_cfg.names_valid && !names_valid.contains(&name){
|
||||
cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigName {
|
||||
name,
|
||||
});
|
||||
}
|
||||
if let Some(value) = value && let Some(values) = check_cfg.values_valid.get(&name) && !values.contains(&value) {
|
||||
cx.emit_lint(
|
||||
UNEXPECTED_CFGS,
|
||||
BuiltinUnexpectedCliConfigValue { name, value },
|
||||
);
|
||||
match check_cfg.expecteds.get(&name) {
|
||||
Some(ExpectedValues::Some(values)) if !values.contains(&value) => {
|
||||
let value = value.unwrap_or(kw::Empty);
|
||||
cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigValue { name, value });
|
||||
}
|
||||
None if check_cfg.exhaustive_names => {
|
||||
cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigName { name });
|
||||
}
|
||||
_ => { /* expected */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ use rustc_middle::middle::stability;
|
|||
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
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::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
|
||||
use rustc_session::Session;
|
||||
|
@ -768,22 +769,52 @@ pub trait LintContext: Sized {
|
|||
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");
|
||||
},
|
||||
BuiltinLintDiagnostics::UnexpectedCfg((name, name_span), None) => {
|
||||
let Some(names_valid) = &sess.parse_sess.check_config.names_valid else {
|
||||
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();
|
||||
BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => {
|
||||
let possibilities: Vec<Symbol> = sess.parse_sess.check_config.expecteds.keys().map(|s| *s).collect();
|
||||
|
||||
// Suggest the most probable if we found one
|
||||
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))) => {
|
||||
let Some(values) = &sess.parse_sess.check_config.values_valid.get(&name) else {
|
||||
BuiltinLintDiagnostics::UnexpectedCfgValue((name, name_span), value) => {
|
||||
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");
|
||||
};
|
||||
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
|
||||
// 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<_>>();
|
||||
possibilities.sort();
|
||||
|
||||
let possibilities = possibilities.join(", ");
|
||||
db.note(format!("expected values for `{name}` are: {possibilities}"));
|
||||
let possibilities = possibilities.join("`, `");
|
||||
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(best_match) = find_best_match_for_name(&possibilities, value, None) {
|
||||
db.span_suggestion(value_span, "did you mean", format!("\"{best_match}\""), Applicability::MaybeIncorrect);
|
||||
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) {
|
||||
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}`"));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -496,7 +496,8 @@ pub enum BuiltinLintDiagnostics {
|
|||
BreakWithLabelAndLoop(Span),
|
||||
NamedAsmLabel(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),
|
||||
SingleUseLifetime {
|
||||
/// Span of the parameter which declares this lifetime.
|
||||
|
|
|
@ -1064,37 +1064,76 @@ pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig
|
|||
|
||||
/// The parsed `--check-cfg` options
|
||||
pub struct CheckCfg<T = String> {
|
||||
/// The set of all `names()`, if None no name checking is performed
|
||||
pub names_valid: Option<FxHashSet<T>>,
|
||||
/// Is well known names activated
|
||||
pub exhaustive_names: bool,
|
||||
/// Is well known values activated
|
||||
pub well_known_values: bool,
|
||||
/// The set of all `values()`
|
||||
pub values_valid: FxHashMap<T, FxHashSet<T>>,
|
||||
pub exhaustive_values: bool,
|
||||
/// All the expected values for a config name
|
||||
pub expecteds: FxHashMap<T, ExpectedValues<T>>,
|
||||
}
|
||||
|
||||
impl<T> Default for CheckCfg<T> {
|
||||
fn default() -> Self {
|
||||
CheckCfg {
|
||||
names_valid: Default::default(),
|
||||
values_valid: Default::default(),
|
||||
well_known_values: false,
|
||||
exhaustive_names: false,
|
||||
exhaustive_values: false,
|
||||
expecteds: FxHashMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
names_valid: self
|
||||
.names_valid
|
||||
.as_ref()
|
||||
.map(|names_valid| names_valid.iter().map(|a| f(a)).collect()),
|
||||
values_valid: self
|
||||
.values_valid
|
||||
.iter()
|
||||
.map(|(a, b)| (f(a), b.iter().map(|b| f(b)).collect()))
|
||||
exhaustive_names: self.exhaustive_names,
|
||||
exhaustive_values: self.exhaustive_values,
|
||||
expecteds: self
|
||||
.expecteds
|
||||
.into_iter()
|
||||
.map(|(name, values)| {
|
||||
(
|
||||
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(),
|
||||
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,
|
||||
/// 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 {
|
||||
cfg.map_data(|s| Symbol::intern(s))
|
||||
cfg.map_data(|s| Symbol::intern(&s))
|
||||
}
|
||||
|
||||
impl CrateCheckConfig {
|
||||
/// Fills a `CrateCheckConfig` with well-known configuration names.
|
||||
fn fill_well_known_names(&mut self) {
|
||||
// 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 {
|
||||
pub fn fill_well_known(&mut self, current_target: &Target) {
|
||||
if !self.exhaustive_values && !self.exhaustive_names {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: This should be kept in sync with `default_configuration` and
|
||||
// `fill_well_known_names`
|
||||
let no_values = || {
|
||||
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();
|
||||
|
||||
|
@ -1174,6 +1182,9 @@ impl CrateCheckConfig {
|
|||
// Unknown possible values:
|
||||
// - `feature`
|
||||
// - `target_feature`
|
||||
for name in [sym::feature, sym::target_feature] {
|
||||
self.expecteds.entry(name).or_insert(ExpectedValues::Any);
|
||||
}
|
||||
|
||||
// No-values
|
||||
for name in [
|
||||
|
@ -1187,20 +1198,23 @@ impl CrateCheckConfig {
|
|||
sym::debug_assertions,
|
||||
sym::target_thread_local,
|
||||
] {
|
||||
self.values_valid.entry(name).or_default();
|
||||
self.expecteds.entry(name).or_insert_with(no_values);
|
||||
}
|
||||
|
||||
// Pre-defined values
|
||||
self.values_valid.entry(sym::panic).or_default().extend(panic_values);
|
||||
self.values_valid.entry(sym::sanitize).or_default().extend(sanitize_values);
|
||||
self.values_valid.entry(sym::target_has_atomic).or_default().extend(atomic_values);
|
||||
self.values_valid
|
||||
.entry(sym::target_has_atomic_load_store)
|
||||
.or_default()
|
||||
self.expecteds.entry(sym::panic).or_insert_with(empty_values).extend(panic_values);
|
||||
self.expecteds.entry(sym::sanitize).or_insert_with(empty_values).extend(sanitize_values);
|
||||
self.expecteds
|
||||
.entry(sym::target_has_atomic)
|
||||
.or_insert_with(no_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)
|
||||
.or_default()
|
||||
.or_insert_with(no_values)
|
||||
.extend(atomic_values);
|
||||
|
||||
// Target specific values
|
||||
|
@ -1218,47 +1232,50 @@ impl CrateCheckConfig {
|
|||
|
||||
// Initialize (if not already initialized)
|
||||
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.
|
||||
// (8 values * 220 targets ~= 1760 times, at the time of writing this comment).
|
||||
let [
|
||||
values_target_os,
|
||||
values_target_family,
|
||||
values_target_arch,
|
||||
values_target_endian,
|
||||
values_target_env,
|
||||
values_target_abi,
|
||||
values_target_vendor,
|
||||
values_target_pointer_width,
|
||||
] = self
|
||||
.values_valid
|
||||
.get_many_mut(VALUES)
|
||||
.expect("unable to get all the check-cfg values buckets");
|
||||
if self.exhaustive_values {
|
||||
// Get all values map at once otherwise it would be costly.
|
||||
// (8 values * 220 targets ~= 1760 times, at the time of writing this comment).
|
||||
let [
|
||||
values_target_os,
|
||||
values_target_family,
|
||||
values_target_arch,
|
||||
values_target_endian,
|
||||
values_target_env,
|
||||
values_target_abi,
|
||||
values_target_vendor,
|
||||
values_target_pointer_width,
|
||||
] = self
|
||||
.expecteds
|
||||
.get_many_mut(VALUES)
|
||||
.expect("unable to get all the check-cfg values buckets");
|
||||
|
||||
for target in TARGETS
|
||||
.iter()
|
||||
.map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
|
||||
.chain(iter::once(current_target.clone()))
|
||||
{
|
||||
values_target_os.insert(Symbol::intern(&target.options.os));
|
||||
values_target_family
|
||||
.extend(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_env.insert(Symbol::intern(&target.options.env));
|
||||
values_target_abi.insert(Symbol::intern(&target.options.abi));
|
||||
values_target_vendor.insert(Symbol::intern(&target.options.vendor));
|
||||
values_target_pointer_width.insert(sym::integer(target.pointer_width));
|
||||
for target in TARGETS
|
||||
.iter()
|
||||
.map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
|
||||
.chain(iter::once(current_target.clone()))
|
||||
{
|
||||
values_target_os.insert(Symbol::intern(&target.options.os));
|
||||
values_target_family.extend(
|
||||
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_env.insert(Symbol::intern(&target.options.env));
|
||||
values_target_abi.insert(Symbol::intern(&target.options.abi));
|
||||
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 {
|
||||
|
|
|
@ -2,7 +2,7 @@ warning: unexpected `cfg` condition name
|
|||
--> $DIR/check-cfg.rs:5:7
|
||||
|
|
||||
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
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value
|
|||
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
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
|
@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value
|
|||
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
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
31
tests/ui/check-cfg/diagnotics.rs
Normal file
31
tests/ui/check-cfg/diagnotics.rs
Normal 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() {}
|
62
tests/ui/check-cfg/diagnotics.stderr
Normal file
62
tests/ui/check-cfg/diagnotics.stderr
Normal 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
|
||||
|
|
@ -2,7 +2,7 @@ warning: unexpected `cfg` condition name
|
|||
--> $DIR/invalid-cfg-name.rs:7:7
|
||||
|
|
||||
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
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ warning: unexpected `cfg` condition value
|
|||
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
|
||||
|
||||
warning: unexpected `cfg` condition value
|
||||
|
@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value
|
|||
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`
|
||||
|
|
||||
|
|
|
@ -12,6 +12,10 @@ fn do_windows_stuff() {}
|
|||
//~^ WARNING unexpected `cfg` condition name
|
||||
fn do_windows_stuff() {}
|
||||
|
||||
#[cfg(feature)]
|
||||
//~^ WARNING unexpected `cfg` condition value
|
||||
fn no_feature() {}
|
||||
|
||||
#[cfg(feature = "foo")]
|
||||
fn use_foo() {}
|
||||
|
||||
|
|
|
@ -2,28 +2,36 @@ warning: unexpected `cfg` condition name
|
|||
--> $DIR/mix.rs:11:7
|
||||
|
|
||||
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
|
||||
|
||||
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
|
||||
--> $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")]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected values for `feature` are: foo
|
||||
= note: expected values for `feature` are: `foo`
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:26:12
|
||||
--> $DIR/mix.rs:30:12
|
||||
|
|
||||
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
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:35:10
|
||||
--> $DIR/mix.rs:39:10
|
||||
|
|
||||
LL | cfg!(widnows);
|
||||
| ^^^^^^^ help: did you mean: `windows`
|
||||
| ^^^^^^^ help: there is a config with a similar name: `windows`
|
||||
|
||||
warning: unexpected `cfg` condition value
|
||||
--> $DIR/mix.rs:38:10
|
||||
--> $DIR/mix.rs:42:10
|
||||
|
|
||||
LL | cfg!(feature = "bar");
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected values for `feature` are: foo
|
||||
= note: expected values for `feature` are: `foo`
|
||||
|
||||
warning: unexpected `cfg` condition value
|
||||
--> $DIR/mix.rs:40:10
|
||||
--> $DIR/mix.rs:44:10
|
||||
|
|
||||
LL | cfg!(feature = "zebra");
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected values for `feature` are: foo
|
||||
= note: expected values for `feature` are: `foo`
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:42:10
|
||||
--> $DIR/mix.rs:46:10
|
||||
|
|
||||
LL | cfg!(xxx = "foo");
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:44:10
|
||||
--> $DIR/mix.rs:48:10
|
||||
|
|
||||
LL | cfg!(xxx);
|
||||
| ^^^
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:46:14
|
||||
--> $DIR/mix.rs:50:14
|
||||
|
|
||||
LL | cfg!(any(xxx, windows));
|
||||
| ^^^
|
||||
|
||||
warning: unexpected `cfg` condition value
|
||||
--> $DIR/mix.rs:48:14
|
||||
--> $DIR/mix.rs:52:14
|
||||
|
|
||||
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
|
||||
--> $DIR/mix.rs:50:23
|
||||
--> $DIR/mix.rs:54:23
|
||||
|
|
||||
LL | cfg!(any(windows, xxx));
|
||||
| ^^^
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:52:20
|
||||
--> $DIR/mix.rs:56:20
|
||||
|
|
||||
LL | cfg!(all(unix, xxx));
|
||||
| ^^^
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:54:14
|
||||
--> $DIR/mix.rs:58:14
|
||||
|
|
||||
LL | cfg!(all(aa, bb));
|
||||
| ^^
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:54:18
|
||||
--> $DIR/mix.rs:58:18
|
||||
|
|
||||
LL | cfg!(all(aa, bb));
|
||||
| ^^
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:57:14
|
||||
--> $DIR/mix.rs:61:14
|
||||
|
|
||||
LL | cfg!(any(aa, bb));
|
||||
| ^^
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:57:18
|
||||
--> $DIR/mix.rs:61:18
|
||||
|
|
||||
LL | cfg!(any(aa, bb));
|
||||
| ^^
|
||||
|
||||
warning: unexpected `cfg` condition value
|
||||
--> $DIR/mix.rs:60:20
|
||||
--> $DIR/mix.rs:64:20
|
||||
|
|
||||
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
|
||||
--> $DIR/mix.rs:62:14
|
||||
--> $DIR/mix.rs:66:14
|
||||
|
|
||||
LL | cfg!(any(xxx, feature = "zebra"));
|
||||
| ^^^
|
||||
|
||||
warning: unexpected `cfg` condition value
|
||||
--> $DIR/mix.rs:62:19
|
||||
--> $DIR/mix.rs:66:19
|
||||
|
|
||||
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
|
||||
--> $DIR/mix.rs:65:14
|
||||
--> $DIR/mix.rs:69:14
|
||||
|
|
||||
LL | cfg!(any(xxx, unix, xxx));
|
||||
| ^^^
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/mix.rs:65:25
|
||||
--> $DIR/mix.rs:69:25
|
||||
|
|
||||
LL | cfg!(any(xxx, unix, xxx));
|
||||
| ^^^
|
||||
|
||||
warning: unexpected `cfg` condition value
|
||||
--> $DIR/mix.rs:68:14
|
||||
--> $DIR/mix.rs:72:14
|
||||
|
|
||||
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
|
||||
--> $DIR/mix.rs:68:33
|
||||
--> $DIR/mix.rs:72:33
|
||||
|
|
||||
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
|
||||
--> $DIR/mix.rs:68:52
|
||||
--> $DIR/mix.rs:72:52
|
||||
|
|
||||
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
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@ warning: unexpected `cfg` condition value
|
|||
--> $DIR/no-values.rs:6:7
|
||||
|
|
||||
LL | #[cfg(feature = "foo")]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^--------
|
||||
| |
|
||||
| help: remove the value
|
||||
|
|
||||
= note: no expected value for `feature`
|
||||
= note: `#[warn(unexpected_cfgs)]` on by default
|
||||
|
|
|
@ -4,9 +4,9 @@ warning: unexpected `cfg` condition value
|
|||
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
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
|
@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name
|
|||
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
|
||||
|
||||
|
@ -14,13 +14,13 @@ warning: unexpected `cfg` condition name
|
|||
LL | #[cfg(features = "foo")]
|
||||
| --------^^^^^^^^
|
||||
| |
|
||||
| help: did you mean: `feature`
|
||||
| help: there is a config with a similar name: `feature`
|
||||
|
||||
warning: unexpected `cfg` condition name
|
||||
--> $DIR/well-known-names.rs:20:7
|
||||
|
|
||||
LL | #[cfg(uniw)]
|
||||
| ^^^^ help: did you mean: `unix`
|
||||
| ^^^^ help: there is a config with a similar name: `unix`
|
||||
|
||||
warning: 3 warnings emitted
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ warning: unexpected `cfg` condition value
|
|||
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
|
||||
|
||||
warning: unexpected `cfg` condition value
|
||||
|
@ -15,9 +15,9 @@ warning: unexpected `cfg` condition value
|
|||
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
|
||||
--> $DIR/well-known-values.rs:21:7
|
||||
|
|
Loading…
Add table
Reference in a new issue