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

Support const evaluation #169

Open
mirsella opened this issue Oct 31, 2024 · 3 comments
Open

Support const evaluation #169

mirsella opened this issue Oct 31, 2024 · 3 comments
Labels
feature request A new feature is requested

Comments

@mirsella
Copy link

the Builder method generated isn't const, and so we can't create use bon when declaring const without using a lazycell.

my use case is im writing a game with a lot of cards, and im declaring the stats of the card in a struct and building with bon.
ideally my Trait Card would have a Card::STATS with my Stats struct.

thanks !

A note for the community from the maintainers

Please vote on this issue by adding a 👍 reaction to help the maintainers with prioritizing it. You may add a comment describing your real use case related to this issue for us to better understand the problem domain.

@Veetaha
Copy link
Contributor

Veetaha commented Oct 31, 2024

Hi, thank you for creating the issue!

I tried to test if this is at all possible. I expanded the code for the following macro usage via Rust Analyzer, edited it manually and managed to make it const-compatible:

#[derive(bon::Builder)]
struct Point {
    x: i32,
    y: i32,
}

What did I have to change?

  • Replace the usage of Default::default() that constructs a tuple of Option<T> with manual (None, None)
  • Replace the usage of Option::unwrap_unchecked() with manual match ... { Some(x) => x, None => std::hint::unreachable_unchecked() }

What other limitations are anticipated

Other than that I expect the following to never work for const builders unless Rust language ships rust-lang/rust#67792:

  • #[builder(default)] can not work because Default::default() is not const. You'd have to write #[builder(default = ...)] instead to construct the default value manually
  • #[builder(into)] can not work because Into::into() is not const

How would the API look like?

I imagine having a #[builder(const)] attribute for #[derive(Builder)] that would enable const on all builder methods. For function syntax: marking them const using the usual rust syntax (i.e. const fn) should also make the builder const-compatible.

I can immediately tell that parsing the attribute #[builder(const)] will be a PITA because syn doesn't support parsing keywords like that. It expects a Path as a key (dtolnay/syn#1458). Easier solutions would be #[builder(const_)] or #[builder(konst)] or #[builder(sig(const))], but that sucks, and I guess this feature would require a big rewrite of bon's attribute parsing code that currently depends on darling and nested syn::Meta syntax.

I fear the problem of parsing #[builder(const)] will require doing something like what David colin-kiegel/rust-derive-builder#310 attempted to do in derive_builder. I imagine this would unlock vis = pub (without quotes) syntax and potentially some other things in the future where the right-hand-side of key = value is not an Expr.

@Veetaha Veetaha added the feature request A new feature is requested label Oct 31, 2024
@mirsella
Copy link
Author

Thanks for the detailed answer ! if this is not doable now in rust, or would require too much weird behavior within bon, this can be closed (or kept open as a tracking issue for the future).

for my case, ill just alloc the struct instead of having a &'static.

Have a good day !

@Veetaha
Copy link
Contributor

Veetaha commented Oct 31, 2024

This is definitely doable, but with some compromises that I think would be obvious to the user.
To me personally, the biggest problem is parsing #[builder(const)], which seems like a trivial thing. It could be localized though and not require rewriting parsing of all attributes with a workaround custom FromMeta impl like there already is one for #[builder(on())].

Indeed, let's keep this issue open and track 👍 reactions to see if there is more demand for this.

@Veetaha Veetaha changed the title support const Support const evaluation Nov 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request A new feature is requested
Projects
None yet
Development

No branches or pull requests

2 participants