Commit 77fdd76c16

mlugg <mlugg@mlugg.co.uk>
2023-04-14 18:29:40
std: fix uses of comptime blocks in non-inline functions
ccf670c made using `return` from within a comptime block in a non-inline function illegal, since it is a use of runtime control flow in a comptime block. It is allowed if the function in question is `inline`, since no actual control flow occurs in this case. A few functions from std (notably `std.fmt.comptimePrint`) needed to be marked `inline` to support this change.
1 parent 1e207f1
Changed files (4)
lib/std/os/windows/user32.zig
@@ -28,13 +28,11 @@ const POINT = windows.POINT;
 const HCURSOR = windows.HCURSOR;
 const HBRUSH = windows.HBRUSH;
 
-fn selectSymbol(comptime function_static: anytype, function_dynamic: *const @TypeOf(function_static), comptime os: std.Target.Os.WindowsVersion) *const @TypeOf(function_static) {
-    comptime {
-        const sym_ok = builtin.os.isAtLeast(.windows, os);
-        if (sym_ok == true) return function_static;
-        if (sym_ok == null) return function_dynamic;
-        if (sym_ok == false) @compileError("Target OS range does not support function, at least " ++ @tagName(os) ++ " is required");
-    }
+inline fn selectSymbol(comptime function_static: anytype, function_dynamic: *const @TypeOf(function_static), comptime os: std.Target.Os.WindowsVersion) *const @TypeOf(function_static) {
+    const sym_ok = comptime builtin.os.isAtLeast(.windows, os);
+    if (sym_ok == true) return function_static;
+    if (sym_ok == null) return function_dynamic;
+    if (sym_ok == false) @compileError("Target OS range does not support function, at least " ++ @tagName(os) ++ " is required");
 }
 
 // === Messages ===
lib/std/enums.zig
@@ -32,7 +32,7 @@ pub fn EnumFieldStruct(comptime E: type, comptime Data: type, comptime field_def
 /// Looks up the supplied fields in the given enum type.
 /// Uses only the field names, field values are ignored.
 /// The result array is in the same order as the input.
-pub fn valuesFromFields(comptime E: type, comptime fields: []const EnumField) []const E {
+pub inline fn valuesFromFields(comptime E: type, comptime fields: []const EnumField) []const E {
     comptime {
         var result: [fields.len]E = undefined;
         for (fields, 0..) |f, i| {
lib/std/fmt.zig
@@ -2005,7 +2005,7 @@ pub fn bufPrintIntToSlice(buf: []u8, value: anytype, base: u8, case: Case, optio
     return buf[0..formatIntBuf(buf, value, base, case, options)];
 }
 
-pub fn comptimePrint(comptime fmt: []const u8, args: anytype) *const [count(fmt, args):0]u8 {
+pub inline fn comptimePrint(comptime fmt: []const u8, args: anytype) *const [count(fmt, args):0]u8 {
     comptime {
         var buf: [count(fmt, args):0]u8 = undefined;
         _ = bufPrint(&buf, fmt, args) catch unreachable;
@@ -2016,8 +2016,8 @@ pub fn comptimePrint(comptime fmt: []const u8, args: anytype) *const [count(fmt,
 
 test "comptimePrint" {
     @setEvalBranchQuota(2000);
-    try std.testing.expectEqual(*const [3:0]u8, @TypeOf(comptime comptimePrint("{}", .{100})));
-    try std.testing.expectEqualSlices(u8, "100", comptime comptimePrint("{}", .{100}));
+    try std.testing.expectEqual(*const [3:0]u8, @TypeOf(comptimePrint("{}", .{100})));
+    try std.testing.expectEqualSlices(u8, "100", comptimePrint("{}", .{100}));
 }
 
 test "parse u64 digit too big" {
lib/std/mem.zig
@@ -3492,8 +3492,7 @@ fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {
     if (comptime !trait.is(.Pointer)(B) or
         (meta.Child(B) != [size]u8 and meta.Child(B) != [size:0]u8))
     {
-        comptime var buf: [100]u8 = undefined;
-        @compileError(std.fmt.bufPrint(&buf, "expected *[{}]u8, passed " ++ @typeName(B), .{size}) catch unreachable);
+        @compileError(std.fmt.comptimePrint("expected *[{}]u8, passed " ++ @typeName(B), .{size}));
     }
 
     return CopyPtrAttrs(B, .One, T);