From 073fa9480accf36df676897e07a70a406d431289 Mon Sep 17 00:00:00 2001 From: millennium Date: Sun, 16 Nov 2025 14:00:07 +0800 Subject: [PATCH 1/2] Support sequencing and var/property/field mutating for LeafExpressionConverter.EvaluateQuotation --- src/FSharp.Core/Linq.fs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/FSharp.Core/Linq.fs b/src/FSharp.Core/Linq.fs index f6bb324f4cc..775b6db9b70 100644 --- a/src/FSharp.Core/Linq.fs +++ b/src/FSharp.Core/Linq.fs @@ -792,6 +792,46 @@ module LeafExpressionConverter = let convType = lambdaTy.MakeGenericType tyargs let convDelegate = Expression.Lambda(convType, bodyP, [| vP |]) |> asExpr Expression.Call(typeof, "ToFSharpFunc", tyargs, [| convDelegate |]) |> asExpr + + | Sequential _ -> + let flattenNestedSeq = function + | Sequential(e1, e2) -> seq { e1; e2 } + | e -> Seq.singleton e + let exprs = + inp + |> flattenNestedSeq + |> Seq.map (ConvExprToLinqInContext env) + |> Array.ofSeq + Expression.Block(exprs) |> asExpr + + | VarSet(v, e) -> + let vP = + try + Map.find v env.varEnv + with + | :? KeyNotFoundException -> invalidOp ("The variable '"+ v.Name + "' was not found in the translation context'") + let eP = ConvExprToLinqInContext env e + Expression.Assign(vP, eP) |> asExpr + + | PropertySet(objOpt, propInfo, args, e) -> + let coerceTo = + if objOpt.IsSome && FSharpType.IsUnion propInfo.DeclaringType && FSharpType.IsUnion propInfo.DeclaringType.BaseType then + Some propInfo.DeclaringType + else + None + let eP = ConvExprToLinqInContext env e + match args with + | [] -> + Expression.Assign(Expression.Property(ConvObjArg env objOpt coerceTo, propInfo), eP) |> asExpr + | _ -> + let argsP = ConvExprsToLinq env args + Expression.Call(ConvObjArg env objOpt coerceTo, propInfo.GetSetMethod(true), argsP) |> asExpr + + | FieldSet(objOpt, fieldInfo, e) -> + let objP = ConvObjArg env objOpt None + let eP = ConvExprToLinqInContext env e + Expression.Assign(Expression.Field(objP, fieldInfo), eP) |> asExpr + | _ -> failConvert inp From b8961e05522c312693f9a25d7b7c21f0d52c61d0 Mon Sep 17 00:00:00 2001 From: millennium Date: Sun, 16 Nov 2025 14:26:01 +0800 Subject: [PATCH 2/2] Ensure LeafExpressionConverter.EvaluateQuotations yields a value when the expression type is System.Void --- src/FSharp.Core/Linq.fs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/FSharp.Core/Linq.fs b/src/FSharp.Core/Linq.fs index 775b6db9b70..003bc05565a 100644 --- a/src/FSharp.Core/Linq.fs +++ b/src/FSharp.Core/Linq.fs @@ -950,6 +950,11 @@ module LeafExpressionConverter = | Value (obj, _) -> obj | _ -> let ty = e.Type + let e = + if ty = typeof then + Expr.Sequential(e, <@ () @>) + else + e let e = Expr.NewDelegate (Expression.GetFuncType([|typeof; ty |]), [new Var("unit", typeof)], e) let linqExpr = (ConvExprToLinq e:?> LambdaExpression) let d = linqExpr.Compile ()