mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
Sema: improve detection of generic parameters
This commit is contained in:
parent
078037ab9b
commit
98a5998d83
@ -7,6 +7,7 @@
|
||||
//! TODO(tiehuis): Benchmark these against other reference implementations.
|
||||
|
||||
const std = @import("std.zig");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const expect = std.testing.expect;
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
@ -30,7 +31,10 @@ pub const Sfc64 = @import("rand/Sfc64.zig");
|
||||
|
||||
pub const Random = struct {
|
||||
ptr: *anyopaque,
|
||||
fillFn: fn (ptr: *anyopaque, buf: []u8) void,
|
||||
fillFn: if (builtin.zig_backend == .stage1)
|
||||
fn (ptr: *anyopaque, buf: []u8) void
|
||||
else
|
||||
*const fn (ptr: *anyopaque, buf: []u8) void,
|
||||
|
||||
pub fn init(pointer: anytype, comptime fillFn: fn (ptr: @TypeOf(pointer), buf: []u8) void) Random {
|
||||
const Ptr = @TypeOf(pointer);
|
||||
|
||||
13
src/Sema.zig
13
src/Sema.zig
@ -5923,6 +5923,10 @@ fn funcCommon(
|
||||
break :ret_ty ret_ty;
|
||||
} else |err| break :err err;
|
||||
} else |err| break :err err;
|
||||
// Check for generic params.
|
||||
for (block.params.items) |param| {
|
||||
if (param.ty.tag() == .generic_poison) is_generic = true;
|
||||
}
|
||||
};
|
||||
switch (err) {
|
||||
error.GenericPoison => {
|
||||
@ -6111,6 +6115,13 @@ fn zirParam(
|
||||
|
||||
if (sema.resolveBody(block, body, inst)) |param_ty_inst| {
|
||||
if (sema.analyzeAsType(block, src, param_ty_inst)) |param_ty| {
|
||||
if (param_ty.zigTypeTag() == .Fn and param_ty.fnInfo().is_generic) {
|
||||
// zirFunc will not emit error.GenericPoison to build a
|
||||
// partial type for generic functions but we still need to
|
||||
// detect if a function parameter is a generic function
|
||||
// to force the parent function to also be generic.
|
||||
break :err error.GenericPoison;
|
||||
}
|
||||
break :param_ty param_ty;
|
||||
} else |err| break :err err;
|
||||
} else |err| break :err err;
|
||||
@ -10965,6 +10976,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
|
||||
|
||||
const operand = try sema.resolveBody(&child_block, body, inst);
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
if (operand_ty.tag() == .generic_poison) return error.GenericPoison;
|
||||
return sema.addType(operand_ty);
|
||||
}
|
||||
|
||||
@ -11044,6 +11056,7 @@ fn zirTypeofPeer(
|
||||
|
||||
for (args) |arg_ref, i| {
|
||||
inst_list[i] = sema.resolveInst(arg_ref);
|
||||
if (sema.typeOf(inst_list[i]).tag() == .generic_poison) return error.GenericPoison;
|
||||
}
|
||||
|
||||
const result_type = try sema.resolvePeerTypes(block, src, inst_list, .{ .typeof_builtin_call_node_offset = extra.data.src_node });
|
||||
|
||||
@ -230,3 +230,16 @@ fn GenNode(comptime T: type) type {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "function parameter is generic" {
|
||||
const S = struct {
|
||||
pub fn init(pointer: anytype, comptime fillFn: fn (ptr: *@TypeOf(pointer)) void) void {
|
||||
_ = fillFn;
|
||||
}
|
||||
pub fn fill(self: *u32) void {
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
var rng: u32 = 2;
|
||||
S.init(rng, S.fill);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user