dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.29k stars 4.74k forks source link

First class span's break EFC #109757

Open Suchiman opened 1 day ago

Suchiman commented 1 day ago

Description

When enabling LangVersion preview, that enables first class span's which then prefers MemoryExtensions.Contains over Enumerable.Contains which then breaks EFC. It seems that EFC internally calls Expression.Compile with preferInterpretation set to true which then eventually crashes.

Reproduction Steps

public class MyDbContext : DbContext
{
    public DbSet<MyTable> MyTable { get; set; }
}

public class MyTable
{
    public int Id { get; set; }
    public string Name { get; set; }
}

string[] filters = ["Test"];

var dbContext = new MyDbContext();
dbContext.MyTable.Where(x => filters.Contains(x.Name)).ToList();

Expected behavior

First class span's should not negatively affect EFC queries

Actual behavior

TypeLoadException: GenericArguments[1], 'System.Span`1[System.String]', on 'System.Linq.Expressions.Interpreter.FuncCallInstruction`2[T0,TRet]' violates the constraint of type parameter 'TRet'.
   at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)
   at System.Linq.Expressions.Interpreter.CallInstruction.GetHelperType(MethodInfo info, Type[] arrTypes)
   at System.Linq.Expressions.Interpreter.CallInstruction.SlowCreate(MethodInfo info, ParameterInfo[] pis)
   at System.Linq.Expressions.Interpreter.CallInstruction.Create(MethodInfo info, ParameterInfo[] parameters)
   at System.Linq.Expressions.Interpreter.LightCompiler.CompileMethodCallExpression(Expression object, MethodInfo method, IArgumentProvider arguments)
   at System.Linq.Expressions.Interpreter.LightCompiler.Compile(Expression expr)
   at System.Linq.Expressions.Interpreter.LightCompiler.CompileConvertUnaryExpression(Expression expr)
   at System.Linq.Expressions.Interpreter.LightCompiler.Compile(Expression expr)
   at System.Linq.Expressions.Interpreter.LightCompiler.CompileTop(LambdaExpression node)
   at System.Linq.Expressions.Expression`1.Compile(Boolean preferInterpretation)
   at Microsoft.EntityFrameworkCore.Query.Internal.ExpressionTreeFuncletizer.<Evaluate>g__EvaluateCore|70_0(Expression expression, String& parameterName, Boolean& isContextAccessor) in Microsoft.EntityFrameworkCore.Query.Internal\ExpressionTreeFuncletizer.cs:line 1755

Regression?

Yes, only when enabling <LangVersion>preview</LangVersion>

Known Workarounds

set <LangVersion>preview</LangVersion> to anything but preview

Configuration

.NET 9.0.0 EFC 9.0.0

Other information

No response

dotnet-policy-service[bot] commented 1 day ago

Tagging subscribers to this area: @cston See info in area-owners.md if you want to be subscribed.

jkotas commented 1 day ago

cc @jjonescz