From 2851759c359f4f08d6c7267a4066b484eddbb1f9 Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Mon, 26 Nov 2018 17:54:24 -0800 Subject: [PATCH] Disallow null coalescing assignment in expression trees. --- .../Portable/CSharpResources.Designer.cs | 11 ++++++++++- .../CSharp/Portable/CSharpResources.resx | 3 +++ .../CSharp/Portable/Errors/ErrorCode.cs | 3 ++- .../DiagnosticsPass_ExpressionTrees.cs | 10 ++++++++++ .../CSharp/Portable/xlf/CSharpResources.cs.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.de.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.es.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.fr.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.it.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.ja.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.ko.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.pl.xlf | 5 +++++ .../Portable/xlf/CSharpResources.pt-BR.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.ru.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.tr.xlf | 5 +++++ .../Portable/xlf/CSharpResources.zh-Hans.xlf | 5 +++++ .../Portable/xlf/CSharpResources.zh-Hant.xlf | 5 +++++ .../CodeGenNullCoalescingAssignmentTests.cs | 18 ++++++++++++++++++ 18 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs index 52adc30fe8a..db745444332 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.CSharp { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class CSharpResources { @@ -4425,6 +4425,15 @@ internal class CSharpResources { } } + /// + /// Looks up a localized string similar to An expression tree may not contain a null coalescing assignment. + /// + internal static string ERR_ExpressionTreeCantContainNullCoalescingAssignment { + get { + return ResourceManager.GetString("ERR_ExpressionTreeCantContainNullCoalescingAssignment", resourceCulture); + } + } + /// /// Looks up a localized string similar to Expression tree cannot contain value of ref struct or restricted type '{0}'.. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index b51b7c80b5d..f1c2a94a0ec 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -5635,4 +5635,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ 'else' cannot start a statement. + + An expression tree may not contain a null coalescing assignment + \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index b2cd9e198b0..c3a7b51ad4e 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1636,7 +1636,8 @@ internal enum ErrorCode WRN_CantInferNullabilityOfMethodTypeArgs = 8638, WRN_NoBestNullabilityArrayElements = 8639, ERR_ExpressionTreeCantContainRefStruct = 8640, - ERR_ElseCannotStartStatement = 8641 + ERR_ElseCannotStartStatement = 8641, + ERR_ExpressionTreeCantContainNullCoalescingAssignment = 8642 #endregion diagnostics introduced for C# 8.0 diff --git a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs index 5318f2561c7..b5749105ffd 100644 --- a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs +++ b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs @@ -614,6 +614,16 @@ public override BoundNode VisitNullCoalescingOperator(BoundNullCoalescingOperato return base.VisitNullCoalescingOperator(node); } + public override BoundNode VisitNullCoalescingAssignmentOperator(BoundNullCoalescingAssignmentOperator node) + { + if (_inExpressionLambda) + { + Error(ErrorCode.ERR_ExpressionTreeCantContainNullCoalescingAssignment, node); + } + + return base.VisitNullCoalescingAssignmentOperator(node); + } + public override BoundNode VisitDynamicInvocation(BoundDynamicInvocation node) { if (_inExpressionLambda) diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 4c37a7978d9..50b905a808b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index de5b43d9022..20591719507 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 13a9c7e156b..a23c2fcd9d4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 6e96040e082..23861e4fd78 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 2362e575c80..8848fc114f0 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index decef136ffa..68b5e9f55f8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 08f130cf5a1..5d216143297 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 5dc50ddb1d7..009233f4572 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index fa4be4bc588..a123e2c4389 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index ed30aba1958..a8aaa8e0f0a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 2ee72e9d994..f8cc406b21e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index f04c17dc270..50196a365e8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 648449a366e..27bfbbc7582 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -62,6 +62,11 @@ The given expression cannot be used in a fixed statement + + An expression tree may not contain a null coalescing assignment + An expression tree may not contain a null coalescing assignment + + Expression tree cannot contain value of ref struct or restricted type '{0}'. Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCoalescingAssignmentTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCoalescingAssignmentTests.cs index 57559b4c40c..ae890ec0fae 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCoalescingAssignmentTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCoalescingAssignmentTests.cs @@ -2351,5 +2351,23 @@ void M() // Span? s2 = null; Diagnostic(ErrorCode.ERR_BadTypeArgument, "Span?").WithArguments("System.Span").WithLocation(9, 9)); } + + [Fact] + [WorkItem(32138, "https://github.com/dotnet/roslyn/issues/31238")] + public void ExpressionTreeNotAllowed() + { + CreateCompilation(@" +using System; +using System.Linq.Expressions; +public class C { + public void M() { + String x = null; + Expression> e0 = () => x ??= null; + } +}").VerifyDiagnostics( + // (7,45): error CS8642: An expression tree may not contain a null coalescing assignment + // Expression> e0 = () => x ??= null; + Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainNullCoalescingAssignment, "x ??= null").WithLocation(7, 45)); + } } } -- GitLab