提交 0c0aaf36 编写于 作者: V VSadov

Made use of extension Add methods in Expression lambdas a compiler error.

Expression Trees specifically require that element initializer methods are instance methods.
Fixes #310
上级 fa8065f2
......@@ -3922,6 +3922,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to An expression tree lambda may not contain an extension collection element initializer..
/// </summary>
internal static string ERR_ExtensionCollectionElementInitializerInExpressionTree {
get {
return ResourceManager.GetString("ERR_ExtensionCollectionElementInitializerInExpressionTree", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Extension methods must be defined in a top level static class; {0} is a nested class.
/// </summary>
......
......@@ -4544,6 +4544,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_DictionaryInitializerInExpressionTree" xml:space="preserve">
<value>An expression tree lambda may not contain a dictionary initializer.</value>
</data>
<data name="ERR_ExtensionCollectionElementInitializerInExpressionTree" xml:space="preserve">
<value>An expression tree lambda may not contain an extension collection element initializer.</value>
</data>
<data name="IDS_FeatureNameof" xml:space="preserve">
<value>nameof operator</value>
</data>
......
......@@ -1289,7 +1289,7 @@ internal enum ErrorCode
ERR_NullPropagatingOpInExpressionTree = 8072,
WRN_NubExprIsConstBool2 = 8073,
ERR_DictionaryInitializerInExpressionTree = 8074,
// available: 8075,
ERR_ExtensionCollectionElementInitializerInExpressionTree = 8075,
ERR_UnclosedExpressionHole = 8076,
ERR_SingleLineCommentInExpressionHole = 8077,
ERR_InsufficientStack = 8078,
......
......@@ -289,6 +289,11 @@ public override BoundNode VisitCall(BoundCall node)
public override BoundNode VisitCollectionElementInitializer(BoundCollectionElementInitializer node)
{
if (_inExpressionLambda && node.AddMethod.IsStatic)
{
Error(ErrorCode.ERR_ExtensionCollectionElementInitializerInExpressionTree, node);
}
VisitCall(node.AddMethod, null, node.Arguments, default(ImmutableArray<RefKind>), default(ImmutableArray<string>), node.Expanded, node);
return base.VisitCollectionElementInitializer(node);
}
......
......@@ -163,10 +163,8 @@ private BoundExpression MakeCollectionInitializer(BoundExpression rewrittenRecei
// the add method was found as an extension method. Replace the implicit receiver (first argument) with the rewritten receiver.
Debug.Assert(addMethod.IsStatic && addMethod.IsExtensionMethod);
Debug.Assert(rewrittenArguments[0].Kind == BoundKind.ImplicitReceiver);
var newArgs = ArrayBuilder<BoundExpression>.GetInstance();
newArgs.AddRange(rewrittenArguments);
newArgs[0] = rewrittenReceiver;
rewrittenArguments = newArgs.ToImmutableAndFree();
Debug.Assert(!_inExpressionLambda, "Expression trees do not support extension Add");
rewrittenArguments = rewrittenArguments.SetItem(0, rewrittenReceiver);
rewrittenReceiver = null;
}
......
......@@ -22237,6 +22237,46 @@ public void DictionaryInitializerInExprLambda1()
{
var text = @"
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace ConsoleApplication31
{
class Program
{
static void Main(string[] args)
{
var o = new Foo();
var x = o.E.Compile()().Pop();
System.Console.WriteLine(x);
}
}
static class StackExtensions
{
public static void Add<T>(this Stack<T> s, T x) => s.Push(x);
}
class Foo
{
public Expression<Func<Stack<int>>> E = () => new Stack<int> { 42 };
}
}
";
CreateCompilationWithMscorlib45(text, new[] { SystemRef_v4_0_30319_17929, SystemCoreRef_v4_0_30319_17929, CSharpRef }).VerifyDiagnostics(
// (25,72): error CS8075: An expression tree lambda may not contain an extension collection element initializer.
// public Expression<Func<Stack<int>>> E = () => new Stack<int> { 42 };
Diagnostic(ErrorCode.ERR_ExtensionCollectionElementInitializerInExpressionTree, "42").WithLocation(25, 72)
);
}
[WorkItem(310, "https://github.com/dotnet/roslyn/issues/310")]
[Fact]
public void ExtensionElementInitializerInExpressionLambda()
{
var text = @"
using System;
using System.Collections;
using System.Linq.Expressions;
class C
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册