diff options
Diffstat (limited to 'compiler/rustc_session')
| -rw-r--r-- | compiler/rustc_session/src/config.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_session/src/config/cfg.rs | 65 | ||||
| -rw-r--r-- | compiler/rustc_session/src/parse.rs | 12 |
3 files changed, 80 insertions, 2 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a60af3f2d71..20c14a98502 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1304,7 +1304,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 4109ebb6d34..a64b1e21e9e 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -17,12 +17,16 @@ //! - Add the activation logic in [`default_configuration`] //! - Add the cfg to [`CheckCfg::fill_well_known`] (and related files), //! so that the compiler can know the cfg is expected +//! - Add the cfg in [`disallow_cfgs`] to disallow users from setting it via `--cfg` //! - Add the feature gating in `compiler/rustc_feature/src/builtin_attrs.rs` use std::hash::Hash; use std::iter; +use rustc_ast::ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; +use rustc_lint_defs::builtin::EXPLICIT_BUILTIN_CFGS_IN_FLAGS; +use rustc_lint_defs::BuiltinLintDiag; use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::Align; use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, Target, TargetTriple, TARGETS}; @@ -82,6 +86,67 @@ impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> { } } +/// Disallow builtin cfgs from the CLI. +pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) { + let disallow = |cfg: &(Symbol, Option<Symbol>), 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.psess.opt_span_buffer_lint( + EXPLICIT_BUILTIN_CFGS_IN_FLAGS, + None, + ast::CRATE_NODE_ID, + BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }, + ) + }; + + // We want to restrict setting builtin cfgs that will produce incoherent behavior + // between the cfg and the rustc cli flag that sets it. + // + // The tests are in tests/ui/cfg/disallowed-cli-cfgs.rs. + + // By-default all builtin cfgs are disallowed, only those are allowed: + // - test: as it makes sense to the have the `test` cfg active without the builtin + // test harness. See Cargo `harness = false` config. + // + // Cargo `--cfg test`: https://github.com/rust-lang/cargo/blob/bc89bffa5987d4af8f71011c7557119b39e44a65/src/cargo/core/compiler/mod.rs#L1124 + + for cfg in user_cfgs { + match cfg { + (sym::overflow_checks, None) => disallow(cfg, "-C overflow-checks"), + (sym::debug_assertions, None) => disallow(cfg, "-C debug-assertions"), + (sym::ub_checks, None) => disallow(cfg, "-Z ub-checks"), + (sym::sanitize, None | Some(_)) => disallow(cfg, "-Z sanitizer"), + ( + sym::sanitizer_cfi_generalize_pointers | sym::sanitizer_cfi_normalize_integers, + None | Some(_), + ) => disallow(cfg, "-Z sanitizer=cfi"), + (sym::proc_macro, None) => disallow(cfg, "--crate-type proc-macro"), + (sym::panic, Some(sym::abort | 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"), + _ => {} + } + } +} + /// Generate the default configs for a given session pub(crate) fn default_configuration(sess: &Session) -> Cfg { let mut ret = Cfg::default(); diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index ebd5021dae1..d6c58e9d1be 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -307,9 +307,19 @@ impl ParseSess { node_id: NodeId, diagnostic: BuiltinLintDiag, ) { + self.opt_span_buffer_lint(lint, Some(span.into()), node_id, diagnostic) + } + + pub fn opt_span_buffer_lint( + &self, + lint: &'static Lint, + span: Option<MultiSpan>, + node_id: NodeId, + diagnostic: BuiltinLintDiag, + ) { self.buffered_lints.with_lock(|buffered_lints| { buffered_lints.push(BufferedEarlyLint { - span: span.into(), + span, node_id, lint_id: LintId::of(lint), diagnostic, |
