diff --git a/src/Sema.zig b/src/Sema.zig index 4deb2b0f29..393a05f123 100644 --- a/src/Sema.zig +++ b/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); diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index e854764649..0dba59f92f 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -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