diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
index 0c0da7afd447245dd1af46541368c9b3b93026c6..2373642d487453fe16ddba5a3f51bf95a15a79bf 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
+++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
@@ -7027,15 +7027,6 @@ internal class CSharpResources {
}
}
- ///
- /// Looks up a localized string similar to Deconstruction is not supported for an 'out' argument..
- ///
- internal static string ERR_OutVarDeconstructionIsNotSupported {
- get {
- return ResourceManager.GetString("ERR_OutVarDeconstructionIsNotSupported", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to '{0}' cannot define overloaded methods that differ only on ref and out.
///
@@ -9331,6 +9322,15 @@ internal class CSharpResources {
}
}
+ ///
+ /// Looks up a localized string similar to The syntax 'var (...)' as an lvalue is reserved..
+ ///
+ internal static string ERR_VarInvocationLvalueReserved {
+ get {
+ return ResourceManager.GetString("ERR_VarInvocationLvalueReserved", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to '{0}': virtual or abstract members cannot be private.
///
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 562014a4122632a1119c376021e6c9ff8d0d32a7..8044e03270a25c6ff0aba136d2d7d1634c6d454d 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -4947,8 +4947,8 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Invalid instrumentation kind: {0}
-
- Deconstruction is not supported for an 'out' argument.
+
+ The syntax 'var (...)' as an lvalue is reserved.
Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers.
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 8577a12e69e16bce2b659df63e0f995c8206ee96..bfcd3ea40bedd6a924d7fab150be4db16e80546f 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -1432,7 +1432,7 @@ internal enum ErrorCode
ERR_ImplicitlyTypedOutVariableUsedInTheSameArgumentList = 8196,
ERR_TypeInferenceFailedForImplicitlyTypedOutVariable = 8197,
ERR_ExpressionTreeContainsOutVariable = 8198,
- ERR_OutVarDeconstructionIsNotSupported = 8199,
+ ERR_VarInvocationLvalueReserved = 8199,
ERR_ExpressionVariableInConstructorOrFieldInitializer = 8200,
#endregion diagnostics for out var
}
diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
index 7e89193e78cea07112ba349d683eb85474186bf5..f0f8de618549455d86c66f49dc44b01b8f2c04f7 100644
--- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
+++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
@@ -3390,6 +3390,7 @@ private ExpressionSyntax ParsePossibleRefExpression()
var expression = this.ParseExpressionCore();
if (refKeyword != default(SyntaxToken))
{
+ expression = CheckValidLvalue(expression);
expression = _syntaxFactory.RefExpression(refKeyword, expression);
}
@@ -4842,6 +4843,7 @@ private static bool CanReuseVariableDeclarator(CSharp.Syntax.VariableDeclaratorS
var init = this.ParseVariableInitializer(isLocal && !isConst);
if (refKeyword != null)
{
+ init = CheckValidLvalue(init);
init = _syntaxFactory.RefExpression(refKeyword, init);
}
@@ -9248,6 +9250,11 @@ private ExpressionSyntax ParseSubExpressionCore(Precedence precedence)
newPrecedence = GetPrecedence(opKind);
var opToken = this.EatToken();
var operand = this.ParseSubExpression(newPrecedence);
+ if (SyntaxFacts.IsIncrementOrDecrementOperator(opToken.Kind))
+ {
+ operand = CheckValidLvalue(operand);
+ }
+
leftOperand = _syntaxFactory.PrefixUnaryExpression(opKind, opToken, operand);
}
else if (IsAwaitExpression())
@@ -9366,6 +9373,7 @@ private ExpressionSyntax ParseSubExpressionCore(Precedence precedence)
opToken = AddTrailingSkippedSyntax(opToken, refToken);
}
+ leftOperand = CheckValidLvalue(leftOperand);
leftOperand = _syntaxFactory.AssignmentExpression(opKind, leftOperand, opToken, this.ParseSubExpression(newPrecedence));
}
else
@@ -9564,6 +9572,7 @@ private ExpressionSyntax ParsePostFixExpression(ExpressionSyntax expr)
case SyntaxKind.PlusPlusToken:
case SyntaxKind.MinusMinusToken:
+ expr = CheckValidLvalue(expr);
expr = _syntaxFactory.PostfixUnaryExpression(SyntaxFacts.GetPostfixUnaryExpression(tk), expr, this.EatToken());
break;
@@ -9843,14 +9852,9 @@ private ArgumentSyntax ParseArgumentExpression(bool isIndexer)
{
expression = this.ParseSubExpression(Precedence.Expression);
- // See if the expression is an invocation that could also be successfully parsed and interpreted
- // as a deconstruction target. I.e. something like "var (x, y)" or "var (x, (y, z))".
- // We should report an error in this case because we plan to support deconstruction for out arguments
- // in the future. We need to ensure that we do not successfully interpret this as an invocation of a
- // ref-returning method named var with two, or more arguments.
- if (IsDeconstructionCompatibleArgument(refOrOutKeyword, expression))
+ if (refOrOutKeyword != null)
{
- expression = this.AddError(expression, ErrorCode.ERR_OutVarDeconstructionIsNotSupported);
+ expression = CheckValidLvalue(expression);
}
}
}
@@ -9858,60 +9862,35 @@ private ArgumentSyntax ParseArgumentExpression(bool isIndexer)
return _syntaxFactory.Argument(nameColon, refOrOutKeyword, expression);
}
- private static bool IsDeconstructionCompatibleArgument(SyntaxToken refOrOutKeyword, ExpressionSyntax expression)
+ private ExpressionSyntax CheckValidLvalue(ExpressionSyntax expression)
{
- if (refOrOutKeyword?.Kind == SyntaxKind.OutKeyword &&
- expression.Kind == SyntaxKind.InvocationExpression)
+ return IsDeconstructionCompatibleArgument(expression)
+ ? this.AddError(expression, ErrorCode.ERR_VarInvocationLvalueReserved)
+ : expression;
+ }
+
+ ///
+ /// See if the expression is an invocation of a method named 'var',
+ /// I.e. something like "var(x, y)" or "var(x, (y, z))" or "var(1)".
+ /// We report an error when such an invocation is used in a certain syntactic contexts that
+ /// will require an lvalue because we may elect to support deconstruction
+ /// in the future. We need to ensure that we do not successfully interpret this as an invocation of a
+ /// ref-returning method named var.
+ ///
+ private static bool IsDeconstructionCompatibleArgument(ExpressionSyntax expression)
+ {
+ if (expression.Kind == SyntaxKind.InvocationExpression)
{
var invocation = (InvocationExpressionSyntax)expression;
ExpressionSyntax invocationTarget = invocation.Expression;
return invocationTarget.Kind == SyntaxKind.IdentifierName &&
- ((IdentifierNameSyntax)invocationTarget).Identifier.IsVar() &&
- invocation.ArgumentList.Arguments.Count > 1 &&
- !expression.GetDiagnostics().Contains(info => info.Severity == DiagnosticSeverity.Error) &&
- IsDeconstructionCompatibleArgumentList(invocation.ArgumentList.Arguments);
+ ((IdentifierNameSyntax)invocationTarget).Identifier.IsVar();
}
return false;
}
- private static bool IsDeconstructionCompatibleArgumentList(SeparatedSyntaxList arguments)
- {
- int count = arguments.Count;
-
- for (int i = 0; i < count; i++)
- {
- ArgumentSyntax argument = arguments[i];
-
- if (argument.NameColon != null || argument.RefOrOutKeyword != null)
- {
- return false;
- }
-
- switch (argument.Expression.Kind)
- {
- case SyntaxKind.IdentifierName:
- // Identifier is compatible
- break;
-
- case SyntaxKind.TupleExpression:
- // Tuple is compatible if its argument list is compatible
- if (!IsDeconstructionCompatibleArgumentList(((TupleExpressionSyntax)argument.Expression).Arguments))
- {
- return false;
- }
- break;
-
- default:
- // Nothing else can be compatible.
- return false;
- }
- }
-
- return true;
- }
-
private bool IsPossibleOutVarDeclaration()
{
var tk = this.CurrentToken.Kind;
diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs
index 6828630b3ab2119f414ce97c3a71d9500285c23a..c82373229b7aeee4402dff614e0f48131eb9d3f3 100644
--- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs
+++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs
@@ -414,6 +414,18 @@ public static SyntaxKind GetPostfixUnaryExpression(SyntaxKind token)
}
}
+ internal static bool IsIncrementOrDecrementOperator(SyntaxKind token)
+ {
+ switch (token)
+ {
+ case SyntaxKind.PlusPlusToken:
+ case SyntaxKind.MinusMinusToken:
+ return true;
+ default:
+ return false;
+ }
+ }
+
public static bool IsUnaryOperatorDeclarationToken(SyntaxKind token)
{
return IsPrefixUnaryExpressionOperatorToken(token) ||
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs
index 28a567adf1ec78dff634f8a9f9563f75053f3e0c..df486d57af5f90eb2415408474b62897a4a3484b 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs
@@ -1982,15 +1982,24 @@ static void Main()
var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef });
comp.VerifyDiagnostics(
+ // (6,9): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // var (int x1, x2) = (1, 2);
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (int x1, x2)").WithLocation(6, 9),
// (6,14): error CS1525: Invalid expression term 'int'
// var (int x1, x2) = (1, 2);
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "int").WithArguments("int").WithLocation(6, 14),
// (6,18): error CS1003: Syntax error, ',' expected
// var (int x1, x2) = (1, 2);
Diagnostic(ErrorCode.ERR_SyntaxError, "x1").WithArguments(",", "").WithLocation(6, 18),
+ // (7,9): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // var (var x3, x4) = (1, 2);
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (var x3, x4)").WithLocation(7, 9),
// (7,18): error CS1003: Syntax error, ',' expected
// var (var x3, x4) = (1, 2);
Diagnostic(ErrorCode.ERR_SyntaxError, "x3").WithArguments(",", "").WithLocation(7, 18),
+ // (8,9): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // var (x5, var (x6, x7)) = (1, (2, 3));
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x5, var (x6, x7))").WithLocation(8, 9),
// (6,18): error CS0103: The name 'x1' does not exist in the current context
// var (int x1, x2) = (1, 2);
Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(6, 18),
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs
index fa5a18a04f2810c1f758e50a1a5e1e232fd91718..4304ef36023a02413f5ee35c332bb08e06e205df 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs
@@ -78,9 +78,9 @@ static object Test1(out int x)
var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
- // (6,19): error CS8199: Deconstruction is not supported for an 'out' argument.
+ // (6,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
// Test1(out var (x1, x2));
- Diagnostic(ErrorCode.ERR_OutVarDeconstructionIsNotSupported, "var (x1, x2)").WithLocation(6, 19),
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x1, x2)").WithLocation(6, 19),
// (6,24): error CS0103: The name 'x1' does not exist in the current context
// Test1(out var (x1, x2));
Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(6, 24),
@@ -277,9 +277,9 @@ static object Test1(out int x)
options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
- // (11,19): error CS8199: Deconstruction is not supported for an 'out' argument.
+ // (11,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
// Test1(out var (x1, (x2, x3)));
- Diagnostic(ErrorCode.ERR_OutVarDeconstructionIsNotSupported, "var (x1, (x2, x3))").WithLocation(11, 19),
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x1, (x2, x3))").WithLocation(11, 19),
// (4,24): warning CS0649: Field 'Cls.F1' is never assigned to, and will always have its default value 0
// private static int F1;
Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F1").WithArguments("Cls.F1", "0").WithLocation(4, 24)
@@ -318,12 +318,13 @@ static object Test1(out int x)
var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
+ // (8,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // Test1(out var (x1));
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x1)").WithLocation(8, 19),
// (4,24): warning CS0649: Field 'Cls.F1' is never assigned to, and will always have its default value 0
// private static int F1;
Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F1").WithArguments("Cls.F1", "0").WithLocation(4, 24)
);
-
- CompileAndVerify(compilation, expectedOutput: "123");
Assert.False(compilation.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType().Any());
}
@@ -358,12 +359,13 @@ static object Test1(out int x)
var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
+ // (9,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // Test1(out var (x1, x2: x2));
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x1, x2: x2)").WithLocation(9, 19),
// (4,24): warning CS0649: Field 'Cls.F1' is never assigned to, and will always have its default value 0
// private static int F1;
Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F1").WithArguments("Cls.F1", "0").WithLocation(4, 24)
);
-
- CompileAndVerify(compilation, expectedOutput: "123");
Assert.False(compilation.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType().Any());
}
@@ -398,12 +400,13 @@ static object Test1(out int x)
var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
+ // (9,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // Test1(out var (ref x1, x2));
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (ref x1, x2)").WithLocation(9, 19),
// (4,24): warning CS0649: Field 'Cls.F1' is never assigned to, and will always have its default value 0
// private static int F1;
Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F1").WithArguments("Cls.F1", "0").WithLocation(4, 24)
);
-
- CompileAndVerify(compilation, expectedOutput: "123");
Assert.False(compilation.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType().Any());
}
@@ -438,12 +441,13 @@ static object Test1(out int x)
var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
+ // (9,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // Test1(out var (x1, (x2)));
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x1, (x2))").WithLocation(9, 19),
// (4,24): warning CS0649: Field 'Cls.F1' is never assigned to, and will always have its default value 0
// private static int F1;
Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F1").WithArguments("Cls.F1", "0").WithLocation(4, 24)
);
-
- CompileAndVerify(compilation, expectedOutput: "123");
Assert.False(compilation.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType().Any());
}
@@ -478,12 +482,13 @@ static object Test1(out int x)
var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
+ // (9,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // Test1(out var ((x1), x2));
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var ((x1), x2)").WithLocation(9, 19),
// (4,24): warning CS0649: Field 'Cls.F1' is never assigned to, and will always have its default value 0
// private static int F1;
Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F1").WithArguments("Cls.F1", "0").WithLocation(4, 24)
);
-
- CompileAndVerify(compilation, expectedOutput: "123");
Assert.False(compilation.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType().Any());
}
@@ -511,9 +516,9 @@ static object Test1(out int x)
var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp6));
compilation.VerifyDiagnostics(
- // (6,19): error CS8199: Deconstruction is not supported for an 'out' argument.
+ // (6,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
// Test1(out var (x1, x2));
- Diagnostic(ErrorCode.ERR_OutVarDeconstructionIsNotSupported, "var (x1, x2)").WithLocation(6, 19),
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x1, x2)").WithLocation(6, 19),
// (6,24): error CS0103: The name 'x1' does not exist in the current context
// Test1(out var (x1, x2));
Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(6, 24),
@@ -605,12 +610,13 @@ static object Test1(ref int x)
var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
+ // (9,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // Test1(ref var (x1, x2));
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x1, x2)").WithLocation(9, 19),
// (4,24): warning CS0649: Field 'Cls.F1' is never assigned to, and will always have its default value 0
// private static int F1;
Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F1").WithArguments("Cls.F1", "0").WithLocation(4, 24)
);
-
- CompileAndVerify(compilation, expectedOutput: "123");
Assert.False(compilation.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType().Any());
}
@@ -731,12 +737,13 @@ static object Test1(out int x)
options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular);
compilation.VerifyDiagnostics(
+ // (11,19): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // Test1(out var (x1, (a: x2, b: x3)));
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x1, (a: x2, b: x3))").WithLocation(11, 19),
// (4,24): warning CS0649: Field 'Cls.F1' is never assigned to, and will always have its default value 0
// private static int F1;
Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F1").WithArguments("Cls.F1", "0").WithLocation(4, 24)
);
-
- CompileAndVerify(compilation, expectedOutput: "123");
Assert.False(compilation.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType().Any());
}
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs
index 6b6484068354984d911a5966b6aebcac47d4e3dc..46925da1685b0534db34ef9f6eaf69762f615387 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs
@@ -1805,5 +1805,61 @@ struct ValueTuple
CreateCompilationWithMscorlib(source).VerifyDiagnostics(
);
}
+
+ public void NoDeconstructionAsLvalue()
+ {
+ var source =
+@"
+class C
+{
+ void M()
+ {
+ var (x, y) = e; // ok, deconstruction declaration
+ var(x, y); // ok, invocation
+ int x = var(x, y); // ok, invocation
+ var(x, y) += e; // error 1
+ var(x, y)++; // error 2
+ ++var(x, y); // error 3
+ M(out var(x, y)); // error 4
+ M(ref var(x, y)); // error 5
+ return ref var(x, y); // error 6
+ ref int x = ref var(x, y); // error 7
+ var (x, 1) = e; // error 8
+ }
+}";
+ ParseAndValidate(source,
+ // (9,9): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // var(x, y) += e; // error 1
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var(x, y)").WithLocation(9, 9),
+ // (10,9): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // var(x, y)++; // error 2
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var(x, y)").WithLocation(10, 9),
+ // (11,11): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // ++var(x, y); // error 3
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var(x, y)").WithLocation(11, 11),
+ // (12,15): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // M(out var(x, y)); // error 4
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var(x, y)").WithLocation(12, 15),
+ // (13,15): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // M(ref var(x, y)); // error 5
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var(x, y)").WithLocation(13, 15),
+ // (14,20): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // return ref var(x, y); // error 6
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var(x, y)").WithLocation(14, 20),
+ // (15,25): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // ref int x = ref var(x, y); // error 7
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var(x, y)").WithLocation(15, 25),
+ // (16,9): error CS8199: The syntax 'var (...)' as an lvalue is reserved.
+ // var (x, 1) = e; // error 8
+ Diagnostic(ErrorCode.ERR_VarInvocationLvalueReserved, "var (x, 1)").WithLocation(16, 9)
+ );
+ }
+
+ public static void ParseAndValidate(string text, params DiagnosticDescription[] expectedErrors)
+ {
+ var parsedTree = ParseWithRoundTripCheck(text);
+ var actualErrors = parsedTree.GetDiagnostics();
+ actualErrors.Verify(expectedErrors);
+ }
}
}