| ... | @@ -1154,6 +1154,29 @@ fn foobar(func: PFN_void) !void { | ... | @@ -1154,6 +1154,29 @@ fn foobar(func: PFN_void) !void { |
| 1154 | try std.testing.expect(@intFromPtr(func) == hardcoded_fn_addr); | 1154 | try std.testing.expect(@intFromPtr(func) == hardcoded_fn_addr); |
| 1155 | } | 1155 | } |
| 1156 | | 1156 | |
| | 1157 | test "cast function with an opaque parameter" { |
| | 1158 | const Container = struct { |
| | 1159 | const Ctx = opaque {}; |
| | 1160 | ctx: *Ctx, |
| | 1161 | func: *const fn (*Ctx) void, |
| | 1162 | }; |
| | 1163 | const Foo = struct { |
| | 1164 | x: i32, |
| | 1165 | y: i32, |
| | 1166 | fn funcImpl(self: *@This()) void { |
| | 1167 | self.x += 1; |
| | 1168 | self.y += 1; |
| | 1169 | } |
| | 1170 | }; |
| | 1171 | var foo = Foo{ .x = 100, .y = 200 }; |
| | 1172 | var c = Container{ |
| | 1173 | .ctx = @ptrCast(&foo), |
| | 1174 | .func = @ptrCast(&Foo.funcImpl), |
| | 1175 | }; |
| | 1176 | c.func(c.ctx); |
| | 1177 | try std.testing.expectEqual(foo, .{ .x = 101, .y = 201 }); |
| | 1178 | } |
| | 1179 | |
| 1157 | test "implicit ptr to *anyopaque" { | 1180 | test "implicit ptr to *anyopaque" { |
| 1158 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1181 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1159 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1182 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |