From f16855b9d70c747423ee81f27d619694856d365b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 11 Sep 2022 21:35:07 -0700 Subject: [PATCH 1/6] remove pointless discards --- lib/std/Thread.zig | 1 - lib/std/heap/general_purpose_allocator.zig | 2 - lib/std/math.zig | 1 - src/AstGen.zig | 53 +++++++++++++++------- test/behavior/bugs/11165.zig | 2 - test/behavior/type.zig | 2 - test/behavior/type_info.zig | 8 +--- 7 files changed, 38 insertions(+), 31 deletions(-) diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index 20985c36a0..a611ff38de 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -404,7 +404,6 @@ fn callFn(comptime f: anytype, args: anytype) switch (Impl) { } // pthreads don't support exit status, ignore value - _ = status; return default_value; }, .ErrorUnion => |info| { diff --git a/lib/std/heap/general_purpose_allocator.zig b/lib/std/heap/general_purpose_allocator.zig index abffad751c..490d352da2 100644 --- a/lib/std/heap/general_purpose_allocator.zig +++ b/lib/std/heap/general_purpose_allocator.zig @@ -582,8 +582,6 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { old_align: u29, ret_addr: usize, ) void { - _ = old_align; - const entry = self.large_allocations.getEntry(@ptrToInt(old_mem.ptr)) orelse { if (config.safety) { @panic("Invalid free"); diff --git a/lib/std/math.zig b/lib/std/math.zig index d1c9326ae2..f519979349 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -171,7 +171,6 @@ pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool { } pub fn approxEq(comptime T: type, x: T, y: T, tolerance: T) bool { - _ = T; _ = x; _ = y; _ = tolerance; diff --git a/src/AstGen.zig b/src/AstGen.zig index 591c48e4d6..00889f9d2a 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -2685,11 +2685,7 @@ fn genDefers( } } -fn checkUsed( - gz: *GenZir, - outer_scope: *Scope, - inner_scope: *Scope, -) InnerError!void { +fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!void { const astgen = gz.astgen; var scope = inner_scope; @@ -2698,15 +2694,23 @@ fn checkUsed( .gen_zir => scope = scope.cast(GenZir).?.parent, .local_val => { const s = scope.cast(Scope.LocalVal).?; - if (!s.used) { + if (s.used == 0 and s.discarded == 0) { try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)}); + } else if (s.used != 0 and s.discarded != 0) { + try astgen.appendErrorTokNotes(s.discarded, "pointless discard of {s}", .{@tagName(s.id_cat)}, &[_]u32{ + try gz.astgen.errNoteTok(s.used, "used here", .{}), + }); } scope = s.parent; }, .local_ptr => { const s = scope.cast(Scope.LocalPtr).?; - if (!s.used) { + if (s.used == 0 and s.discarded == 0) { try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)}); + } else if (s.used != 0 and s.discarded != 0) { + try astgen.appendErrorTokNotes(s.discarded, "pointless discard of {s}", .{@tagName(s.id_cat)}, &[_]u32{ + try gz.astgen.errNoteTok(s.used, "used here", .{}), + }); } scope = s.parent; }, @@ -6848,11 +6852,10 @@ fn localVarRef( scope: *Scope, rl: ResultLoc, ident: Ast.Node.Index, - ident_token: Ast.Node.Index, + ident_token: Ast.TokenIndex, ) InnerError!Zir.Inst.Ref { const astgen = gz.astgen; const gpa = astgen.gpa; - const name_str_index = try astgen.identAsString(ident_token); var s = scope; var found_already: ?Ast.Node.Index = null; // we have found a decl with the same name already @@ -6865,7 +6868,11 @@ fn localVarRef( if (local_val.name == name_str_index) { // Locals cannot shadow anything, so we do not need to look for ambiguous // references in this case. - local_val.used = true; + if (rl == .discard) { + local_val.discarded = ident_token; + } else { + local_val.used = ident_token; + } const value_inst = try tunnelThroughClosure( gz, @@ -6884,7 +6891,11 @@ fn localVarRef( .local_ptr => { const local_ptr = s.cast(Scope.LocalPtr).?; if (local_ptr.name == name_str_index) { - local_ptr.used = true; + if (rl == .discard) { + local_ptr.discarded = ident_token; + } else { + local_ptr.used = ident_token; + } // Can't close over a runtime variable if (num_namespaces_out != 0 and !local_ptr.maybe_comptime) { @@ -7519,7 +7530,7 @@ fn builtinCall( .local_val => { const local_val = s.cast(Scope.LocalVal).?; if (local_val.name == decl_name) { - local_val.used = true; + local_val.used = ident_token; _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ .operand = local_val.inst, .options = try comptimeExpr(gz, scope, .{ .coerced_ty = .export_options_type }, params[1]), @@ -7533,7 +7544,7 @@ fn builtinCall( if (local_ptr.name == decl_name) { if (!local_ptr.maybe_comptime) return astgen.failNode(params[0], "unable to export runtime-known value", .{}); - local_ptr.used = true; + local_ptr.used = ident_token; const loaded = try gz.addUnNode(.load, local_ptr.ptr, node); _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ .operand = loaded, @@ -10065,11 +10076,15 @@ const Scope = struct { inst: Zir.Inst.Ref, /// Source location of the corresponding variable declaration. token_src: Ast.TokenIndex, + /// Track the first identifer where it is referenced. + /// 0 means never referenced. + used: Ast.TokenIndex = 0, + /// Track the identifier where it is discarded, like this `_ = foo;`. + /// 0 means never discarded. + discarded: Ast.TokenIndex = 0, /// String table index. name: u32, id_cat: IdCat, - /// Track whether the name has been referenced. - used: bool = false, }; /// This could be a `const` or `var` local. It has a pointer instead of a value. @@ -10084,14 +10099,18 @@ const Scope = struct { ptr: Zir.Inst.Ref, /// Source location of the corresponding variable declaration. token_src: Ast.TokenIndex, + /// Track the first identifer where it is referenced. + /// 0 means never referenced. + used: Ast.TokenIndex = 0, + /// Track the identifier where it is discarded, like this `_ = foo;`. + /// 0 means never discarded. + discarded: Ast.TokenIndex = 0, /// String table index. name: u32, id_cat: IdCat, /// true means we find out during Sema whether the value is comptime. /// false means it is already known at AstGen the value is runtime-known. maybe_comptime: bool, - /// Track whether the name has been referenced. - used: bool = false, }; const Defer = struct { diff --git a/test/behavior/bugs/11165.zig b/test/behavior/bugs/11165.zig index 60677743ad..828b7f2462 100644 --- a/test/behavior/bugs/11165.zig +++ b/test/behavior/bugs/11165.zig @@ -14,7 +14,6 @@ test "bytes" { .a = undefined, .c = "12345".*, // this caused problems }; - _ = s_1; var u_2 = U{ .s = s_1 }; _ = u_2; @@ -35,7 +34,6 @@ test "aggregate" { .a = undefined, .c = c, // this caused problems }; - _ = s_1; var u_2 = U{ .s = s_1 }; _ = u_2; diff --git a/test/behavior/type.zig b/test/behavior/type.zig index 8cef86b5dd..f59ac7cb27 100644 --- a/test/behavior/type.zig +++ b/test/behavior/type.zig @@ -486,7 +486,6 @@ test "Type.Union from Type.Enum" { .decls = &.{}, }, }); - _ = T; _ = @typeInfo(T).Union; } @@ -505,7 +504,6 @@ test "Type.Union from regular enum" { .decls = &.{}, }, }); - _ = T; _ = @typeInfo(T).Union; } diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 968c3e7490..76d67c8aec 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -425,12 +425,8 @@ fn generic2(comptime T: type, param: T, param2: u8) void { _ = param; _ = param2; } -fn generic3(param: anytype) @TypeOf(param) { - _ = param; -} -fn generic4(comptime param: anytype) @TypeOf(param) { - _ = param; -} +fn generic3(param: anytype) @TypeOf(param) {} +fn generic4(comptime param: anytype) @TypeOf(param) {} test "typeInfo with comptime parameter in struct fn def" { const S = struct { From 188902a710a64b08762d7731aab81cb695322184 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 11 Sep 2022 21:48:52 -0700 Subject: [PATCH 2/6] Sema: introduce Type.ptrAlignmentAdvanced I'm not sure why the other commits in this branch caused this fix to be necessary. Also, there seems to be more fixes necessary before tests will pass. --- src/Sema.zig | 22 +++++++++++----------- src/type.zig | 25 ++++++++++++++++++------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index f5e4402ea8..6e48fafeaf 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -17575,30 +17575,30 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const operand_coerced = try sema.coerce(block, Type.usize, operand_res, operand_src); const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; - const type_res = try sema.resolveType(block, src, extra.lhs); - try sema.checkPtrType(block, type_src, type_res); - try sema.resolveTypeLayout(block, src, type_res.elemType2()); - const ptr_align = type_res.ptrAlignment(sema.mod.getTarget()); + const ptr_ty = try sema.resolveType(block, src, extra.lhs); + const elem_ty = ptr_ty.elemType2(); + try sema.checkPtrType(block, type_src, ptr_ty); const target = sema.mod.getTarget(); + const ptr_align = try ptr_ty.ptrAlignmentAdvanced(target, sema.kit(block, src)); if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| { const addr = val.toUnsignedInt(target); - if (!type_res.isAllowzeroPtr() and addr == 0) - return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res.fmt(sema.mod)}); + if (!ptr_ty.isAllowzeroPtr() and addr == 0) + return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(sema.mod)}); if (addr != 0 and addr % ptr_align != 0) - return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res.fmt(sema.mod)}); + return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)}); const val_payload = try sema.arena.create(Value.Payload.U64); val_payload.* = .{ .base = .{ .tag = .int_u64 }, .data = addr, }; - return sema.addConstant(type_res, Value.initPayload(&val_payload.base)); + return sema.addConstant(ptr_ty, Value.initPayload(&val_payload.base)); } try sema.requireRuntimeBlock(block, src, operand_src); - if (block.wantSafety() and try sema.typeHasRuntimeBits(block, sema.src, type_res.elemType2())) { - if (!type_res.isAllowzeroPtr()) { + if (block.wantSafety() and try sema.typeHasRuntimeBits(block, sema.src, elem_ty)) { + if (!ptr_ty.isAllowzeroPtr()) { const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize); try sema.addSafetyCheck(block, is_non_zero, .cast_to_null); } @@ -17618,7 +17618,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment); } } - return block.addBitCast(type_res, operand_coerced); + return block.addBitCast(ptr_ty, operand_coerced); } fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { diff --git a/src/type.zig b/src/type.zig index ec7e155d4e..c72cf2be84 100644 --- a/src/type.zig +++ b/src/type.zig @@ -2715,8 +2715,12 @@ pub const Type = extern union { } /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit. - pub fn ptrAlignment(self: Type, target: Target) u32 { - switch (self.tag()) { + pub fn ptrAlignment(ty: Type, target: Target) u32 { + return ptrAlignmentAdvanced(ty, target, null) catch unreachable; + } + + pub fn ptrAlignmentAdvanced(ty: Type, target: Target, sema_kit: ?Module.WipAnalysis) !u32 { + switch (ty.tag()) { .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -2728,8 +2732,12 @@ pub const Type = extern union { .optional_single_const_pointer, .optional_single_mut_pointer, => { - const child_type = self.cast(Payload.ElemType).?.data; - return child_type.abiAlignment(target); + const child_type = ty.cast(Payload.ElemType).?.data; + if (sema_kit) |sk| { + const res = try child_type.abiAlignmentAdvanced(target, .{ .sema_kit = sk }); + return res.scalar; + } + return (child_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar; }, .manyptr_u8, @@ -2740,14 +2748,17 @@ pub const Type = extern union { => return 1, .pointer => { - const ptr_info = self.castTag(.pointer).?.data; + const ptr_info = ty.castTag(.pointer).?.data; if (ptr_info.@"align" != 0) { return ptr_info.@"align"; + } else if (sema_kit) |sk| { + const res = try ptr_info.pointee_type.abiAlignmentAdvanced(target, .{ .sema_kit = sk }); + return res.scalar; } else { - return ptr_info.pointee_type.abiAlignment(target); + return (ptr_info.pointee_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar; } }, - .optional => return self.castTag(.optional).?.data.ptrAlignment(target), + .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(target, sema_kit), else => unreachable, } From f8a9bc57ce1a2a5a1b90e9a33501b64f2dd79019 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 12 Sep 2022 19:37:03 -0700 Subject: [PATCH 3/6] translate-c: lower discards differently This makes translate-c lower discards as `_ = @TypeOf(foo);` to avoid tripping the "pointless discard" error. Ideally, translate-c would avoid emitting pointless discards, in which case this commit can be reverted, however, that is a separate enhancement. --- src/translate_c/ast.zig | 29 +++++++--- test/translate_c.zig | 114 ++++++++++++++++++++-------------------- 2 files changed, 78 insertions(+), 65 deletions(-) diff --git a/src/translate_c/ast.zig b/src/translate_c/ast.zig index 307a7e9ea7..ce88a1a292 100644 --- a/src/translate_c/ast.zig +++ b/src/translate_c/ast.zig @@ -1550,14 +1550,27 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { .main_token = try c.addToken(.identifier, "_"), .data = undefined, }); - return c.addNode(.{ - .tag = .assign, - .main_token = try c.addToken(.equal, "="), - .data = .{ - .lhs = lhs, - .rhs = try renderNode(c, payload.value), - }, - }); + const main_token = try c.addToken(.equal, "="); + if (payload.value.tag() == .identifier) { + // Render as `_ = @TypeOf(foo);` to avoid tripping "pointless discard" error. + return c.addNode(.{ + .tag = .assign, + .main_token = main_token, + .data = .{ + .lhs = lhs, + .rhs = try renderBuiltinCall(c, "@TypeOf", &.{payload.value}), + }, + }); + } else { + return c.addNode(.{ + .tag = .assign, + .main_token = main_token, + .data = .{ + .lhs = lhs, + .rhs = try renderNode(c, payload.value), + }, + }); + } }, .@"while" => { const payload = node.castTag(.@"while").?.data; diff --git a/test/translate_c.zig b/test/translate_c.zig index 54b4ad6081..ea2e441194 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -116,10 +116,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn foo() void { \\ while (true) if (true) { \\ var a: c_int = 1; - \\ _ = a; + \\ _ = @TypeOf(a); \\ } else { \\ var b: c_int = 2; - \\ _ = b; + \\ _ = @TypeOf(b); \\ }; \\ if (true) if (true) {}; \\} @@ -192,7 +192,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ .B = 0, \\ .C = 0, \\ }; - \\ _ = a; + \\ _ = @TypeOf(a); \\ { \\ const struct_Foo_1 = extern struct { \\ A: c_int, @@ -204,7 +204,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ .B = 0, \\ .C = 0, \\ }; - \\ _ = a_2; + \\ _ = @TypeOf(a_2); \\ } \\} }); @@ -233,24 +233,24 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ B: c_int, \\ C: c_int, \\ }; - \\ _ = union_unnamed_1; + \\ _ = @TypeOf(union_unnamed_1); \\ const Foo = union_unnamed_1; \\ var a: Foo = Foo{ \\ .A = @as(c_int, 0), \\ }; - \\ _ = a; + \\ _ = @TypeOf(a); \\ { \\ const union_unnamed_2 = extern union { \\ A: c_int, \\ B: c_int, \\ C: c_int, \\ }; - \\ _ = union_unnamed_2; + \\ _ = @TypeOf(union_unnamed_2); \\ const Foo_1 = union_unnamed_2; \\ var a_2: Foo_1 = Foo_1{ \\ .A = @as(c_int, 0), \\ }; - \\ _ = a_2; + \\ _ = @TypeOf(a_2); \\ } \\} }); @@ -318,7 +318,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ const bar_1 = struct { \\ threadlocal var static: c_int = 2; \\ }; - \\ _ = bar_1; + \\ _ = @TypeOf(bar_1); \\ return 0; \\} }); @@ -337,7 +337,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} \\pub export fn bar() c_int { \\ var a: c_int = 2; - \\ _ = a; + \\ _ = @TypeOf(a); \\ return 0; \\} \\pub export fn baz() c_int { @@ -352,7 +352,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , &[_][]const u8{ \\pub export fn main() void { \\ var a: c_int = @bitCast(c_int, @truncate(c_uint, @alignOf(c_int))); - \\ _ = a; + \\ _ = @TypeOf(a); \\} }); @@ -500,7 +500,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\#define bar(x) (&x, +3, 4 == 4, 5 * 6, baz(1, 2), 2 % 2, baz(1,2)) , &[_][]const u8{ \\pub const foo = blk: { - \\ _ = foo; + \\ _ = @TypeOf(foo); \\ break :blk bar; \\}; , @@ -724,7 +724,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn function(arg_opaque_1: ?*struct_opaque) void { \\ var opaque_1 = arg_opaque_1; \\ var cast: ?*struct_opaque_2 = @ptrCast(?*struct_opaque_2, opaque_1); - \\ _ = cast; + \\ _ = @TypeOf(cast); \\} }); @@ -761,7 +761,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn my_fn() align(128) void {} \\pub export fn other_fn() void { \\ var ARR: [16]u8 align(16) = undefined; - \\ _ = ARR; + \\ _ = @TypeOf(ARR); \\} }); } @@ -798,17 +798,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , &[_][]const u8{ \\pub export fn foo() void { \\ var a: c_int = undefined; - \\ _ = a; + \\ _ = @TypeOf(a); \\ var b: u8 = 123; - \\ _ = b; + \\ _ = @TypeOf(b); \\ const c: c_int = undefined; - \\ _ = c; + \\ _ = @TypeOf(c); \\ const d: c_uint = @bitCast(c_uint, @as(c_int, 440)); - \\ _ = d; + \\ _ = @TypeOf(d); \\ var e: c_int = 10; - \\ _ = e; + \\ _ = @TypeOf(e); \\ var f: c_uint = 10; - \\ _ = f; + \\ _ = @TypeOf(f); \\} }); @@ -867,7 +867,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ const v2 = struct { \\ const static: [5:0]u8 = "2.2.2".*; \\ }; - \\ _ = v2; + \\ _ = @TypeOf(v2); \\} }); @@ -911,7 +911,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn bar() void { \\ var func_ptr: ?*anyopaque = @ptrCast(?*anyopaque, foo); \\ var typed_func_ptr: ?*const fn () callconv(.C) void = @intToPtr(?*const fn () callconv(.C) void, @intCast(c_ulong, @ptrToInt(func_ptr))); - \\ _ = typed_func_ptr; + \\ _ = @TypeOf(typed_func_ptr); \\} }); } @@ -1353,7 +1353,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , &[_][]const u8{ \\pub export fn foo() void { \\ var a: c_int = undefined; - \\ _ = a; + \\ _ = @TypeOf(a); \\} }); @@ -1524,23 +1524,23 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ var p: ?*anyopaque = undefined; \\ { \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@import("std").meta.alignment([*c]u8), p)); - \\ _ = to_char; + \\ _ = @TypeOf(to_char); \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@import("std").meta.alignment([*c]c_short), p)); - \\ _ = to_short; + \\ _ = @TypeOf(to_short); \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@import("std").meta.alignment([*c]c_int), p)); - \\ _ = to_int; + \\ _ = @TypeOf(to_int); \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@import("std").meta.alignment([*c]c_longlong), p)); - \\ _ = to_longlong; + \\ _ = @TypeOf(to_longlong); \\ } \\ { \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@import("std").meta.alignment([*c]u8), p)); - \\ _ = to_char; + \\ _ = @TypeOf(to_char); \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@import("std").meta.alignment([*c]c_short), p)); - \\ _ = to_short; + \\ _ = @TypeOf(to_short); \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@import("std").meta.alignment([*c]c_int), p)); - \\ _ = to_int; + \\ _ = @TypeOf(to_int); \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@import("std").meta.alignment([*c]c_longlong), p)); - \\ _ = to_longlong; + \\ _ = @TypeOf(to_longlong); \\ } \\} }); @@ -1786,11 +1786,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ var arr: [10]u8 = [1]u8{ \\ 1, \\ } ++ [1]u8{0} ** 9; - \\ _ = arr; + \\ _ = @TypeOf(arr); \\ var arr1: [10][*c]u8 = [1][*c]u8{ \\ null, \\ } ++ [1][*c]u8{null} ** 9; - \\ _ = arr1; + \\ _ = @TypeOf(arr1); \\} }); @@ -2038,16 +2038,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub var c: c_int = 4; \\pub export fn foo(arg_c_1: u8) void { \\ var c_1 = arg_c_1; - \\ _ = c_1; + \\ _ = @TypeOf(c_1); \\ var a_2: c_int = undefined; \\ var b_3: u8 = 123; \\ b_3 = @bitCast(u8, @truncate(i8, a_2)); \\ { \\ var d: c_int = 5; - \\ _ = d; + \\ _ = @TypeOf(d); \\ } \\ var d: c_uint = @bitCast(c_uint, @as(c_int, 440)); - \\ _ = d; + \\ _ = @TypeOf(d); \\} }); @@ -2146,7 +2146,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ { \\ var i: c_int = 2; \\ var b: c_int = 4; - \\ _ = b; + \\ _ = @TypeOf(b); \\ while ((i + @as(c_int, 2)) != 0) : (i = 2) { \\ var a: c_int = 2; \\ _ = blk: { @@ -2159,7 +2159,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ } \\ } \\ var i: u8 = 2; - \\ _ = i; + \\ _ = @TypeOf(i); \\} }); @@ -2396,27 +2396,27 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , &[_][]const u8{ \\pub export fn escapes() [*c]const u8 { \\ var a: u8 = '\''; - \\ _ = a; + \\ _ = @TypeOf(a); \\ var b: u8 = '\\'; - \\ _ = b; + \\ _ = @TypeOf(b); \\ var c: u8 = '\x07'; - \\ _ = c; + \\ _ = @TypeOf(c); \\ var d: u8 = '\x08'; - \\ _ = d; + \\ _ = @TypeOf(d); \\ var e: u8 = '\x0c'; - \\ _ = e; + \\ _ = @TypeOf(e); \\ var f: u8 = '\n'; - \\ _ = f; + \\ _ = @TypeOf(f); \\ var g: u8 = '\r'; - \\ _ = g; + \\ _ = @TypeOf(g); \\ var h: u8 = '\t'; - \\ _ = h; + \\ _ = @TypeOf(h); \\ var i: u8 = '\x0b'; - \\ _ = i; + \\ _ = @TypeOf(i); \\ var j: u8 = '\x00'; - \\ _ = j; + \\ _ = @TypeOf(j); \\ var k: u8 = '"'; - \\ _ = k; + \\ _ = @TypeOf(k); \\ return "'\\\x07\x08\x0c\n\r\t\x0b\x00\""; \\} }); @@ -2612,7 +2612,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn foo() c_int { \\ return blk: { \\ var a: c_int = 1; - \\ _ = a; + \\ _ = @TypeOf(a); \\ break :blk a; \\ }; \\} @@ -2716,7 +2716,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\int bar(void) { return 0; } , &[_][]const u8{ \\pub inline fn CALL(arg: anytype) @TypeOf(bar()) { - \\ _ = arg; + \\ _ = @TypeOf(arg); \\ return bar(); \\} }); @@ -2775,14 +2775,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn foo() void { \\ if (true) { \\ var a: c_int = 2; - \\ _ = a; + \\ _ = @TypeOf(a); \\ } \\ if ((blk: { \\ _ = @as(c_int, 2); \\ break :blk @as(c_int, 5); \\ }) != 0) { \\ var a: c_int = 2; - \\ _ = a; + \\ _ = @TypeOf(a); \\ } \\} }); @@ -3285,7 +3285,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\#define a 2 , &[_][]const u8{ \\pub inline fn FOO(bar: anytype) @TypeOf(baz(@import("std").zig.c_translation.cast(?*anyopaque, baz))) { - \\ _ = bar; + \\ _ = @TypeOf(bar); \\ return baz(@import("std").zig.c_translation.cast(?*anyopaque, baz)); \\} , @@ -3425,7 +3425,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , &[_][]const u8{ \\pub export fn foo(arg_a: [*c]c_int) void { \\ var a = arg_a; - \\ _ = a; + \\ _ = @TypeOf(a); \\} \\pub export fn bar(arg_a: [*c]const c_int) void { \\ var a = arg_a; @@ -3785,12 +3785,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn bar(arg_x: c_int, arg_y: c_int) c_int { \\ var x = arg_x; \\ var y = arg_y; - \\ _ = y; + \\ _ = @TypeOf(y); \\ return x; \\} , \\pub inline fn FOO(A: anytype, B: anytype) @TypeOf(A) { - \\ _ = B; + \\ _ = @TypeOf(B); \\ return A; \\} }); From bec70a1a39398a3f4e2b1edf914c4755a9ebb623 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 12 Sep 2022 19:38:08 -0700 Subject: [PATCH 4/6] stage2: remove pointless discards from source code Good riddance! --- src/Autodoc.zig | 4 ---- src/Sema.zig | 4 ---- src/arch/aarch64/CodeGen.zig | 3 --- src/arch/arm/CodeGen.zig | 4 ---- src/arch/riscv64/CodeGen.zig | 3 --- src/arch/sparc64/CodeGen.zig | 2 -- src/arch/x86_64/CodeGen.zig | 2 -- src/link/Plan9.zig | 1 - src/print_air.zig | 1 - 9 files changed, 24 deletions(-) diff --git a/src/Autodoc.zig b/src/Autodoc.zig index cb17c19cb3..a124cd5621 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -2506,7 +2506,6 @@ fn walkInstruction( try self.srcLocInfo(file, sn, parent_src) else parent_src; - _ = src_info; const decls_len = if (small.has_decls_len) blk: { const decls_len = file.zir.extra[extra_index]; @@ -2627,7 +2626,6 @@ fn walkInstruction( extra_index += 1; break :blk fields_len; } else 0; - _ = fields_len; const decls_len = if (small.has_decls_len) blk: { const decls_len = file.zir.extra[extra_index]; @@ -2759,7 +2757,6 @@ fn walkInstruction( extra_index += 1; break :blk fields_len; } else 0; - _ = fields_len; const decls_len = if (small.has_decls_len) blk: { const decls_len = file.zir.extra[extra_index]; @@ -2901,7 +2898,6 @@ fn walkInstruction( extra_index += 1; break :blk fields_len; } else 0; - _ = fields_len; const decls_len = if (small.has_decls_len) blk: { const decls_len = file.zir.extra[extra_index]; diff --git a/src/Sema.zig b/src/Sema.zig index 6e48fafeaf..1afecef461 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -19670,8 +19670,6 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |src_ptr_val| { if (!src_ptr_val.isComptimeMutablePtr()) break :rs src_src; if (try sema.resolveDefinedValue(block, len_src, len)) |len_val| { - _ = dest_ptr_val; - _ = src_ptr_val; _ = len_val; return sema.fail(block, src, "TODO: Sema.zirMemcpy at comptime", .{}); } else break :rs len_src; @@ -19713,7 +19711,6 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void if (!ptr_val.isComptimeMutablePtr()) break :rs dest_src; if (try sema.resolveDefinedValue(block, len_src, len)) |len_val| { if (try sema.resolveMaybeUndefVal(block, value_src, value)) |val| { - _ = ptr_val; _ = len_val; _ = val; return sema.fail(block, src, "TODO: Sema.zirMemset at comptime", .{}); @@ -19941,7 +19938,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A if (val.tag() == .generic_poison) { break :blk FuncLinkSection{ .generic = {} }; } - _ = val; return sema.fail(block, section_src, "TODO implement linksection on functions", .{}); } else if (extra.data.bits.has_section_ref) blk: { const section_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index a54c8e059c..75f4717f55 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -2581,7 +2581,6 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { } fn airErrReturnTrace(self: *Self, inst: Air.Inst.Index) !void { - _ = inst; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else @@ -3614,7 +3613,6 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { const ptr = try self.resolveInst(un_op); const ptr_ty = self.air.typeOf(un_op); const ret_ty = self.fn_type.fnReturnType(); - _ = ret_ty; switch (self.ret_mcv) { .none => {}, @@ -5099,7 +5097,6 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne } else { return self.fail("TODO codegen non-ELF const Decl pointer", .{}); } - _ = tv; } fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 0eeb7a7ded..d3ec760607 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -2111,7 +2111,6 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { } fn airErrReturnTrace(self: *Self, inst: Air.Inst.Index) !void { - _ = inst; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else @@ -3353,7 +3352,6 @@ fn divFloat( ) InnerError!MCValue { _ = lhs_bind; _ = rhs_bind; - _ = lhs_ty; _ = rhs_ty; _ = maybe_inst; @@ -3420,7 +3418,6 @@ fn divExact( ) InnerError!MCValue { _ = lhs_bind; _ = rhs_bind; - _ = lhs_ty; _ = rhs_ty; _ = maybe_inst; @@ -3506,7 +3503,6 @@ fn modulo( ) InnerError!MCValue { _ = lhs_bind; _ = rhs_bind; - _ = lhs_ty; _ = rhs_ty; _ = maybe_inst; diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index cd1d0e4050..1dad5a4ac6 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -1316,7 +1316,6 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { } fn airErrReturnTrace(self: *Self, inst: Air.Inst.Index) !void { - _ = inst; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else @@ -1598,7 +1597,6 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { return self.structFieldPtr(ty_op.operand, ty_op.ty, index); } fn structFieldPtr(self: *Self, operand: Air.Inst.Ref, ty: Air.Inst.Ref, index: u32) !void { - _ = self; _ = operand; _ = ty; _ = index; @@ -1615,7 +1613,6 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { } fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { - _ = self; _ = inst; return self.fail("TODO implement codegen airFieldParentPtr", .{}); } diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index cd891f0fa3..cd8098e581 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -2084,9 +2084,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { } fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { - _ = self; _ = inst; - return self.fail("TODO implement switch for {}", .{self.target.cpu.arch}); } diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 05d7f2b73b..c9c03e4646 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1960,7 +1960,6 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { } fn airErrReturnTrace(self: *Self, inst: Air.Inst.Index) !void { - _ = inst; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else @@ -6590,7 +6589,6 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.Block, ty_pl.payload); - _ = ty_pl; _ = extra; return self.fail("TODO implement x86 airCmpxchg", .{}); // return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value }); diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 9a8927dcb4..1da33bdf86 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -622,7 +622,6 @@ pub fn updateDeclExports( ) !void { try self.seeDecl(decl_index); // we do all the things in flush - _ = self; _ = module; _ = exports; } diff --git a/src/print_air.zig b/src/print_air.zig index 04dec25f5f..fb6f7e6cf2 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -324,7 +324,6 @@ const Writer = struct { fn writeNoOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { _ = w; _ = inst; - _ = s; // no-op, no argument to write } From ebd082d3f6813f1d919ed1c1886fdc58b9d31b7d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 13 Sep 2022 02:03:26 -0700 Subject: [PATCH 5/6] remove pointless discards in test cases --- .../compile_errors/non-comptime-parameter-used-as-array-size.zig | 1 - test/cases/type_of.0.zig | 1 - 2 files changed, 2 deletions(-) diff --git a/test/cases/compile_errors/non-comptime-parameter-used-as-array-size.zig b/test/cases/compile_errors/non-comptime-parameter-used-as-array-size.zig index b5495480ed..0456bc9c8e 100644 --- a/test/cases/compile_errors/non-comptime-parameter-used-as-array-size.zig +++ b/test/cases/compile_errors/non-comptime-parameter-used-as-array-size.zig @@ -6,7 +6,6 @@ export fn entry() void { } fn makeLlamas(count: usize) [count]u8 { - _ = count; } // error diff --git a/test/cases/type_of.0.zig b/test/cases/type_of.0.zig index d8a97d1444..5f7702ef2c 100644 --- a/test/cases/type_of.0.zig +++ b/test/cases/type_of.0.zig @@ -1,6 +1,5 @@ pub fn main() void { var x: usize = 0; - _ = x; const z = @TypeOf(x, @as(u128, 5)); assert(z == u128); } From b2e94de3585e0a1242e3a5d6c8fd331da9f2d4f5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 13 Sep 2022 10:01:17 -0700 Subject: [PATCH 6/6] add compile error test for pointless discards --- test/cases/compile_errors/pointless discard.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/cases/compile_errors/pointless discard.zig diff --git a/test/cases/compile_errors/pointless discard.zig b/test/cases/compile_errors/pointless discard.zig new file mode 100644 index 0000000000..048bf8ac8d --- /dev/null +++ b/test/cases/compile_errors/pointless discard.zig @@ -0,0 +1,12 @@ +export fn foo() void { + var x: i32 = 1234; + x += 1; + _ = x; +} + +// error +// backend=stage2 +// target=native +// +// :4:9: error: pointless discard of local variable +// :3:5: note: used here