Skip to content

Commit 7c5cf16

Browse files
committed
Use syn::Error for error reporting
1 parent 0f1d63d commit 7c5cf16

File tree

3 files changed

+19
-33
lines changed

3 files changed

+19
-33
lines changed

enumflags_derive/src/lib.rs

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ extern crate quote;
66
use syn::{Data, Ident, DeriveInput, DataEnum, spanned::Spanned};
77
use proc_macro2::TokenStream;
88
use proc_macro2::Span;
9-
use std::convert::From;
109

1110
/// Shorthand for a quoted `compile_error!`.
1211
macro_rules! error {
@@ -27,7 +26,7 @@ pub fn derive_enum_flags(input: proc_macro::TokenStream)
2726
match ast.data {
2827
Data::Enum(ref data) => {
2928
gen_enumflags(&ast.ident, &ast, data)
30-
.unwrap_or_else(|err| err)
29+
.unwrap_or_else(|err| err.to_compile_error())
3130
.into()
3231
}
3332
Data::Struct(ref data) => {
@@ -39,25 +38,8 @@ pub fn derive_enum_flags(input: proc_macro::TokenStream)
3938
}
4039
}
4140

42-
#[derive(Debug)]
43-
enum EvaluationError {
44-
LiteralOutOfRange(Span),
45-
}
46-
47-
impl From<EvaluationError> for TokenStream {
48-
fn from(why: EvaluationError) -> TokenStream {
49-
use crate::EvaluationError::*;
50-
51-
match why {
52-
LiteralOutOfRange(span) => {
53-
error!(span => "Integer literal out of range")
54-
}
55-
}
56-
}
57-
}
58-
5941
/// Try to evaluate the expression given.
60-
fn fold_expr(expr: &syn::Expr) -> Result<Option<u64>, EvaluationError> {
42+
fn fold_expr(expr: &syn::Expr) -> Result<Option<u64>, syn::Error> {
6143
/// Recurse, but bubble-up both kinds of errors.
6244
/// (I miss my monad transformers)
6345
macro_rules! fold_expr {
@@ -70,13 +52,13 @@ fn fold_expr(expr: &syn::Expr) -> Result<Option<u64>, EvaluationError> {
7052
}
7153

7254
use syn::Expr;
73-
use crate::EvaluationError::*;
7455
match expr {
7556
Expr::Lit(ref expr_lit) => {
7657
match expr_lit.lit {
7758
syn::Lit::Int(ref lit_int) => {
7859
Ok(Some(lit_int.base10_parse()
79-
.map_err(|_| LiteralOutOfRange(expr.span()))?))
60+
.map_err(|_| syn::Error::new_spanned(lit_int,
61+
"Integer literal out of range"))?))
8062
}
8163
_ => Ok(None),
8264
}
@@ -96,15 +78,15 @@ fn fold_expr(expr: &syn::Expr) -> Result<Option<u64>, EvaluationError> {
9678
/// Given a list of attributes, find the `repr`, if any, and return the integer
9779
/// type specified.
9880
fn extract_repr(attrs: &[syn::Attribute])
99-
-> Result<Option<syn::Ident>, TokenStream>
81+
-> Result<Option<syn::Ident>, syn::Error>
10082
{
10183
use syn::{Meta, NestedMeta};
10284
attrs.iter()
10385
.find_map(|attr| {
10486
match attr.parse_meta() {
10587
Err(why) => {
106-
let error = format!("Couldn't parse attribute: {}", why);
107-
Some(Err(error!(attr.span() => #error)))
88+
Some(Err(syn::Error::new_spanned(attr,
89+
format!("Couldn't parse attribute: {}", why))))
10890
}
10991
Ok(Meta::List(ref meta)) if meta.path.is_ident("repr") => {
11092
meta.nested.iter()
@@ -126,18 +108,22 @@ fn extract_repr(attrs: &[syn::Attribute])
126108
fn verify_flag_values<'a>(
127109
type_name: &Ident,
128110
variants: impl Iterator<Item=&'a syn::Variant>
129-
) -> Result<TokenStream, TokenStream> {
111+
) -> Result<TokenStream, syn::Error> {
130112
let mut deferred_checks: Vec<TokenStream> = vec![];
131113
for variant in variants {
114+
if !matches!(variant.fields, syn::Fields::Unit) {
115+
return Err(syn::Error::new_spanned(&variant.fields,
116+
"Bitflag variants cannot contain additional data"));
117+
}
118+
132119
let discr = variant.discriminant.as_ref()
133-
.ok_or_else(|| error!(variant.span() =>
120+
.ok_or_else(|| syn::Error::new_spanned(variant,
134121
"Please add an explicit discriminant"))?;
135122
match fold_expr(&discr.1) {
136123
Ok(Some(flag)) => {
137124
if !flag.is_power_of_two() {
138-
return Err(error!(variant.discriminant.as_ref()
139-
.unwrap().1.span() =>
140-
"Flags must have exactly one set bit."));
125+
return Err(syn::Error::new_spanned(&discr.1,
126+
"Flags must have exactly one set bit"));
141127
}
142128
}
143129
Ok(None) => {
@@ -168,7 +154,7 @@ fn verify_flag_values<'a>(
168154
}
169155

170156
fn gen_enumflags(ident: &Ident, item: &DeriveInput, data: &DataEnum)
171-
-> Result<TokenStream, TokenStream>
157+
-> Result<TokenStream, syn::Error>
172158
{
173159
let span = Span::call_site();
174160
// for quote! interpolation

test_suite/ui/multiple_bits.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: Flags must have exactly one set bit.
1+
error: Flags must have exactly one set bit
22
--> $DIR/multiple_bits.rs:4:20
33
|
44
4 | MultipleBits = 6,

test_suite/ui/zero_disciminant.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: Flags must have exactly one set bit.
1+
error: Flags must have exactly one set bit
22
--> $DIR/zero_disciminant.rs:3:12
33
|
44
3 | Zero = 0,

0 commit comments

Comments
 (0)