Conversation
| ref arguments, | ||
| ref argRefKinds); | ||
|
|
||
| Debug.Assert(arguments.IsDefault && argRefKinds.IsDefault && receiver.Kind == BoundKind.TypeExpression); |
There was a problem hiding this comment.
receiver.Kind == BoundKind.TypeExpression [](start = 77, length = 41)
What is this type? #Closed
There was a problem hiding this comment.
Made the var explicit and added some more verification of the remapped method.
In reply to: 445955503 [](ancestors = 445955503)
| return base.VisitDelegateCreationExpression(node); | ||
| } | ||
|
|
||
| public override BoundNode VisitFunctionPointerLoad(BoundFunctionPointerLoad node) |
There was a problem hiding this comment.
VisitFunctionPointerLoad [](start = 34, length = 24)
Did you check other places where we override VisitDelegateCreationExpression to confirm that we don't need to add VisitFunctionPointerLoad? We probably have several visitors that introduce virtual methods with names like that. #Closed
There was a problem hiding this comment.
I've taken a look. I'll add an override in MethodToClassRewriter, but I can't find a case that it will actually change, as other than this it's only used for iterator and async method rewriting. Since we don't allow you to refer to the compiler-generated underlying methods of these from source, there's nothing that we can test. If we add a new thing that gets remapped in the future, though, it will function as expected.
In reply to: 445956108 [](ancestors = 445956108)
| delegate*<void> a = &local; | ||
| a(); | ||
|
|
||
| static void local() => System.Console.Write(""local""); |
There was a problem hiding this comment.
Consider adding a test where the contents of this method body exist within a lambda expression. Verifying the rewriting works in a nested environment. #Resolved
|
Done with review pass (iteration 3) #Closed |
* Additional tests for nested function contexts. * Override VisitFunctionPointerLoad in MethodToClassRewriter. * Adjust debug asserts.
|
@AlekseyTs addressed feedback. This PR now addresses an additional issue I found when testing locally, where an In reply to: 649949098 [](ancestors = 649949098) |
| if (used) | ||
| { | ||
| _builder.EmitOpCode(ILOpCode.Ldftn); | ||
| EmitSymbolToken(load.TargetMethod, load.Syntax, optArgList: null); |
There was a problem hiding this comment.
EmitSymbolToken(load.TargetMethod, load.Syntax, optArgList: null); [](start = 16, length = 66)
Can this have a side effect, for example an exception? Is this conditional handling consistent with what we do for delegate creation? I.e. if a delegate instance is not used, are we not loading the address of a target method? #Closed
There was a problem hiding this comment.
If I hadn't fixed the remapped local function bug, it would have an effect, but the only effect from this I could see now is if a tree-trimming algorithm decides the referenced method isn't used (which it isn't) and decides to remove it. However, when I implemented this I checked our handling for delegates:
static void M()
{
System.Action a = M;
}produces this IL in release mode:
.method private hidebysig static
void M () cil managed
{
// Method begins at RVA 0x2050
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method C::M
In reply to: 446421466 [](ancestors = 446421466)
There was a problem hiding this comment.
My intuition was that the tree trimming aspect was fine, and likely desired. The fact that it lines up with delegate behavior makes me feel good about this outcome.
| if (used) | ||
| { | ||
| _builder.EmitOpCode(ILOpCode.Ldftn); | ||
| EmitSymbolToken(load.TargetMethod, load.Syntax, optArgList: null); |
There was a problem hiding this comment.
My intuition was that the tree trimming aspect was fine, and likely desired. The fact that it lines up with delegate behavior makes me feel good about this outcome.
|
|
||
| public override BoundNode VisitFunctionPointerLoad(BoundFunctionPointerLoad node) | ||
| { | ||
| return node.Update(VisitMethodSymbol(node.TargetMethod), node.Type); |
There was a problem hiding this comment.
node.Type [](start = 69, length = 9)
It looks like we should also visit type. #Closed
|
Done with review pass (iteration 5) #Closed |
|
@AlekseyTs addressed feedback. In reply to: 650448547 [](ancestors = 650448547) |
AlekseyTs
left a comment
There was a problem hiding this comment.
LGTM (iteration 6), assuming CI is passing
Fixes a couple of function pointer bugs:
ldftninstruction, and corrects handling of non-static local functions. This fixes Address of local function not working #45447.@dotnet/roslyn-compiler @AlekseyTs for review.