Implement cfg(target_abi) (RFC 2992)
Add an `abi` field to `TargetOptions`, defaulting to "". Support using `cfg(target_abi = "...")` for conditional compilation on that field. Gated by `feature(cfg_target_abi)`. Add a test for `target_abi`, and a test for the feature gate. Add `target_abi` to tidy as a platform-specific cfg. This does not add an abi to any existing target.
This commit is contained in:
parent
c0bd5a584d
commit
84d6e8aed3
@ -687,6 +687,9 @@ pub fn set(&self, features: &mut Features, span: Span) {
|
|||||||
/// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
|
/// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
|
||||||
(active, more_qualified_paths, "1.54.0", Some(80080), None),
|
(active, more_qualified_paths, "1.54.0", Some(80080), None),
|
||||||
|
|
||||||
|
/// Allows `cfg(target_abi = "...")`.
|
||||||
|
(active, cfg_target_abi, "1.55.0", Some(80970), None),
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// feature-group-end: actual feature gates
|
// feature-group-end: actual feature gates
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
@ -23,6 +23,7 @@ macro_rules! cfg_fn {
|
|||||||
/// `cfg(...)`'s that are feature gated.
|
/// `cfg(...)`'s that are feature gated.
|
||||||
const GATED_CFGS: &[GatedCfg] = &[
|
const GATED_CFGS: &[GatedCfg] = &[
|
||||||
// (name in cfg, feature, function to check if the feature is enabled)
|
// (name in cfg, feature, function to check if the feature is enabled)
|
||||||
|
(sym::target_abi, sym::cfg_target_abi, cfg_fn!(cfg_target_abi)),
|
||||||
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
|
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
|
||||||
(sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
(sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
||||||
(sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
(sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
||||||
|
@ -805,6 +805,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
|
|||||||
let wordsz = sess.target.pointer_width.to_string();
|
let wordsz = sess.target.pointer_width.to_string();
|
||||||
let os = &sess.target.os;
|
let os = &sess.target.os;
|
||||||
let env = &sess.target.env;
|
let env = &sess.target.env;
|
||||||
|
let abi = &sess.target.abi;
|
||||||
let vendor = &sess.target.vendor;
|
let vendor = &sess.target.vendor;
|
||||||
let min_atomic_width = sess.target.min_atomic_width();
|
let min_atomic_width = sess.target.min_atomic_width();
|
||||||
let max_atomic_width = sess.target.max_atomic_width();
|
let max_atomic_width = sess.target.max_atomic_width();
|
||||||
@ -814,7 +815,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let mut ret = FxHashSet::default();
|
let mut ret = FxHashSet::default();
|
||||||
ret.reserve(6); // the minimum number of insertions
|
ret.reserve(7); // the minimum number of insertions
|
||||||
// Target bindings.
|
// Target bindings.
|
||||||
ret.insert((sym::target_os, Some(Symbol::intern(os))));
|
ret.insert((sym::target_os, Some(Symbol::intern(os))));
|
||||||
for fam in &sess.target.families {
|
for fam in &sess.target.families {
|
||||||
@ -829,6 +830,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
|
|||||||
ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str()))));
|
ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str()))));
|
||||||
ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
|
ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
|
||||||
ret.insert((sym::target_env, Some(Symbol::intern(env))));
|
ret.insert((sym::target_env, Some(Symbol::intern(env))));
|
||||||
|
ret.insert((sym::target_abi, Some(Symbol::intern(abi))));
|
||||||
ret.insert((sym::target_vendor, Some(Symbol::intern(vendor))));
|
ret.insert((sym::target_vendor, Some(Symbol::intern(vendor))));
|
||||||
if sess.target.has_elf_tls {
|
if sess.target.has_elf_tls {
|
||||||
ret.insert((sym::target_thread_local, None));
|
ret.insert((sym::target_thread_local, None));
|
||||||
|
@ -353,6 +353,7 @@
|
|||||||
cfg_eval,
|
cfg_eval,
|
||||||
cfg_panic,
|
cfg_panic,
|
||||||
cfg_sanitize,
|
cfg_sanitize,
|
||||||
|
cfg_target_abi,
|
||||||
cfg_target_feature,
|
cfg_target_feature,
|
||||||
cfg_target_has_atomic,
|
cfg_target_has_atomic,
|
||||||
cfg_target_thread_local,
|
cfg_target_thread_local,
|
||||||
@ -1199,6 +1200,7 @@
|
|||||||
sync,
|
sync,
|
||||||
sync_trait,
|
sync_trait,
|
||||||
t32,
|
t32,
|
||||||
|
target_abi,
|
||||||
target_arch,
|
target_arch,
|
||||||
target_endian,
|
target_endian,
|
||||||
target_env,
|
target_env,
|
||||||
|
@ -1025,6 +1025,9 @@ pub struct TargetOptions {
|
|||||||
pub os: String,
|
pub os: String,
|
||||||
/// Environment name to use for conditional compilation (`target_env`). Defaults to "".
|
/// Environment name to use for conditional compilation (`target_env`). Defaults to "".
|
||||||
pub env: String,
|
pub env: String,
|
||||||
|
/// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"`
|
||||||
|
/// or `"eabihf"`. Defaults to "".
|
||||||
|
pub abi: String,
|
||||||
/// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
|
/// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
|
||||||
pub vendor: String,
|
pub vendor: String,
|
||||||
/// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
|
/// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
|
||||||
@ -1342,6 +1345,7 @@ fn default() -> TargetOptions {
|
|||||||
c_int_width: "32".to_string(),
|
c_int_width: "32".to_string(),
|
||||||
os: "none".to_string(),
|
os: "none".to_string(),
|
||||||
env: String::new(),
|
env: String::new(),
|
||||||
|
abi: String::new(),
|
||||||
vendor: "unknown".to_string(),
|
vendor: "unknown".to_string(),
|
||||||
linker_flavor: LinkerFlavor::Gcc,
|
linker_flavor: LinkerFlavor::Gcc,
|
||||||
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
|
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
|
||||||
@ -1919,6 +1923,7 @@ macro_rules! key {
|
|||||||
key!(c_int_width = "target-c-int-width");
|
key!(c_int_width = "target-c-int-width");
|
||||||
key!(os);
|
key!(os);
|
||||||
key!(env);
|
key!(env);
|
||||||
|
key!(abi);
|
||||||
key!(vendor);
|
key!(vendor);
|
||||||
key!(linker_flavor, LinkerFlavor)?;
|
key!(linker_flavor, LinkerFlavor)?;
|
||||||
key!(linker, optional);
|
key!(linker, optional);
|
||||||
@ -2152,6 +2157,7 @@ macro_rules! target_option_val {
|
|||||||
target_option_val!(c_int_width, "target-c-int-width");
|
target_option_val!(c_int_width, "target-c-int-width");
|
||||||
target_option_val!(os);
|
target_option_val!(os);
|
||||||
target_option_val!(env);
|
target_option_val!(env);
|
||||||
|
target_option_val!(abi);
|
||||||
target_option_val!(vendor);
|
target_option_val!(vendor);
|
||||||
target_option_val!(linker_flavor);
|
target_option_val!(linker_flavor);
|
||||||
target_option_val!(linker);
|
target_option_val!(linker);
|
||||||
|
10
src/test/ui/cfg/cfg-target-abi.rs
Normal file
10
src/test/ui/cfg/cfg-target-abi.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// run-pass
|
||||||
|
#![feature(cfg_target_abi)]
|
||||||
|
|
||||||
|
#[cfg(target_abi = "eabihf")]
|
||||||
|
pub fn main() {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_abi = "eabihf"))]
|
||||||
|
pub fn main() {
|
||||||
|
}
|
11
src/test/ui/feature-gates/feature-gate-cfg-target-abi.rs
Normal file
11
src/test/ui/feature-gates/feature-gate-cfg-target-abi.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#[cfg(target_abi = "x")] //~ ERROR `cfg(target_abi)` is experimental
|
||||||
|
#[cfg_attr(target_abi = "x", x)] //~ ERROR `cfg(target_abi)` is experimental
|
||||||
|
struct Foo(u64, u64);
|
||||||
|
|
||||||
|
#[cfg(not(any(all(target_abi = "x"))))] //~ ERROR `cfg(target_abi)` is experimental
|
||||||
|
fn foo() {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
cfg!(target_abi = "x");
|
||||||
|
//~^ ERROR `cfg(target_abi)` is experimental and subject to change
|
||||||
|
}
|
39
src/test/ui/feature-gates/feature-gate-cfg-target-abi.stderr
Normal file
39
src/test/ui/feature-gates/feature-gate-cfg-target-abi.stderr
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
error[E0658]: `cfg(target_abi)` is experimental and subject to change
|
||||||
|
--> $DIR/feature-gate-cfg-target-abi.rs:2:12
|
||||||
|
|
|
||||||
|
LL | #[cfg_attr(target_abi = "x", x)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
|
||||||
|
= help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0658]: `cfg(target_abi)` is experimental and subject to change
|
||||||
|
--> $DIR/feature-gate-cfg-target-abi.rs:1:7
|
||||||
|
|
|
||||||
|
LL | #[cfg(target_abi = "x")]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
|
||||||
|
= help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0658]: `cfg(target_abi)` is experimental and subject to change
|
||||||
|
--> $DIR/feature-gate-cfg-target-abi.rs:5:19
|
||||||
|
|
|
||||||
|
LL | #[cfg(not(any(all(target_abi = "x"))))]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
|
||||||
|
= help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0658]: `cfg(target_abi)` is experimental and subject to change
|
||||||
|
--> $DIR/feature-gate-cfg-target-abi.rs:9:10
|
||||||
|
|
|
||||||
|
LL | cfg!(target_abi = "x");
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
|
||||||
|
= help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
@ -122,6 +122,7 @@ fn check_cfgs(
|
|||||||
|
|
||||||
let contains_platform_specific_cfg = cfg.contains("target_os")
|
let contains_platform_specific_cfg = cfg.contains("target_os")
|
||||||
|| cfg.contains("target_env")
|
|| cfg.contains("target_env")
|
||||||
|
|| cfg.contains("target_abi")
|
||||||
|| cfg.contains("target_vendor")
|
|| cfg.contains("target_vendor")
|
||||||
|| cfg.contains("unix")
|
|| cfg.contains("unix")
|
||||||
|| cfg.contains("windows");
|
|| cfg.contains("windows");
|
||||||
|
Loading…
Reference in New Issue
Block a user