authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-28 01:37:10-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-28 01:37:10-08:00
log6b6c1b1b0e04d70a4917f073a6a8bc87a5e8abb3
treec3b32e4ab3e3c081c9ab1091cd0ca860dc477c4f
parent5c44934e20fedb29b88616f51de70c92e5d4ba42

Revert "Merge pull request #22898 from kristoff-it/deprecated-proposal"

This reverts commit dea72d15da4fba909dc3ccb2e9dc5286372ac023, reversing changes made to ab381933c87bcc744058d25a876cfdc0d23fc674. The changeset does not work as advertised and does not have sufficient test coverage. Reopens #22822

17 files changed, 15 insertions(+), 251 deletions(-)

doc/langref.html.in+13-49
......@@ -2288,7 +2288,7 @@ or
22882288 {#code|test_aligned_struct_fields.zig#}
22892289
22902290 <p>
2291 Equating packed structs results in a comparison of the backing integer,
2291 Equating packed structs results in a comparison of the backing integer,
22922292 and only works for the `==` and `!=` operators.
22932293 </p>
22942294 {#code|test_packed_struct_equality.zig#}
......@@ -4086,7 +4086,7 @@ fn performFn(start_value: i32) i32 {
40864086 special-case syntax.
40874087 </p>
40884088 <p>
4089 Here is an example of a generic {#syntax#}List{#endsyntax#} data structure.
4089 Here is an example of a generic {#syntax#}List{#endsyntax#} data structure.
40904090 </p>
40914091 {#code|generic_data_structure.zig#}
40924092
......@@ -4291,10 +4291,10 @@ pub fn print(self: *Writer, arg0: []const u8, arg1: i32) !void {
42914291 <pre>{#syntax#}@addrSpaceCast(ptr: anytype) anytype{#endsyntax#}</pre>
42924292 <p>
42934293 Converts a pointer from one address space to another. The new address space is inferred
4294 based on the result type. Depending on the current target and address spaces, this cast
4295 may be a no-op, a complex operation, or illegal. If the cast is legal, then the resulting
4296 pointer points to the same memory location as the pointer operand. It is always valid to
4297 cast a pointer between the same address spaces.
4294 based on the result type. Depending on the current target and address spaces, this cast
4295 may be a no-op, a complex operation, or illegal. If the cast is legal, then the resulting
4296 pointer points to the same memory location as the pointer operand. It is always valid to
4297 cast a pointer between the same address spaces.
42984298 </p>
42994299 {#header_close#}
43004300 {#header_open|@addWithOverflow#}
......@@ -4307,7 +4307,7 @@ pub fn print(self: *Writer, arg0: []const u8, arg1: i32) !void {
43074307 <pre>{#syntax#}@alignCast(ptr: anytype) anytype{#endsyntax#}</pre>
43084308 <p>
43094309 {#syntax#}ptr{#endsyntax#} can be {#syntax#}*T{#endsyntax#}, {#syntax#}?*T{#endsyntax#}, or {#syntax#}[]T{#endsyntax#}.
4310 Changes the alignment of a pointer. The alignment to use is inferred based on the result type.
4310 Changes the alignment of a pointer. The alignment to use is inferred based on the result type.
43114311 </p>
43124312 <p>A {#link|pointer alignment safety check|Incorrect Pointer Alignment#} is added
43134313 to the generated code to make sure the pointer is aligned as promised.</p>
......@@ -4384,7 +4384,7 @@ comptime {
43844384 <pre>{#syntax#}@bitCast(value: anytype) anytype{#endsyntax#}</pre>
43854385 <p>
43864386 Converts a value of one type to another type. The return type is the
4387 inferred result type.
4387 inferred result type.
43884388 </p>
43894389 <p>
43904390 Asserts that {#syntax#}@sizeOf(@TypeOf(value)) == @sizeOf(DestType){#endsyntax#}.
......@@ -4741,42 +4741,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
47414741 {#see_also|@cVaArg|@cVaCopy|@cVaEnd#}
47424742 {#header_close#}
47434743
4744 {#header_open|@deprecated#}
4745 <pre>{#syntax#}@deprecated(value: anytype) @TypeOf(value){#endsyntax#}</pre>
4746 <pre>{#syntax#}@deprecated() void{#endsyntax#}</pre>
4747 <p>
4748 Marks a given code path as scheduled for removal. Evaluates to the same
4749 value passed in as argument, or the {#syntax#}void{#endsyntax#} value
4750 when given none.
4751 </p>
4752 <p>
4753 When a public declaration has been moved to a new location, the old
4754 location can be marked {#syntax#}@deprecated{#endsyntax#}:
4755 </p>
4756 {#syntax_block|zig|root.zig#}
4757pub const fooToBar = @deprecated(bar.fromFoo); // moved
4758 {#end_syntax_block#}
4759 <p>
4760 By default deprecated code paths are disallowed in a module defined by
4761 the root package but allowed in modules defined by the rest of the
4762 dependency tree. This behavior can be overridden by passing
4763 <code>-fallow-deprecated</code> or <code>-fno-allow-deprecated</code> to
4764 <code>zig build</code>.
4765 </p>
4766 <p>
4767 The purpose of {#syntax#}@deprecated{#endsyntax#} is to provide at least
4768 one version (a "grace period") of a package that supports both old and new APIs
4769 simultaneously, while providing tooling for programmers to discover what needs
4770 to be upgraded to migrate to the new API. Such a grace period has the key property
4771 that it allows a project's dependency tree to be upgraded <em>one package at a time</em>.
4772 </p>
4773 <p>
4774 Using {#syntax#}@deprecated{#endsyntax#} without an argument can be
4775 useful inside of conditionally compiled blocks:
4776 </p>
4777 {#code|test_deprecated_builtin.zig#}
4778 {#header_close#}
4779
47804744 {#header_open|@divExact#}
47814745 <pre>{#syntax#}@divExact(numerator: T, denominator: T) T{#endsyntax#}</pre>
47824746 <p>
......@@ -4891,8 +4855,8 @@ pub const fooToBar = @deprecated(bar.fromFoo); // moved
48914855 <pre>{#syntax#}@errorCast(value: anytype) anytype{#endsyntax#}</pre>
48924856 <p>
48934857 Converts an error set or error union value from one error set to another error set. The return type is the
4894 inferred result type. Attempting to convert an error which is not in the destination error
4895 set results in safety-checked {#link|Illegal Behavior#}.
4858 inferred result type. Attempting to convert an error which is not in the destination error
4859 set results in safety-checked {#link|Illegal Behavior#}.
48964860 </p>
48974861 {#header_close#}
48984862
......@@ -4971,7 +4935,7 @@ pub const fooToBar = @deprecated(bar.fromFoo); // moved
49714935 <pre>{#syntax#}@floatFromInt(int: anytype) anytype{#endsyntax#}</pre>
49724936 <p>
49734937 Converts an integer to the closest floating point representation. The return type is the inferred result type.
4974 To convert the other way, use {#link|@intFromFloat#}. This operation is legal
4938 To convert the other way, use {#link|@intFromFloat#}. This operation is legal
49754939 for all values of all integer types.
49764940 </p>
49774941 {#header_close#}
......@@ -5063,7 +5027,7 @@ pub const fooToBar = @deprecated(bar.fromFoo); // moved
50635027 <pre>{#syntax#}@intCast(int: anytype) anytype{#endsyntax#}</pre>
50645028 <p>
50655029 Converts an integer to another integer while keeping the same numerical value.
5066 The return type is the inferred result type.
5030 The return type is the inferred result type.
50675031 Attempting to convert a number which is out of range of the destination type results in
50685032 safety-checked {#link|Illegal Behavior#}.
50695033 </p>
......@@ -5316,7 +5280,7 @@ pub const fooToBar = @deprecated(bar.fromFoo); // moved
53165280 <pre>{#syntax#}@ptrFromInt(address: usize) anytype{#endsyntax#}</pre>
53175281 <p>
53185282 Converts an integer to a {#link|pointer|Pointers#}. The return type is the inferred result type.
5319 To convert the other way, use {#link|@intFromPtr#}. Casting an address of 0 to a destination type
5283 To convert the other way, use {#link|@intFromPtr#}. Casting an address of 0 to a destination type
53205284 which in not {#link|optional|Optional Pointers#} and does not have the {#syntax#}allowzero{#endsyntax#} attribute will result in a
53215285 {#link|Pointer Cast Invalid Null#} panic when runtime safety checks are enabled.
53225286 </p>
doc/langref/test_deprecated_builtin.zig deleted-22
......@@ -1,22 +0,0 @@
1test "deprecated code path" {
2 compute(.greedy, false, 42);
3}
4
5const Strategy = enum { greedy, expensive, fast };
6fn compute(comptime strat: Strategy, comptime foo: bool, bar: usize) void {
7 switch (strat) {
8 .greedy => {
9 // This combination turned out to be ineffective.
10 if (!foo) @deprecated(); // use fast strategy when foo is false
11 runGreedy(foo, bar);
12 },
13 .expensive => runExpensive(foo, bar),
14 .fast => runFast(foo, bar),
15 }
16}
17
18extern fn runGreedy(foo: bool, bar: usize) void;
19extern fn runExpensive(foo: bool, bar: usize) void;
20extern fn runFast(foo: bool, bar: usize) void;
21
22// test_error=deprecated
lib/compiler/build_runner.zig-8
......@@ -80,7 +80,6 @@ pub fn main() !void {
8080 .query = .{},
8181 .result = try std.zig.system.resolveTargetQuery(.{}),
8282 },
83 .root_builder = undefined, // populated below
8483 };
8584
8685 graph.cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() });
......@@ -95,7 +94,6 @@ pub fn main() !void {
9594 local_cache_directory,
9695 dependencies.root_deps,
9796 );
98 graph.root_builder = builder;
9997
10098 var targets = ArrayList([]const u8).init(arena);
10199 var debug_log_scopes = ArrayList([]const u8).init(arena);
......@@ -262,10 +260,6 @@ pub fn main() !void {
262260 graph.incremental = true;
263261 } else if (mem.eql(u8, arg, "-fno-incremental")) {
264262 graph.incremental = false;
265 } else if (mem.eql(u8, arg, "-fallow-deprecated")) {
266 graph.allow_deprecated = true;
267 } else if (mem.eql(u8, arg, "-fno-allow-deprecated")) {
268 graph.allow_deprecated = false;
269263 } else if (mem.eql(u8, arg, "-fwine")) {
270264 builder.enable_wine = true;
271265 } else if (mem.eql(u8, arg, "-fno-wine")) {
......@@ -1296,8 +1290,6 @@ fn usage(b: *std.Build, out_stream: anytype) !void {
12961290 \\ new Omit cached steps
12971291 \\ failures (Default) Only print failed steps
12981292 \\ none Do not print the build summary
1299 \\ -fallow-deprecated Allow usage of deprecated code for the entire build graph
1300 \\ -fno-allow-deprecated Disallow usage of deprecated code for the entire build graph
13011293 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
13021294 \\ --maxrss <bytes> Limit memory usage (default is to use available memory)
13031295 \\ --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss
lib/std/Build.zig-2
......@@ -121,8 +121,6 @@ pub const Graph = struct {
121121 random_seed: u32 = 0,
122122 dependency_cache: InitializedDepMap = .empty,
123123 allow_so_scripts: ?bool = null,
124 allow_deprecated: ?bool = null,
125 root_builder: *std.Build,
126124};
127125
128126const AvailableDeps = []const struct { []const u8, []const u8 };
lib/std/Build/Module.zig-4
......@@ -557,10 +557,6 @@ pub fn appendZigProcessFlags(
557557 try addFlag(zig_args, m.pic, "-fPIC", "-fno-PIC");
558558 try addFlag(zig_args, m.red_zone, "-mred-zone", "-mno-red-zone");
559559
560 // -fno-allow-deprecated is the CLI default, and not inherited, so only pass the flag if true.
561 const allow_deprecated = m.owner.graph.allow_deprecated orelse (m.owner.graph.root_builder != m.owner);
562 if (allow_deprecated == true) try zig_args.append("-fallow-deprecated");
563
564560 if (m.dwarf_format) |dwarf_format| {
565561 try zig_args.append(switch (dwarf_format) {
566562 .@"32" => "-gdwarf32",
lib/std/Build/Step/Options.zig-3
......@@ -514,7 +514,6 @@ test Options {
514514 .result = try std.zig.system.resolveTargetQuery(.{}),
515515 },
516516 .zig_lib_directory = std.Build.Cache.Directory.cwd(),
517 .root_builder = undefined,
518517 };
519518
520519 var builder = try std.Build.create(
......@@ -524,8 +523,6 @@ test Options {
524523 &.{},
525524 );
526525
527 graph.root_builder = builder;
528
529526 const options = builder.addOptions();
530527
531528 const KeywordEnum = enum {
lib/std/zig/AstGen.zig-13
......@@ -9695,19 +9695,6 @@ fn builtinCall(
96959695 .volatile_cast,
96969696 => return ptrCast(gz, scope, ri, node),
96979697
9698 .deprecated => {
9699 _ = try gz.addExtendedNodeSmall(.deprecated, node, 0);
9700 switch (params.len) {
9701 0 => return .void_value,
9702 1 => return expr(gz, scope, ri, params[0]),
9703 else => return astgen.failNode(
9704 node,
9705 "expected 0 or 1 argument, found {}",
9706 .{params.len},
9707 ),
9708 }
9709 },
9710
97119698 // zig fmt: off
97129699 .has_decl => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_decl),
97139700 .has_field => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_field),
lib/std/zig/AstRlAnnotate.zig+2-5
......@@ -817,6 +817,8 @@ fn blockExpr(astrl: *AstRlAnnotate, parent_block: ?*Block, ri: ResultInfo, node:
817817}
818818
819819fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.Node.Index, args: []const Ast.Node.Index) !bool {
820 _ = ri; // Currently, no builtin consumes its result location.
821
820822 const tree = astrl.tree;
821823 const main_tokens = tree.nodes.items(.main_token);
822824 const builtin_token = main_tokens[node];
......@@ -826,11 +828,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
826828 if (expected != args.len) return false;
827829 }
828830 switch (info.tag) {
829 .deprecated => if (args.len >= 1) {
830 return astrl.expr(args[0], block, ri);
831 } else {
832 return false;
833 },
834831 .import => return false,
835832 .branch_hint => {
836833 _ = try astrl.expr(args[0], block, ResultInfo.type_only);
lib/std/zig/BuiltinFn.zig-9
......@@ -121,7 +121,6 @@ pub const Tag = enum {
121121 work_item_id,
122122 work_group_size,
123123 work_group_id,
124 deprecated,
125124};
126125
127126pub const EvalToError = enum {
......@@ -1017,14 +1016,6 @@ pub const list = list: {
10171016 .illegal_outside_function = true,
10181017 },
10191018 },
1020 .{
1021 "@deprecated",
1022 .{
1023 .tag = .deprecated,
1024 .param_count = null,
1025 .eval_to_error = .maybe,
1026 },
1027 },
10281019 });
10291020};
10301021
lib/std/zig/Zir.zig-4
......@@ -2112,9 +2112,6 @@ pub const Inst = struct {
21122112 /// any code may have gone here, avoiding false-positive "unreachable code" errors.
21132113 astgen_error,
21142114
2115 /// `operand` is `src_node: i32`.
2116 deprecated,
2117
21182115 pub const InstData = struct {
21192116 opcode: Extended,
21202117 small: u16,
......@@ -4366,7 +4363,6 @@ fn findTrackableInner(
43664363 .tuple_decl,
43674364 .dbg_empty_stmt,
43684365 .astgen_error,
4369 .deprecated,
43704366 => return,
43714367
43724368 // `@TypeOf` has a body.
src/Compilation.zig-1
......@@ -868,7 +868,6 @@ pub const cache_helpers = struct {
868868 hh.add(mod.sanitize_c);
869869 hh.add(mod.sanitize_thread);
870870 hh.add(mod.fuzz);
871 hh.add(mod.allow_deprecated);
872871 hh.add(mod.unwind_tables);
873872 hh.add(mod.structured_cfg);
874873 hh.add(mod.no_builtin);
src/Package/Module.zig-10
......@@ -27,7 +27,6 @@ red_zone: bool,
2727sanitize_c: bool,
2828sanitize_thread: bool,
2929fuzz: bool,
30allow_deprecated: bool,
3130unwind_tables: std.builtin.UnwindTables,
3231cc_argv: []const []const u8,
3332/// (SPIR-V) whether to generate a structured control flow graph or not
......@@ -96,7 +95,6 @@ pub const CreateOptions = struct {
9695 sanitize_c: ?bool = null,
9796 sanitize_thread: ?bool = null,
9897 fuzz: ?bool = null,
99 allow_deprecated: ?bool = null,
10098 structured_cfg: ?bool = null,
10199 no_builtin: ?bool = null,
102100 };
......@@ -236,11 +234,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
236234 break :b false;
237235 };
238236
239 const allow_deprecated = b: {
240 if (options.inherited.allow_deprecated) |x| break :b x;
241 break :b false;
242 };
243
244237 const code_model = b: {
245238 if (options.inherited.code_model) |x| break :b x;
246239 if (options.parent) |p| break :b p.code_model;
......@@ -387,7 +380,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
387380 .sanitize_c = sanitize_c,
388381 .sanitize_thread = sanitize_thread,
389382 .fuzz = fuzz,
390 .allow_deprecated = allow_deprecated,
391383 .unwind_tables = unwind_tables,
392384 .cc_argv = options.cc_argv,
393385 .structured_cfg = structured_cfg,
......@@ -482,7 +474,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
482474 .sanitize_c = sanitize_c,
483475 .sanitize_thread = sanitize_thread,
484476 .fuzz = fuzz,
485 .allow_deprecated = allow_deprecated,
486477 .unwind_tables = unwind_tables,
487478 .cc_argv = &.{},
488479 .structured_cfg = structured_cfg,
......@@ -541,7 +532,6 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P
541532 .sanitize_c = undefined,
542533 .sanitize_thread = undefined,
543534 .fuzz = undefined,
544 .allow_deprecated = undefined,
545535 .unwind_tables = undefined,
546536 .cc_argv = undefined,
547537 .structured_cfg = undefined,
src/Sema.zig-11
......@@ -1091,7 +1091,6 @@ fn analyzeBodyInner(
10911091 const map = &sema.inst_map;
10921092 const tags = sema.code.instructions.items(.tag);
10931093 const datas = sema.code.instructions.items(.data);
1094 const mod = block.ownerModule();
10951094
10961095 var crash_info = crash_report.prepAnalyzeBody(sema, block, body);
10971096 crash_info.push();
......@@ -1405,16 +1404,6 @@ fn analyzeBodyInner(
14051404 i += 1;
14061405 continue;
14071406 },
1408 .deprecated => {
1409 if (!mod.allow_deprecated) {
1410 const src_node: i32 = @bitCast(extended.operand);
1411 const src = block.nodeOffset(src_node);
1412 return sema.fail(block, src, "reached deprecated code", .{});
1413 }
1414
1415 i += 1;
1416 continue;
1417 },
14181407 .disable_instrumentation => {
14191408 try sema.zirDisableInstrumentation();
14201409 i += 1;
src/main.zig-6
......@@ -520,8 +520,6 @@ const usage_build_generic =
520520 \\ -fno-sanitize-thread Disable Thread Sanitizer
521521 \\ -ffuzz Enable fuzz testing instrumentation
522522 \\ -fno-fuzz Disable fuzz testing instrumentation
523 \\ -fallow-deprecated Allow usage of deprecated code
524 \\ -fno-allow-deprecated Disallow usage of deprecated code
525523 \\ -funwind-tables Always produce unwind table entries for all functions
526524 \\ -fasync-unwind-tables Always produce asynchronous unwind table entries for all functions
527525 \\ -fno-unwind-tables Never produce unwind table entries
......@@ -1456,10 +1454,6 @@ fn buildOutputType(
14561454 mod_opts.fuzz = true;
14571455 } else if (mem.eql(u8, arg, "-fno-fuzz")) {
14581456 mod_opts.fuzz = false;
1459 } else if (mem.eql(u8, arg, "-fallow-deprecated")) {
1460 mod_opts.allow_deprecated = true;
1461 } else if (mem.eql(u8, arg, "-fno-allow-deprecated")) {
1462 mod_opts.allow_deprecated = false;
14631457 } else if (mem.eql(u8, arg, "-fllvm")) {
14641458 create_module.opts.use_llvm = true;
14651459 } else if (mem.eql(u8, arg, "-fno-llvm")) {
src/print_zir.zig-1
......@@ -535,7 +535,6 @@ const Writer = struct {
535535 .c_va_start,
536536 .in_comptime,
537537 .value_placeholder,
538 .deprecated,
539538 => try self.writeExtNode(stream, extended),
540539
541540 .builtin_src => {
test/cases/compile_errors/deprecated.zig deleted-9
......@@ -1,9 +0,0 @@
1const bad = @deprecated(42);
2
3pub export fn foo() usize {
4 return bad;
5}
6
7// error
8//
9// :1:13: error: reached deprecated code
test/tests.zig-94
......@@ -1176,100 +1176,6 @@ pub fn addCliTests(b: *std.Build) *Step {
11761176 step.dependOn(&cleanup.step);
11771177 }
11781178
1179 {
1180 // Test `zig build -fallow-deprecated`.
1181
1182 const deprecated_check: std.Build.Step.Run.StdIo.Check = .{
1183 .expect_stderr_match = "reached deprecated code",
1184 };
1185
1186 const tmp_path = b.makeTempPath();
1187
1188 // create custom main.zig file containing a deprecated decl
1189 {
1190 const new_main_src =
1191 \\const bad = @deprecated(42);
1192 \\
1193 \\pub fn main() u8 {
1194 \\ return bad;
1195 \\}
1196 \\
1197 \\test {
1198 \\ if (bad != 42) return error.Bad;
1199 \\}
1200 ;
1201
1202 var src_dir = std.fs.cwd().makeOpenPath(b.pathJoin(&.{ tmp_path, "src" }), .{}) catch @panic("unable to create tmp path");
1203 defer src_dir.close();
1204
1205 var main = src_dir.createFile("main.zig", .{}) catch @panic("unable to create main.zig");
1206 defer main.close();
1207
1208 main.writeAll(new_main_src) catch @panic("unable to write to main.zig");
1209 }
1210
1211 const init_exe = b.addSystemCommand(&.{ b.graph.zig_exe, "init" });
1212 init_exe.setCwd(.{ .cwd_relative = tmp_path });
1213 init_exe.setName("zig init");
1214 init_exe.expectStdOutEqual("");
1215 init_exe.expectStdErrEqual("info: created build.zig\n" ++
1216 "info: created build.zig.zon\n" ++
1217 "info: preserving already existing file: src" ++ s ++ "main.zig\n" ++
1218 "info: created src" ++ s ++ "root.zig\n");
1219
1220 const run_test_bad = b.addSystemCommand(&.{ b.graph.zig_exe, "build", "test", "--color", "off" });
1221 run_test_bad.setCwd(.{ .cwd_relative = tmp_path });
1222 run_test_bad.setName("zig build test");
1223 run_test_bad.expectExitCode(1);
1224 run_test_bad.expectStdOutEqual("");
1225 run_test_bad.addCheck(deprecated_check);
1226 run_test_bad.step.dependOn(&init_exe.step);
1227
1228 const run_test = b.addSystemCommand(&.{
1229 b.graph.zig_exe,
1230 "build",
1231 "test",
1232 "--color",
1233 "off",
1234 "-fallow-deprecated",
1235 });
1236 run_test.setCwd(.{ .cwd_relative = tmp_path });
1237 run_test.setName("zig build test");
1238 run_test.expectExitCode(0);
1239 run_test.expectStdOutEqual("");
1240 run_test.expectStdErrEqual("");
1241 run_test.step.dependOn(&init_exe.step);
1242
1243 const run_build_bad = b.addSystemCommand(&.{ b.graph.zig_exe, "build", "--color", "off" });
1244 run_build_bad.setCwd(.{ .cwd_relative = tmp_path });
1245 run_build_bad.setName("zig build test");
1246 run_build_bad.expectExitCode(1);
1247 run_build_bad.expectStdOutEqual("");
1248 run_build_bad.addCheck(deprecated_check);
1249 run_build_bad.step.dependOn(&init_exe.step);
1250
1251 const run_build = b.addSystemCommand(&.{
1252 b.graph.zig_exe,
1253 "build",
1254 "--color",
1255 "off",
1256 "-fallow-deprecated",
1257 });
1258 run_build.setCwd(.{ .cwd_relative = tmp_path });
1259 run_build.setName("zig build test");
1260 run_build.expectExitCode(0);
1261 run_build.expectStdOutEqual("");
1262 run_build.expectStdErrEqual("");
1263 run_build.step.dependOn(&init_exe.step);
1264
1265 const cleanup = b.addRemoveDirTree(.{ .cwd_relative = tmp_path });
1266 cleanup.step.dependOn(&run_test.step);
1267 cleanup.step.dependOn(&run_test_bad.step);
1268 cleanup.step.dependOn(&run_build.step);
1269 cleanup.step.dependOn(&run_build_bad.step);
1270
1271 step.dependOn(&cleanup.step);
1272 }
12731179 // Test Godbolt API
12741180 if (builtin.os.tag == .linux and builtin.cpu.arch == .x86_64) {
12751181 const tmp_path = b.makeTempPath();