Skip to content

Commit

Permalink
Auto merge of #1293 - strake:use_associated_consts, r=emilio
Browse files Browse the repository at this point in the history
optionally use associated constants in bitfields

See #1166

r? @emilio
  • Loading branch information
bors-servo authored Apr 7, 2018
2 parents 0b4f5be + 7024cf6 commit 0a601d6
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 43 deletions.
40 changes: 26 additions & 14 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2126,7 +2126,7 @@ impl EnumVariation {

fn is_bitfield(&self) -> bool {
match *self {
EnumVariation::Bitfield => true,
EnumVariation::Bitfield {..} => true,
_ => false
}
}
Expand Down Expand Up @@ -2247,6 +2247,7 @@ impl<'a> EnumBuilder<'a> {
mangling_prefix: Option<&str>,
rust_ty: quote::Tokens,
result: &mut CodegenResult<'b>,
is_ty_named: bool,
) -> Self {
let variant_name = ctx.rust_mangle(variant.name());
let expr = match variant.val() {
Expand Down Expand Up @@ -2278,19 +2279,28 @@ impl<'a> EnumBuilder<'a> {
}
}

EnumBuilder::Bitfield { .. } => {
let constant_name = match mangling_prefix {
Some(prefix) => {
Cow::Owned(format!("{}_{}", prefix, variant_name))
}
None => variant_name,
};

let ident = ctx.rust_ident(constant_name);
result.push(quote! {
#doc
pub const #ident : #rust_ty = #rust_ty ( #expr );
});
EnumBuilder::Bitfield { canonical_name, .. } => {
if ctx.options().rust_features().associated_const && is_ty_named {
let enum_ident = ctx.rust_ident(canonical_name);
let variant_ident = ctx.rust_ident(variant_name);
result.push(quote! {
impl #enum_ident {
#doc
pub const #variant_ident : #rust_ty = #rust_ty ( #expr );
}
});
} else {
let ident = ctx.rust_ident(match mangling_prefix {
Some(prefix) => {
Cow::Owned(format!("{}_{}", prefix, variant_name))
}
None => variant_name,
});
result.push(quote! {
#doc
pub const #ident : #rust_ty = #rust_ty ( #expr );
});
}

self
}
Expand Down Expand Up @@ -2625,6 +2635,7 @@ impl CodeGenerator for Enum {
constant_mangling_prefix,
enum_rust_ty.clone(),
result,
enum_ty.name().is_some(),
);
}
}
Expand All @@ -2635,6 +2646,7 @@ impl CodeGenerator for Enum {
constant_mangling_prefix,
enum_rust_ty.clone(),
result,
enum_ty.name().is_some(),
);

