提交 1914c044 编写于 作者: N Neal Gafter 提交者: Andy Gocke

Fix a bug in lambda type inference for `delegate {...}`. (#13804)

The bug is that, as an optimization, we use 'null' as the delegate type for
a parameterless `delegate` lambda, but code elsewhere in the compiler
assumes that a null delegate type occurs only in error recovery situations.
Fixes #13797
上级 3535dc87
......@@ -2615,36 +2615,26 @@ private TypeSymbol InferReturnType(BoundExpression source, NamedTypeSymbol targe
}
var anonymousFunction = (UnboundLambda)source;
if (anonymousFunction.HasSignature)
{
// Optimization:
// We know that the anonymous function has a parameter list. If it does not
// have the same arity as the delegate, then it cannot possibly be applicable.
// Rather than have type inference fail, we will simply not make a return
// type inference and have type inference continue on. Either inference
// will fail, or we will infer a nonapplicable method. Either way, there
// is no change to the semantics of overload resolution.
var originalDelegateParameters = target.DelegateParameters();
if (originalDelegateParameters.IsDefault)
{
return null;
}
// If the anonymous function is an anonymous method with no formal parameter
// list then infer the return type; there are no parameters to be typed, so
// we should be able to work out the return type regardless of the delegate type.
// Future optimization: we could return null if
// the delegate has any out parameters, since this will then not be applicable.
if (!anonymousFunction.HasSignature)
{
return anonymousFunction.InferReturnType(null, ref useSiteDiagnostics);
}
// Optimization:
// We know that the anonymous function has a parameter list. If it does not
// have the same arity as the delegate, then it cannot possibly be applicable.
// Rather than have type inference fail, we will simply not make a return
// type inference and have type inference continue on. Either inference
// will fail, or we will infer a nonapplicable method. Either way, there
// is no change to the semantics of overload resolution.
var originalDelegateParameters = target.DelegateParameters();
if (originalDelegateParameters.IsDefault)
{
return null;
}
if (originalDelegateParameters.Length != anonymousFunction.ParameterCount)
{
return null;
if (originalDelegateParameters.Length != anonymousFunction.ParameterCount)
{
return null;
}
}
var fixedDelegate = GetFixedDelegate(target);
......
......@@ -2271,5 +2271,24 @@ static void Main(string[] args)
Assert.NotEmpty(typeInfo.Type.GetMembers("Replace"));
}
}
[Fact]
[WorkItem(13797, "https://github.com/dotnet/roslyn/issues/13797")]
public void DelegateAsAction()
{
var source = @"
using System;
public static class C
{
public static void M() => Dispatch(delegate { });
public static T Dispatch<T>(Func<T> func) => default(T);
public static void Dispatch(Action func) { }
}";
var comp = CreateCompilationWithMscorlib(source);
CompileAndVerify(comp);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册