authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-12-19 22:27:24+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-19 19:45:48-05:00
log84549b42678fa1f2755b2ec7bf4f4936d8f513af
tree6d1b3222ce827cc7e166f6cc15b6d81d4421b8c8
parentdd7b816d98840f26988c993eda9be21fa9b0ab50

stage1: Fix for generic fn monomorphization

Don't use the instantiation argument types to build the function parameter array. f416535768fc30195cad6cd481f73fd1e80082aa worked around the problem, this commit solves it.

3 files changed, 27 insertions(+), 5 deletions(-)

lib/std/crypto/tlcsprng.zig+1-3
......@@ -117,9 +117,7 @@ fn setupPthreadAtforkAndFill(buffer: []u8) void {
117117}
118118
119119fn childAtForkHandler() callconv(.C) void {
120 // TODO this is a workaround for https://github.com/ziglang/zig/issues/7495
121 var wipe_slice: []u8 = undefined;
122 wipe_slice = @ptrCast([*]u8, &wipe_me)[0..@sizeOf(@TypeOf(wipe_me))];
120 const wipe_slice = @ptrCast([*]u8, &wipe_me)[0..@sizeOf(@TypeOf(wipe_me))];
123121 std.crypto.utils.secureZero(u8, wipe_slice);
124122}
125123
src/stage1/ir.cpp+7-1
......@@ -20226,9 +20226,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
2022620226 bool is_var_args = param_decl_node->data.param_decl.is_var_args;
2022720227 bool arg_part_of_generic_id = false;
2022820228 IrInstGen *casted_arg;
20229
20230 ZigType *param_info_type = nullptr;
2022920231 if (is_var_args) {
2023020232 arg_part_of_generic_id = true;
2023120233 casted_arg = arg;
20234 param_info_type = arg->value->type;
2023220235 } else {
2023320236 if (param_decl_node->data.param_decl.anytype_token == nullptr) {
2023420237 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
2023920242 casted_arg = ir_implicit_cast2(ira, arg_src, arg, param_type);
2024020243 if (type_is_invalid(casted_arg->value->type))
2024120244 return false;
20245
20246 param_info_type = param_type;
2024220247 } else {
2024320248 arg_part_of_generic_id = true;
2024420249 casted_arg = arg;
20250 param_info_type = arg->value->type;
2024520251 }
2024620252 }
2024720253
......@@ -20298,7 +20304,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
2029820304 if (!comptime_arg) {
2029920305 casted_args[fn_type_id->param_count] = casted_arg;
2030020306 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count];
20301 param_info->type = casted_arg->value->type;
20307 param_info->type = param_info_type;
2030220308 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias;
2030320309 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node;
2030420310 fn_type_id->param_count += 1;
test/stage1/behavior/generics.zig+19-1
......@@ -1,4 +1,7 @@
1const expect = @import("std").testing.expect;
1const std = @import("std");
2const testing = std.testing;
3const expect = testing.expect;
4const expectEqual = testing.expectEqual;
25
36test "simple generic fn" {
47 expect(max(i32, 3, -1) == 3);
......@@ -149,3 +152,18 @@ test "array of generic fns" {
149152 expect(foos[0](true));
150153 expect(!foos[1](true));
151154}
155
156test "generic fn keeps non-generic parameter types" {
157 const A = 128;
158
159 const S = struct {
160 fn f(comptime T: type, s: []T) void {
161 expect(A != @typeInfo(@TypeOf(s)).Pointer.alignment);
162 }
163 };
164
165 // The compiler monomorphizes `S.f` for `T=u8` on its first use, check that
166 // `x` type not affect `s` parameter type.
167 var x: [16]u8 align(A) = undefined;
168 S.f(u8, &x);
169}