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

implicitly require fmt::Display on all type parameters unless overridden #28

Merged

Conversation

cosmicexplorer
Copy link
Contributor

@cosmicexplorer cosmicexplorer commented Jun 16, 2021

Problem

I love this crate!! I wanted to use it on an enum struct with a type parameter but I ran into the Problem in #19!

Solution

Adding the Display impl

I didn't take a look at derive_more as mentioned in #19; instead, I noticed that we are not modifying struct or enum definitions to implicitly require fmt::Display, but that our own fmt::Display impl was unable to infer it for arguments which depended on a type parameter. For example, the following fails to compile right now:

use displaydoc::Display;

/// oh no, an error: {0}
#[derive(Display)]
pub struct Error<E>(pub E);

let error: Error<&str> = Error("muahaha i am an error");
assert!("oh no, an error: muahaha i am an error" == &format!("{}", error));

Producing:

error[E0599]: the method `__displaydoc_display` exists for reference `&E`, but its trait bounds were not satisfied
 --> src/lib.rs:41:1
  |
6 | /// oh no, an error: {0}
  | ^^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `&E` due to unsatisfied trait bounds
  |
  = note: the following trait bounds were not satisfied:
          `E: std::fmt::Display`
          which is required by `&E: DisplayToDisplayDoc`

So I basically just tried to hack it so that where E: core::fmt::Display would be written where we generate our Display impl.

Result

The benefit of this change is that it lets an enum deriving displaydoc::Display become usable as a generic parameterized result type for a generic method without making that enum have to carry the where _: Display, as demonstrated below. This behavior is very similar to the built-in #[derive(...)] macros for Debug, PartialEq, Hash, etc:

  /// Each individual element that can be matched against some input in a case.
  #[derive(Debug, Display, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
  pub enum CaseElement<Lit, PR> {
    /// literal value {0}
    Lit(Lit),
    /// production reference {0}
    Prod(PR),
  }

@cosmicexplorer
Copy link
Contributor Author

Realized the "shoddy workaround" would break existing code, so was thinking about changing this to not adding the where _: Display clause if there are any predicate clauses for that type parameter already, and not try to scan for "Display" specifically. Will try to implement that now.

@cosmicexplorer
Copy link
Contributor Author

Done!

@cosmicexplorer cosmicexplorer force-pushed the allow-display-if-param-impls-display branch from d23ecba to efa8f4d Compare June 16, 2021 18:45
Copy link
Owner

@yaahc yaahc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is amazing Danny, thank you for this PR, particularly the comments which made reviewing this a breeze.

I love this crate!!

This brings me joy 😄

src/lib.rs Outdated Show resolved Hide resolved
src/expand.rs Outdated Show resolved Hide resolved
src/expand.rs Outdated Show resolved Hide resolved
src/expand.rs Outdated Show resolved Hide resolved
src/expand.rs Outdated Show resolved Hide resolved
@yaahc
Copy link
Owner

yaahc commented Aug 10, 2021

Hey @cosmicexplorer, are you still interested in landing this change?

@cosmicexplorer cosmicexplorer force-pushed the allow-display-if-param-impls-display branch from efa8f4d to 92571d2 Compare August 13, 2021 02:35
@cosmicexplorer
Copy link
Contributor Author

cosmicexplorer commented Oct 8, 2021

Yes! I ended up moving across the country very soon after providing this first draft and there's absolutely no reason I should have put this off as it remains useful to me! Upon finally mustering the courage to check over your comments just now I'm seeing that I need to think a little harder about where constraints e.g. where crate::Type: Display as you mentioned! I seem to recall that part was very much a first draft and I wish I'd written down my thinking in comments at the time!

Sorry for making this drag out so long, I will respond to the rest of your comments by tomorrow. Thanks for your patience!

@cosmicexplorer cosmicexplorer force-pushed the allow-display-if-param-impls-display branch 2 times, most recently from 0fdbb0a to 3b74bb0 Compare October 8, 2021 21:27
@yaahc
Copy link
Owner

yaahc commented Oct 8, 2021

Sorry for making this drag out so long, I will respond to the rest of your comments by tomorrow. Thanks for your patience!

No problem at all, take your time Danny.

@cosmicexplorer cosmicexplorer force-pushed the allow-display-if-param-impls-display branch 9 times, most recently from 2412bec to f6433f4 Compare October 8, 2021 22:37
src/expand.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
@yaahc
Copy link
Owner

yaahc commented Oct 8, 2021

Gonna bump the MSRV to 1.45 to make mixed_site compile then I'll restart the CI.

@cosmicexplorer cosmicexplorer force-pushed the allow-display-if-param-impls-display branch from 1286462 to cf6a9f7 Compare October 9, 2021 01:26
- add doctest and FAQ
- clarify that if fields impl Debug, they don't need to impl Display
- make pedantic spelling change
- add note on how destructuring is used for format strings
- clarify the mechanism of adding Display only when otherwise unconstrained and add TODO
@cosmicexplorer cosmicexplorer force-pushed the allow-display-if-param-impls-display branch from cf6a9f7 to e2cb86f Compare October 9, 2021 01:33
@yaahc
Copy link
Owner

yaahc commented Oct 11, 2021

Thank you again!

@yaahc yaahc merged commit 7159bb5 into yaahc:master Oct 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants