From c4df147c3d0acb7dcf50d6d054037057d06305c9 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Thu, 6 Apr 2017 16:11:23 +0100 Subject: [PATCH] fix 2661 (#2807) * fix 2661 * add test --- src/fsharp/TastOps.fs | 19 +++++++++++++++++-- tests/fsharp/optimize/inline/lib.fs | 27 +++++++++++++++++++++++++++ tests/fsharp/tests.fs | 2 ++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 52179e4b7..9860e00ec 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -6444,6 +6444,20 @@ let MultiLambdaToTupledLambda g vs body = tupledv, untupler body +let (|RefTuple|_|) expr = + match expr with + | Expr.Op (TOp.Tuple (TupInfo.Const false),_,args,_) -> Some args + | _ -> None + +let MultiLambdaToTupledLambdaIfNeeded g (vs,arg) body = + match vs,arg with + | [],_ -> failwith "MultiLambdaToTupledLambda: expected some argments" + | [v],_ -> [(v,arg)],body + | vs,RefTuple args when args.Length = vs.Length -> List.zip vs args,body + | vs,_ -> + let tupledv, untupler = untupledToRefTupled g vs + [(tupledv, arg)], untupler body + //-------------------------------------------------------------------------- // Beta reduction via let-bindings. Reduce immediate apps. of lambdas to let bindings. // Includes binding the immediate application of generic @@ -6495,8 +6509,9 @@ let rec MakeApplicationAndBetaReduceAux g (f, fty, tyargsl : TType list list, ar match tryStripLambdaN argsl.Length f with | Some (argvsl, body) -> assert (argvsl.Length = argsl.Length) - let argvs,body = List.mapFoldBack (MultiLambdaToTupledLambda g) argvsl body - mkLetsBind m (mkCompGenBinds argvs argsl) body + let pairs,body = List.mapFoldBack (MultiLambdaToTupledLambdaIfNeeded g) (List.zip argvsl argsl) body + let argvs2, args2 = List.unzip (List.concat pairs) + mkLetsBind m (mkCompGenBinds argvs2 args2) body | _ -> mkExprApplAux g f fty argsl m diff --git a/tests/fsharp/optimize/inline/lib.fs b/tests/fsharp/optimize/inline/lib.fs index 5050560b0..d04958a78 100644 --- a/tests/fsharp/optimize/inline/lib.fs +++ b/tests/fsharp/optimize/inline/lib.fs @@ -2,6 +2,8 @@ namespace ThisNamespaceHasToBeTheSame #nowarn "9" +open System + open System.Runtime.InteropServices [] @@ -131,3 +133,28 @@ do() [] do() + +[] +[] +type StructInt32 = + val mutable Value: int32 + new(value) = { Value = value } + static member Write(value, x: StructInt32 byref) = + x.Value <- value; + static member inline InlineWrite(value, x: StructInt32 byref) = + x.Value <- value; + +module PeverifyTest = + // The test here is simply to peverify the code + let ``StaticWriteResultANewValue`` () = + let mutable v = StructInt32(3); + StructInt32.Write(2, &v); + let result = v.Value + (2, result) + + // The test here is simply to peverify the code + let ``StaticInlineWriteResultANewValue`` () = + let mutable v = StructInt32(3) + StructInt32.InlineWrite(2, &v) + let result = v.Value + (2, result) diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index b6e402701..bed6d7f34 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -1586,6 +1586,8 @@ module OptimizationTests = fsc cfg "%s -g --optimize- --target:library -o:lib.dll" cfg.fsc_flags ["lib.fs"; "lib2.fs"] + peverify cfg "lib.dll " + fsc cfg "%s -g --optimize- --target:library -o:lib3.dll -r:lib.dll " cfg.fsc_flags ["lib3.fs"] fsc cfg "%s -g --optimize- -o:test.exe -r:lib.dll -r:lib3.dll" cfg.fsc_flags ["test.fs "] -- GitLab