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

Conversation

tyranron
Copy link
Collaborator

@tyranron tyranron commented Aug 9, 2024

Follows #377
Resolves #411

Synopsis

At the moment, the following example:

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

expand incorrectly as:

#[automatically_derived]
impl derive_more::Display for Enum {
    fn fmt(&self, __derive_more_f: &mut derive_more::core::fmt::Formatter<'_>) -> derive_more::core::fmt::Result {
        match self {
            Self::A(_0) => { derive_more::core::write!(__derive_more_f, "A {_0}", _0 = *_0) }
            Self::B {
                field
            } => { derive_more::core::write!(__derive_more_f, "B {}", field, ) }
            Self::C => { __derive_more_f.write_str("C") }
        } 
    } 
}

This is because transparency check of the shared #[display(...)] formatting attribute doesn't consider the actual trait, called transparently, in correspondence with the implemented trait.

Solution

Instead of

let has_shared_attr = self
    .shared_attr
    .map_or(false, |a| a.transparent_call().is_none());

do this

let has_shared_attr = self.shared_attr.map_or(false, |a| {
    a.transparent_call()
        .map_or(true, |(_, called_trait)| &called_trait != self.trait_ident)
});

Additionally

As discussed below, the original replacing behavior of a shared attribute (when it has no {_variant} placeholder) is deadly wrong, that's why this PR also changes it to acts as default one.

Checklist

  • Documentation is updated (not required)
  • Tests are added/updated
  • CHANGELOG entry is added

@tyranron tyranron self-assigned this Aug 9, 2024
@tyranron tyranron added the bug label Aug 9, 2024
@tyranron tyranron modified the milestones: 1.0.0, 1.1.0, 1.0.1 Aug 9, 2024
@tyranron tyranron marked this pull request as draft August 9, 2024 10:45
@tyranron tyranron marked this pull request as draft December 30, 2024 10:24
@tyranron tyranron changed the title Fix transparency check on shared attribute formatting on enums (#377) Fix transparency and behavior of shared attribute formatting on enums (#377, #411) Dec 30, 2024
@tyranron
Copy link
Collaborator Author

@JelteF as discussed above, I've extended tests suite to match the "defaulting" behavior when no {_variant} placeholder specified, thus introducing the breaking behavior we wanted. Also, I've described this more clear in derive(Display) docs.

@tyranron tyranron marked this pull request as ready for review December 30, 2024 10:37
@tyranron tyranron enabled auto-merge (squash) December 30, 2024 10:39
@tyranron tyranron requested a review from JelteF December 30, 2024 10:39
@tyranron tyranron merged commit 17d61c3 into master Jan 3, 2025
17 checks passed
@tyranron tyranron deleted the fix-shared-transparency-check branch January 3, 2025 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Change display on enum without _variant to "use as default" behaviour
2 participants