Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove use of unreachable for unions #123

Merged
merged 2 commits into from
Feb 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions core/src/ast/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,28 @@ pub enum Data<V, F> {

impl<V, F> Data<V, F> {
/// Creates an empty body of the same shape as the passed-in body.
///
/// # Panics
/// This function will panic if passed `syn::Data::Union`.
pub fn empty_from(src: &syn::Data) -> Self {
match *src {
syn::Data::Enum(_) => Data::Enum(vec![]),
syn::Data::Struct(ref vd) => Data::Struct(Fields::empty_from(&vd.fields)),
syn::Data::Union(_) => unreachable!(),
syn::Data::Union(_) => panic!("Unions are not supported"),
}
}

/// Creates an empty body of the same shape as the passed-in body.
///
/// `darling` does not support unions; calling this function with a union body will return an error.
pub fn try_empty_from(src: &syn::Data) -> Result<Self> {
match *src {
syn::Data::Enum(_) => Ok(Data::Enum(vec![])),
syn::Data::Struct(ref vd) => Ok(Data::Struct(Fields::empty_from(&vd.fields))),
// This deliberately doesn't set a span on the error message, as the error is most useful if
// applied to the call site of the offending macro. Given that the message is very generic,
// putting it on the union keyword ends up being confusing.
syn::Data::Union(_) => Err(Error::custom("Unions are not supported")),
}
}

Expand Down Expand Up @@ -120,7 +137,10 @@ impl<V: FromVariant, F: FromField> Data<V, F> {
}
}
syn::Data::Struct(ref data) => Ok(Data::Struct(Fields::try_from(&data.fields)?)),
syn::Data::Union(_) => unreachable!(),
// This deliberately doesn't set a span on the error message, as the error is most useful if
// applied to the call site of the offending macro. Given that the message is very generic,
// putting it on the union keyword ends up being confusing.
syn::Data::Union(_) => Err(Error::custom("Unions are not supported")),
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions core/src/options/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ pub struct Core {

impl Core {
/// Partially initializes `Core` by reading the identity, generics, and body shape.
pub fn start(di: &syn::DeriveInput) -> Self {
Core {
pub fn start(di: &syn::DeriveInput) -> Result<Self> {
Ok(Core {
ident: di.ident.clone(),
generics: di.generics.clone(),
data: Data::empty_from(&di.data),
data: Data::try_empty_from(&di.data)?,
default: Default::default(),
// See https://github.com/TedDriggs/darling/issues/10: We default to snake_case
// for enums to help authors produce more idiomatic APIs.
Expand All @@ -57,7 +57,7 @@ impl Core {
map: Default::default(),
bound: Default::default(),
allow_unknown_fields: Default::default(),
}
})
}

fn as_codegen_default<'a>(&'a self) -> Option<codegen::DefaultExpression<'a>> {
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct FdiOptions {
impl FdiOptions {
pub fn new(di: &syn::DeriveInput) -> Result<Self> {
(FdiOptions {
base: OuterFrom::start(di),
base: OuterFrom::start(di)?,
vis: Default::default(),
generics: Default::default(),
data: Default::default(),
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct FromFieldOptions {
impl FromFieldOptions {
pub fn new(di: &syn::DeriveInput) -> Result<Self> {
(FromFieldOptions {
base: OuterFrom::start(di),
base: OuterFrom::start(di)?,
vis: Default::default(),
ty: Default::default(),
})
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct FromMetaOptions {
impl FromMetaOptions {
pub fn new(di: &syn::DeriveInput) -> Result<Self> {
(FromMetaOptions {
base: Core::start(di),
base: Core::start(di)?,
})
.parse_attributes(&di.attrs)?
.parse_body(&di.data)
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_type_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct FromTypeParamOptions {
impl FromTypeParamOptions {
pub fn new(di: &syn::DeriveInput) -> Result<Self> {
(FromTypeParamOptions {
base: OuterFrom::start(di),
base: OuterFrom::start(di)?,
bounds: None,
default: None,
})
Expand Down
2 changes: 1 addition & 1 deletion core/src/options/from_variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct FromVariantOptions {
impl FromVariantOptions {
pub fn new(di: &DeriveInput) -> Result<Self> {
(FromVariantOptions {
base: OuterFrom::start(di),
base: OuterFrom::start(di)?,
discriminant: Default::default(),
fields: Default::default(),
supports: Default::default(),
Expand Down
8 changes: 4 additions & 4 deletions core/src/options/outer_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ pub struct OuterFrom {
}

impl OuterFrom {
pub fn start(di: &syn::DeriveInput) -> Self {
OuterFrom {
container: Core::start(di),
pub fn start(di: &syn::DeriveInput) -> Result<Self> {
Ok(OuterFrom {
container: Core::start(di)?,
attrs: Default::default(),
ident: Default::default(),
attr_names: Default::default(),
forward_attrs: Default::default(),
from_ident: Default::default(),
}
})
}
}

Expand Down