diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index b8dacc6968d30..1fdc42fbc02e7 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -14,6 +14,10 @@ session_crate_name_empty = crate name must not be empty session_crate_name_invalid = crate names cannot start with a `-`, but `{$s}` has a leading hyphen +session_disallow_cli_cfg = unexpected `--cfg {$cfg}` flag + .controlled_by = config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}` + .issue = see for more information + session_expr_parentheses_needed = parentheses are required to parse this as an expression session_failed_to_create_profiler = failed to create profiler: {$err} diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a622f1b577df4..3ebe8ad2b2873 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1292,7 +1292,10 @@ pub(crate) const fn default_lib_output() -> CrateType { } pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg { - // Combine the configuration requested by the session (command line) with + // First disallow some configuration given on the command line + cfg::disallow_cfgs(sess, &user_cfg); + + // Then combine the configuration requested by the session (command line) with // some default and generated configuration items. user_cfg.extend(cfg::default_configuration(sess)); user_cfg diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index 2fa04bbe345e8..5100b30c9a030 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -26,6 +26,7 @@ use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet}; use rustc_target::spec::{Target, TargetTriple, TARGETS}; use crate::config::CrateType; +use crate::errors::DisallowConfig; use crate::Session; use std::hash::Hash; @@ -379,3 +380,54 @@ impl CheckCfg { ins!(sym::windows, no_values); } } + +pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) { + let disallow = |cfg: &(Symbol, Option), controlled_by| { + let cfg_name = cfg.0; + let cfg = if let Some(value) = cfg.1 { + format!(r#"{}="{}""#, cfg_name, value) + } else { + format!("{}", cfg_name) + }; + sess.dcx().emit_fatal(DisallowConfig { cfg, cfg_name, controlled_by }) + }; + + // We want to restrict setting cfgs that will produce "incoherent" behavior between + // the cfg and the "real" flag that sets it, but not all cfgs produce incoherent + // behavior, we therefore exclude those cfgs: + // + // - test + // - clippy + // - doc + // - doctest + // - miri + // - rustfmt + // - overflow_checks + // - debug_assertions + // - ub_checks + + for cfg in user_cfgs { + match cfg { + (sym::proc_macro, None) => disallow(cfg, "--crate-type proc-macro"), + (sym::panic, Some(sym::abort)) => disallow(cfg, "-C panic"), + (sym::panic, Some(sym::unwind)) => disallow(cfg, "-C panic"), + (sym::target_feature, Some(_)) => disallow(cfg, "-C target-feature"), + (sym::unix, None) + | (sym::windows, None) + | (sym::relocation_model, Some(_)) + | (sym::target_abi, None | Some(_)) + | (sym::target_arch, Some(_)) + | (sym::target_endian, Some(_)) + | (sym::target_env, None | Some(_)) + | (sym::target_family, Some(_)) + | (sym::target_os, Some(_)) + | (sym::target_pointer_width, Some(_)) + | (sym::target_vendor, None | Some(_)) + | (sym::target_has_atomic, Some(_)) + | (sym::target_has_atomic_equal_alignment, Some(_)) + | (sym::target_has_atomic_load_store, Some(_)) + | (sym::target_thread_local, None) => disallow(cfg, "--target"), + _ => {} + } + } +} diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index dce56382a53a0..758fa77a11ddd 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -472,3 +472,13 @@ pub(crate) struct FunctionReturnThunkExternRequiresNonLargeCodeModel; pub(crate) struct FailedToCreateProfiler { pub(crate) err: String, } + +#[derive(Diagnostic)] +#[diag(session_disallow_cli_cfg)] +#[note(session_controlled_by)] +#[note(session_issue)] +pub(crate) struct DisallowConfig { + pub(crate) cfg: String, + pub(crate) cfg_name: Symbol, + pub(crate) controlled_by: &'static str, +} diff --git a/tests/ui/cfg/disallowed-cli-cfgs.debug_assertions.stderr b/tests/ui/cfg/disallowed-cli-cfgs.debug_assertions.stderr new file mode 100644 index 0000000000000..91ddcb2f31ce8 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.debug_assertions.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg debug_assertions` flag + | + = note: config `debug_assertions` is only supposed to be controlled by `-C debug_assertions` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.panic.stderr b/tests/ui/cfg/disallowed-cli-cfgs.panic.stderr new file mode 100644 index 0000000000000..71d010b157003 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.panic.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg panic="abort"` flag + | + = note: config `panic` is only supposed to be controlled by `-C panic` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.proc_macro.stderr b/tests/ui/cfg/disallowed-cli-cfgs.proc_macro.stderr new file mode 100644 index 0000000000000..23022da03892e --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.proc_macro.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg proc_macro` flag + | + = note: config `proc_macro` is only supposed to be controlled by `--crate-type proc-macro` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.relocation_model.stderr b/tests/ui/cfg/disallowed-cli-cfgs.relocation_model.stderr new file mode 100644 index 0000000000000..a1c79d65299cd --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.relocation_model.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg relocation_model="a"` flag + | + = note: config `relocation_model` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.rs b/tests/ui/cfg/disallowed-cli-cfgs.rs new file mode 100644 index 0000000000000..73fbabc8dee77 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.rs @@ -0,0 +1,27 @@ +//@ check-fail +//@ revisions: proc_macro panic target_feature unix windows target_abi +//@ revisions: target_arch target_endian target_env target_family target_os target_pointer_width +//@ revisions: target_vendor target_has_atomic target_has_atomic_equal_alignment +//@ revisions: target_has_atomic_load_store target_thread_local relocation_model + +//@ [proc_macro]compile-flags: --cfg proc_macro +//@ [panic]compile-flags: --cfg panic="abort" +//@ [target_feature]compile-flags: --cfg target_feature="sse3" +//@ [unix]compile-flags: --cfg unix +//@ [windows]compile-flags: --cfg windows +//@ [target_abi]compile-flags: --cfg target_abi="gnu" +//@ [target_arch]compile-flags: --cfg target_arch="arm" +//@ [target_endian]compile-flags: --cfg target_endian="little" +//@ [target_env]compile-flags: --cfg target_env +//@ [target_family]compile-flags: --cfg target_family="unix" +//@ [target_os]compile-flags: --cfg target_os="linux" +//@ [target_pointer_width]compile-flags: --cfg target_pointer_width="32" +//@ [target_vendor]compile-flags: --cfg target_vendor +//@ [target_has_atomic]compile-flags: --cfg target_has_atomic="32" +//@ [target_has_atomic_equal_alignment]compile-flags: --cfg target_has_atomic_equal_alignment="32" +//@ [target_has_atomic_load_store]compile-flags: --cfg target_has_atomic_load_store="32" +//@ [target_thread_local]compile-flags: --cfg target_thread_local +//@ [relocation_model]compile-flags: --cfg relocation_model="a" + + +fn main() {} diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_abi.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_abi.stderr new file mode 100644 index 0000000000000..87d0249dc239d --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_abi.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_abi` flag + | + = note: config `target_abi` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_arch.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_arch.stderr new file mode 100644 index 0000000000000..c04e38715ca84 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_arch.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_arch="arm"` flag + | + = note: config `target_arch` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_endian.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_endian.stderr new file mode 100644 index 0000000000000..e0b0a7b4812ac --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_endian.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_endian="little"` flag + | + = note: config `target_endian` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_env.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_env.stderr new file mode 100644 index 0000000000000..ff7cbd55432a1 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_env.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_env` flag + | + = note: config `target_env` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_family.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_family.stderr new file mode 100644 index 0000000000000..3d469c17a38d7 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_family.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_family="unix"` flag + | + = note: config `target_family` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_feature.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_feature.stderr new file mode 100644 index 0000000000000..e691c3502b86e --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_feature.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_feature="sse3"` flag + | + = note: config `target_feature` is only supposed to be controlled by `-C target-feature` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic.stderr new file mode 100644 index 0000000000000..9ced89af47dd9 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_has_atomic="32"` flag + | + = note: config `target_has_atomic` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic_equal_alignment.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic_equal_alignment.stderr new file mode 100644 index 0000000000000..99673aca7566d --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic_equal_alignment.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_has_atomic_equal_alignment="32"` flag + | + = note: config `target_has_atomic_equal_alignment` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic_load_store.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic_load_store.stderr new file mode 100644 index 0000000000000..1b50065c2a5ff --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic_load_store.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_has_atomic_load_store="32"` flag + | + = note: config `target_has_atomic_load_store` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_os.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_os.stderr new file mode 100644 index 0000000000000..348cc553cec1c --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_os.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_os="linux"` flag + | + = note: config `target_os` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_pointer_width.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_pointer_width.stderr new file mode 100644 index 0000000000000..0608b03c27bcd --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_pointer_width.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_pointer_width="32"` flag + | + = note: config `target_pointer_width` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_thread_local.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_thread_local.stderr new file mode 100644 index 0000000000000..375ca43975ab2 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_thread_local.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_thread_local` flag + | + = note: config `target_thread_local` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.target_vendor.stderr b/tests/ui/cfg/disallowed-cli-cfgs.target_vendor.stderr new file mode 100644 index 0000000000000..79b7eabf921dc --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.target_vendor.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg target_vendor` flag + | + = note: config `target_vendor` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.test.stderr b/tests/ui/cfg/disallowed-cli-cfgs.test.stderr new file mode 100644 index 0000000000000..0080fc7a8c54c --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.test.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg test` flag + | + = note: config `test` is only supposed to be controlled by `--test` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.unix.stderr b/tests/ui/cfg/disallowed-cli-cfgs.unix.stderr new file mode 100644 index 0000000000000..a492e8699e553 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.unix.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg unix` flag + | + = note: config `unix` is only supposed to be controlled by `--target` + = note: see for more information + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.windows.stderr b/tests/ui/cfg/disallowed-cli-cfgs.windows.stderr new file mode 100644 index 0000000000000..8342348606dfa --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.windows.stderr @@ -0,0 +1,5 @@ +error: unexpected `--cfg windows` flag + | + = note: config `windows` is only supposed to be controlled by `--target` + = note: see for more information +