未验证 提交 f6979530 编写于 作者: J Julien Couvreur 提交者: GitHub

Avoid crash with 'new ref[]' (#25505)

上级 4b3405ec
......@@ -3605,16 +3605,19 @@ protected BoundExpression BindObjectCreationExpression(ObjectCreationExpressionS
// script class is synthesized and should not be used as a type of a new expression:
throw ExceptionUtilities.UnexpectedValue(type.TypeKind);
case TypeKind.Dynamic:
// we didn't find any type called "dynamic" so we are using the builtin dynamic type, which has no constructors:
Error(diagnostics, ErrorCode.ERR_NoConstructors, node.Type, type);
return BadExpression(node, LookupResultKind.NotCreatable);
case TypeKind.Pointer:
type = new ExtendedErrorTypeSymbol(type, LookupResultKind.NotCreatable,
diagnostics.Add(ErrorCode.ERR_UnsafeTypeInObjectCreation, node.Location, type));
goto case TypeKind.Class;
case TypeKind.Dynamic:
// we didn't find any type called "dynamic" so we are using the builtin dynamic type, which has no constructors:
case TypeKind.Array:
// ex: new ref[]
type = new ExtendedErrorTypeSymbol(type, LookupResultKind.NotCreatable,
diagnostics.Add(ErrorCode.ERR_InvalidObjectCreation, node.Type.Location, type));
goto case TypeKind.Class;
default:
throw ExceptionUtilities.UnexpectedValue(type.TypeKind);
}
......
......@@ -5929,6 +5929,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Invalid object creation.
/// </summary>
internal static string ERR_InvalidObjectCreation {
get {
return ResourceManager.GetString("ERR_InvalidObjectCreation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid output name: {0}.
/// </summary>
......
......@@ -5312,6 +5312,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_ConWithUnmanagedCon" xml:space="preserve">
<value>Type parameter '{1}' has the 'unmanaged' constraint so '{1}' cannot be used as a constraint for '{0}'</value>
</data>
<data name="ERR_InvalidObjectCreation" xml:space="preserve">
<value>Invalid object creation</value>
</data>
<data name="IDS_FeatureStackAllocInitializer" xml:space="preserve">
<value>stackalloc initializer</value>
</data>
......
......@@ -1574,7 +1574,8 @@ internal enum ErrorCode
ERR_ExpressionTreeContainsTupleBinOp = 8382,
WRN_TupleBinopLiteralNameMismatch = 8383,
ERR_TupleSizesMismatchForBinOps = 8384,
ERR_ExprCannotBeFixed = 9385,
ERR_ExprCannotBeFixed = 8385,
ERR_InvalidObjectCreation = 8386,
#endregion diagnostics introduced for C# 7.3
}
// Note: you will need to re-generate compiler code after adding warnings (build\scripts\generate-compiler-code.cmd)
......
......@@ -8730,6 +8730,11 @@ Pokud chcete odstranit toto varování, můžete místo toho použít /reference
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ Um die Warnung zu beheben, können Sie stattdessen /reference verwenden (Einbett
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ Para eliminar la advertencia puede usar /reference (establezca la propiedad Embe
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ Pour supprimer l'avertissement, vous pouvez utiliser la commande /reference (dé
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ Per rimuovere l'avviso, è invece possibile usare /reference (impostare la propr
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ Aby usunąć ostrzeżenie, możesz zamiast tego użyć opcji /reference (ustaw w
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ Para incorporar informações de tipo de interoperabilidade para os dois assembl
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ Uyarıyı kaldırmak için, /reference kullanabilirsiniz (Birlikte Çalışma T
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -8730,6 +8730,11 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<target state="new">indexing movable fixed buffers</target>
<note />
</trans-unit>
<trans-unit id="ERR_InvalidObjectCreation">
<source>Invalid object creation</source>
<target state="new">Invalid object creation</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -3120,5 +3120,44 @@ public void F()
Diagnostic(ErrorCode.ERR_ArrayInitToNonArrayType, "{7,8,9}").WithLocation(14, 28)
);
}
[Fact, WorkItem(25264, "https://github.com/dotnet/roslyn/issues/25264")]
public void TestNewRefArray()
{
var text = @"
public class C
{
public static void Main()
{
_ = /*<bind>*/ new ref[] { 1 } /*</bind>*/ ;
}
}
";
string expectedOperationTree = @"
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'new ref[] { 1 }')
Children(1):
IObjectOrCollectionInitializerOperation (OperationKind.ObjectOrCollectionInitializer, Type: ?[]) (Syntax: '{ 1 }')
Initializers(1):
IInvalidOperation (OperationKind.Invalid, Type: ?, IsImplicit) (Syntax: '1')
Children(2):
IOperation: (OperationKind.None, Type: null, IsImplicit) (Syntax: '1')
Children(1):
IInstanceReferenceOperation (OperationKind.InstanceReference, Type: ?[], IsInvalid, IsImplicit) (Syntax: 'ref[]')
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
";
var expectedDiagnostics = new[]
{
// file.cs(6,31): error CS1031: Type expected
// _ = /*<bind>*/ new ref[] { 1 } /*</bind>*/ ;
Diagnostic(ErrorCode.ERR_TypeExpected, "[").WithLocation(6, 31),
// file.cs(6,28): error CS8382: Invalid object creation
// _ = /*<bind>*/ new ref[] { 1 } /*</bind>*/ ;
Diagnostic(ErrorCode.ERR_InvalidObjectCreation, "ref[]").WithArguments("?[]").WithLocation(6, 28)
};
VerifyOperationTreeAndDiagnosticsForTest<ObjectCreationExpressionSyntax>(text, expectedOperationTree, expectedDiagnostics);
}
}
}
......@@ -2372,6 +2372,7 @@ int M()
#region Collection and Object initializers
[Fact]
[CompilerTrait(CompilerFeature.IOperation)]
public void DynamicNew()
{
string source = @"
......@@ -2379,22 +2380,55 @@ class C
{
static void M()
{
var x = new dynamic
var x = /*<bind>*/ new dynamic
{
a = 1,
b =
{
c = f()
}
};
} /*</bind>*/ ;
}
}
";
CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics(
// (6,15): error CS0143: The type 'dynamic' has no constructors defined
Diagnostic(ErrorCode.ERR_NoConstructors, "dynamic").WithArguments("dynamic"),
// (11,21): error CS0103: The name 'f' does not exist in the current context
Diagnostic(ErrorCode.ERR_NameNotInContext, "f").WithArguments("f"));
string expectedOperationTree = @"
IInvalidOperation (OperationKind.Invalid, Type: dynamic, IsInvalid) (Syntax: 'new dynamic ... }')
Children(1):
IObjectOrCollectionInitializerOperation (OperationKind.ObjectOrCollectionInitializer, Type: dynamic, IsInvalid) (Syntax: '{ ... }')
Initializers(2):
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: dynamic) (Syntax: 'a = 1')
Left:
IOperation: (OperationKind.None, Type: null) (Syntax: 'a')
Right:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
IMemberInitializerOperation (OperationKind.MemberInitializer, Type: dynamic, IsInvalid) (Syntax: 'b = ... }')
InitializedMember:
IOperation: (OperationKind.None, Type: null) (Syntax: 'b')
Initializer:
IObjectOrCollectionInitializerOperation (OperationKind.ObjectOrCollectionInitializer, Type: dynamic, IsInvalid) (Syntax: '{ ... }')
Initializers(1):
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: dynamic, IsInvalid) (Syntax: 'c = f()')
Left:
IOperation: (OperationKind.None, Type: null) (Syntax: 'c')
Right:
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'f()')
Children(1):
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'f')
Children(0)
";
var expectedDiagnostics = new[]
{
// file.cs(11,21): error CS0103: The name 'f' does not exist in the current context
// c = f()
Diagnostic(ErrorCode.ERR_NameNotInContext, "f").WithArguments("f").WithLocation(11, 21),
// file.cs(6,26): error CS8382: Invalid object creation
// var x = /*<bind>*/ new dynamic
Diagnostic(ErrorCode.ERR_InvalidObjectCreation, "dynamic").WithArguments("dynamic").WithLocation(6, 26)
};
VerifyOperationTreeAndDiagnosticsForTest<ObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[Fact]
......@@ -2603,72 +2637,74 @@ static void Main()
}
";
CreateCompilationWithMscorlib40AndSystemCore(new[] { Parse(source, options: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp5)) }).VerifyDiagnostics(
// (43,55): warning CS1981: Using 'is' to test compatibility with 'dynamic' is essentially identical to testing compatibility with 'Object' and will succeed for all non-null values
// Expression<Func<dynamic, dynamic>> e18 = x => d is dynamic; // ok, warning
Diagnostic(ErrorCode.WRN_IsDynamicIsConfusing, "d is dynamic").WithArguments("is", "dynamic", "Object"),
// (46,59): error CS0143: The type 'dynamic' has no constructors defined
Diagnostic(ErrorCode.WRN_IsDynamicIsConfusing, "d is dynamic").WithArguments("is", "dynamic", "Object").WithLocation(43, 55),
// (46,59): error CS8382: Invalid object creation
// Expression<Func<dynamic, dynamic>> e21 = x => new dynamic();
Diagnostic(ErrorCode.ERR_NoConstructors, "dynamic").WithArguments("dynamic"),
Diagnostic(ErrorCode.ERR_InvalidObjectCreation, "dynamic").WithArguments("dynamic").WithLocation(46, 59),
// (25,52): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<C>> e0 = () => new C { P = d };
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(25, 52),
// (27,54): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<C>> e2 = () => new C { D = { X = { Y = 1 }, Z = 1 } };
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "X"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "X").WithLocation(27, 54),
// (27,60): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<C>> e2 = () => new C { D = { X = { Y = 1 }, Z = 1 } };
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "Y"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "Y").WithLocation(27, 60),
// (27,69): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<C>> e2 = () => new C { D = { X = { Y = 1 }, Z = 1 } };
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "Z"),
// (28,50): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<C>> e3 = () => new C() { { d }, { d, d, d } };
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "{ d }"),
// (28,57): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<C>> e3 = () => new C() { { d }, { d, d, d } };
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "{ d, d, d }"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "Z").WithLocation(27, 69),
// (28,44): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<C>> e3 = () => new C() { { d }, { d, d, d } };
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "{ d }").WithLocation(28, 44),
// (28,51): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<C>> e3 = () => new C() { { d }, { d, d, d } };
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "{ d, d, d }").WithLocation(28, 51),
// (29,54): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e4 = x => x.goo();
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x.goo()"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x.goo()").WithLocation(29, 54),
// (29,54): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e4 = x => x.goo();
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x.goo"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x.goo").WithLocation(29, 54),
// (30,54): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e5 = x => x[1];
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x[1]"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x[1]").WithLocation(30, 54),
// (31,54): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e6 = x => x.y.z;
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x.y.z"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x.y.z").WithLocation(31, 54),
// (31,54): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e6 = x => x.y.z;
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x.y"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x.y").WithLocation(31, 54),
// (32,54): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e7 = x => x + 1;
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x + 1"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x + 1").WithLocation(32, 54),
// (33,54): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e8 = x => -x;
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "-x"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "-x").WithLocation(33, 54),
// (34,54): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e9 = x => f(d);
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "f(d)"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "f(d)").WithLocation(34, 54),
// (36,55): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e11 = x => f((dynamic)1);
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "f((dynamic)1)"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "f((dynamic)1)").WithLocation(36, 55),
// (37,55): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e12 = x => f(d ?? null);
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "f(d ?? null)"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "f(d ?? null)").WithLocation(37, 55),
// (38,55): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e13 = x => d ? 1 : 2;
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(38, 55),
// (39,56): error CS1989: Async lambda expressions cannot be converted to expression trees
// Expression<Func<dynamic, Task<dynamic>>> e14 = async x => await d;
Diagnostic(ErrorCode.ERR_BadAsyncExpressionTree, "async x => await d"),
Diagnostic(ErrorCode.ERR_BadAsyncExpressionTree, "async x => await d").WithLocation(39, 56),
// (47,84): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e22 = x => from a in new[] { d } select a + 1;
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "a + 1"),
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "a + 1").WithLocation(47, 84),
// (49,55): error CS1963: An expression tree may not contain a dynamic operation
// Expression<Func<dynamic, dynamic>> e24 = x => new string(x);
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "new string(x)"));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "new string(x)").WithLocation(49, 55)
);
}
[Fact, WorkItem(578401, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/578401")]
......
......@@ -12368,12 +12368,9 @@ static void Main(string[] args)
Assert.Null(semanticInfo.ConvertedType);
Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind);
Assert.Null(semanticInfo.Symbol);
Assert.Equal(CandidateReason.NotCreatable, semanticInfo.CandidateReason);
Assert.Equal(1, semanticInfo.CandidateSymbols.Length);
var sortedCandidates = semanticInfo.CandidateSymbols.OrderBy(s => s.ToTestDisplayString(), StringComparer.Ordinal).ToArray();
Assert.Equal("dynamic", sortedCandidates[0].ToTestDisplayString());
Assert.Equal(SymbolKind.DynamicType, sortedCandidates[0].Kind);
Assert.Equal("dynamic", semanticInfo.Symbol.ToTestDisplayString());
Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason);
Assert.Equal(0, semanticInfo.CandidateSymbols.Length);
Assert.Equal(0, semanticInfo.MethodGroup.Length);
......@@ -12396,8 +12393,8 @@ static void Main(string[] args)
";
var semanticInfo = GetSemanticInfoForTest<ObjectCreationExpressionSyntax>(sourceCode);
Assert.Equal("?", semanticInfo.Type.ToTestDisplayString());
Assert.Equal(TypeKind.Error, semanticInfo.Type.TypeKind);
Assert.Equal("dynamic", semanticInfo.Type.ToTestDisplayString());
Assert.Equal(TypeKind.Dynamic, semanticInfo.Type.TypeKind);
Assert.Equal("System.Object", semanticInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(TypeKind.Class, semanticInfo.ConvertedType.TypeKind);
Assert.Equal(ConversionKind.NoConversion, semanticInfo.ImplicitConversion.Kind);
......
......@@ -479,5 +479,54 @@ class Test
// void M(ref readonly int p) => throw null;
Diagnostic(ErrorCode.WRN_UnreferencedField, "p").WithArguments("Test.p").WithLocation(4, 29));
}
[Fact, WorkItem(25264, "https://github.com/dotnet/roslyn/issues/25264")]
public void TestNewRefArray()
{
UsingStatement("new ref[];",
// (1,8): error CS1031: Type expected
// new ref[];
Diagnostic(ErrorCode.ERR_TypeExpected, "[").WithLocation(1, 8),
// (1,10): error CS1526: A new expression requires (), [], or {} after type
// new ref[];
Diagnostic(ErrorCode.ERR_BadNewExpr, ";").WithLocation(1, 10)
);
N(SyntaxKind.ExpressionStatement);
{
N(SyntaxKind.ObjectCreationExpression);
{
N(SyntaxKind.NewKeyword);
N(SyntaxKind.RefType);
{
N(SyntaxKind.RefKeyword);
N(SyntaxKind.ArrayType);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
N(SyntaxKind.ArrayRankSpecifier);
{
N(SyntaxKind.OpenBracketToken);
N(SyntaxKind.OmittedArraySizeExpression);
{
N(SyntaxKind.OmittedArraySizeExpressionToken);
}
N(SyntaxKind.CloseBracketToken);
}
}
}
M(SyntaxKind.ArgumentList);
{
M(SyntaxKind.OpenParenToken);
M(SyntaxKind.CloseParenToken);
}
}
N(SyntaxKind.SemicolonToken);
}
EOF();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册