mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 03:03:09 +00:00
Sema: fix in-memory coercion of functions introducing new generic parameters
While it is not allowed for a function coercion to change whether a function is generic, it *is* okay to make existing concrete parameters of a generic function also generic, or vice versa. Either of these cases implies that the result is a generic function, so comptime type checks will happen when the function is ultimately called. Resolves: #21099
This commit is contained in:
parent
98640cbeb8
commit
26fdb81c16
25
src/Sema.zig
25
src/Sema.zig
@ -30422,20 +30422,17 @@ fn coerceInMemoryAllowedFns(
|
||||
} };
|
||||
}
|
||||
|
||||
switch (src_param_ty.toIntern()) {
|
||||
.generic_poison_type => {},
|
||||
else => {
|
||||
// Note: Cast direction is reversed here.
|
||||
const param = try sema.coerceInMemoryAllowed(block, src_param_ty, dest_param_ty, dest_is_mut, target, dest_src, src_src, null);
|
||||
if (param != .ok) {
|
||||
return .{ .fn_param = .{
|
||||
.child = try param.dupe(sema.arena),
|
||||
.actual = src_param_ty,
|
||||
.wanted = dest_param_ty,
|
||||
.index = param_i,
|
||||
} };
|
||||
}
|
||||
},
|
||||
if (!src_param_ty.isGenericPoison() and !dest_param_ty.isGenericPoison()) {
|
||||
// Note: Cast direction is reversed here.
|
||||
const param = try sema.coerceInMemoryAllowed(block, src_param_ty, dest_param_ty, dest_is_mut, target, dest_src, src_src, null);
|
||||
if (param != .ok) {
|
||||
return .{ .fn_param = .{
|
||||
.child = try param.dupe(sema.arena),
|
||||
.actual = src_param_ty,
|
||||
.wanted = dest_param_ty,
|
||||
.index = param_i,
|
||||
} };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -732,3 +732,27 @@ test "inline function return type is evaluated at comptime" {
|
||||
comptime assert(@TypeOf(result) == u16);
|
||||
try expect(result == 123);
|
||||
}
|
||||
|
||||
test "coerce generic function making concrete parameter generic" {
|
||||
const S = struct {
|
||||
fn foo(_: anytype, x: u32) u32 {
|
||||
comptime assert(@TypeOf(x) == u32);
|
||||
return x;
|
||||
}
|
||||
};
|
||||
const coerced: fn (anytype, anytype) u32 = S.foo;
|
||||
const result = coerced({}, 123);
|
||||
try expect(result == 123);
|
||||
}
|
||||
|
||||
test "coerce generic function making generic parameter concrete" {
|
||||
const S = struct {
|
||||
fn foo(_: anytype, x: anytype) u32 {
|
||||
comptime assert(@TypeOf(x) == u32);
|
||||
return x;
|
||||
}
|
||||
};
|
||||
const coerced: fn (anytype, u32) u32 = S.foo;
|
||||
const result = coerced({}, 123);
|
||||
try expect(result == 123);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user