-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Support SkipLocalsInitAttribute in local functions #41183
Support SkipLocalsInitAttribute in local functions #41183
Conversation
7f7133b
to
5cd9fbf
Compare
@@ -367,15 +367,6 @@ public override Symbol AssociatedSymbol | |||
} | |||
} | |||
|
|||
public override bool AreLocalsZeroed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deleted redundant implementation that was inadvertently left around after a merge. The implementation was already in SourceMethodSymbolWithAttributes. #ByDesign
5cd9fbf
to
cf0f6ff
Compare
@@ -345,13 +345,12 @@ internal sealed override CSharpAttributeData EarlyDecodeWellKnownAttribute(ref E | |||
return base.EarlyDecodeWellKnownAttribute(ref arguments); | |||
} | |||
|
|||
// PROTOTYPE(local-function-attributes): test local function with SkipLocalsInit | |||
public override bool AreLocalsZeroed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
override [](start = 15, length = 8)
Can we seal this implementation? #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to override it in SynthesizedMethodBaseSymbol.
In reply to: 371410335 [](ancestors = 371410335)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to override it in SynthesizedMethodBaseSymbol.
SynthesizedMethodBaseSymbol inherits from SourceMemberMethodSymbol
In reply to: 371421097 [](ancestors = 371421097,371410335)
int y = 4; | ||
y = y + y + y; | ||
|
||
void LF() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void LF() [](start = 12, length = 9)
It looks like we are missing a positive test for a scenario when a local function is nested into a lambda. #Closed
@@ -33,6 +33,27 @@ protected static void ReportBadRefToken(TypeSyntax returnTypeSyntax, DiagnosticB | |||
} | |||
} | |||
|
|||
protected bool AreContainingSymbolLocalsZeroed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could do
protected bool AreContainingSymbolLocalsZeroed => ContainingSymbol switch
{
SourceMethodSymbol m => m.AreLocalsZeroed,
SourceNamedTypeSymbol t => t.AreLocalsZeroed,
_ => true
};
#Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this handle the scenario where the ContainingSymbol is a SourceFieldSymbolFromDeclarator and the containing type has SkipLocalsInitAttribute? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think when I was triaging this I was surprised to find this as the ContainingSymbol for some scenario or other, but I tried to create a test that would create a bad behavior here and couldn't do it, so I'm good with taking your suggestion. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aleksey came up with a test case involving a field initializer containing a lambda, where the ContainingSymbol is a FieldSymbol and we have to instead look up to the ContainingType. So I reverted the suggestion. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were you thinking of a lambda inside a field initializer? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could see that as being a reasonable scenario that would be broken with my code. #Resolved
public void M() | ||
{ | ||
[System.Runtime.CompilerServices.SkipLocalsInitAttribute] | ||
void F() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void F() [](start = 8, length = 8)
I think we should also test scenarios when the attribute is applied to a containing member (including events/properties if allowed), or containing type, or containing module. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of these scenarios already had tests, such as SkipLocalsInitAttributeOnMethodPropagatesToLocalFunction
, but I added tests for the other scenarios you mentioned.
In reply to: 371418225 [](ancestors = 371418225)
Done with review pass (iteration 1) #Closed |
@dotnet/roslyn-compiler Please review #Closed |
@@ -10789,6 +11284,45 @@ static int M(out int x) | |||
Assert.False(verifier.HasLocalsInit("C..ctor")); | |||
} | |||
|
|||
[Fact] | |||
public void SkipLocalsInitFieldInitializer() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SkipLocalsInitFieldInitializer [](start = 20, length = 30)
It doesn't look like this test actually tests anything in field initializer. However, I think this is an interesting scenario to test. We could have a lambda with a local function within a field initializer. We also could have two constructors: one with an attribute and one without. It feels like the attributes on the constructors shouldn't have any effect on the lambda and the local function. But the attribute on the type/module should have an effect. Please add a test like this. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's a more appropriate term for this test? "ImplicitConstructor"?
In reply to: 371973916 [](ancestors = 371973916)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's a more appropriate term for this test? "ImplicitConstructor"?
Yes, I think this term will describe the purpose of the test more accurately.
In reply to: 371989150 [](ancestors = 371989150,371973916)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (iteration 4), with test suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Related to #38801