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

Add required bounds to derived impl #421

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

JustusFluegel
Copy link

@JustusFluegel JustusFluegel commented Feb 2, 2025

This is an attempt to make the derive macro for Diagnostic work better with generics, allowing to write code like for example

#[derive(Debug, thiserror::Error, miette::Diagnostic)
enum MyError<T> {
     #[error(transparent)]
     #[diagnostic(transparent)]
     Other(#[from] T).
     #[error("bar")]
     #[diagnostic(help = "baz")]
     Foo
}

This should for example make #162 just work, as well as things like

#[derive(Debug, thiserror::Error, miette::Diagnostic)
struct MyOtherError<T> {
     #[label]
     label: T
}

and the other supported attributes.

AFAIK the only gotcha with this implementation right now is that #[related] only works with concrete collection types and not with generic collections, but the type inside the collection can be generic. (meaning: Vec<T> works but not any arbitrary C where C: IntoIter<Item: Diagnostic>), and I think that is a current limitation of the rust compiler / the current Diagnostic trait design.

Questions: Do we want to gate this behind a feature flag since it pulls in extra-traits from syn and performs a bunch of extra work?

@JustusFluegel JustusFluegel marked this pull request as ready for review February 2, 2025 22:20
@JustusFluegel
Copy link
Author

This should be mostly good, I'll add some tests but I'd appreciate a comment-type review in the meantime if possible :)

@JustusFluegel
Copy link
Author

JustusFluegel commented Feb 3, 2025

ok tests are now there as well (thought I would do it later but I noticed
i had some extra time on hand so I did it now), I am sure there are some things I should change since this is a pretty big pr and I am not that familiar with this project but from my perspective this should be finished apart from that.

@JustusFluegel
Copy link
Author

JustusFluegel commented Feb 4, 2025

Oh and I just noticed since I added an explicit to_owned instead of just relying on an implicit copy for the label (I think, should test, maybe add a unit test for that?) #377 should work just fine as well. Since Copy ⊂ Clone ⊂ ToOwned this shouldn't actually be breaking (?), and make the derive strictly more flexible (although might be worth to check if that is actually the case)

@zkat zkat added the breaking A semver-major breaking change label Mar 2, 2025
@zkat
Copy link
Owner

zkat commented Mar 2, 2025

Putting it behind a feature flag seems wise, yes.

@zkat zkat removed the breaking A semver-major breaking change label Mar 2, 2025
@JustusFluegel
Copy link
Author

JustusFluegel commented Mar 3, 2025

Hi, as I am in the process of moving right now I will probably only get back to this the next weekend or so, but my current plan for this is:

  • Add the suggested feature flag ( I would probably name it perfect_derive which aligns with other work on the same idea across the ecosystem )
    • Since we don't add bounds to the impl at all right now this should be a purely additive feature, which is what all feature flags should be
  • Write a higher level summary on the changes of this pr
    • explicitly list all the codegen changes inside the derive macro ( to make it easier to spot accidental breaking changes in review, even though I didn't mean to introduce any )
    • summarize how this feature actually works
  • Add docs to document the feature flag in more detail on both docs.rs as well crates.io ( if applicable )
  • fix the ci breakages
  • and, since I thought a bit more about the changes I did here I think I found a few ways to simplify things that I am then also going to do while I am at it :)

And finally, after all this is done I should probably prepare a change log entry, so I am going to do that as well.

If that sounds like a reasonable plan feel free to let me know what you think (or any other things I should do) otherwise I would just go ahead with that plan once I've got some more time to work on this ( as I've mentioned probably around next weekend )

@JustusFluegel
Copy link
Author

( accidentally pressed the close button, sorry for the noise )

This is implemented using a new TypeBoundsStore struct which tracks
usage of types during parsing and stores required bounds for generics,
trying to use some heuristics to remove unneeded bounds.

Signed-off-by: Justus Fluegel <[email protected]>
Signed-off-by: Justus Flügel <[email protected]>
Signed-off-by: Justus Fluegel <[email protected]>
Signed-off-by: Justus Flügel <[email protected]>
…ementation strictly more flexible using to_owned over clone

Signed-off-by: Justus Fluegel <[email protected]>
Signed-off-by: Justus Flügel <[email protected]>
@JustusFluegel JustusFluegel force-pushed the add-required-bounds-while-deriving branch 4 times, most recently from 661f537 to e35e69e Compare March 10, 2025 21:10
@JustusFluegel JustusFluegel force-pushed the add-required-bounds-while-deriving branch from e35e69e to ea48010 Compare March 10, 2025 21:14
@JustusFluegel JustusFluegel marked this pull request as draft March 11, 2025 11:25
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