提交 e27214f0 编写于 作者: L lorcanmooney 提交者: Charles Stoner

Disallow object initializers in default parameter values

上级 7a9eda0e
......@@ -176,25 +176,6 @@ internal static class ParameterHelpers
Conversion conversion = binder.Conversions.ClassifyImplicitConversionFromExpression(defaultExpression, parameterType, ref useSiteDiagnostics);
diagnostics.Add(defaultExpression.Syntax, useSiteDiagnostics);
// SPEC VIOLATION:
// By the spec an optional parameter initializer is required to be either:
// * a constant,
// * new S() where S is a value type
// * default(S) where S is a value type.
//
// The native compiler considers default(T) to be a valid
// initializer regardless of whether T is a value type
// reference type, type parameter type, and so on.
// We should consider simply allowing this in the spec.
//
// Also when valuetype S has a parameterless constructor,
// new S() is clearly not a constant expression and should produce an error
bool isValidDefaultValue = (defaultExpression.ConstantValue != null) ||
(defaultExpression.Kind == BoundKind.DefaultOperator) ||
(defaultExpression.Kind == BoundKind.ObjectCreationExpression &&
((BoundObjectCreationExpression)defaultExpression).Constructor.IsDefaultValueTypeConstructor());
SyntaxToken outKeyword;
SyntaxToken refKeyword;
SyntaxToken paramsKeyword;
......@@ -234,7 +215,7 @@ internal static class ParameterHelpers
hasErrors = true;
}
}
else if (!defaultExpression.HasAnyErrors && !isValidDefaultValue)
else if (!defaultExpression.HasAnyErrors && !IsValidDefaultValue(defaultExpression))
{
// error CS1736: Default parameter value for '{0}' must be a compile-time constant
diagnostics.Add(ErrorCode.ERR_DefaultValueMustBeConstant, parameterSyntax.Default.Value.Location, parameterSyntax.Identifier.ValueText);
......@@ -319,6 +300,32 @@ internal static class ParameterHelpers
return hasErrors;
}
private static bool IsValidDefaultValue(BoundExpression expression)
{
// SPEC VIOLATION:
// By the spec an optional parameter initializer is required to be either:
// * a constant,
// * new S() where S is a value type
// * default(S) where S is a value type.
//
// The native compiler considers default(T) to be a valid
// initializer regardless of whether T is a value type
// reference type, type parameter type, and so on.
// We should consider simply allowing this in the spec.
//
// Also when valuetype S has a parameterless constructor,
// new S() is clearly not a constant expression and should produce an error
return (expression.ConstantValue != null) ||
(expression.Kind == BoundKind.DefaultOperator) ||
(expression.Kind == BoundKind.ObjectCreationExpression &&
IsValidDefaultValue((BoundObjectCreationExpression)expression));
}
private static bool IsValidDefaultValue(BoundObjectCreationExpression expression)
{
return expression.Constructor.IsDefaultValueTypeConstructor() && expression.InitializerExpressionOpt == null;
}
internal static MethodSymbol FindContainingGenericMethod(Symbol symbol)
{
for (Symbol current = symbol; (object)current != null; current = current.ContainingSymbol)
......
......@@ -845,6 +845,27 @@ public void OptionalValueInvokesStaticMethod()
Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "M2()").WithArguments("value").WithLocation(5, 37));
}
[WorkItem(11638, "https://github.com/dotnet/roslyn/issues/11638")]
[Fact]
public void OptionalValueHasObjectInitializer()
{
var source =
@"class C
{
static void Test(Vector3 vector = new Vector3() { X = 1f, Y = 1f, Z = 1f}) { }
}
public struct Vector3
{
public float X;
public float Y;
public float Z;
}";
CreateCompilationWithMscorlib(source).VerifyDiagnostics(
// (3,39): error CS1736: Default parameter value for 'vector' must be a compile-time constant
Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "new Vector3() { X = 1f, Y = 1f, Z = 1f}").WithArguments("vector").WithLocation(3, 39));
}
[WorkItem(542411, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542411")]
[WorkItem(542365, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542365")]
[Fact]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册