|
17 | 17 | //! - Add the activation logic in [`default_configuration`]
|
18 | 18 | //! - Add the cfg to [`CheckCfg::fill_well_known`] (and related files),
|
19 | 19 | //! so that the compiler can know the cfg is expected
|
| 20 | +//! - Add the cfg in [`disallow_cfgs`] to disallow users from setting it via `--cfg` |
20 | 21 | //! - Add the feature gating in `compiler/rustc_feature/src/builtin_attrs.rs`
|
21 | 22 |
|
| 23 | +use rustc_ast::ast; |
22 | 24 | use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
| 25 | +use rustc_lint_defs::builtin::UNEXPECTED_BUILTIN_CFGS; |
| 26 | +use rustc_lint_defs::BuiltinLintDiag; |
23 | 27 | use rustc_span::symbol::{sym, Symbol};
|
24 | 28 | use rustc_target::abi::Align;
|
25 | 29 | use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet};
|
@@ -83,6 +87,76 @@ impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
|
83 | 87 | }
|
84 | 88 | }
|
85 | 89 |
|
| 90 | +/// Disallow "builtin" cfgs from the CLI as they produce incoherent behavior |
| 91 | +pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) { |
| 92 | + let disallow = |cfg: &(Symbol, Option<Symbol>), controlled_by| { |
| 93 | + let cfg_name = cfg.0; |
| 94 | + let cfg = if let Some(value) = cfg.1 { |
| 95 | + format!(r#"{}="{}""#, cfg_name, value) |
| 96 | + } else { |
| 97 | + format!("{}", cfg_name) |
| 98 | + }; |
| 99 | + sess.psess.opt_span_buffer_lint( |
| 100 | + UNEXPECTED_BUILTIN_CFGS, |
| 101 | + None, |
| 102 | + ast::CRATE_NODE_ID, |
| 103 | + BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }, |
| 104 | + ) |
| 105 | + }; |
| 106 | + |
| 107 | + // We want to restrict setting cfgs that will produce "incoherent" behavior between |
| 108 | + // the cfg and the "real" flag that sets it. |
| 109 | + // |
| 110 | + // The tests are in tests/ui/cfg/disallowed-cli-cfgs.rs. |
| 111 | + // |
| 112 | + // Not all "well known cfgs" can be disallowed, as they are set by external tools via the |
| 113 | + // CLI, we therefore don't lint on them: |
| 114 | + // |
| 115 | + // - test |
| 116 | + // - clippy |
| 117 | + // - doc |
| 118 | + // - doctest |
| 119 | + // - miri |
| 120 | + // - rustfmt |
| 121 | + // |
| 122 | + // test: https://github.com/rust-lang/cargo/blob/bc89bffa5987d4af8f71011c7557119b39e44a65/src/cargo/core/compiler/mod.rs#L1124 |
| 123 | + // doc/doctest: https://github.com/rust-lang/rust/blob/d03d6c0fead582c98c6446ec92456ca8fd03ff65/src/librustdoc/doctest.rs#L134-L135 |
| 124 | + // clippy: https://github.com/rust-lang/rust/blob/f1b0d54ca9a5ea43950c279985a6e12dcf387de8/src/tools/clippy/src/driver.rs#L276 |
| 125 | + // miri: https://github.com/rust-lang/rust/blob/d03d6c0fead582c98c6446ec92456ca8fd03ff65/src/tools/miri/src/lib.rs#L161 |
| 126 | + |
| 127 | + for cfg in user_cfgs { |
| 128 | + match cfg { |
| 129 | + (sym::overflow_checks, None) => disallow(cfg, "-C overflow-checks"), |
| 130 | + (sym::debug_assertions, None) => disallow(cfg, "-C debug-assertions"), |
| 131 | + (sym::ub_checks, None) => disallow(cfg, "-Z ub-checks"), |
| 132 | + (sym::sanitize, None | Some(_)) => disallow(cfg, "-Z sanitizer"), |
| 133 | + ( |
| 134 | + sym::sanitizer_cfi_generalize_pointers | sym::sanitizer_cfi_normalize_integers, |
| 135 | + None | Some(_), |
| 136 | + ) => disallow(cfg, "-Z sanitizer=cfi"), |
| 137 | + (sym::proc_macro, None) => disallow(cfg, "--crate-type proc-macro"), |
| 138 | + (sym::panic, Some(sym::abort | sym::unwind)) => disallow(cfg, "-C panic"), |
| 139 | + (sym::target_feature, Some(_)) => disallow(cfg, "-C target-feature"), |
| 140 | + (sym::unix, None) |
| 141 | + | (sym::windows, None) |
| 142 | + | (sym::relocation_model, Some(_)) |
| 143 | + | (sym::target_abi, None | Some(_)) |
| 144 | + | (sym::target_arch, Some(_)) |
| 145 | + | (sym::target_endian, Some(_)) |
| 146 | + | (sym::target_env, None | Some(_)) |
| 147 | + | (sym::target_family, Some(_)) |
| 148 | + | (sym::target_os, Some(_)) |
| 149 | + | (sym::target_pointer_width, Some(_)) |
| 150 | + | (sym::target_vendor, None | Some(_)) |
| 151 | + | (sym::target_has_atomic, Some(_)) |
| 152 | + | (sym::target_has_atomic_equal_alignment, Some(_)) |
| 153 | + | (sym::target_has_atomic_load_store, Some(_)) |
| 154 | + | (sym::target_thread_local, None) => disallow(cfg, "--target"), |
| 155 | + _ => {} |
| 156 | + } |
| 157 | + } |
| 158 | +} |
| 159 | + |
86 | 160 | /// Generate the default configs for a given session
|
87 | 161 | pub(crate) fn default_configuration(sess: &Session) -> Cfg {
|
88 | 162 | let mut ret = Cfg::default();
|
|
0 commit comments