-
-
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
Implement @deprecated
#22898
base: master
Are you sure you want to change the base?
Implement @deprecated
#22898
Conversation
because of allow-deprecated flags used by `@deprecated`
@@ -284,6 +285,7 @@ pub fn init( | |||
.owner = owner, | |||
.root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null, | |||
.import_table = .{}, | |||
.allow_deprecated = owner.graph.allow_deprecated orelse !owner.is_root, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this version of the code modules track individually whether they're allowed to use deprecated code or not, giving to users the option of overriding the default behavior. See later comments for an alternative way of approaching this, although AFAIK it's not possible to make this system fully abuse-proof.
@@ -94,6 +94,9 @@ available_deps: AvailableDeps, | |||
|
|||
release_mode: ReleaseMode, | |||
|
|||
// True only for the top-level builder. | |||
is_root: bool = false, | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I'm aware whichever way this functionality is implemented requires tracking this information, which could be abused by users, for example by making the root builder forget that it's the root one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that while this could be abused, there's no way around it.
@@ -557,6 +559,10 @@ pub fn appendZigProcessFlags( | |||
try addFlag(zig_args, m.pic, "-fPIC", "-fno-PIC"); | |||
try addFlag(zig_args, m.red_zone, "-mred-zone", "-mno-red-zone"); | |||
|
|||
if (m.root_source_file != null) { | |||
try addFlag(zig_args, m.allow_deprecated, "-fallow-deprecated", "-fno-allow-deprecated"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's desirable to prevent individual modules in the Zig build system from overriding their allow-deprecated behavior, here we could instead check the is_root
property of the builder that owns m
.
As mentioned earlier this would not be a full solution though, since the root builder could be modified by the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a better idea. It's not so much that we want to stop people from sneakily changing the field; it's more that this is just a simpler way to do it (don't duplicate data needlessly!).
I definitely don't think the build system should support changing this flag on a per-module basis for now; assume YAGNI.
@@ -523,6 +523,8 @@ const usage_build_generic = | |||
\\ -fno-sanitize-thread Disable Thread Sanitizer | |||
\\ -ffuzz Enable fuzz testing instrumentation | |||
\\ -fno-fuzz Disable fuzz testing instrumentation | |||
\\ -fallow-deprecated Allow usage of deprecated code | |||
\\ -fno-allow-deprecated Disallow usage of deprecated code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've only added these flags for zig build
(in the build runner) and here for modules, which means that the flags can't be used directly with zig build-exe
or zig run
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what you mean here. What you've changed here is the usage string and arg handling loop for build-exe
, run
, etc. Clearly you can pass this to build-exe
; otherwise, the build system wouldn't be able to pass it. What did you mean by this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm saying that zig build-exe foo.zig -fallow-deprecated
doesn't work, because that's a module flag, not a global flag.
Maybe a global flag is desirable but then I'm not sure if it's ok for all of those to have the same name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not how this works. If you never use -M
, there's effectively an implicit -Mroot=the_source_file_you_passed
at the end. If per-module flags didn't work with an implicit root module, then huge chunks of the compiler usage would be broken.
378c387
to
a46c2b2
Compare
mlugg suggested a better way of implementing analysis of an istruction that cannot be referenced by other instructions.
a46c2b2
to
a9d609a
Compare
Can't wait to use this immediately, like this: if (std.meta.hasMethod(T, "format")) {
if (fmt.len > 0 and fmt[0] == 'f') {
return value.format(fmt[1..], options, bw);
} else {
@deprecated();
// After 0.14.0 is tagged, uncomment this next line:
//@compileError("ambiguous format string; specify {f} to call format method, or {any} to skip it");
//and then delete the `hasMethod` condition
return value.format(fmt, options, bw);
}
} |
@andrewrk rewiew it and it's all yours :^) |
<pre>{#syntax#}@deprecated() void{#endsyntax#}</pre> | ||
<p> | ||
Used to mark a given code path as deprecated. It evaluates to the same value | ||
passed in as argument, or the {#syntax#}void{#endsyntax#} value when given none. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
passed in as argument, or the {#syntax#}void{#endsyntax#} value when given none. | |
passed in as argument, or to {#syntax#}{}{#endsyntax#} value when no argument is given. |
Mainly the first bit; "the void value" reads like it might literally mean void
As an example, in Zig 0.14.0 {#syntax#}std.time.sleep{#endsyntax#} was | ||
deprecated and the sleep function was moved to {#syntax#}std.Thread.sleep{#endsyntax#}. | ||
This is how this deprecation could have been expressed: | ||
|
||
{#syntax_block|zig|lib/std/time.zig#} | ||
pub const sleep = @deprecated(std.Thread.sleep); // moved | ||
{#end_syntax_block#} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The langref ought not to refer to specific old deprecations IMO. Perhaps:
As an example, in Zig 0.14.0 {#syntax#}std.time.sleep{#endsyntax#} was | |
deprecated and the sleep function was moved to {#syntax#}std.Thread.sleep{#endsyntax#}. | |
This is how this deprecation could have been expressed: | |
{#syntax_block|zig|lib/std/time.zig#} | |
pub const sleep = @deprecated(std.Thread.sleep); // moved | |
{#end_syntax_block#} | |
For instance, consider a function which is moved to a different namespace, with a deprecated alias in the old namespace for compatibility. This is written as follows: | |
{#syntax_block|zig|old_namespace.zig#} | |
pub const my_function = @deprecated(new_namespace.my_function); // moved | |
{#end_syntax_block#} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, is it correct for syntax blocks to be inside a <p>
? IIRC they should be outside of it, but I haven't checked.
{#end_syntax_block#} | ||
</p> | ||
<p> | ||
By default it is a <b>compile error</b> to depend on deprecated code in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default it is a <b>compile error</b> to depend on deprecated code in | |
By default it is a <b>compile error</b> to reference deprecated code in |
"depend on" is vague
</p> | ||
|
||
<p> | ||
{#syntax#}@deprecated{#endsyntax#} can also be used without argument: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{#syntax#}@deprecated{#endsyntax#} can also be used without argument: | |
Using {#syntax#}@deprecated{#endsyntax#} without an argument can be useful inside of blocks: |
We already know this usage exists; more helpfully, say why it exists!
@@ -557,6 +559,10 @@ pub fn appendZigProcessFlags( | |||
try addFlag(zig_args, m.pic, "-fPIC", "-fno-PIC"); | |||
try addFlag(zig_args, m.red_zone, "-mred-zone", "-mno-red-zone"); | |||
|
|||
if (m.root_source_file != null) { | |||
try addFlag(zig_args, m.allow_deprecated, "-fallow-deprecated", "-fno-allow-deprecated"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a better idea. It's not so much that we want to stop people from sneakily changing the field; it's more that this is just a simpler way to do it (don't duplicate data needlessly!).
I definitely don't think the build system should support changing this flag on a per-module basis for now; assume YAGNI.
@@ -523,6 +523,8 @@ const usage_build_generic = | |||
\\ -fno-sanitize-thread Disable Thread Sanitizer | |||
\\ -ffuzz Enable fuzz testing instrumentation | |||
\\ -fno-fuzz Disable fuzz testing instrumentation | |||
\\ -fallow-deprecated Allow usage of deprecated code | |||
\\ -fno-allow-deprecated Disallow usage of deprecated code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what you mean here. What you've changed here is the usage string and arg handling loop for build-exe
, run
, etc. Clearly you can pass this to build-exe
; otherwise, the build system wouldn't be able to pass it. What did you mean by this?
{ | ||
const case = ctx.obj("usage of deprecated code", b.graph.host); | ||
|
||
case.addError( | ||
\\const bad = @deprecated(42); | ||
\\ | ||
\\pub export fn foo() usize { | ||
\\ return bad; | ||
\\} | ||
, &[_][]const u8{ | ||
":1:13: error: found deprecated code", | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file should have a big comment at the top saying "DON'T PUT THINGS HERE" :P
Please put this test in test/cases/compile_errors/deprecated.zig
(or something like that) instead.
// Test `zig build -fallow-deprecated`. | ||
|
||
const deprecated_check: std.Build.Step.Run.StdIo.Check = .{ | ||
.expect_stderr_match = "found deprecated code", | ||
}; | ||
|
||
const tmp_path = b.makeTempPath(); | ||
|
||
// create custom main.zig file containing a deprecated decl | ||
{ | ||
const new_main_src = | ||
\\const bad = @deprecated(42); | ||
\\ | ||
\\pub fn main() u8 { | ||
\\ return bad; | ||
\\} | ||
\\ | ||
\\test { | ||
\\ if (bad != 42) return error.Bad; | ||
\\} | ||
; | ||
|
||
var src_dir = std.fs.cwd().makeOpenPath(b.pathJoin(&.{ tmp_path, "src" }), .{}) catch unreachable; | ||
defer src_dir.close(); | ||
|
||
var main = src_dir.createFile("main.zig", .{}) catch unreachable; | ||
defer main.close(); | ||
|
||
main.writeAll(new_main_src) catch unreachable; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't your fault, since you've just taken it from some of the surrounding cases, but... ooh, using std.fs
in a build script is very naughty. I'm not gonna ask you to change this for now, though, since you're just following the surrounding cases.
However, these should be @panic
s, not unreachable
; please do fix that.
Implements #22822
The part I'm most unsure about this implementation relates to how the build system represents
-fallow-deprecated
and-fno-allow-deprecated
internally and how then this is reflected in the CLI invocation ofbuild-exe
and related subcommands.