-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
@deprecated()
builtin
#22822
Comments
Can't wait for when we deprecate the |
Is there merit in requiring the author to provide a string or alternative symbol to steer users in the right direction? Is a comment on the same line enough? |
i think the rejection of #3320 and the demonstration of the userspace solution shows that this would fit much better as a standard library module or 3rd party package, than as a builtin |
Pros:
Cons:
My conclusion: Due to the virality of -fno-deprecated and the fundamental change to compile flags I think this should not be added. Maybe we add it but don't ever generate errors for it just so tooling/linters can reliably detect it. |
So maybe implement this as a std function
It should definitely take a comptime string as an argument. This would make the message more explicit than a comment, which can easily get overlooked. Something like this should work:
Maybe make this behavior configurable in the |
As proposed, Speaking purely in the context of As much as I hate the term "code smell" it's also important to realize that using a deprecated API is a code smell, not a bug; a questionable pattern in your code that you should probably address, but not something that should necessarily break your build until you fix it. Any solution to the problem with status quo deprecations should focus on addressing the question "how can we let users know that they are using a deprecated API?" before it tries to go for "how do we prevent users from using a deprecated API?". If there was some static analyzer or linter, either provided by a third-party or built into the |
Accepted, with adjustments:
In other words, maintainers by default cannot make the mistake of calling into deprecated API, however, the dependency tree by default will not fail in "other people's code" due to deprecations. To those who think this is the same thing as "sloppy mode": whereas sloppy mode would create two factions in the ecosystem who each prefer a different dialect of Zig, nobody wants to be using deprecated code. Programmers will naturally steer clear of any packages that require |
to clarify, you're saying the default should be that |
Yes Andrew is changing the default behavior. |
One pain point with deprecation for library authors is remembering when to turn a value into a compile error. Release schedules can be far apart, with deprecation being applied to many APIs over the course of months. Should an additional parameter fn deprecated(value: anytype, comptime until: []const u8) @TypeOf(value) {} For example: pub const sleep = @deprecated(std.Thread.sleep, "0.16.0"); Library authors would put the semantic version of when the value should be removed. And then when the build system attempts a build of the library with semantic version greater than or equal to "0.16.0" it would result in a compile error for the author. Edit: No, this is already possible in user space with |
How well will this play with #8284? Under MVS, if I directly depend on Package A version 1.4, but I also depend on Package B which in turn depends on Package A version 1.2, the build system will pick version 1.4 of Package A. If Package A has marked APIs with (Semver specifies that "minor version [...] MUST be incremented if any public API functionality is marked as deprecated". Deprecations are not considered backward-incompatible and don't require a major version bump.)
For third-party libraries, this may be true, but for At that point, the value of deprecation notices in |
Since the meaning of |
Ah, now that's a delightfully productive question. Note that this case still fits the pattern that the project built fine with So it is still satisfying this use case:
However, I'm going to backtrack a little bit, because it is still a bit of a problem in the sense that the purpose of deprecation, as pointed out via the semver quote, is to have a grace period in which the code continues to compile by default. The thing that makes me willing to backtrack here is considering the fact that the deprecated API can simply be removed when it is time for it to be a compile error, and the purpose of tooling-aware deprecation, then, is specifically for avoiding compilation errors while providing an upgrade path. Anyway, here's the adjusted plan:
|
In my mind, it would be better to have a type of compile error, like the logging levels we have in loggers. |
Ah yes, lets call it a "warning" 🙃
To me this feels just like a distinction without a difference - why would I want to be using "sloppy" code either? Weakening Zig's stance on warnings specifically just for |
Motivation
It's already an established pattern in the Zig ecosystem to deprecate declarations first via a doc comment, and after a while by turning the old decl into a
@compileError
once the deprecation "grace period" is over, to then finally delete the decl altogether after some more time.Currently a user that is interested in discovering early which APIs are being deprecated must grep the codebase for the word, find the decl the comment refers to, and figure out if and where its being used (directly or not) in the codebase.
Conversely, a library author that wants to maintain backwards compatibility (i.e. avoid a major version bump for a v1 package) will not want to set deprecated decls to
@compileError
as that would be a compatibility breakage, never giving users an opportunity to leverage compile errors to migrate their API usage.It is possible today to implement a better solution entirely in userland:
Running
zig build -Ddeprecated
will turn deprecated decls in compile errors giving both a nice compiler-driven upgrade experience to users, while letting library authors maintain backwards compatibility.This pattern seems so useful that might be worth enshrining it as a standardized practice.
Proposal
Introduce a
@deprecated()
builtin and a new-fdeprecated
compiler flag to be used like so (this is a contrived example to showcase the workflow):A less contrived example would be the current deprecation of
std.time.sleep
in the Zig standard library:A second example: using
@deprecated
in a function body:Lastly, since
@deprecated
conveys intent more precisely, tooling like LSPs and linters could offer diagnostics about deprecation automatically to the user in a more streamlined fashion than with the full userland solution.A branch with
@deprecated
implemented can be found here: https://github.com/kristoff-it/zig/tree/deprecated-proposal (diff)The text was updated successfully, but these errors were encountered: