diff --git a/lib/std/crypto/tlcsprng.zig b/lib/std/crypto/tlcsprng.zig index ee71d6f13e..384216a81b 100644 --- a/lib/std/crypto/tlcsprng.zig +++ b/lib/std/crypto/tlcsprng.zig @@ -117,9 +117,7 @@ fn setupPthreadAtforkAndFill(buffer: []u8) void { } fn childAtForkHandler() callconv(.C) void { - // TODO this is a workaround for https://github.com/ziglang/zig/issues/7495 - var wipe_slice: []u8 = undefined; - wipe_slice = @ptrCast([*]u8, &wipe_me)[0..@sizeOf(@TypeOf(wipe_me))]; + const wipe_slice = @ptrCast([*]u8, &wipe_me)[0..@sizeOf(@TypeOf(wipe_me))]; std.crypto.utils.secureZero(u8, wipe_slice); } diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index fb94762b05..0e1c659642 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -20226,9 +20226,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod bool is_var_args = param_decl_node->data.param_decl.is_var_args; bool arg_part_of_generic_id = false; IrInstGen *casted_arg; + + ZigType *param_info_type = nullptr; if (is_var_args) { arg_part_of_generic_id = true; casted_arg = arg; + param_info_type = arg->value->type; } else { if (param_decl_node->data.param_decl.anytype_token == nullptr) { AstNode *param_type_node = param_decl_node->data.param_decl.type; @@ -20239,9 +20242,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod casted_arg = ir_implicit_cast2(ira, arg_src, arg, param_type); if (type_is_invalid(casted_arg->value->type)) return false; + + param_info_type = param_type; } else { arg_part_of_generic_id = true; casted_arg = arg; + param_info_type = arg->value->type; } } @@ -20298,7 +20304,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod if (!comptime_arg) { casted_args[fn_type_id->param_count] = casted_arg; FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; - param_info->type = casted_arg->value->type; + param_info->type = param_info_type; param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; fn_type_id->param_count += 1; diff --git a/test/stage1/behavior/generics.zig b/test/stage1/behavior/generics.zig index 6b584e381d..ee6496bcaa 100644 --- a/test/stage1/behavior/generics.zig +++ b/test/stage1/behavior/generics.zig @@ -1,4 +1,7 @@ -const expect = @import("std").testing.expect; +const std = @import("std"); +const testing = std.testing; +const expect = testing.expect; +const expectEqual = testing.expectEqual; test "simple generic fn" { expect(max(i32, 3, -1) == 3); @@ -149,3 +152,18 @@ test "array of generic fns" { expect(foos[0](true)); expect(!foos[1](true)); } + +test "generic fn keeps non-generic parameter types" { + const A = 128; + + const S = struct { + fn f(comptime T: type, s: []T) void { + expect(A != @typeInfo(@TypeOf(s)).Pointer.alignment); + } + }; + + // The compiler monomorphizes `S.f` for `T=u8` on its first use, check that + // `x` type not affect `s` parameter type. + var x: [16]u8 align(A) = undefined; + S.f(u8, &x); +}