derive_more icon indicating copy to clipboard operation
derive_more copied to clipboard

Fix transparency check on shared attribute formatting on enums (#377)

Open tyranron opened this issue 1 year ago • 0 comments
trafficstars

Follows #377

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)
});

Checklist

  • [x] ~~Documentation is updated~~ (not required)
  • [x] Tests are added/updated
  • [x] CHANGELOG entry is added

tyranron avatar Aug 09 '24 10:08 tyranron