From f16855b9d70c747423ee81f27d619694856d365b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 11 Sep 2022 21:35:07 -0700 Subject: [PATCH] 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 {