Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement support for captured Primary Constructor parameters in EE when portable PDB is used. #67266

Merged
merged 2 commits into from
Mar 15, 2023

Conversation

AlekseyTs
Copy link
Contributor

@AlekseyTs AlekseyTs commented Mar 11, 2023

Closes #67107
Closes #67103

@AlekseyTs
Copy link
Contributor Author

@cston, @jjonescz, @tmat Please review

@AlekseyTs
Copy link
Contributor Author

@dotnet/roslyn-compiler Please review

src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs Outdated Show resolved Hide resolved
@@ -309,9 +315,10 @@ internal static (Guid ModuleVersionId, ISymUnmanagedReader SymReader, int Method
string expr,
int atLineNumber = -1,
bool includeSymbols = true,
TargetFramework targetFramework = TargetFramework.Standard)
TargetFramework targetFramework = TargetFramework.Standard,
DebugInformationFormat debugFormat = DebugInformationFormat.Pdb)
Copy link
Member

@jjonescz jjonescz Mar 14, 2023

Choose a reason for hiding this comment

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

Is this changing the default here so now even existing tests are evaluated only against PDB and not also against portable PDB as previously? #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.

Is this changing the default here so now even existing tests are evaluated only against PDB and not also against portable PDB as previously?

That was not my intent and I do not think the default is changed. See the change on the line 369 below.

resultProperties: out _,
error: out string error);

Assert.Equal("error CS0103: The name 'y' does not exist in the current context", error);
Copy link
Member

@jjonescz jjonescz Mar 14, 2023

Choose a reason for hiding this comment

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

Why can't we access y here? It's just a field like x, right? #Closed

Copy link
Contributor Author

@AlekseyTs AlekseyTs Mar 14, 2023

Choose a reason for hiding this comment

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

Why can't we access y here? It's just a field like x, right?

The lambda doesn't have access to the instance because this isn't captured. <>c__DisplayClass0_0 has only x.

internal class C
{
    [CompilerGenerated]
    private sealed class <>c__DisplayClass0_0
    {
        public int x;

        internal int <.ctor>b__0()
        {
            return x;
        }
    }

    [CompilerGenerated]
    private int <y>PC__BackingField;

    [System.Runtime.CompilerServices.Nullable(1)]
    private Func<int> Y;

    public C(int y, int x)
    {
        <y>PC__BackingField = y;
        <>c__DisplayClass0_0 <>c__DisplayClass0_ = new <>c__DisplayClass0_0();
        <>c__DisplayClass0_.x = x;
        Y = new Func<int>(<>c__DisplayClass0_.<.ctor>b__0);
        base..ctor();
    }

    private int M()
    {
        return <y>PC__BackingField;
    }
}

@AlekseyTs
Copy link
Contributor Author

@cston, @dotnet/roslyn-compiler For the second review

MethodSymbol currentFrame,
ImmutableArray<string> shadowingParameterNames,
TypeSymbol possiblyCapturingType,
(DisplayClassInstance? Instance, ConsList<FieldSymbol> Fields) possiblyCapturingTypeInstance,
Copy link
Member

@cston cston Mar 14, 2023

Choose a reason for hiding this comment

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

(DisplayClassInstance? Instance, ConsList Fields) possiblyCapturingTypeInstance

Why a tuple rather than two separate parameters? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why a tuple rather than two separate parameters?

The values are closely related and I felt the code is easier to follow this way. At least it was easier to write for me.

sawCapturedParameters = true;

if (!displayClassVariablesBuilder.ContainsKey(parameterName) &&
!shadowingParameterNames.Any((n1, n2) => n1 == n2, parameterName))
Copy link
Member

@cston cston Mar 14, 2023

Choose a reason for hiding this comment

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

shadowingParameterNames.Any((n1, n2) => n1 == n2, parameterName)

Perhaps shadowingParameterNames.Contains(parameterName) #Resolved

displayClassVariablesBuilder, displayClassVariableNamesOutsideInOrderBuilder);
}

if (checkForPrimaryConstructor && displayClassVariablesBuilder.Values.FirstOrDefault(v => v.Kind == DisplayClassVariableKind.This) is { } thisProxy)
Copy link
Member

@cston cston Mar 14, 2023

Choose a reason for hiding this comment

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

&&

Should the check include && !currentFrame.IsStatic? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should the check include && !currentFrame.IsStatic?

I don't think we care if the method itself is static as long as it has a "thisProxy" which can be supplied trough a parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All we care is whether we have access to this by whatever means

}

[Fact]
public void PrimaryConstructors_01201_CapturedParameterInsideLocalFunctionInInstanceMethod_WithDisplayClass()
Copy link
Member

Choose a reason for hiding this comment

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

PrimaryConstructors_01201_CapturedParameterInsideLocalFunctionInInstanceMethod_WithDisplayClass

How does this test differ from the previous test? Consider adding a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How does this test differ from the previous test? Consider adding a comment.

The difference is in the name of the primary constructor parameter - "value". See the same name used for display class parameter of the frame method - System.Int32 <>x.<>m0(C <>4__this, ref C.<>c__DisplayClass2_0 value)

Co-authored-by: Jan Jones <jan.jones.cz@gmail.com>
@AlekseyTs AlekseyTs enabled auto-merge (squash) March 15, 2023 17:04
Copy link
Member

@tmat tmat left a comment

Choose a reason for hiding this comment

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

:shipit:

@AlekseyTs AlekseyTs merged commit b4f1246 into dotnet:main Mar 15, 2023
@ghost ghost added this to the Next milestone Mar 15, 2023
@allisonchou allisonchou modified the milestones: Next, 17.6 P3 Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants