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

Fix transparency and behavior of shared attribute formatting on enums (#377, #411) #395

Merged
merged 14 commits into from
Jan 3, 2025
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## 1.0.1 - Unreleased

### Fixed

- A top level `#[display("...")]` attribute on an enum being incorrectly
treated as transparent.
([#395](https://github.com/JelteF/derive_more/pull/395))


## 1.0.0 - 2024-08-07
Expand Down
18 changes: 10 additions & 8 deletions impl/src/fmt/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,18 @@ impl<'a> Expansion<'a> {
fn generate_body(&self) -> syn::Result<TokenStream> {
let mut body = TokenStream::new();

// If `shared_attr` is a transparent call, then we consider it being absent.
let has_shared_attr = self
let shared_attr_contains_variant = self
.shared_attr
.map_or(false, |a| a.transparent_call().is_none());
.map_or(true, |a| a.contains_arg("_variant"));

if !has_shared_attr
|| self
.shared_attr
.map_or(true, |a| a.contains_arg("_variant"))
{
// If `shared_attr` is a transparent call to `_variant`, then we consider it being absent.
let has_shared_attr = self.shared_attr.map_or(false, |attr| {
attr.transparent_call().map_or(true, |(_, called_trait)| {
&called_trait != self.trait_ident || !shared_attr_contains_variant
})
});

if !has_shared_attr || shared_attr_contains_variant {
body = match &self.attrs.fmt {
Some(fmt) => {
if has_shared_attr {
Expand Down
45 changes: 45 additions & 0 deletions tests/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1445,6 +1445,28 @@ mod enums {
}
}

mod only_field {
use super::*;

#[derive(Display)]
#[display("{_0}")]
enum Enum<T> {
#[display("A")]
tyranron marked this conversation as resolved.
Show resolved Hide resolved
A(i32),
#[display("B")]
B(&'static str),
#[display("C")]
C(T),
}

#[test]
fn assert() {
assert_eq!(Enum::<u8>::A(1).to_string(), "1");
assert_eq!(Enum::<u8>::B("abc").to_string(), "abc");
assert_eq!(Enum::<u8>::C(9).to_string(), "9");
}
}

mod use_field_and_variant {
use super::*;

Expand All @@ -1467,6 +1489,29 @@ mod enums {
}
}

mod as_debug {
use super::*;

#[derive(Debug, Display)]
#[display("{self:?}")]
enum Enum {
#[display("A {_0}")]
A(i32),
#[display("B {}", field)]
B {
field: i32,
},
C,
}

#[test]
fn assert() {
assert_eq!(Enum::A(1).to_string(), "A(1)");
assert_eq!(Enum::B { field: 2 }.to_string(), "B { field: 2 }");
assert_eq!(Enum::C.to_string(), "C");
}
}

mod pointer {
use super::*;

Expand Down