let variant_name = ctx.rust_ident(variant.name());
Expand Down
8 changes: 8 additions & 0 deletions src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ macro_rules! rust_target_base {
=> Stable_1_0 => 1.0;
/// Rust stable 1.19
=> Stable_1_19 => 1.19;
/// Rust stable 1.20
=> Stable_1_20 => 1.20;
/// Rust stable 1.21
=> Stable_1_21 => 1.21;
/// Rust stable 1.25
Expand Down Expand Up @@ -142,6 +144,8 @@ rust_feature_def!(
=> 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 {
Expand All @@ -152,6 +156,10 @@ impl From<RustTarget> for RustFeatures {
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;
}
Expand Down
32 changes: 24 additions & 8 deletions tests/expectations/tests/bitfield-enum-basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@

#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]

pub const Foo_Bar: Foo = Foo(2);
pub const Foo_Baz: Foo = Foo(4);
pub const Foo_Duplicated: Foo = Foo(4);
pub const Foo_Negative: Foo = Foo(-3);
impl Foo {
pub const Bar: Foo = Foo(2);
}
impl Foo {
pub const Baz: Foo = Foo(4);
}
impl Foo {
pub const Duplicated: Foo = Foo(4);
}
impl Foo {
pub const Negative: Foo = Foo(-3);
}
impl ::std::ops::BitOr<Foo> for Foo {
type Output = Self;
#[inline]
Expand Down Expand Up @@ -35,10 +43,18 @@ impl ::std::ops::BitAndAssign for Foo {
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Foo(pub i32);
pub const Buz_Bar: Buz = Buz(2);
pub const Buz_Baz: Buz = Buz(4);
pub const Buz_Duplicated: Buz = Buz(4);
pub const Buz_Negative: Buz = Buz(-3);
impl Buz {
pub const Bar: Buz = Buz(2);
}
impl Buz {
pub const Baz: Buz = Buz(4);
}
impl Buz {
pub const Duplicated: Buz = Buz(4);
}
impl Buz {
pub const Negative: Buz = Buz(-3);
}
impl ::std::ops::BitOr<Buz> for Buz {
type Output = Self;
#[inline]
Expand Down
42 changes: 27 additions & 15 deletions tests/expectations/tests/enum-doc-bitfield.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,33 @@

#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]

/// Document field with three slashes
pub const B_VAR_A: B = B(0);
/// Document field with preceeding star
pub const B_VAR_B: B = B(1);
/// Document field with preceeding exclamation
pub const B_VAR_C: B = B(2);
/// < Document field with following star
pub const B_VAR_D: B = B(3);
/// < Document field with following exclamation
pub const B_VAR_E: B = B(4);
/// Document field with preceeding star, with a loong long multiline
/// comment.
///
/// Very interesting documentation, definitely.
pub const B_VAR_F: B = B(5);
impl B {
/// Document field with three slashes
pub const VAR_A: B = B(0);
}
impl B {
/// Document field with preceeding star
pub const VAR_B: B = B(1);
}
impl B {
/// Document field with preceeding exclamation
pub const VAR_C: B = B(2);
}
impl B {
/// < Document field with following star
pub const VAR_D: B = B(3);
}
impl B {
/// < Document field with following exclamation
pub const VAR_E: B = B(4);
}
impl B {
/// Document field with preceeding star, with a loong long multiline
/// comment.
///
/// Very interesting documentation, definitely.
pub const VAR_F: B = B(5);
}
impl ::std::ops::BitOr<B> for B {
type Output = Self;
#[inline]
Expand Down
24 changes: 18 additions & 6 deletions tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@

#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]

pub const MyDupeEnum_A: MyDupeEnum = MyDupeEnum(0);
pub const MyDupeEnum_A_alias: MyDupeEnum = MyDupeEnum(0);
pub const MyDupeEnum_B: MyDupeEnum = MyDupeEnum(1);
impl MyDupeEnum {
pub const A: MyDupeEnum = MyDupeEnum(0);
}
impl MyDupeEnum {
pub const A_alias: MyDupeEnum = MyDupeEnum(0);
}
impl MyDupeEnum {
pub const B: MyDupeEnum = MyDupeEnum(1);
}
impl ::std::ops::BitOr<MyDupeEnum> for MyDupeEnum {
type Output = Self;
#[inline]
Expand Down Expand Up @@ -34,9 +40,15 @@ impl ::std::ops::BitAndAssign for MyDupeEnum {
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct MyDupeEnum(pub u32);
pub const MyOtherDupeEnum_C: MyOtherDupeEnum = MyOtherDupeEnum(0);
pub const MyOtherDupeEnum_C_alias: MyOtherDupeEnum = MyOtherDupeEnum(0);
pub const MyOtherDupeEnum_D: MyOtherDupeEnum = MyOtherDupeEnum(1);
impl MyOtherDupeEnum {
pub const C: MyOtherDupeEnum = MyOtherDupeEnum(0);
}
impl MyOtherDupeEnum {
pub const C_alias: MyOtherDupeEnum = MyOtherDupeEnum(0);
}
impl MyOtherDupeEnum {
pub const D: MyOtherDupeEnum = MyOtherDupeEnum(1);
}
impl ::std::ops::BitOr<MyOtherDupeEnum> for MyOtherDupeEnum {
type Output = Self;
#[inline]
Expand Down

0 comments on commit 0a601d6

Please sign in to comment.