Parse repr attribute on enums
diff --git a/syntax/attrs.rs b/syntax/attrs.rs
index f48a210..16541a3 100644
--- a/syntax/attrs.rs
+++ b/syntax/attrs.rs
@@ -1,5 +1,7 @@
use crate::syntax::report::Errors;
+use crate::syntax::Atom::{self, *};
use crate::syntax::{Derive, Doc};
+use proc_macro2::Ident;
use syn::parse::{ParseStream, Parser as _};
use syn::{Attribute, Error, LitStr, Path, Result, Token};
@@ -7,6 +9,7 @@
pub struct Parser<'a> {
pub doc: Option<&'a mut Doc>,
pub derives: Option<&'a mut Vec<Derive>>,
+ pub repr: Option<&'a mut Option<Atom>>,
}
pub(super) fn parse_doc(cx: &mut Errors, attrs: &[Attribute]) -> Doc {
@@ -44,6 +47,16 @@
}
Err(err) => return cx.push(err),
}
+ } else if attr.path.is_ident("repr") {
+ match attr.parse_args_with(parse_repr_attribute) {
+ Ok(attr) => {
+ if let Some(repr) = &mut parser.repr {
+ **repr = Some(attr);
+ continue;
+ }
+ }
+ Err(err) => return cx.push(err),
+ }
}
return cx.error(attr, "unsupported attribute");
}
@@ -69,3 +82,18 @@
})
.collect()
}
+
+fn parse_repr_attribute(input: ParseStream) -> Result<Atom> {
+ let begin = input.cursor();
+ let ident: Ident = input.parse()?;
+ if let Some(atom) = Atom::from(&ident) {
+ match atom {
+ U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize => return Ok(atom),
+ _ => {}
+ }
+ }
+ Err(Error::new_spanned(
+ begin.token_stream(),
+ "unrecognized repr",
+ ))
+}
diff --git a/syntax/discriminant.rs b/syntax/discriminant.rs
index 388a117..c65b3f4 100644
--- a/syntax/discriminant.rs
+++ b/syntax/discriminant.rs
@@ -20,9 +20,9 @@
}
impl DiscriminantSet {
- pub fn new() -> Self {
+ pub fn new(repr: Option<Atom>) -> Self {
DiscriminantSet {
- repr: None,
+ repr,
values: BTreeSet::new(),
previous: None,
}
diff --git a/syntax/parse.rs b/syntax/parse.rs
index ab5dcc1..a11a5c8 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -60,6 +60,7 @@
attrs::Parser {
doc: Some(&mut doc),
derives: Some(&mut derives),
+ ..Default::default()
},
);
@@ -103,10 +104,20 @@
));
}
- let doc = attrs::parse_doc(cx, &item.attrs);
+ let mut doc = Doc::new();
+ let mut repr = None;
+ attrs::parse(
+ cx,
+ &item.attrs,
+ attrs::Parser {
+ doc: Some(&mut doc),
+ repr: Some(&mut repr),
+ ..Default::default()
+ },
+ );
let mut variants = Vec::new();
- let mut discriminants = DiscriminantSet::new();
+ let mut discriminants = DiscriminantSet::new(repr);
for variant in item.variants {
match variant.fields {
Fields::Unit => {}