Correctly support local functions in function pointer loads. Fixes...

Correctly support local functions in function pointer loads. Fixes https://github.com/dotnet/roslyn/issues/45447.
上级 7a836c8e
......@@ -292,7 +292,7 @@ private static bool OverloadResolutionResultIsValid<TMember>(ArrayBuilder<Member
if (isFunctionPointerResolution)
{
RemoveCallingConventionMismatches(results, callingConvention);
RemoveStaticInstanceMismatches(results, requireStatic: true);
RemoveMethodsNotDeclaredStatic(results);
}
// NB: As in dev12, we do this AFTER removing less derived members.
......@@ -387,6 +387,22 @@ private static bool OverloadResolutionResultIsValid<TMember>(ArrayBuilder<Member
}
}
private static void RemoveMethodsNotDeclaredStatic<TMember>(ArrayBuilder<MemberResolutionResult<TMember>> results) where TMember : Symbol
{
// RemoveStaticInstanceMistmatches allows methods that do not need a reciever but are not declared static,
// such as a local function that is not declared static. This eliminates methods that are not actually
// declared as static
for (int f = 0; f < results.Count; f++)
{
var result = results[f];
TMember member = result.Member;
if (result.Result.IsValid && !member.IsStatic)
{
results[f] = new MemberResolutionResult<TMember>(member, result.LeastOverriddenMember, MemberAnalysisResult.StaticInstanceMismatch());
}
}
}
private void RemoveConstraintViolations<TMember>(ArrayBuilder<MemberResolutionResult<TMember>> results) where TMember : Symbol
{
// When the feature 'ImprovedOverloadCandidates' is enabled, we do not include methods for which the type arguments
......
......@@ -1303,6 +1303,30 @@ public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationE
return base.VisitDelegateCreationExpression(node);
}
public override BoundNode VisitFunctionPointerLoad(BoundFunctionPointerLoad node)
{
if (node.TargetMethod.MethodKind == MethodKind.LocalFunction)
{
Debug.Assert(node.TargetMethod is { RequiresInstanceReceiver: false, IsStatic: true });
ImmutableArray<BoundExpression> arguments = default;
ImmutableArray<RefKind> argRefKinds = default;
RemapLocalFunction(
node.Syntax,
node.TargetMethod,
out var receiver,
out var remappedMethod,
ref arguments,
ref argRefKinds);
Debug.Assert(arguments.IsDefault && argRefKinds.IsDefault && receiver.Kind == BoundKind.TypeExpression);
return node.Update(remappedMethod, node.Type);
}
return base.VisitFunctionPointerLoad(node);
}
public override BoundNode VisitConversion(BoundConversion conversion)
{
// a conversion with a method should have been rewritten, e.g. to an invocation
......
......@@ -7101,6 +7101,62 @@ .locals init (delegate*<System.Span<char>, System.Span<char>> V_0)
");
}
[Fact, WorkItem(45447, "https://github.com/dotnet/roslyn/issues/45447")]
public void LocalFunction_ValidStatic()
{
var verifier = CompileAndVerifyFunctionPointers(@"
unsafe class FunctionPointer
{
public static void Main()
{
delegate*<void> a = &local;
a();
static void local() => System.Console.Write(""local"");
}
}
", expectedOutput: "local");
verifier.VerifyIL("FunctionPointer.Main", @"
{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldftn ""void FunctionPointer.<Main>g__local|0_0()""
IL_0006: calli ""delegate*<void>""
IL_000b: ret
}
");
}
[Fact, WorkItem(45447, "https://github.com/dotnet/roslyn/issues/45447")]
public void LocalFunction_InvalidNonStatic()
{
var comp = CreateCompilationWithFunctionPointers(@"
unsafe class FunctionPointer
{
public static void M()
{
int local = 1;
delegate*<void> first = &noCaptures;
delegate*<void> second = &capturesLocal;
void noCaptures() { }
void capturesLocal() { local++; }
}
}");
comp.VerifyDiagnostics(
// (8,34): error CS8759: Cannot create a function pointer for 'noCaptures()' because it is not a static method
// delegate*<void> first = &noCaptures;
Diagnostic(ErrorCode.ERR_FuncPtrMethMustBeStatic, "noCaptures").WithArguments("noCaptures()").WithLocation(8, 34),
// (9,35): error CS8759: Cannot create a function pointer for 'capturesLocal()' because it is not a static method
// delegate*<void> second = &capturesLocal;
Diagnostic(ErrorCode.ERR_FuncPtrMethMustBeStatic, "capturesLocal").WithArguments("capturesLocal()").WithLocation(9, 35)
);
}
private static readonly Guid s_guid = new Guid("97F4DBD4-F6D1-4FAD-91B3-1001F92068E5");
private static readonly BlobContentId s_contentId = new BlobContentId(s_guid, 0x04030201);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册