Commit f16855b9d7

Andrew Kelley <andrew@ziglang.org>
2022-09-12 06:35:07
remove pointless discards
1 parent e323cf1
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");
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;
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| {
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 {
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;
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;
 }
 
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 {