diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 27ad3e45366..7f9918e4f12 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -354,6 +354,12 @@ lint_builtin_unreachable_pub = unreachable `pub` {$what} .suggestion = consider restricting its visibility .help = or consider exporting it for use by other crates +lint_builtin_unexpected_cli_config_name = unexpected `{$name}` as condition name + .help = was set with `--cfg` but isn't in the `--check-cfg` expected names + +lint_builtin_unexpected_cli_config_value = unexpected condition value `{$value}` for condition name `{$name}` + .help = was set with `--cfg` but isn't in the `--check-cfg` expected values + lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 4e9c209a584..48942211eba 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -3250,3 +3250,39 @@ fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) { } } } + +pub use rustc_session::lint::builtin::UNEXPECTED_CFGS; + +declare_lint_pass!(UnexpectedCfgs => [UNEXPECTED_CFGS]); + +impl EarlyLintPass for UnexpectedCfgs { + fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { + 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 { + if !names_valid.contains(&name) { + cx.lookup(UNEXPECTED_CFGS, None::, |diag| { + diag.build(fluent::lint::builtin_unexpected_cli_config_name) + .help(fluent::lint::help) + .set_arg("name", name) + .emit(); + }); + } + } + if let Some(value) = value { + if let Some(values) = &check_cfg.values_valid.get(&name) { + if !values.contains(&value) { + cx.lookup(UNEXPECTED_CFGS, None::, |diag| { + diag.build(fluent::lint::builtin_unexpected_cli_config_value) + .help(fluent::lint::help) + .set_arg("name", name) + .set_arg("value", value) + .emit(); + }); + } + } + } + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 3478be1ed5d..e6cb90cdcca 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -144,6 +144,7 @@ macro_rules! early_lint_passes { IncompleteFeatures: IncompleteFeatures, RedundantSemicolons: RedundantSemicolons, UnusedDocComment: UnusedDocComment, + UnexpectedCfgs: UnexpectedCfgs, ] ); }; diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 845563338ea..ca01599acc8 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3365,7 +3365,6 @@ DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, DUPLICATE_MACRO_ATTRIBUTES, SUSPICIOUS_AUTO_TRAIT_IMPLS, - UNEXPECTED_CFGS, DEPRECATED_WHERE_CLAUSE_LOCATION, TEST_UNSTABLE_LINT, FFI_UNWIND_CALLS, diff --git a/src/test/ui/check-cfg/allow-at-crate-level.rs b/src/test/ui/check-cfg/allow-at-crate-level.rs new file mode 100644 index 00000000000..ce3383a2961 --- /dev/null +++ b/src/test/ui/check-cfg/allow-at-crate-level.rs @@ -0,0 +1,8 @@ +// This test check that #![allow(unexpected_cfgs)] works with --cfg +// +// check-pass +// compile-flags: --cfg=unexpected --check-cfg=names() -Z unstable-options + +#![allow(unexpected_cfgs)] + +fn main() {} diff --git a/src/test/ui/check-cfg/invalid-cfg-value.stderr b/src/test/ui/check-cfg/invalid-cfg-value.stderr index 6cce31d3392..7db2aadec17 100644 --- a/src/test/ui/check-cfg/invalid-cfg-value.stderr +++ b/src/test/ui/check-cfg/invalid-cfg-value.stderr @@ -15,5 +15,9 @@ LL | #[cfg(feature = "rand")] | = note: expected values for `feature` are: full, serde -warning: 2 warnings emitted +warning: unexpected condition value `rand` for condition name `feature` + | + = help: was set with `--cfg` but isn't in the `--check-cfg` expected values + +warning: 3 warnings emitted diff --git a/src/test/ui/check-cfg/mix.rs b/src/test/ui/check-cfg/mix.rs index 8e3d20d5045..4e488fc03ec 100644 --- a/src/test/ui/check-cfg/mix.rs +++ b/src/test/ui/check-cfg/mix.rs @@ -3,7 +3,7 @@ // we correctly lint on the `cfg!` macro and `cfg_attr` attribute. // // check-pass -// compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") --cfg feature="bar" -Z unstable-options +// compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") --cfg feature="bar" --cfg unknown_name -Z unstable-options #[cfg(windows)] fn do_windows_stuff() {} diff --git a/src/test/ui/check-cfg/mix.stderr b/src/test/ui/check-cfg/mix.stderr index e51b75b3d43..9cf887ec788 100644 --- a/src/test/ui/check-cfg/mix.stderr +++ b/src/test/ui/check-cfg/mix.stderr @@ -28,6 +28,14 @@ warning: unexpected `cfg` condition name LL | #[cfg_attr(uu, test)] | ^^ +warning: unexpected condition value `bar` for condition name `feature` + | + = help: was set with `--cfg` but isn't in the `--check-cfg` expected values + +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 | @@ -170,5 +178,5 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | = note: expected values for `feature` are: foo -warning: 25 warnings emitted +warning: 27 warnings emitted