Skip to content

Conversation

@Rekkonnect
Copy link
Contributor

@Rekkonnect Rekkonnect commented May 8, 2025

Closes #73498
Closes #77545

Fixes one part of #75833, the appropriate tests were adjusted to reflect the new behavior

With this PR, the GetSymbolInfo API and all the corresponding APIs using it will be affected for the scenarios where an object creation expression used a constructor overload that doesn't exist, whilst the expression was being implicitly converted to another type. The previous behavior would resolve to the target type of the conversion, since the binding result would be an overload resolution, whereas now it has been changed to resolve to the existing overload resolution result.

The goal of this change is also reflected in GTD which will now correctly navigate to the type whose constructor was not found, instead of the target conversion type, or the implicit conversion method.

This also adds tests for explicit conversions on object creation expressions, covering the above scenaria, as well as testing the existing correct behaviors of when there is no conversion, or when there is no overload resolution failure.

@Rekkonnect Rekkonnect requested review from a team as code owners May 8, 2025 21:13
@ghost ghost added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels May 8, 2025
@dotnet-policy-service dotnet-policy-service bot added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label May 8, 2025
@Rekkonnect Rekkonnect marked this pull request as draft May 9, 2025 06:54
@AlekseyTs
Copy link
Contributor

AlekseyTs commented May 9, 2025

We need to have direct tests for SemanticModel API, plus an explanation what was the old behavior, why it was wrong, etc. #Closed

@Rekkonnect Rekkonnect marked this pull request as ready for review May 10, 2025 13:41
@Rekkonnect
Copy link
Contributor Author

@AlekseyTs this is ready for review

@AlekseyTs
Copy link
Contributor

AlekseyTs commented May 30, 2025

plus an explanation what was the old behavior, why it was wrong, etc.

Was the explanation provided? Basically we need a clear description of the problem with the SemanticModel API. The reason why you think the present behavior is wrong, a description of the expected behavior with a reason behind the expectation.

#Closed

@Rekkonnect
Copy link
Contributor Author

Was the explanation provided?
I added an explanation here: https://github.com/dotnet/roslyn/pull/78514/files#diff-d901fc0a7ce2d67b0336c3708a45962ee31ae1ce7c9c67e79d3def4fc8f947bfR1913-R1916

I can reword it if you feel like it doesn't provide enough information

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jun 3, 2025

I think this isn't quite what I was looking for. I was looking for a description of your intent in this PR and the reason behind the intent. Something like: "I intend to change behavior *** API for the scenarios ***. The current behavior of the API is ***. I think it should be *** instead, because ***." Obviously your ultimate goal is to get some IDE scenarios working, but simply stating that is not sufficient for changing how compiler API behaves. In order for the Compiler team to review the PR, we need the intent stated in "Compiler API" terms. #Closed

@AlekseyTs AlekseyTs added the Need More Info The issue needs more information to proceed. label Jun 17, 2025
@Rekkonnect
Copy link
Contributor Author

@AlekseyTs updated the description and brought the PR up to date, ptal

var overloadResolutionSuffices = resultKind == LookupResultKind.OverloadResolutionFailure
&& boundExpr.Kind is BoundKind.BadExpression
&& highestBoundNode is BoundConversion { Conversion.Method: not null };
if (!overloadResolutionSuffices && highestBoundNode is BoundExpression highestBoundExpr)
Copy link
Contributor

@AlekseyTs AlekseyTs Oct 18, 2025

Choose a reason for hiding this comment

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

if (!overloadResolutionSuffices && highestBoundNode is BoundExpression highestBoundExpr)

The original if statement looked like a "voodoo magic" and with this adjustment it looks even more "magical".
I was able to clarify/simplify it to the following:

            if (highestBoundNode is BoundBadExpression badExpression)
            {
                // Downgrade result kind if highest node is BoundBadExpression
                LookupResultKind highestResultKind;
                bool highestIsDynamic;
                ImmutableArray<Symbol> unusedHighestMemberGroup;
                OneOrMany<Symbol> highestSymbols = GetSemanticSymbols(
                    badExpression, boundNodeForSyntacticParent, binderOpt, options, out highestIsDynamic, out highestResultKind, out unusedHighestMemberGroup);

                if (highestResultKind != LookupResultKind.Empty && highestResultKind < resultKind)
                {
                    resultKind = highestResultKind;
                    isDynamic = highestIsDynamic;
                }
            }
            else if (boundExpr is BoundMethodGroup &&
                resultKind == LookupResultKind.OverloadResolutionFailure &&
                highestBoundNode is BoundConversion { ConversionKind: ConversionKind.MethodGroup } boundConversion)
            {
                LookupResultKind highestResultKind;
                bool highestIsDynamic;
                ImmutableArray<Symbol> unusedHighestMemberGroup;
                OneOrMany<Symbol> highestSymbols = GetSemanticSymbols(
                    boundConversion, boundNodeForSyntacticParent, binderOpt, options, out highestIsDynamic, out highestResultKind, out unusedHighestMemberGroup);

                if (highestSymbols.Count > 0)
                {
                    symbols = highestSymbols;
                    resultKind = highestResultKind;
                    isDynamic = highestIsDynamic;
                }
            }

With this code all tests but two are passing, and the two failing tests are:

  • GetSymbolInfo_ImplicitUserDefinedConversionOnMethodGroup_InLocalDeclaration
  • GetSymbolInfo_ImplicitUserDefinedConversionOnMethodGroup_InAssignment

According to #75833, the failures is a desired behavior change. Though, #75833 is not completely fixed. #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed code

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Oct 18, 2025

Done with review pass (commit 8) #Closed

Rekkonnect and others added 2 commits October 18, 2025 18:13
Co-Authored-By: AlekseyTs <[email protected]>
Co-Authored-By: AlekseyTs <[email protected]>
@Rekkonnect
Copy link
Contributor Author

Rekkonnect commented Oct 18, 2025

@AlekseyTs resolved your comments, could you ptal again?

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

LGTM (commit 11)

@AlekseyTs AlekseyTs requested a review from a team October 18, 2025 18:34
@AlekseyTs
Copy link
Contributor

@dotnet/roslyn-compiler For a second review for a community PR.

2 similar comments
@AlekseyTs
Copy link
Contributor

@dotnet/roslyn-compiler For a second review for a community PR.

@AlekseyTs
Copy link
Contributor

@dotnet/roslyn-compiler For a second review for a community PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers Community The pull request was submitted by a contributor who is not a Microsoft employee. Need More Info The issue needs more information to proceed. untriaged Issues and PRs which have not yet been triaged by a lead

Projects

None yet

3 participants