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.
This commit is contained in:
mlugg 2023-04-14 17:29:40 +01:00 committed by Andrew Kelley
parent 1e207f1edd
commit 77fdd76c16
4 changed files with 10 additions and 13 deletions

View File

@ -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| {

View File

@ -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" {

View File

@ -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);

View File

@ -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 ===