Extract integer suffix of discriminants as the repr
diff --git a/syntax/atom.rs b/syntax/atom.rs
index a2ff7b7..6e5fa88 100644
--- a/syntax/atom.rs
+++ b/syntax/atom.rs
@@ -23,8 +23,12 @@
impl Atom {
pub fn from(ident: &Ident) -> Option<Self> {
+ Self::from_str(ident.to_string().as_str())
+ }
+
+ pub fn from_str(s: &str) -> Option<Self> {
use self::Atom::*;
- match ident.to_string().as_str() {
+ match s {
"bool" => Some(Bool),
"u8" => Some(U8),
"u16" => Some(U16),
diff --git a/syntax/discriminant.rs b/syntax/discriminant.rs
index 06a6d1b..7293824 100644
--- a/syntax/discriminant.rs
+++ b/syntax/discriminant.rs
@@ -1,3 +1,4 @@
+use crate::syntax::Atom::{self, *};
use proc_macro2::{Literal, Span, TokenStream};
use quote::ToTokens;
use std::collections::HashSet;
@@ -6,6 +7,7 @@
use syn::{Error, Expr, Lit, Result, Token, UnOp};
pub struct DiscriminantSet {
+ repr: Option<Atom>,
values: HashSet<Discriminant>,
previous: Option<Discriminant>,
}
@@ -19,13 +21,15 @@
impl DiscriminantSet {
pub fn new() -> Self {
DiscriminantSet {
+ repr: None,
values: HashSet::new(),
previous: None,
}
}
pub fn insert(&mut self, expr: &Expr) -> Result<Discriminant> {
- let discriminant = expr_to_discriminant(expr)?;
+ let (discriminant, repr) = expr_to_discriminant(expr)?;
+ self.repr = self.repr.or(repr);
insert(self, discriminant)
}
@@ -52,18 +56,20 @@
}
}
-fn expr_to_discriminant(expr: &Expr) -> Result<Discriminant> {
+fn expr_to_discriminant(expr: &Expr) -> Result<(Discriminant, Option<Atom>)> {
match expr {
Expr::Lit(expr) => {
if let Lit::Int(lit) = &expr.lit {
- return lit.base10_parse::<Discriminant>();
+ let discriminant = lit.base10_parse::<Discriminant>()?;
+ let repr = parse_int_suffix(lit.suffix())?;
+ return Ok((discriminant, repr));
}
}
Expr::Unary(unary) => {
if let UnOp::Neg(_) = unary.op {
- let mut discriminant = expr_to_discriminant(&unary.expr)?;
+ let (mut discriminant, repr) = expr_to_discriminant(&unary.expr)?;
discriminant.negative ^= true;
- return Ok(discriminant);
+ return Ok((discriminant, repr));
}
}
_ => {}
@@ -131,3 +137,17 @@
}
}
}
+
+fn parse_int_suffix(suffix: &str) -> Result<Option<Atom>> {
+ if suffix.is_empty() {
+ return Ok(None);
+ }
+ if let Some(atom) = Atom::from_str(suffix) {
+ match atom {
+ U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize => return Ok(Some(atom)),
+ _ => {}
+ }
+ }
+ let msg = format!("unrecognized integer suffix: `{}`", suffix);
+ Err(Error::new(Span::call_site(), msg))
+}