From 686c4914b0f90e41e6251cd3f1c83394a61e4418 Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Mon, 29 Jan 2024 05:23:48 +0000 Subject: [PATCH] fix pointer unwrapping when detecting self parameters (#1730) fixes #1729 --- src/analysis.zig | 27 ++++++++++++--------------- tests/lsp_features/inlay_hints.zig | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index cd40d1c2e..179c1b243 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -269,24 +269,21 @@ pub fn firstParamIs( const param = ast.nextFnParam(&it).?; if (param.type_expr == 0) return false; - if (try analyser.resolveTypeOfNodeInternal(.{ + const resolved_type = try analyser.resolveTypeOfNodeInternal(.{ .node = param.type_expr, .handle = handle, - })) |resolved_type| { - if (resolved_type.eql(expected)) - return true; - } + }) orelse return false; + if (!resolved_type.is_type_val) return false; - if (ast.fullPtrType(tree, param.type_expr)) |ptr_type| { - if (try analyser.resolveTypeOfNodeInternal(.{ - .node = ptr_type.ast.child_type, - .handle = handle, - })) |resolved_prefix_op| { - if (resolved_prefix_op.eql(expected)) - return true; - } - } - return false; + const deref_type = switch (resolved_type.data) { + .pointer => |info| switch (info.size) { + .One => info.elem_ty.*, + .Many, .Slice, .C => return false, + }, + else => resolved_type, + }; + + return deref_type.eql(expected); } pub fn getVariableSignature(allocator: std.mem.Allocator, tree: Ast, var_decl: Ast.full.VarDecl) error{OutOfMemory}![]const u8 { diff --git a/tests/lsp_features/inlay_hints.zig b/tests/lsp_features/inlay_hints.zig index b1acd897e..25545501f 100644 --- a/tests/lsp_features/inlay_hints.zig +++ b/tests/lsp_features/inlay_hints.zig @@ -44,6 +44,11 @@ test "inlayhints - function self parameter" { \\const foo: Foo = .{}; \\const _ = foo.bar(5); , .Parameter); + try testInlayHints( + \\const Foo = struct { pub fn bar(self: *Foo, alpha: u32) void {} }; + \\const foo: *Foo = undefined; + \\const _ = foo.bar(5); + , .Parameter); try testInlayHints( \\const Foo = struct { pub fn bar(_: Foo, alpha: u32, beta: []const u8) void {} }; \\const foo: Foo = .{}; @@ -54,6 +59,11 @@ test "inlayhints - function self parameter" { \\const foo: Foo = .{}; \\const _ = foo.bar(5,4); , .Parameter); + try testInlayHints( + \\const Foo = struct { pub fn bar(self: Foo, alpha: u32, beta: anytype) void {} }; + \\const foo: *Foo = undefined; + \\const _ = foo.bar(5,4); + , .Parameter); try testInlayHints( \\const Foo = struct { pub fn bar(self: Foo, alpha: u32, beta: []const u8) void {} }; \\const _ = Foo.bar(undefined,5,""); @@ -68,6 +78,14 @@ test "inlayhints - function self parameter" { , .Parameter); } +test "inlayhints - function self parameter with pointer type in type declaration" { + try testInlayHints( + \\const Foo = *opaque { pub fn bar(self: Foo, alpha: u32) void {} }; + \\const foo: Foo = undefined; + \\const _ = foo.bar(5); + , .Parameter); +} + test "inlayhints - resolve alias" { try testInlayHints( \\fn foo(alpha: u32) void {}