-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
clap_derive can parse arbitrary Rust code, which is not always necessary and costs compile time #5657
Comments
Note that anything we do here would be a breaking change. For myself, I feel like feature flags are a crude tool to work with and try as much as possible to reduce their use. From what you've described, I'm not sure there is enough benefit for this to outweigh that cost. If we do anything with this, know of any good documentation on the difference between |
I haven't found much documentation on the difference when I looked into this, but there are clues. The doc comment for syn::Expr says "most of the variants are not available unless “full” is enabled" and each variant just wraps an
Looking at this list, ExprRange and possibly ExprArray ( |
If someone is willing to see if |
While preparing to open a syn issue, I found out it already has some support for handling these and other expressions without "full", if only to figure out the extent of the expression and package those parts of the token stream into the enum Foo {
A = [1, 2, 3].len(),
B = range_length(4..9),
C = (|x| x * 2)(6),
} This was added specifically for discriminant expressions (dtolnay/syn#1513). As far as I can tell, it currently can't be used for anything else, like clap_derive's attribute parsing, but that doesn't seem like a fundamental limitation. Exposing this ability may be an easier ask (fewer downsides e.g. for compile time) than moving more code from "full" into "derive". The behavioral differences would be:
So now my plan changed to asking syn to expose this "recognize expression, stuff tokens in |
I would be open to using that! |
Please complete the following tasks
Clap Version
4.5.15
Describe your use case
I have a workspace where I care a little too much about build times (e.g., for iterating on cargo profile settings / RUSTFLAGS) and use a handful of syn-based custom derives, including clap's. Unlike most other derives I've seen (and unlike all others I'm using in this workspace), clap_derive enables syn's "full" feature that enables parsing arbitrary expressions, items, etc. instead of just the parts that are usually needed for derives. This has negative effects for compilation time (cc #2037):
cargo test
, out of ca. 10s total) because there happens to be enough independent work for the number of CPUs I have and another critical path in the schedule. It matters more in smaller workspaces (or with more CPUs, presumably), e.g., for the git-derive example by itself, disabling syn/full reduces clean dev builds from 5s to 4.3s on my machine.Describe the solution you'd like
Ideally, the syn/full feature could just be removed completely (cc #4784). clap_derive does build when the feature is removed (some care is needed while testing this because several dev-dependencies in clap's workspace enable it anyway), but some uses of the derives break because syn can't parse some kinds of expressions without the "full" feature. I don't have a full list of what's affected, but at least it causes an error for
arg(num_args = n..=m)
as used e.g., in the git-derive example. From my understanding of how clap_derive works, I think it's always possible to work around this by extracting those expressions into separate constants, but that's still annoying and a breaking change.On the other hand, many simpler expressions (literals, identifiers, paths, binary operators, taking references, etc.) don't seem to be affected. Case in point, my aforementioned workspace works just fine if test a patched version of clap_derive minus syn/full via
[patch.crates-io]
. So instead I propose a new feature, enabled by default, flag that controls whether syn/full is enabled. Those who care to fiddle around with feature flags and find that disabling this one doesn't break their project can do so, while everyone else is unaffected.Alternatives, if applicable
In addition to or instead of a new feature flag, the breaking change of not enabling syn/full (by default or ever) could be rolled into clap v5. But I don't seriously want to propose this without fully understanding the consequences. Are there any clap features that would become annoying or even impossible to use via the derive API without syn/full? For example, is there an ergonomic alternative for
num_args = n..=m
?Additional Context
No response
The text was updated successfully, but these errors were encountered: