summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2018-07-11 12:04:02 +1000
committerGitHub <noreply@github.com>2018-07-11 12:04:02 +1000
commitd61ab759e3512d79131eb6c455862915c6b6c4d2 (patch)
treef40bb80d987d7f7a785fb8070a6a34024c2f034e
parent651d1a7d8279e7cdbc0d8a7ae49b1d0190b2e44e (diff)
parentb0a1752e26923672184fd1606daea7076b44ff41 (diff)
Merge pull request #1348 from tmfink/feature-refactor. r=emilio
Track Rust target features with declaration macro
-rw-r--r--src/features.rs116
1 files changed, 73 insertions, 43 deletions
diff --git a/src/features.rs b/src/features.rs
index 93ebbc34..257d7697 100644
--- a/src/features.rs
+++ b/src/features.rs
@@ -110,72 +110,74 @@ pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_21;
/// Create RustFeatures struct definition, new(), and a getter for each field
macro_rules! rust_feature_def {
- ( $( $( #[$attr:meta] )* => $feature:ident; )* ) => {
+ (
+ $( $rust_target:ident {
+ $( $( #[$attr:meta] )* => $feature:ident; )*
+ } )*
+ ) => {
/// Features supported by a rust target
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct RustFeatures {
- $(
+ $( $(
$(
#[$attr]
)*
pub $feature: bool,
- )*
+ )* )*
}
impl RustFeatures {
/// Gives a RustFeatures struct with all features disabled
fn new() -> Self {
RustFeatures {
- $(
+ $( $(
$feature: false,
- )*
+ )* )*
}
}
}
- }
-}
-rust_feature_def!(
- /// Untagged unions ([RFC 1444](https://github.com/rust-lang/rfcs/blob/master/text/1444-union.md))
- => untagged_union;
- /// `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202))
- => thiscall_abi;
- /// builtin impls for `Clone` ([PR](https://github.com/rust-lang/rust/pull/43690))
- => builtin_clone_impls;
- /// repr(align) https://github.com/rust-lang/rust/pull/47006
- => repr_align;
- /// associated constants https://github.com/rust-lang/rust/issues/29646
- => associated_const;
-);
+ impl From<RustTarget> for RustFeatures {
+ fn from(rust_target: RustTarget) -> Self {
+ let mut features = RustFeatures::new();
-impl From<RustTarget> for RustFeatures {
- fn from(rust_target: RustTarget) -> Self {
- let mut features = RustFeatures::new();
-
- if rust_target >= RustTarget::Stable_1_19 {
- features.untagged_union = true;
- }
-
- if rust_target >= RustTarget::Stable_1_20 {
- features.associated_const = true;
- }
-
- if rust_target >= RustTarget::Stable_1_21 {
- features.builtin_clone_impls = true;
- }
-
- if rust_target >= RustTarget::Stable_1_25 {
- features.repr_align = true;
- }
+ $(
+ if rust_target >= RustTarget::$rust_target {
+ $(
+ features.$feature = true;
+ )*
+ }
+ )*
- if rust_target >= RustTarget::Nightly {
- features.thiscall_abi = true;
+ features
+ }
}
-
- features
}
}
+rust_feature_def!(
+ Stable_1_19 {
+ /// Untagged unions ([RFC 1444](https://github.com/rust-lang/rfcs/blob/master/text/1444-union.md))
+ => untagged_union;
+ }
+ Stable_1_20 {
+ /// associated constants ([PR](https://github.com/rust-lang/rust/pull/42809))
+ => associated_const;
+ }
+ Stable_1_21 {
+ /// builtin impls for `Clone` ([PR](https://github.com/rust-lang/rust/pull/43690))
+ => builtin_clone_impls;
+ }
+ Stable_1_25 {
+ /// repr(align) ([PR](https://github.com/rust-lang/rust/pull/47006))
+ => repr_align;
+ }
+ Nightly {
+ /// `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202))
+ => thiscall_abi;
+ }
+);
+
impl Default for RustFeatures {
fn default() -> Self {
let default_rust_target: RustTarget = Default::default();
@@ -185,9 +187,37 @@ impl Default for RustFeatures {
#[cfg(test)]
mod test {
-#![allow(unused_imports)]
+ #![allow(unused_imports)]
use super::*;
+ #[test]
+ fn target_features() {
+ let f_1_0 = RustFeatures::from(RustTarget::Stable_1_0);
+ assert!(
+ !f_1_0.untagged_union
+ && !f_1_0.associated_const
+ && !f_1_0.builtin_clone_impls
+ && !f_1_0.repr_align
+ && !f_1_0.thiscall_abi
+ );
+ let f_1_21 = RustFeatures::from(RustTarget::Stable_1_21);
+ assert!(
+ f_1_21.untagged_union
+ && f_1_21.associated_const
+ && f_1_21.builtin_clone_impls
+ && !f_1_21.repr_align
+ && !f_1_21.thiscall_abi
+ );
+ let f_nightly = RustFeatures::from(RustTarget::Nightly);
+ assert!(
+ f_nightly.untagged_union
+ && f_nightly.associated_const
+ && f_nightly.builtin_clone_impls
+ && f_nightly.repr_align
+ && f_nightly.thiscall_abi
+ );
+ }
+
fn test_target(target_str: &str, target: RustTarget) {
let target_string: String = target.into();
assert_eq!(target_str, target_string);