mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 13:58:27 +00:00
Sema: allow method calls on optional pointers
This commit is contained in:
parent
c75e11bf6a
commit
2be347a2c8
35
src/Sema.zig
35
src/Sema.zig
@ -23738,7 +23738,6 @@ fn fieldCallBind(
|
||||
{
|
||||
const first_param_type = decl_type.fnParamType(0);
|
||||
const first_param_tag = first_param_type.tag();
|
||||
var opt_buf: Type.Payload.ElemType = undefined;
|
||||
// zig fmt: off
|
||||
if (first_param_tag == .var_args_param or
|
||||
first_param_tag == .generic_poison or (
|
||||
@ -23764,17 +23763,29 @@ fn fieldCallBind(
|
||||
.arg0_inst = deref,
|
||||
});
|
||||
return sema.addConstant(ty, value);
|
||||
} else if (first_param_tag != .generic_poison and first_param_type.zigTypeTag() == .Optional and
|
||||
first_param_type.optionalChild(&opt_buf).eql(concrete_ty, sema.mod))
|
||||
{
|
||||
const deref = try sema.analyzeLoad(block, src, object_ptr, src);
|
||||
const ty = Type.Tag.bound_fn.init();
|
||||
const value = try Value.Tag.bound_fn.create(arena, .{
|
||||
.func_inst = decl_val,
|
||||
.arg0_inst = deref,
|
||||
});
|
||||
return sema.addConstant(ty, value);
|
||||
} else if (first_param_tag != .generic_poison and first_param_type.zigTypeTag() == .ErrorUnion and
|
||||
} else if (first_param_type.zigTypeTag() == .Optional) {
|
||||
var opt_buf: Type.Payload.ElemType = undefined;
|
||||
const child = first_param_type.optionalChild(&opt_buf);
|
||||
if (child.eql(concrete_ty, sema.mod)) {
|
||||
const deref = try sema.analyzeLoad(block, src, object_ptr, src);
|
||||
const ty = Type.Tag.bound_fn.init();
|
||||
const value = try Value.Tag.bound_fn.create(arena, .{
|
||||
.func_inst = decl_val,
|
||||
.arg0_inst = deref,
|
||||
});
|
||||
return sema.addConstant(ty, value);
|
||||
} else if (child.zigTypeTag() == .Pointer and
|
||||
child.ptrSize() == .One and
|
||||
child.childType().eql(concrete_ty, sema.mod))
|
||||
{
|
||||
const ty = Type.Tag.bound_fn.init();
|
||||
const value = try Value.Tag.bound_fn.create(arena, .{
|
||||
.func_inst = decl_val,
|
||||
.arg0_inst = object_ptr,
|
||||
});
|
||||
return sema.addConstant(ty, value);
|
||||
}
|
||||
} else if (first_param_type.zigTypeTag() == .ErrorUnion and
|
||||
first_param_type.errorUnionPayload().eql(concrete_ty, sema.mod))
|
||||
{
|
||||
const deref = try sema.analyzeLoad(block, src, object_ptr, src);
|
||||
|
||||
@ -455,6 +455,23 @@ test "method call with optional and error union first param" {
|
||||
try s.errUnion();
|
||||
}
|
||||
|
||||
test "method call with optional pointer first param" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
x: i32 = 1234,
|
||||
|
||||
fn method(s: ?*@This()) !void {
|
||||
try expect(s.?.x == 1234);
|
||||
}
|
||||
};
|
||||
var s: S = .{};
|
||||
try s.method();
|
||||
const s_ptr = &s;
|
||||
try s_ptr.method();
|
||||
}
|
||||
|
||||
test "using @ptrCast on function pointers" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user