diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs index d8621b03cdd22..f4c2aa2f74baf 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs @@ -26,7 +26,7 @@ public abstract class LambdaExpression : Expression, IParameterProvider private readonly Expression _body; // This can be flipped to false using feature switches at publishing time - public static bool CanCompileToIL => true; + public static bool CanCompileToIL => RuntimeFeature.IsDynamicCodeSupported; // This could be flipped to false using feature switches at publishing time public static bool CanInterpret => true; @@ -154,7 +154,7 @@ public Delegate Compile() /// A delegate containing the compiled version of the lambda. public Delegate Compile(bool preferInterpretation) { - if (CanCompileToIL && CanInterpret && preferInterpretation) + if (CanInterpret && preferInterpretation) { return new Interpreter.LightCompiler().CompileTop(this).CreateDelegate(); } @@ -234,7 +234,7 @@ internal Expression(Expression body) /// A delegate containing the compiled version of the lambda. public new TDelegate Compile(bool preferInterpretation) { - if (CanCompileToIL && CanInterpret && preferInterpretation) + if (CanInterpret && preferInterpretation) { return (TDelegate)(object)new Interpreter.LightCompiler().CompileTop(this).CreateDelegate(); } diff --git a/src/libraries/System.Linq.Expressions/tests/CompilerTests.cs b/src/libraries/System.Linq.Expressions/tests/CompilerTests.cs index 069d72e6abcef..3c2f4bc6b5698 100644 --- a/src/libraries/System.Linq.Expressions/tests/CompilerTests.cs +++ b/src/libraries/System.Linq.Expressions/tests/CompilerTests.cs @@ -3,6 +3,7 @@ using System.Runtime.CompilerServices; using System.Text.RegularExpressions; +using Microsoft.DotNet.RemoteExecutor; using Xunit; namespace System.Linq.Expressions.Tests @@ -429,6 +430,29 @@ private static void Verify_VariableBinder_CatchBlock_Filter(CatchBlock @catch) Assert.Throws(() => e.Compile()); } + + /// + /// Verifies that compiling and executing a lambda method works when IsDynamicCodeSupported == false. + /// + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void CompileWorksWhenDynamicCodeNotSupported() + { + RemoteInvokeOptions options = new RemoteInvokeOptions(); + options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", false.ToString()); + + using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke(static () => + { + ParameterExpression param = Expression.Parameter(typeof(int)); + + Func typedDel = + Expression.Lambda>(Expression.Add(param, Expression.Constant(4)), param).Compile(); + Assert.Equal(304, typedDel(300)); + + Delegate del = + Expression.Lambda(Expression.Add(param, Expression.Constant(5)), param).Compile(); + Assert.Equal(305, del.DynamicInvoke(300)); + }, options); + } } public enum ConstantsEnum diff --git a/src/libraries/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj b/src/libraries/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj index 481d04cc820ac..97ead77d06810 100644 --- a/src/libraries/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj +++ b/src/libraries/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj @@ -1,6 +1,7 @@ $(NetCoreAppCurrent);$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-maccatalyst + true