Skip to content

gopls/implementation: fall back gracefully for non-dynamic calls at "("#632

Closed
abhay1999 wants to merge 3 commits intogolang:masterfrom
abhay1999:gopls-impl-fallback-non-dynamic
Closed

gopls/implementation: fall back gracefully for non-dynamic calls at "("#632
abhay1999 wants to merge 3 commits intogolang:masterfrom
abhay1999:gopls-impl-fallback-non-dynamic

Conversation

@abhay1999
Copy link
Copy Markdown
Contributor

Problem

When a user invokes textDocument/implementation with the cursor on
the ( of a non-dynamic call (e.g. err.Error(), len(""), or a
type conversion), gopls returned a hard error:

textDocument/implementation: not a dynamic function call

This message is confusing because it leaks an internal concept
("dynamic function call") and blocks the normal method-sets fallback.

Fix

In implFuncs, when the call at ( is not a dynamic function call,
return errNotHandled instead of a real error. This lets the caller
fall through to implementationsMsets (the regular method-sets
algorithm).

That algorithm also cannot resolve an implementation from a bare (
token (it needs a type name or method identifier), so it returns
"no identifier found" — a standard, editor-friendly error — rather
than the gopls-specific message. Users are guided to query on the
method name identifier instead (e.g. Error in err.Error()).

This is consistent with the treatment of ( in
textDocument/references (golang/go#76872) and preserves the intended
design separation between dynamic-function-type queries (keyed by
func or () and interface-method queries (keyed by a method
identifier).

Fixes golang/go#77784

…re a declaration

When a user places the cursor immediately after "//" (with no trailing
space) on a line directly above a declaration, gopls already suggests the
declaration name as a completion candidate. However the suggested insert
text lacked the conventional space, producing "//Name" instead of the
proper Go doc comment form "// Name".

Detect this case in populateCommentCompletions (cursor at slash+2 with
comment text exactly "//") and set a new commentNeedsLeadingSpace flag on
the completionContext. item() checks the flag and prepends a space to the
insert text (and snippet), so accepting the completion yields "// Name".

A marker test is added to comment.txt that asserts the candidate appears
when the cursor is right after "//", above a function declaration.

Fixes golang/go#76374
…es after //

Previously, commentNeedsLeadingSpace was only set when the cursor was
exactly at slash+2 and the comment text was exactly "//". This missed
the case where the user had partially typed an identifier (e.g. "//Foo")
and triggered completion mid-word.

Fix: use c.surrounding.start (the start of the edit range, set by
setSurroundingForComment) instead. If the edit range starts at slash+2,
there is no space between "//" and the identifier being replaced, so
completions should prepend a space.

Also add a marker test for the partial-prefix case.
implFuncs handles the "(" paren of a CallExpr as an entry point for
finding dynamic function-call implementations. When the call is not
dynamic (e.g. err.Error(), len(""), or a type conversion), it
previously returned a hard error "not a dynamic function call" which
blocked the method-sets fallback and produced a confusing message.

Change the non-dynamic case to return errNotHandled instead, which
lets the caller fall through to the regular method-sets algorithm.
That algorithm also cannot find an implementation from a bare "(" (it
needs an identifier), so it returns "no identifier found" — a standard
error that editors handle gracefully — rather than a gopls-specific
message.

The fix is consistent with the treatment of "(" in
textDocument/references (#76872) and preserves the intended separation
between dynamic-function-type queries (keyed by "func" or "(") and
interface-method queries (keyed by the method name identifier).

Update the affected marker tests to expect "no identifier found".

Fixes golang/go#77784
@abhay1999
Copy link
Copy Markdown
Contributor Author

Closing in favor of #617 by @manimz which addresses the same issue and was submitted first. Sorry for the duplicate!

@abhay1999 abhay1999 closed this Apr 8, 2026
@abhay1999 abhay1999 deleted the gopls-impl-fallback-non-dynamic branch April 8, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

x/tools/gopls: implementation at ( paren should fall back for non-dynamic calls

1 participant