Skip to content

Commit a4e9d97

Browse files
author
Ahmed Abdelraoof
committed
Reject enums with attribute macros
This patch checks if there is any top level attribute macro expansion, and if there it, we report it as an error. fixes: #1 Signed-off-by: Ahmed Abdelraoof <ahmed.abdelraoof@huawei.com>
1 parent ffbbb9a commit a4e9d97

File tree

5 files changed

+51
-0
lines changed

5 files changed

+51
-0
lines changed

safe-discriminant-derive/src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,30 @@ fn validate_all_variants(variants: impl Iterator<Item = Variant>) -> Result<()>
8080
.unwrap_or(Ok(()))
8181
}
8282

83+
/// Returns true if there is any #[x] where x is not `derive` or `repr`
84+
/// returns false otherwise.
85+
fn contains_attribute_macros(attrs: &[Attribute]) -> bool {
86+
attrs
87+
.iter()
88+
.filter(|attr| !attr.path().is_ident("repr"))
89+
.count()
90+
!= 0
91+
}
8392
/// Constructs Discriminant trait implementation for given enum.
8493
/// Returns error in one of two cases:
8594
/// 1- No valid `#[repr(x)]` is found.
8695
/// 2- Any of the enum variants is missing discriminant.
96+
/// 3- contains any additional top level attribute macros.
8797
fn derive_discriminant_inner(tagged_enum: ItemEnum) -> Result<TokenStream> {
8898
let prim = get_enum_repr_prim(&tagged_enum.attrs, tagged_enum.ident.span())?;
8999
validate_all_variants(tagged_enum.variants.into_iter())?;
100+
if contains_attribute_macros(&tagged_enum.attrs) {
101+
return Err(Error::new(
102+
tagged_enum.ident.span(),
103+
"Discriminant is not compatiable with any top \
104+
level `#[attr]` except `#[repr(_)]`.",
105+
));
106+
}
90107
let name = tagged_enum.ident;
91108
let generics = tagged_enum.generics;
92109
let derive = quote! {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use safe_discriminant::Discriminant;
2+
use safe_discriminant_derive::remove_repr;
3+
4+
#[remove_repr]
5+
#[derive(Discriminant)]
6+
#[repr(u8)]
7+
pub enum Foo {
8+
A = 0,
9+
B = 1,
10+
}
11+
12+
fn main() {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
error: Discriminant requires a `#[repr(x)] where x is one of u8, i8, u16, i16, u32, i32, u64, i64, u128, i128.
2+
--> tests/fail/remove_repr_disc1.rs:7:10
3+
|
4+
7 | pub enum Foo {
5+
| ^^^
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use safe_discriminant::Discriminant;
2+
use safe_discriminant_derive::remove_repr;
3+
4+
#[derive(Discriminant)]
5+
#[remove_repr]
6+
#[repr(u8)]
7+
pub enum Foo {
8+
A = 0,
9+
B = 1,
10+
}
11+
12+
fn main() {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
error: Discriminant is not compatiable with any top level `#[attr]` except `#[repr(_)]`.
2+
--> tests/fail/remove_repr_disc2.rs:7:10
3+
|
4+
7 | pub enum Foo {
5+
| ^^^

0 commit comments

Comments
 (0)