Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 4, 2025

Fix "managed" and "unmanaged" keywords not appearing after typing in function pointer expressions

Problem

The managed and unmanaged keywords were not offered in IntelliSense completion after the user started typing following delegate* in function pointer declarations. The keywords only appeared when the completion list was opened immediately after typing delegate*.

Example:

class C
{
    unsafe static void M()
    {
        _ = (delegate*manag)&M;  // "managed" keyword not suggested
    }
}

Root Cause

The IsFunctionPointerCallingConventionContext method only checked if the targetToken was the asterisk token with complex parent type checks, which failed when the user started typing after delegate*.

Solution

Simplified IsFunctionPointerCallingConventionContext to just check:

  • The current token is an asterisk, AND
  • The previous token is the delegate keyword

This ensures that keywords appear both:

  • Immediately after delegate* → keywords appear ✓
  • After typing delegate*manag → keywords appear ✓
  • In cast expressions like (delegate*manag)&M → keywords appear ✓

Changes

  • Simplified IsFunctionPointerCallingConventionContext implementation
  • Added WorkItem attributes to tests
  • Added test coverage for cast expression scenario from original bug report
  • Verified all 35 managed/unmanaged keyword recommender tests pass
Original prompt

This section details on the original issue you should resolve

<issue_title>"managed" and "unmanaged" keywords are not offered in cast expressions to function pointers after starting to type</issue_title>
<issue_description>Version Used: VS 18.0.0 Insiders [11201.2]

Steps to Reproduce:
At the marked location, do the following:

  1. Open the autocomplete list
  2. Close the autocomplete list, type "manag" and open the autocomplete list again.
class C
{
    unsafe static void M()
    {
        _ = (delegate*$$)&M;
    }
}

Expected Behavior:
In both cases, managed and unmanaged are offered as keywords.

Actual Behavior:

  1. Behaves as expected.
  2. Everything but managed and unmanaged is offered. They also don't show up if you filter the list by keywords.
Image Image

Image</issue_description>

<agent_instructions>@copilot just update IsFunctionPointerCallingConventionContext to be simpler. It just needs to check if it's after delegate* and nothing more complex than that.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

delegate*$$
""");

[Fact]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot use [Fact, WorkItem("...")]. Also, test the specific case i n the original bug, where the function pointer type was being written inside a cast.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in a9e5e87. Added WorkItem attribute and test for the cast expression case from the original bug report.

Copilot AI changed the title [WIP] Fix autocomplete for managed and unmanaged keywords Fix managed/unmanaged keyword completion after typing in function pointer contexts Nov 4, 2025
return targetToken.IsKind(SyntaxKind.AsteriskToken) &&
targetToken.Parent is FunctionPointerTypeSyntax functionPointerType &&
targetToken == functionPointerType.AsteriskToken;
// Check if we're at or after delegate*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot you just need to check that the target token is an asterix, and the .GetPreviousToken() from it is the delegate keyword. That's all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in a9e5e87. Simplified to just check that targetToken is an asterisk and the previous token is the delegate keyword.

Copilot finished work on behalf of CyrusNajmabadi November 4, 2025 02:12
@CyrusNajmabadi CyrusNajmabadi marked this pull request as ready for review November 4, 2025 02:14
@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner November 4, 2025 02:14
@CyrusNajmabadi CyrusNajmabadi merged commit 8559c14 into main Nov 4, 2025
26 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"managed" and "unmanaged" keywords are not offered in cast expressions to function pointers after starting to type

3 participants