Skip to content

Improve order of returned items when overload resolution fails#81572

Closed
CyrusNajmabadi wants to merge 6 commits intodotnet:mainfrom
CyrusNajmabadi:betterRecovery
Closed

Improve order of returned items when overload resolution fails#81572
CyrusNajmabadi wants to merge 6 commits intodotnet:mainfrom
CyrusNajmabadi:betterRecovery

Conversation

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor

@CyrusNajmabadi CyrusNajmabadi commented Dec 6, 2025

Fixes #78533

Sorts the candidate symbols returned by GetSymbolInfo in overload resolution error cases, prioritizing candidates that matched better

@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner December 6, 2025 13:49
@CyrusNajmabadi
Copy link
Copy Markdown
Contributor Author

@dotnet/roslyn-compiler ptal.

methodBuilder.Free();
return filteredMethodBuilder.ToOneOrManyAndFree();

static bool argumentTypesMatchParameterTypes(MethodSymbol method, ImmutableArray<BoundExpression> arguments)
Copy link
Copy Markdown
Contributor Author

@CyrusNajmabadi CyrusNajmabadi Dec 6, 2025

Choose a reason for hiding this comment

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

@dotnet/roslyn-compiler is there some existing function that would help with this. For example, i could imagine taking advantage of refkind/optional-argument info.

This was the simplest approach given that i don'tk now what is available in the rest of the compiler. But if there is something i could make use of, that would be nice.

Basically, a sort of light-weight overload resolution.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@jcouv i think you wrote such a thing for the IDE for sig-help. Do you know if compiler has anything like that? Note: the goal is not to be perfect. Just to help order things

Assert.Equal("IApplicationBuilder IApplicationBuilder.Use(System.Func<RequestDelegate, RequestDelegate> middleware)", symbolInfo1.CandidateSymbols[0].ToTestDisplayString());
Assert.Equal("IApplicationBuilder IApplicationBuilder.Use(System.Func<HttpContext, System.Func<System.Threading.Tasks.Task>, System.Threading.Tasks.Task> middleware)", symbolInfo1.CandidateSymbols[1].ToTestDisplayString());
Assert.Equal("IApplicationBuilder IApplicationBuilder.Use(System.Func<HttpContext, System.Func<System.Threading.Tasks.Task>, System.Threading.Tasks.Task> middleware)", symbolInfo1.CandidateSymbols[0].ToTestDisplayString());
Assert.Equal("IApplicationBuilder IApplicationBuilder.Use(System.Func<RequestDelegate, RequestDelegate> middleware)", symbolInfo1.CandidateSymbols[1].ToTestDisplayString());
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

these results changed order. the new order is better and reflects that the Use method was passed an async lambda (which then should be returning a Task). Same with the test below.

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor Author

Note: we do not need to take this PR. I worked around this on the IDE side by reorderign the results. But if tehre is interest, i'll keep this open.

@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner December 8, 2025 14:54
}

private static Func<JToken, object> CreateDeserializeDelegate(JToken key)
private static object CreateDeserializeDelegate(JToken key)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is the PREFERED result. The code in question is: _deserializeHelpers.GetOrAdd(type, key => [|CreateDeserializeDelegate|](key));

So since we know we're padding a type we know the second argument is a Func<JToken, object>, which makes key => a JToken. And since we need a Func<JToken, object> that means we want the return type of CreateDeserializeDelegate to be object to properly match that delegate sig.

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Dec 9, 2025

  1. It would be good to include an overview of the change in OP. In this case, the PR "sorts the candidate symbols returned by GetSymbolInfo in overload resolution error cases, prioritizing candidates that matched better by some heuristic".
  2. We should discuss whether this belongs in the compiler layer. It feels like this sort of heuristic belongs in the IDE layer.

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor Author

It feels like this sort of heuristic belongs in the IDE layer.

the challenge doing this at IDE layer is that it means every callsite in the IDE that goes through GetSymbolInfo now needs to go through the GetSymbolInfoButApplyHeuristicsToMakeupForLackOfOrderingInCompilerResult.

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Jan 8, 2026

I worked around this on the IDE side by reordering the results. But if there is interest, i'll keep this open.

I think that's a good outcome and would close the PR.
@dotnet/roslyn-compiler any objections?

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor Author

Closing out. We'll do this as a heuristic in the IDE.

@CyrusNajmabadi CyrusNajmabadi deleted the betterRecovery branch January 20, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"Go to definition" goes to incorrect function in SourceLinks/disassembled sources

2 participants