-
Notifications
You must be signed in to change notification settings - Fork 123
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
Avoid branch in Display
match
statement for empty enums
#196
Conversation
Can you add regression test for the case that this fix is solving |
While trying to work out a test case to proof the match arm was I came accros the thread that in the end concludes:
reference issue: rust-lang/rust#4499 (comment) So you simply cannot construct an empty enum and as such I think I should maybe change this PR to remove to code to handle Display for them. The only test case of this just checks that you can derive If we remove the So in conclusion I think this PR should be renamed and instead remove that code to no longer handle empty enums that cannot be created (unless using UB). If you do wish to keep this code that serves (at least in my opion) then I would at least take this improvment in the code as this causes the code to still compile and no emit that Sadly this is impossible to test as far as I can see unless we expand the macro before calling stringify and extract match all match arms from that but that is impossible see this question that you cannot control expansion order of macros. TL;DR this code is makes it so a case that should never occur no longer causes other happening cases to generate more code that needed. As in generating an |
Thanks for the detailed comment. Removing the empty enum support sounds like the best approach indeed then, please update the PR to do so. I'm preparing a 1.0.0 release anyway, so if people rely on this at least its support will be removed in a major release. |
Just for refrence this is what a crate like thiserror does in case of an empty enum #![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
enum E {}
#[allow(unused_qualifications)]
impl std::error::Error for E {}
#[allow(unused_qualifications)]
impl std::fmt::Display for E {
fn fmt(&self, __formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
#[allow(unused_variables, deprecated, clippy::used_underscore_binding)]
match *self {}
}
}
#[automatically_derived]
impl ::core::fmt::Debug for E {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
unsafe { ::core::intrinsics::unreachable() }
}
} source code being: #[derive(thiserror::Error, Debug)]
enum E {} Do you think we can change the Ok(quote! {
impl #impl_generics #trait_path for #name #ty_generics #where_clause
{
#[allow(unused_variables)]
#[inline]
fn fmt(&self, _derive_more_display_formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
#helper_struct
match self {
#arms
}
}
}
})
I'll make this chances that I've described here. If you think the reasoning here is unclear or their are better solutions I'll be happy to adjust the PR more. Should I also change the title now the PR purpose is changed is commit messages okay (if you squash merge the PR title won't be seen in the history -- I think ?) |
Changing So I see 2 solutions we can use here: let body = if arms.is_empty() {
quote! {
#helper_struct
match self {
#arms
}
}
} else {
quote! { Ok(()) }
};
Ok(quote! {
impl #impl_generics #trait_path for #name #ty_generics #where_clause
{
#[allow(unused_variables)]
#[inline]
fn fmt(&self, _derive_more_display_formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
#body
}
}
})
|
I implemented option 2. If you would rather have option 1 I'll be happy to change to it. The code that will be used for option 1 is above. I have added the impls crate to write an easy test for the Lastly I've formatted |
If you don't want the |
Why? match self {
Self::Some(val) => ...
} just becomes match *self {
Self::Some(ref val) => ...
} This shouldn't be a burden. The code like
It still may have sense for trait bounds in generics contexts where |
I agree and changed the PR accordingly. Now we use |
@tvercruyssen for the nightly backtrace errors we should wait #195 being resolved. This will happen soon. @JelteF additionally, could you move |
Display
match
statement for empty enums
I've changed the title of the PR to reflect what the current changes will do. |
This removes a match arm that will never be triggered for non empty enums.
So now only if their are no arms in the enum will the code for empty enums be generated.
This changes no functionally and is a bug fix.