From fc42ec9bc18740ccc3a1e41ed1082cb091f5c31f Mon Sep 17 00:00:00 2001 From: Brian Rourke Boll Date: Tue, 7 May 2024 06:34:44 -0400 Subject: [PATCH] Computed collections: optimize simple mappings with preludes (#17067) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Gather up any prelude & reapply after lowering * E.g., ```fsharp [let y = f () in for … in … -> …] ``` and ```fsharp [f (); g (); for … in … -> …] ``` are transformed into something like ```fsharp let y = f () in [for … in … -> …] ``` and ```fsharp f (); g (); [for … in … -> …] ``` so that the existing pattern recognition of simple mappings and integral ranges may succeed. --- .../.FSharp.Compiler.Service/8.0.400.md | 1 + .../Optimize/LowerComputedCollections.fs | 265 +- .../ComputedCollections/ForNInRangeArrays.fs | 5 + .../ForNInRangeArrays.fs.il.bsl | 236 ++ .../ComputedCollections/ForNInRangeLists.fs | 5 + .../ForNInRangeLists.fs.il.bsl | 220 ++ .../ForXInArray_ToArray.fs | 5 + .../ForXInArray_ToArray.fs.il.bsl | 800 +++--- .../ComputedCollections/ForXInArray_ToList.fs | 5 + .../ForXInArray_ToList.fs.il.bsl | 280 ++ .../ComputedCollections/ForXInList_ToArray.fs | 5 + .../ForXInList_ToArray.fs.il.bsl | 276 ++ .../ComputedCollections/ForXInList_ToList.fs | 5 + .../ForXInList_ToList.fs.il.bsl | 771 +++--- .../ComputedCollections/ForXInSeq_ToArray.fs | 5 + .../ForXInSeq_ToArray.fs.il.bsl | 276 ++ .../ComputedCollections/ForXInSeq_ToList.fs | 5 + .../ForXInSeq_ToList.fs.il.bsl | 280 ++ .../TheBigFileOfDebugStepping.fsx | 2273 +++++++++++++++++ 19 files changed, 5032 insertions(+), 686 deletions(-) create mode 100644 tests/walkthroughs/DebugStepping/TheBigFileOfDebugStepping.fsx diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md index 4203d7f41f8..fd28a3c2736 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md @@ -1,5 +1,6 @@ ### Fixed +* Optimize simple mappings with preludes in computed collections. ([PR #17067](https://github.com/dotnet/fsharp/pull/17067)) * Improve error reporting for abstract members when used in classes. ([PR #17063](https://github.com/dotnet/fsharp/pull/17063)) * Improve error reporting when property has same name as DU case. ([Issue #16646](https://github.com/dotnet/fsharp/issues/16646), [PR #17088](https://github.com/dotnet/fsharp/pull/17088)) * Make typechecking of indexed setters with tuples on the right more consistent. ([Issue #16987](https://github.com/dotnet/fsharp/issues/16987), [PR #17017](https://github.com/dotnet/fsharp/pull/17017)) diff --git a/src/Compiler/Optimize/LowerComputedCollections.fs b/src/Compiler/Optimize/LowerComputedCollections.fs index 5d755daf4b1..2d2e02a9df3 100644 --- a/src/Compiler/Optimize/LowerComputedCollections.fs +++ b/src/Compiler/Optimize/LowerComputedCollections.fs @@ -11,8 +11,10 @@ open FSharp.Compiler.LowerSequenceExpressions open FSharp.Compiler.MethodCalls open FSharp.Compiler.Syntax open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text open FSharp.Compiler.TypeRelations open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TypeHierarchy @@ -257,8 +259,63 @@ let (|SeqToArray|_|) g expr = | _ -> ValueNone module List = + /// Makes the equivalent of an inlined call to List.map. + let mkMap tcVal (g: TcGlobals) amap m (mBody, spFor, _spIn, mFor, mIn, spInWhile) srcList overallElemTy loopVal body = + let collectorTy = g.mk_ListCollector_ty overallElemTy + let srcListTy = tyOfExpr g srcList + + mkCompGenLetMutableIn m "collector" collectorTy (mkDefault (m, collectorTy)) (fun (_, collector) -> + let reader = InfoReader (g, amap) + + // Adapted from DetectAndOptimizeForEachExpression in TypedTreeOps.fs. + + let IndexHead = 0 + let IndexTail = 1 + + let currentVar, currentExpr = mkMutableCompGenLocal mIn "current" srcListTy + let nextVar, nextExpr = mkMutableCompGenLocal mIn "next" srcListTy + let srcElemTy = loopVal.val_type + + let guardExpr = mkNonNullTest g mFor nextExpr + let headOrDefaultExpr = mkUnionCaseFieldGetUnprovenViaExprAddr (currentExpr, g.cons_ucref, [srcElemTy], IndexHead, mIn) + let tailOrNullExpr = mkUnionCaseFieldGetUnprovenViaExprAddr (currentExpr, g.cons_ucref, [srcElemTy], IndexTail, mIn) + + let body = + mkInvisibleLet mIn loopVal headOrDefaultExpr + (mkSequential mIn + (mkCallCollectorAdd tcVal g reader mIn collector body) + (mkSequential mIn + (mkValSet mIn (mkLocalValRef currentVar) nextExpr) + (mkValSet mIn (mkLocalValRef nextVar) tailOrNullExpr))) + + let loop = + // let mutable current = enumerableExpr + mkLet spFor m currentVar srcList + // let mutable next = current.TailOrNull + (mkInvisibleLet mFor nextVar tailOrNullExpr + // while nonNull next do + (mkWhile g (spInWhile, WhileLoopForCompiledForEachExprMarker, guardExpr, body, mBody))) + + let close = mkCallCollectorClose tcVal g reader m collector + + mkSequential m loop close + ) + /// Makes an expression that will build a list from an integral range. - let mkFromIntegralRange tcVal (g: TcGlobals) amap m rangeTy overallElemTy rangeExpr start step finish body = + let mkFromIntegralRange + tcVal + (g: TcGlobals) + amap + m + (mBody, _spFor, _spIn, mFor, mIn, spInWhile) + rangeTy + overallElemTy + (rangeExpr: Expr) + start + step + finish + (body: (Val * Expr) option) + = let collectorTy = g.mk_ListCollector_ty overallElemTy /// let collector = ListCollector () in @@ -275,15 +332,15 @@ module List = |> Option.map (fun (loopVal, body) -> mkInvisibleLet m loopVal loopVar body) |> Option.defaultValue loopVar - mkCallCollectorAdd tcVal g reader m collector body) + mkCallCollectorAdd tcVal g reader mBody collector body) - let close = mkCallCollectorClose tcVal g reader m collector + let close = mkCallCollectorClose tcVal g reader mBody collector mkSequential m loop close ) mkOptimizedRangeLoop g - (m, m, m, DebugPointAtWhile.No) + (mBody, mFor, mIn, spInWhile) (rangeTy, rangeExpr) (start, step, finish) (fun count mkLoop -> @@ -299,6 +356,78 @@ module List = ) module Array = + let private mkIlInstr (g: TcGlobals) specific any ilTy = + if ilTy = g.ilg.typ_Int32 then specific DT_I4 + elif ilTy = g.ilg.typ_Int64 then specific DT_I8 + elif ilTy = g.ilg.typ_UInt64 then specific DT_U8 + elif ilTy = g.ilg.typ_UInt32 then specific DT_U4 + elif ilTy = g.ilg.typ_IntPtr then specific DT_I + elif ilTy = g.ilg.typ_UIntPtr then specific DT_U + elif ilTy = g.ilg.typ_Int16 then specific DT_I2 + elif ilTy = g.ilg.typ_UInt16 then specific DT_U2 + elif ilTy = g.ilg.typ_SByte then specific DT_I1 + elif ilTy = g.ilg.typ_Byte then specific DT_U1 + elif ilTy = g.ilg.typ_Char then specific DT_U2 + elif ilTy = g.ilg.typ_Double then specific DT_R8 + elif ilTy = g.ilg.typ_Single then specific DT_R4 + else any ilTy + + /// Makes the equivalent of an inlined call to Array.map. + let mkMap g m (mBody, _spFor, _spIn, mFor, mIn, spInWhile) srcArray srcIlTy destIlTy overallElemTy loopVal body = + let len = mkLdlen g mIn srcArray + let arrayTy = mkArrayType g overallElemTy + + /// (# "newarr !0" type ('T) count : 'T array #) + let array = + mkAsmExpr + ( + [I_newarr (ILArrayShape.SingleDimensional, destIlTy)], + [], + [len], + [arrayTy], + m + ) + + let ldelem = mkIlInstr g I_ldelem (fun ilTy -> I_ldelem_any (ILArrayShape.SingleDimensional, ilTy)) srcIlTy + let stelem = mkIlInstr g I_stelem (fun ilTy -> I_stelem_any (ILArrayShape.SingleDimensional, ilTy)) destIlTy + + let mapping = + mkCompGenLetIn m (nameof array) arrayTy array (fun (_, array) -> + mkCompGenLetMutableIn mFor "i" g.int32_ty (mkTypedZero g mIn g.int32_ty) (fun (iVal, i) -> + let body = + // Rebind the loop val to pull directly from the source array. + let body = mkInvisibleLet mBody loopVal (mkAsmExpr ([ldelem], [], [srcArray; i], [loopVal.val_type], mBody)) body + + // destArray[i] <- body srcArray[i] + let setArrSubI = mkAsmExpr ([stelem], [], [array; i; body], [], mIn) + + // i <- i + 1 + let incrI = mkValSet mIn (mkLocalValRef iVal) (mkAsmExpr ([AI_add], [], [i; mkTypedOne g mIn g.int32_ty], [g.int32_ty], mIn)) + + mkSequential mIn setArrSubI incrI + + let guard = mkILAsmClt g mFor i (mkLdlen g mFor array) + + let loop = + mkWhile + g + ( + spInWhile, + NoSpecialWhileLoopMarker, + guard, + body, + mIn + ) + + // while i < array.Length do done + // array + mkSequential m loop array + ) + ) + + // Add a debug point at the `for`, before anything gets evaluated. + Expr.DebugPoint (DebugPointAtLeafExpr.Yes mFor, mapping) + /// Whether to check for overflow when converting a value to a native int. [] type Ovf = @@ -310,7 +439,7 @@ module Array = | NoCheckOvf /// Makes an expression that will build an array from an integral range. - let mkFromIntegralRange g m rangeTy ilTy overallElemTy rangeExpr start step finish body = + let mkFromIntegralRange g m (mBody, _spFor, _spIn, mFor, mIn, spInWhile) rangeTy ilTy overallElemTy (rangeExpr: Expr) start step finish (body: (Val * Expr) option) = let arrayTy = mkArrayType g overallElemTy let convToNativeInt ovf expr = @@ -323,31 +452,17 @@ module Array = | CheckOvf -> AI_conv_ovf_un DT_I if typeEquivAux EraseMeasures g ty g.int64_ty then - mkAsmExpr ([conv], [], [expr], [g.nativeint_ty], m) + mkAsmExpr ([conv], [], [expr], [g.nativeint_ty], mIn) elif typeEquivAux EraseMeasures g ty g.nativeint_ty then - mkAsmExpr ([conv], [], [mkAsmExpr ([AI_conv DT_I8], [], [expr], [g.int64_ty], m)], [g.nativeint_ty], m) + mkAsmExpr ([conv], [], [mkAsmExpr ([AI_conv DT_I8], [], [expr], [g.int64_ty], mIn)], [g.nativeint_ty], mIn) elif typeEquivAux EraseMeasures g ty g.uint64_ty then - mkAsmExpr ([conv], [], [expr], [g.nativeint_ty], m) + mkAsmExpr ([conv], [], [expr], [g.nativeint_ty], mIn) elif typeEquivAux EraseMeasures g ty g.unativeint_ty then - mkAsmExpr ([conv], [], [mkAsmExpr ([AI_conv DT_U8], [], [expr], [g.uint64_ty], m)], [g.nativeint_ty], m) + mkAsmExpr ([conv], [], [mkAsmExpr ([AI_conv DT_U8], [], [expr], [g.uint64_ty], mIn)], [g.nativeint_ty], mIn) else expr - let stelem = - if ilTy = g.ilg.typ_Int32 then I_stelem DT_I4 - elif ilTy = g.ilg.typ_Int64 then I_stelem DT_I8 - elif ilTy = g.ilg.typ_UInt64 then I_stelem DT_U8 - elif ilTy = g.ilg.typ_UInt32 then I_stelem DT_U4 - elif ilTy = g.ilg.typ_IntPtr then I_stelem DT_I - elif ilTy = g.ilg.typ_UIntPtr then I_stelem DT_U - elif ilTy = g.ilg.typ_Int16 then I_stelem DT_I2 - elif ilTy = g.ilg.typ_UInt16 then I_stelem DT_U2 - elif ilTy = g.ilg.typ_SByte then I_stelem DT_I1 - elif ilTy = g.ilg.typ_Byte then I_stelem DT_U1 - elif ilTy = g.ilg.typ_Char then I_stelem DT_U2 - elif ilTy = g.ilg.typ_Double then I_stelem DT_R8 - elif ilTy = g.ilg.typ_Single then I_stelem DT_R4 - else I_stelem_any (ILArrayShape.SingleDimensional, ilTy) + let stelem = mkIlInstr g I_stelem (fun ilTy -> I_stelem_any (ILArrayShape.SingleDimensional, ilTy)) ilTy /// (# "newarr !0" type ('T) count : 'T array #) let mkNewArray count = @@ -364,21 +479,21 @@ module Array = /// /// array let mkArrayInit count mkLoop = - mkCompGenLetIn m "array" arrayTy (mkNewArray count) (fun (_, array) -> + mkCompGenLetIn mFor "array" arrayTy (mkNewArray count) (fun (_, array) -> let loop = mkLoop (fun idxVar loopVar -> let body = body - |> Option.map (fun (loopVal, body) -> mkInvisibleLet m loopVal loopVar body) + |> Option.map (fun (loopVal, body) -> mkInvisibleLet mBody loopVal loopVar body) |> Option.defaultValue loopVar - mkAsmExpr ([stelem], [], [array; convToNativeInt NoCheckOvf idxVar; body], [], m)) + mkAsmExpr ([stelem], [], [array; convToNativeInt NoCheckOvf idxVar; body], [], mBody)) mkSequential m loop array) mkOptimizedRangeLoop g - (m, m, m, DebugPointAtWhile.No) + (mBody, mFor, mIn, spInWhile) (rangeTy, rangeExpr) (start, step, finish) (fun count mkLoop -> @@ -413,19 +528,49 @@ module Array = /// /// E.g., in [for x in … do f (); …; yield x] [] -let (|SimpleSequential|_|) g expr = +let (|SimpleSequential|_|) g expr : Expr voption = let rec loop expr cont = match expr with | Expr.Sequential (expr1, DebugPoints (ValApp g g.seq_singleton_vref (_, [body], _), debug), kind, m) -> ValueSome (cont (expr1, debug body, kind, m)) - | Expr.Sequential (expr1, body, kind, m) -> - loop body (cont >> fun body -> Expr.Sequential (expr1, body, kind, m)) + | Expr.Sequential (expr1, DebugPoints (body, debug), kind, m) -> + loop body (cont >> fun body -> Expr.Sequential (expr1, debug body, kind, m)) | _ -> ValueNone loop expr Expr.Sequential +/// Extracts any let-bindings or sequential +/// expressions that directly precede the specified mapping application, e.g., +/// +/// [let y = f () in for … in … -> …] +/// +/// [f (); g (); for … in … -> …] +/// +/// Returns a function that will re-prefix the prelude to the +/// lowered mapping, as well as the mapping to lower, i.e., +/// to transform the above into something like: +/// +/// let y = f () in [for … in … -> …] +/// +/// f (); g (); [for … in … -> …] +let gatherPrelude ((|App|_|) : _ -> _ voption) expr = + let rec loop expr cont = + match expr with + | Expr.Let (binding, DebugPoints (body, debug), m, frees) -> + loop body (cont << fun body -> Expr.Let (binding, debug body, m, frees)) + + | Expr.Sequential (expr1, DebugPoints (body, debug), kind, m) -> + loop body (cont << fun body -> Expr.Sequential (expr1, debug body, kind, m)) + + | App contents -> + ValueSome (cont, contents) + + | _ -> ValueNone + + loop expr id + /// The representation used for /// /// for … in … -> … @@ -434,21 +579,31 @@ let (|SimpleSequential|_|) g expr = /// /// for … in … do yield … [] -let (|SeqMap|_|) g expr = - match expr with - | ValApp g g.seq_map_vref ([ty1; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = body) as mapping; input], _) -> - ValueSome (ty1, ty2, input, mapping, loopVal, body) - | _ -> ValueNone +let (|SeqMap|_|) g = + gatherPrelude (function + | ValApp g g.seq_map_vref ([ty1; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = body; range = mIn) as mapping; input], mFor) -> + let spIn = match mIn.NotedSourceConstruct with NotedSourceConstruct.InOrTo -> DebugPointAtInOrTo.Yes mIn | _ -> DebugPointAtInOrTo.No + let spFor = DebugPointAtBinding.Yes mFor + let spInWhile = match spIn with DebugPointAtInOrTo.Yes m -> DebugPointAtWhile.Yes m | DebugPointAtInOrTo.No -> DebugPointAtWhile.No + let ranges = body.Range, spFor, spIn, mFor, mIn, spInWhile + ValueSome (ty1, ty2, input, mapping, loopVal, body, ranges) + + | _ -> ValueNone) /// The representation used for /// /// for … in … do f (); …; yield … [] -let (|SeqCollectSingle|_|) g expr = - match expr with - | ValApp g g.seq_collect_vref ([ty1; _; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = SimpleSequential g body) as mapping; input], _) -> - ValueSome (ty1, ty2, input, mapping, loopVal, body) - | _ -> ValueNone +let (|SeqCollectSingle|_|) g = + gatherPrelude (function + | ValApp g g.seq_collect_vref ([ty1; _; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = SimpleSequential g body; range = mIn) as mapping; input], mFor) -> + let spIn = match mIn.NotedSourceConstruct with NotedSourceConstruct.InOrTo -> DebugPointAtInOrTo.Yes mIn | _ -> DebugPointAtInOrTo.No + let spFor = DebugPointAtBinding.Yes mFor + let spInWhile = match spIn with DebugPointAtInOrTo.Yes m -> DebugPointAtWhile.Yes m | DebugPointAtInOrTo.No -> DebugPointAtWhile.No + let ranges = body.Range, spFor, spIn, mFor, mIn, spInWhile + ValueSome (ty1, ty2, input, mapping, loopVal, body, ranges) + + | _ -> ValueNone) /// for … in … -> … /// for … in … do yield … @@ -458,11 +613,11 @@ let (|SimpleMapping|_|) g expr = match expr with // for … in … -> … // for … in … do yield … - | ValApp g g.seq_delay_vref (_, [Expr.Lambda (bodyExpr = SeqMap g (ty1, ty2, input, mapping, loopVal, body))], _) + | ValApp g g.seq_delay_vref (_, [Expr.Lambda (bodyExpr = DebugPoints (SeqMap g (cont, (ty1, ty2, input, mapping, loopVal, body, ranges)), debug))], _) // for … in … do f (); …; yield … - | ValApp g g.seq_delay_vref (_, [Expr.Lambda (bodyExpr = SeqCollectSingle g (ty1, ty2, input, mapping, loopVal, body))], _) -> - ValueSome (ty1, ty2, input, mapping, loopVal, body) + | ValApp g g.seq_delay_vref (_, [Expr.Lambda (bodyExpr = DebugPoints (SeqCollectSingle g (cont, (ty1, ty2, input, mapping, loopVal, body, ranges)), debug))], _) -> + ValueSome (debug >> cont, (ty1, ty2, input, mapping, loopVal, body, ranges)) | _ -> ValueNone @@ -484,24 +639,25 @@ let LowerComputedListOrArrayExpr tcVal (g: TcGlobals) amap ilTyForTy overallExpr | SeqToList g (OptionalCoerce (OptionalSeq g amap (overallSeqExpr, overallElemTy)), m) -> match overallSeqExpr with // [for … in xs -> …] (* When xs is a list. *) - | SimpleMapping g (ty1, ty2, List g list, mapping, _, _) when + | SimpleMapping g (cont, (_, _, List g list, _, loopVal, body, ranges)) when g.langVersion.SupportsFeature LanguageFeature.LowerSimpleMappingsInComprehensionsToDirectCallsToMap -> - Some (mkCallListMap g m ty1 ty2 mapping list) + Some (cont (List.mkMap tcVal g amap m ranges list overallElemTy loopVal body)) // [start..finish] // [start..step..finish] | IntegralRange g (rangeTy, (start, step, finish)) when g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops -> - Some (List.mkFromIntegralRange tcVal g amap m rangeTy overallElemTy overallSeqExpr start step finish None) + let ranges = m, DebugPointAtBinding.NoneAtInvisible, DebugPointAtInOrTo.No, m, m, DebugPointAtWhile.No + Some (List.mkFromIntegralRange tcVal g amap m ranges rangeTy overallElemTy overallSeqExpr start step finish None) // [for … in start..finish -> …] // [for … in start..step..finish -> …] - | SimpleMapping g (_, _, rangeExpr & IntegralRange g (rangeTy, (start, step, finish)), _, loopVal, body) when + | SimpleMapping g (cont, (_, _, DebugPoints (rangeExpr & IntegralRange g (rangeTy, (start, step, finish)), debug), _, loopVal, body, ranges)) when g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops -> - Some (List.mkFromIntegralRange tcVal g amap m rangeTy overallElemTy rangeExpr start step finish (Some (loopVal, body))) + Some (cont (debug (List.mkFromIntegralRange tcVal g amap m ranges rangeTy overallElemTy rangeExpr start step finish (Some (loopVal, body))))) // [(* Anything more complex. *)] | _ -> @@ -512,24 +668,25 @@ let LowerComputedListOrArrayExpr tcVal (g: TcGlobals) amap ilTyForTy overallExpr | SeqToArray g (OptionalCoerce (OptionalSeq g amap (overallSeqExpr, overallElemTy)), m) -> match overallSeqExpr with // [|for … in xs -> …|] (* When xs is an array. *) - | SimpleMapping g (ty1, ty2, Array g array, mapping, _, _) when + | SimpleMapping g (cont, (ty1, ty2, Array g array, _, loopVal, body, ranges)) when g.langVersion.SupportsFeature LanguageFeature.LowerSimpleMappingsInComprehensionsToDirectCallsToMap -> - Some (mkCallArrayMap g m ty1 ty2 mapping array) + Some (cont (Array.mkMap g m ranges array (ilTyForTy ty1) (ilTyForTy ty2) overallElemTy loopVal body)) // [|start..finish|] // [|start..step..finish|] | IntegralRange g (rangeTy, (start, step, finish)) when g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops -> - Some (Array.mkFromIntegralRange g m rangeTy (ilTyForTy overallElemTy) overallElemTy overallSeqExpr start step finish None) + let ranges = m, DebugPointAtBinding.NoneAtInvisible, DebugPointAtInOrTo.No, m, m, DebugPointAtWhile.No + Some (Array.mkFromIntegralRange g m ranges rangeTy (ilTyForTy overallElemTy) overallElemTy overallSeqExpr start step finish None) // [|for … in start..finish -> …|] // [|for … in start..step..finish -> …|] - | SimpleMapping g (_, _, rangeExpr & IntegralRange g (rangeTy, (start, step, finish)), _, loopVal, body) when + | SimpleMapping g (cont, (_, _, DebugPoints (rangeExpr & IntegralRange g (rangeTy, (start, step, finish)), debug), _, loopVal, body, ranges)) when g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops -> - Some (Array.mkFromIntegralRange g m rangeTy (ilTyForTy overallElemTy) overallElemTy rangeExpr start step finish (Some (loopVal, body))) + Some (cont (debug (Array.mkFromIntegralRange g m ranges rangeTy (ilTyForTy overallElemTy) overallElemTy rangeExpr start step finish (Some (loopVal, body))))) // [|(* Anything more complex. *)|] | _ -> diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs index 5e2867fae3a..e2466ab7f5f 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs @@ -30,3 +30,8 @@ let f25 f g h = [|for n in f ()..g ()..h () -> n|] let f26 start step finish = [|for n in start..step..finish -> n, float n|] let f27 start step finish = [|for n in start..step..finish -> struct (n, float n)|] let f28 start step finish = [|for n in start..step..finish -> let x = n + 1 in n * n|] + +let f29 f g = [|let y = f () in let z = g () in for x in 1..2..10 -> x + y + z|] +let f30 f g = [|let y = f () in g (); for x in 1..2..10 -> x + y|] +let f31 f g = [|f (); g (); for x in 1..2..10 -> x|] +let f32 f g = [|f (); let y = g () in for x in 1..2..10 -> x + y|] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs.il.bsl index 2d2e4a99be3..980616689ba 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs.il.bsl @@ -2431,6 +2431,242 @@ IL_007a: ret } + .method public static int32[] f29(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 6 + .locals init (int32 V_0, + int32 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.0 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.1 + IL_0011: ldc.i4.5 + IL_0012: conv.i8 + IL_0013: conv.ovf.i.un + IL_0014: newarr [runtime]System.Int32 + IL_0019: stloc.2 + IL_001a: ldc.i4.0 + IL_001b: conv.i8 + IL_001c: stloc.3 + IL_001d: ldc.i4.1 + IL_001e: stloc.s V_4 + IL_0020: br.s IL_003b + + IL_0022: ldloc.2 + IL_0023: ldloc.3 + IL_0024: conv.i + IL_0025: ldloc.s V_4 + IL_0027: stloc.s V_5 + IL_0029: ldloc.s V_5 + IL_002b: ldloc.0 + IL_002c: add + IL_002d: ldloc.1 + IL_002e: add + IL_002f: stelem.i4 + IL_0030: ldloc.s V_4 + IL_0032: ldc.i4.2 + IL_0033: add + IL_0034: stloc.s V_4 + IL_0036: ldloc.3 + IL_0037: ldc.i4.1 + IL_0038: conv.i8 + IL_0039: add + IL_003a: stloc.3 + IL_003b: ldloc.3 + IL_003c: ldc.i4.5 + IL_003d: conv.i8 + IL_003e: blt.un.s IL_0022 + + IL_0040: ldloc.2 + IL_0041: ret + } + + .method public static int32[] f30(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 6 + .locals init (int32 V_0, + int32[] V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.0 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: ldc.i4.5 + IL_0012: conv.i8 + IL_0013: conv.ovf.i.un + IL_0014: newarr [runtime]System.Int32 + IL_0019: stloc.1 + IL_001a: ldc.i4.0 + IL_001b: conv.i8 + IL_001c: stloc.2 + IL_001d: ldc.i4.1 + IL_001e: stloc.3 + IL_001f: br.s IL_0035 + + IL_0021: ldloc.1 + IL_0022: ldloc.2 + IL_0023: conv.i + IL_0024: ldloc.3 + IL_0025: stloc.s V_4 + IL_0027: ldloc.s V_4 + IL_0029: ldloc.0 + IL_002a: add + IL_002b: stelem.i4 + IL_002c: ldloc.3 + IL_002d: ldc.i4.2 + IL_002e: add + IL_002f: stloc.3 + IL_0030: ldloc.2 + IL_0031: ldc.i4.1 + IL_0032: conv.i8 + IL_0033: add + IL_0034: stloc.2 + IL_0035: ldloc.2 + IL_0036: ldc.i4.5 + IL_0037: conv.i8 + IL_0038: blt.un.s IL_0021 + + IL_003a: ldloc.1 + IL_003b: ret + } + + .method public static int32[] f31(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: ldc.i4.5 + IL_0012: conv.i8 + IL_0013: conv.ovf.i.un + IL_0014: newarr [runtime]System.Int32 + IL_0019: stloc.0 + IL_001a: ldc.i4.0 + IL_001b: conv.i8 + IL_001c: stloc.1 + IL_001d: ldc.i4.1 + IL_001e: stloc.2 + IL_001f: br.s IL_0031 + + IL_0021: ldloc.0 + IL_0022: ldloc.1 + IL_0023: conv.i + IL_0024: ldloc.2 + IL_0025: stloc.3 + IL_0026: ldloc.3 + IL_0027: stelem.i4 + IL_0028: ldloc.2 + IL_0029: ldc.i4.2 + IL_002a: add + IL_002b: stloc.2 + IL_002c: ldloc.1 + IL_002d: ldc.i4.1 + IL_002e: conv.i8 + IL_002f: add + IL_0030: stloc.1 + IL_0031: ldloc.1 + IL_0032: ldc.i4.5 + IL_0033: conv.i8 + IL_0034: blt.un.s IL_0021 + + IL_0036: ldloc.0 + IL_0037: ret + } + + .method public static int32[] f32(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 6 + .locals init (int32 V_0, + int32[] V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.0 + IL_0011: ldc.i4.5 + IL_0012: conv.i8 + IL_0013: conv.ovf.i.un + IL_0014: newarr [runtime]System.Int32 + IL_0019: stloc.1 + IL_001a: ldc.i4.0 + IL_001b: conv.i8 + IL_001c: stloc.2 + IL_001d: ldc.i4.1 + IL_001e: stloc.3 + IL_001f: br.s IL_0035 + + IL_0021: ldloc.1 + IL_0022: ldloc.2 + IL_0023: conv.i + IL_0024: ldloc.3 + IL_0025: stloc.s V_4 + IL_0027: ldloc.s V_4 + IL_0029: ldloc.0 + IL_002a: add + IL_002b: stelem.i4 + IL_002c: ldloc.3 + IL_002d: ldc.i4.2 + IL_002e: add + IL_002f: stloc.3 + IL_0030: ldloc.2 + IL_0031: ldc.i4.1 + IL_0032: conv.i8 + IL_0033: add + IL_0034: stloc.2 + IL_0035: ldloc.2 + IL_0036: ldc.i4.5 + IL_0037: conv.i8 + IL_0038: blt.un.s IL_0021 + + IL_003a: ldloc.1 + IL_003b: ret + } + } .class private abstract auto ansi sealed ''.$assembly diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs index 3562a5bfa71..28a0890e1e4 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs @@ -30,3 +30,8 @@ let f25 f g h = [for n in f ()..g ()..h () -> n] let f26 start step finish = [for n in start..step..finish -> n, float n] let f27 start step finish = [for n in start..step..finish -> struct (n, float n)] let f28 start step finish = [for n in start..step..finish -> let x = n + 1 in n * n] + +let f29 f g = [let y = f () in let z = g () in for x in 1..2..10 -> x + y + z] +let f30 f g = [let y = f () in g (); for x in 1..2..10 -> x + y] +let f31 f g = [f (); g (); for x in 1..2..10 -> x] +let f32 f g = [f (); let y = g () in for x in 1..2..10 -> x + y] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs.il.bsl index e5a3adcb69c..5b7741302d7 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs.il.bsl @@ -2144,6 +2144,226 @@ IL_006d: ret } + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f29(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + int32 V_1, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.0 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.1 + IL_0011: ldc.i4.0 + IL_0012: conv.i8 + IL_0013: stloc.3 + IL_0014: ldc.i4.1 + IL_0015: stloc.s V_4 + IL_0017: br.s IL_0036 + + IL_0019: ldloca.s V_2 + IL_001b: ldloc.s V_4 + IL_001d: stloc.s V_5 + IL_001f: ldloc.s V_5 + IL_0021: ldloc.0 + IL_0022: add + IL_0023: ldloc.1 + IL_0024: add + IL_0025: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002a: nop + IL_002b: ldloc.s V_4 + IL_002d: ldc.i4.2 + IL_002e: add + IL_002f: stloc.s V_4 + IL_0031: ldloc.3 + IL_0032: ldc.i4.1 + IL_0033: conv.i8 + IL_0034: add + IL_0035: stloc.3 + IL_0036: ldloc.3 + IL_0037: ldc.i4.5 + IL_0038: conv.i8 + IL_0039: blt.un.s IL_0019 + + IL_003b: ldloca.s V_2 + IL_003d: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0042: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f30(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.0 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: ldc.i4.0 + IL_0012: conv.i8 + IL_0013: stloc.2 + IL_0014: ldc.i4.1 + IL_0015: stloc.3 + IL_0016: br.s IL_0030 + + IL_0018: ldloca.s V_1 + IL_001a: ldloc.3 + IL_001b: stloc.s V_4 + IL_001d: ldloc.s V_4 + IL_001f: ldloc.0 + IL_0020: add + IL_0021: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0026: nop + IL_0027: ldloc.3 + IL_0028: ldc.i4.2 + IL_0029: add + IL_002a: stloc.3 + IL_002b: ldloc.2 + IL_002c: ldc.i4.1 + IL_002d: conv.i8 + IL_002e: add + IL_002f: stloc.2 + IL_0030: ldloc.2 + IL_0031: ldc.i4.5 + IL_0032: conv.i8 + IL_0033: blt.un.s IL_0018 + + IL_0035: ldloca.s V_1 + IL_0037: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003c: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f31(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: ldc.i4.0 + IL_0012: conv.i8 + IL_0013: stloc.1 + IL_0014: ldc.i4.1 + IL_0015: stloc.2 + IL_0016: br.s IL_002c + + IL_0018: ldloca.s V_0 + IL_001a: ldloc.2 + IL_001b: stloc.3 + IL_001c: ldloc.3 + IL_001d: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0022: nop + IL_0023: ldloc.2 + IL_0024: ldc.i4.2 + IL_0025: add + IL_0026: stloc.2 + IL_0027: ldloc.1 + IL_0028: ldc.i4.1 + IL_0029: conv.i8 + IL_002a: add + IL_002b: stloc.1 + IL_002c: ldloc.1 + IL_002d: ldc.i4.5 + IL_002e: conv.i8 + IL_002f: blt.un.s IL_0018 + + IL_0031: ldloca.s V_0 + IL_0033: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0038: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f32(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.0 + IL_0011: ldc.i4.0 + IL_0012: conv.i8 + IL_0013: stloc.2 + IL_0014: ldc.i4.1 + IL_0015: stloc.3 + IL_0016: br.s IL_0030 + + IL_0018: ldloca.s V_1 + IL_001a: ldloc.3 + IL_001b: stloc.s V_4 + IL_001d: ldloc.s V_4 + IL_001f: ldloc.0 + IL_0020: add + IL_0021: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0026: nop + IL_0027: ldloc.3 + IL_0028: ldc.i4.2 + IL_0029: add + IL_002a: stloc.3 + IL_002b: ldloc.2 + IL_002c: ldc.i4.1 + IL_002d: conv.i8 + IL_002e: add + IL_002f: stloc.2 + IL_0030: ldloc.2 + IL_0031: ldc.i4.5 + IL_0032: conv.i8 + IL_0033: blt.un.s IL_0018 + + IL_0035: ldloca.s V_1 + IL_0037: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003c: ret + } + } .class private abstract auto ansi sealed ''.$assembly diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs index 148a7f971ee..c552cb7dee1 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs @@ -5,3 +5,8 @@ let f4 f g (array: int array) = [|for x in array -> f (); g(); x|] let f5 (array: int array) = [|for x in array do yield x|] let f6 f (array: int array) = [|for x in array do f (); yield x|] let f7 f g (array: int array) = [|for x in array do f (); g (); yield x|] + +let f8 f g (array: int array) = [|let y = f () in let z = g () in for x in array -> x + y + z|] +let f9 f g (array: int array) = [|let y = f () in g (); for x in array -> x + y|] +let f10 f g (array: int array) = [|f (); g (); for x in array -> x|] +let f11 f g (array: int array) = [|f (); let y = g () in for x in array -> x + y|] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl index dc64917f820..b91b49aec7d 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl @@ -43,274 +43,43 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit f1@1 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field static assembly initonly class assembly/f1@1 @_instance - .method assembly specialname rtspecialname instance void .ctor() cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ret - } - - .method public strict virtual instance int32 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ret - } - - .method private specialname rtspecialname static void .cctor() cil managed - { - - .maxstack 10 - IL_0000: newobj instance void assembly/f1@1::.ctor() - IL_0005: stsfld class assembly/f1@1 assembly/f1@1::@_instance - IL_000a: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f2@2 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 class assembly/f2@2::f - IL_000d: ret - } - - .method public strict virtual instance !a Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 class assembly/f2@2::f - IL_0006: ldarg.1 - IL_0007: tail. - IL_0009: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000e: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f3@3 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f3@3::f - IL_000d: ret - } - - .method public strict virtual instance int32 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f3@3::f - IL_0006: ldnull - IL_0007: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000c: pop - IL_000d: ldarg.1 - IL_000e: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f4@4 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g - .method assembly specialname rtspecialname - instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f4@4::f - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f4@4::g - IL_0014: ret - } - - .method public strict virtual instance int32 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f4@4::f - IL_0006: ldnull - IL_0007: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000c: pop - IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f4@4::g - IL_0013: ldnull - IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0019: pop - IL_001a: ldarg.1 - IL_001b: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f5@5 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field static assembly initonly class assembly/f5@5 @_instance - .method assembly specialname rtspecialname instance void .ctor() cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ret - } - - .method public strict virtual instance int32 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ret - } - - .method private specialname rtspecialname static void .cctor() cil managed - { - - .maxstack 10 - IL_0000: newobj instance void assembly/f5@5::.ctor() - IL_0005: stsfld class assembly/f5@5 assembly/f5@5::@_instance - IL_000a: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f6@6 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f6@6::f - IL_000d: ret - } - - .method public strict virtual instance class [runtime]System.Collections.Generic.IEnumerable`1 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f6@6::f - IL_0006: ldnull - IL_0007: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000c: pop - IL_000d: ldarg.1 - IL_000e: tail. - IL_0010: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) - IL_0015: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f7@7 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g - .method assembly specialname rtspecialname - instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f7@7::f - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f7@7::g - IL_0014: ret - } - - .method public strict virtual instance class [runtime]System.Collections.Generic.IEnumerable`1 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f7@7::f - IL_0006: ldnull - IL_0007: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000c: pop - IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f7@7::g - IL_0013: ldnull - IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0019: pop - IL_001a: ldarg.1 - IL_001b: tail. - IL_001d: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) - IL_0022: ret - } - - } - .method public static int32[] f1(int32[] 'array') cil managed { - .maxstack 8 - IL_0000: ldsfld class assembly/f1@1 assembly/f1@1::@_instance - IL_0005: ldarg.0 - IL_0006: tail. - IL_0008: call !!1[] [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - !!0[]) - IL_000d: ret + .maxstack 6 + .locals init (int32[] V_0, + int32 V_1, + int32 V_2) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldlen + IL_0003: conv.i4 + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: stloc.1 + IL_000c: br.s IL_001a + + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: ldarg.0 + IL_0011: ldloc.1 + IL_0012: ldelem.i4 + IL_0013: stloc.2 + IL_0014: ldloc.2 + IL_0015: stelem.i4 + IL_0016: ldloc.1 + IL_0017: ldc.i4.1 + IL_0018: add + IL_0019: stloc.1 + IL_001a: ldloc.1 + IL_001b: ldloc.0 + IL_001c: ldlen + IL_001d: conv.i4 + IL_001e: blt.s IL_000e + + IL_0020: ldloc.0 + IL_0021: ret } .method public static !!a[] f2(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, @@ -318,14 +87,42 @@ { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void class assembly/f2@2::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0006: ldarg.1 - IL_0007: tail. - IL_0009: call !!1[] [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - !!0[]) - IL_000e: ret + .maxstack 6 + .locals init (!!a[] V_0, + int32 V_1, + int32 V_2) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldlen + IL_0003: conv.i4 + IL_0004: newarr !!a + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: stloc.1 + IL_000c: br.s IL_0024 + + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: ldarg.1 + IL_0011: ldloc.1 + IL_0012: ldelem.i4 + IL_0013: stloc.2 + IL_0014: ldarg.0 + IL_0015: ldloc.2 + IL_0016: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001b: stelem !!a + IL_0020: ldloc.1 + IL_0021: ldc.i4.1 + IL_0022: add + IL_0023: stloc.1 + IL_0024: ldloc.1 + IL_0025: ldloc.0 + IL_0026: ldlen + IL_0027: conv.i4 + IL_0028: blt.s IL_000e + + IL_002a: ldloc.0 + IL_002b: ret } .method public static int32[] f3(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, @@ -333,14 +130,44 @@ { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void assembly/f3@3::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0006: ldarg.1 - IL_0007: tail. - IL_0009: call !!1[] [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - !!0[]) - IL_000e: ret + .maxstack 6 + .locals init (int32[] V_0, + int32 V_1, + int32 V_2) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldlen + IL_0003: conv.i4 + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: stloc.1 + IL_000c: br.s IL_0022 + + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: ldarg.1 + IL_0011: ldloc.1 + IL_0012: ldelem.i4 + IL_0013: stloc.2 + IL_0014: ldarg.0 + IL_0015: ldnull + IL_0016: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001b: pop + IL_001c: ldloc.2 + IL_001d: stelem.i4 + IL_001e: ldloc.1 + IL_001f: ldc.i4.1 + IL_0020: add + IL_0021: stloc.1 + IL_0022: ldloc.1 + IL_0023: ldloc.0 + IL_0024: ldlen + IL_0025: conv.i4 + IL_0026: blt.s IL_000e + + IL_0028: ldloc.0 + IL_0029: ret } .method public static int32[] f4(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, @@ -350,28 +177,87 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: newobj instance void assembly/f4@4::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0007: ldarg.2 - IL_0008: tail. - IL_000a: call !!1[] [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - !!0[]) - IL_000f: ret + .maxstack 6 + .locals init (int32[] V_0, + int32 V_1, + int32 V_2) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: ldlen + IL_0003: conv.i4 + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: stloc.1 + IL_000c: br.s IL_002a + + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: ldarg.2 + IL_0011: ldloc.1 + IL_0012: ldelem.i4 + IL_0013: stloc.2 + IL_0014: ldarg.0 + IL_0015: ldnull + IL_0016: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001b: pop + IL_001c: ldarg.1 + IL_001d: ldnull + IL_001e: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0023: pop + IL_0024: ldloc.2 + IL_0025: stelem.i4 + IL_0026: ldloc.1 + IL_0027: ldc.i4.1 + IL_0028: add + IL_0029: stloc.1 + IL_002a: ldloc.1 + IL_002b: ldloc.0 + IL_002c: ldlen + IL_002d: conv.i4 + IL_002e: blt.s IL_000e + + IL_0030: ldloc.0 + IL_0031: ret } .method public static int32[] f5(int32[] 'array') cil managed { - .maxstack 8 - IL_0000: ldsfld class assembly/f5@5 assembly/f5@5::@_instance - IL_0005: ldarg.0 - IL_0006: tail. - IL_0008: call !!1[] [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - !!0[]) - IL_000d: ret + .maxstack 6 + .locals init (int32[] V_0, + int32 V_1, + int32 V_2) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldlen + IL_0003: conv.i4 + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: stloc.1 + IL_000c: br.s IL_001a + + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: ldarg.0 + IL_0011: ldloc.1 + IL_0012: ldelem.i4 + IL_0013: stloc.2 + IL_0014: ldloc.2 + IL_0015: stelem.i4 + IL_0016: ldloc.1 + IL_0017: ldc.i4.1 + IL_0018: add + IL_0019: stloc.1 + IL_001a: ldloc.1 + IL_001b: ldloc.0 + IL_001c: ldlen + IL_001d: conv.i4 + IL_001e: blt.s IL_000e + + IL_0020: ldloc.0 + IL_0021: ret } .method public static int32[] f6(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, @@ -379,14 +265,44 @@ { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void assembly/f6@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0006: ldarg.1 - IL_0007: tail. - IL_0009: call !!1[] [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - !!0[]) - IL_000e: ret + .maxstack 6 + .locals init (int32[] V_0, + int32 V_1, + int32 V_2) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldlen + IL_0003: conv.i4 + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: stloc.1 + IL_000c: br.s IL_0022 + + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: ldarg.1 + IL_0011: ldloc.1 + IL_0012: ldelem.i4 + IL_0013: stloc.2 + IL_0014: ldarg.0 + IL_0015: ldnull + IL_0016: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001b: pop + IL_001c: ldloc.2 + IL_001d: stelem.i4 + IL_001e: ldloc.1 + IL_001f: ldc.i4.1 + IL_0020: add + IL_0021: stloc.1 + IL_0022: ldloc.1 + IL_0023: ldloc.0 + IL_0024: ldlen + IL_0025: conv.i4 + IL_0026: blt.s IL_000e + + IL_0028: ldloc.0 + IL_0029: ret } .method public static int32[] f7(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, @@ -396,16 +312,268 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: newobj instance void assembly/f7@7::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0007: ldarg.2 - IL_0008: tail. - IL_000a: call !!1[] [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - !!0[]) - IL_000f: ret + .maxstack 6 + .locals init (int32[] V_0, + int32 V_1, + int32 V_2) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: ldlen + IL_0003: conv.i4 + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: stloc.1 + IL_000c: br.s IL_002a + + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: ldarg.2 + IL_0011: ldloc.1 + IL_0012: ldelem.i4 + IL_0013: stloc.2 + IL_0014: ldarg.0 + IL_0015: ldnull + IL_0016: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001b: pop + IL_001c: ldarg.1 + IL_001d: ldnull + IL_001e: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0023: pop + IL_0024: ldloc.2 + IL_0025: stelem.i4 + IL_0026: ldloc.1 + IL_0027: ldc.i4.1 + IL_0028: add + IL_0029: stloc.1 + IL_002a: ldloc.1 + IL_002b: ldloc.0 + IL_002c: ldlen + IL_002d: conv.i4 + IL_002e: blt.s IL_000e + + IL_0030: ldloc.0 + IL_0031: ret + } + + .method public static int32[] f8(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + int32[] 'array') cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 6 + .locals init (int32 V_0, + int32 V_1, + int32[] V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.0 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.1 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: ldlen + IL_0014: conv.i4 + IL_0015: newarr [runtime]System.Int32 + IL_001a: stloc.2 + IL_001b: ldc.i4.0 + IL_001c: stloc.3 + IL_001d: br.s IL_0031 + + IL_001f: ldloc.2 + IL_0020: ldloc.3 + IL_0021: ldarg.2 + IL_0022: ldloc.3 + IL_0023: ldelem.i4 + IL_0024: stloc.s V_4 + IL_0026: ldloc.s V_4 + IL_0028: ldloc.0 + IL_0029: add + IL_002a: ldloc.1 + IL_002b: add + IL_002c: stelem.i4 + IL_002d: ldloc.3 + IL_002e: ldc.i4.1 + IL_002f: add + IL_0030: stloc.3 + IL_0031: ldloc.3 + IL_0032: ldloc.2 + IL_0033: ldlen + IL_0034: conv.i4 + IL_0035: blt.s IL_001f + + IL_0037: ldloc.2 + IL_0038: ret + } + + .method public static int32[] f9(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + int32[] 'array') cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 6 + .locals init (int32 V_0, + int32[] V_1, + int32 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.0 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: ldlen + IL_0014: conv.i4 + IL_0015: newarr [runtime]System.Int32 + IL_001a: stloc.1 + IL_001b: ldc.i4.0 + IL_001c: stloc.2 + IL_001d: br.s IL_002d + + IL_001f: ldloc.1 + IL_0020: ldloc.2 + IL_0021: ldarg.2 + IL_0022: ldloc.2 + IL_0023: ldelem.i4 + IL_0024: stloc.3 + IL_0025: ldloc.3 + IL_0026: ldloc.0 + IL_0027: add + IL_0028: stelem.i4 + IL_0029: ldloc.2 + IL_002a: ldc.i4.1 + IL_002b: add + IL_002c: stloc.2 + IL_002d: ldloc.2 + IL_002e: ldloc.1 + IL_002f: ldlen + IL_0030: conv.i4 + IL_0031: blt.s IL_001f + + IL_0033: ldloc.1 + IL_0034: ret + } + + .method public static int32[] f10(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + int32[] 'array') cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 6 + .locals init (int32[] V_0, + int32 V_1, + int32 V_2) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: ldlen + IL_0014: conv.i4 + IL_0015: newarr [runtime]System.Int32 + IL_001a: stloc.0 + IL_001b: ldc.i4.0 + IL_001c: stloc.1 + IL_001d: br.s IL_002b + + IL_001f: ldloc.0 + IL_0020: ldloc.1 + IL_0021: ldarg.2 + IL_0022: ldloc.1 + IL_0023: ldelem.i4 + IL_0024: stloc.2 + IL_0025: ldloc.2 + IL_0026: stelem.i4 + IL_0027: ldloc.1 + IL_0028: ldc.i4.1 + IL_0029: add + IL_002a: stloc.1 + IL_002b: ldloc.1 + IL_002c: ldloc.0 + IL_002d: ldlen + IL_002e: conv.i4 + IL_002f: blt.s IL_001f + + IL_0031: ldloc.0 + IL_0032: ret + } + + .method public static int32[] f11(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + int32[] 'array') cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 6 + .locals init (int32 V_0, + int32[] V_1, + int32 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.0 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: ldlen + IL_0014: conv.i4 + IL_0015: newarr [runtime]System.Int32 + IL_001a: stloc.1 + IL_001b: ldc.i4.0 + IL_001c: stloc.2 + IL_001d: br.s IL_002d + + IL_001f: ldloc.1 + IL_0020: ldloc.2 + IL_0021: ldarg.2 + IL_0022: ldloc.2 + IL_0023: ldelem.i4 + IL_0024: stloc.3 + IL_0025: ldloc.3 + IL_0026: ldloc.0 + IL_0027: add + IL_0028: stelem.i4 + IL_0029: ldloc.2 + IL_002a: ldc.i4.1 + IL_002b: add + IL_002c: stloc.2 + IL_002d: ldloc.2 + IL_002e: ldloc.1 + IL_002f: ldlen + IL_0030: conv.i4 + IL_0031: blt.s IL_001f + + IL_0033: ldloc.1 + IL_0034: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToList.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToList.fs index 9aaf97f514b..fb12ad5c4de 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToList.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToList.fs @@ -5,3 +5,8 @@ let f4 f g (array: int array) = [for x in array -> f (); g(); x] let f5 (array: int array) = [for x in array do yield x] let f6 f (array: int array) = [for x in array do f (); yield x] let f7 f g (array: int array) = [for x in array do f (); g (); yield x] + +let f8 f g (array: int array) = [let y = f () in let z = g () in for x in array -> x + y + z] +let f9 f g (array: int array) = [let y = f () in g (); for x in array -> x + y] +let f10 f g (array: int array) = [f (); g (); for x in array -> x] +let f11 f g (array: int array) = [f (); let y = g () in for x in array -> x + y] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToList.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToList.fs.il.bsl index 4118a624e8a..9cc03990ad7 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToList.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToList.fs.il.bsl @@ -459,6 +459,286 @@ IL_0054: ret } + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f8(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + int32[] 'array') cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + int32 V_1, + int32 V_2, + class [runtime]System.Collections.Generic.IEnumerator`1 V_3, + class [runtime]System.Collections.Generic.IEnumerable`1 V_4, + int32 V_5, + class [runtime]System.IDisposable V_6) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.1 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.2 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.3 + .try + { + IL_0019: br.s IL_0031 + + IL_001b: ldloc.3 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_5 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_5 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: ldloc.2 + IL_002a: add + IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0030: nop + IL_0031: ldloc.3 + IL_0032: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0037: brtrue.s IL_001b + + IL_0039: ldnull + IL_003a: stloc.s V_4 + IL_003c: leave.s IL_0053 + + } + finally + { + IL_003e: ldloc.3 + IL_003f: isinst [runtime]System.IDisposable + IL_0044: stloc.s V_6 + IL_0046: ldloc.s V_6 + IL_0048: brfalse.s IL_0052 + + IL_004a: ldloc.s V_6 + IL_004c: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_0051: endfinally + IL_0052: endfinally + } + IL_0053: ldloc.s V_4 + IL_0055: pop + IL_0056: ldloca.s V_0 + IL_0058: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_005d: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f9(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + int32[] 'array') cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + int32 V_1, + class [runtime]System.Collections.Generic.IEnumerator`1 V_2, + class [runtime]System.Collections.Generic.IEnumerable`1 V_3, + int32 V_4, + class [runtime]System.IDisposable V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.1 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.2 + .try + { + IL_0019: br.s IL_002f + + IL_001b: ldloc.2 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_4 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_4 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002e: nop + IL_002f: ldloc.2 + IL_0030: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0035: brtrue.s IL_001b + + IL_0037: ldnull + IL_0038: stloc.3 + IL_0039: leave.s IL_0050 + + } + finally + { + IL_003b: ldloc.2 + IL_003c: isinst [runtime]System.IDisposable + IL_0041: stloc.s V_5 + IL_0043: ldloc.s V_5 + IL_0045: brfalse.s IL_004f + + IL_0047: ldloc.s V_5 + IL_0049: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004e: endfinally + IL_004f: endfinally + } + IL_0050: ldloc.3 + IL_0051: pop + IL_0052: ldloca.s V_0 + IL_0054: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0059: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f10(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + int32[] 'array') cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [runtime]System.Collections.Generic.IEnumerator`1 V_1, + class [runtime]System.Collections.Generic.IEnumerable`1 V_2, + int32 V_3, + class [runtime]System.IDisposable V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.1 + .try + { + IL_0019: br.s IL_002b + + IL_001b: ldloc.1 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.3 + IL_0022: ldloca.s V_0 + IL_0024: ldloc.3 + IL_0025: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002a: nop + IL_002b: ldloc.1 + IL_002c: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0031: brtrue.s IL_001b + + IL_0033: ldnull + IL_0034: stloc.2 + IL_0035: leave.s IL_004c + + } + finally + { + IL_0037: ldloc.1 + IL_0038: isinst [runtime]System.IDisposable + IL_003d: stloc.s V_4 + IL_003f: ldloc.s V_4 + IL_0041: brfalse.s IL_004b + + IL_0043: ldloc.s V_4 + IL_0045: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004a: endfinally + IL_004b: endfinally + } + IL_004c: ldloc.2 + IL_004d: pop + IL_004e: ldloca.s V_0 + IL_0050: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0055: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f11(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + int32[] 'array') cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + int32 V_1, + class [runtime]System.Collections.Generic.IEnumerator`1 V_2, + class [runtime]System.Collections.Generic.IEnumerable`1 V_3, + int32 V_4, + class [runtime]System.IDisposable V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.1 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.2 + .try + { + IL_0019: br.s IL_002f + + IL_001b: ldloc.2 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_4 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_4 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002e: nop + IL_002f: ldloc.2 + IL_0030: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0035: brtrue.s IL_001b + + IL_0037: ldnull + IL_0038: stloc.3 + IL_0039: leave.s IL_0050 + + } + finally + { + IL_003b: ldloc.2 + IL_003c: isinst [runtime]System.IDisposable + IL_0041: stloc.s V_5 + IL_0043: ldloc.s V_5 + IL_0045: brfalse.s IL_004f + + IL_0047: ldloc.s V_5 + IL_0049: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004e: endfinally + IL_004f: endfinally + } + IL_0050: ldloc.3 + IL_0051: pop + IL_0052: ldloca.s V_0 + IL_0054: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0059: ret + } + } .class private abstract auto ansi sealed ''.$assembly diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToArray.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToArray.fs index 4ffd4887562..62b7b9bc6c0 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToArray.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToArray.fs @@ -5,3 +5,8 @@ let f4 f g (list: int list) = [|for x in list -> f (); g(); x|] let f5 (list: int list) = [|for x in list do yield x|] let f6 f (list: int list) = [|for x in list do f (); yield x|] let f7 f g (list: int list) = [|for x in list do f (); g (); yield x|] + +let f8 f g (list: int list) = [|let y = f () in let z = g () in for x in list -> x + y + z|] +let f9 f g (list: int list) = [|let y = f () in g (); for x in list -> x + y|] +let f10 f g (list: int list) = [|f (); g (); for x in list -> x|] +let f11 f g (list: int list) = [|f (); let y = g () in for x in list -> x + y|] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToArray.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToArray.fs.il.bsl index 67fb0aca055..34dd7e2af69 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToArray.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToArray.fs.il.bsl @@ -454,6 +454,282 @@ IL_0054: ret } + .method public static int32[] f8(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1 V_0, + int32 V_1, + int32 V_2, + class [runtime]System.Collections.Generic.IEnumerator`1 V_3, + class [runtime]System.Collections.Generic.IEnumerable`1 V_4, + int32 V_5, + class [runtime]System.IDisposable V_6) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.1 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.2 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.3 + .try + { + IL_0019: br.s IL_0031 + + IL_001b: ldloc.3 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_5 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_5 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: ldloc.2 + IL_002a: add + IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_0030: nop + IL_0031: ldloc.3 + IL_0032: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0037: brtrue.s IL_001b + + IL_0039: ldnull + IL_003a: stloc.s V_4 + IL_003c: leave.s IL_0053 + + } + finally + { + IL_003e: ldloc.3 + IL_003f: isinst [runtime]System.IDisposable + IL_0044: stloc.s V_6 + IL_0046: ldloc.s V_6 + IL_0048: brfalse.s IL_0052 + + IL_004a: ldloc.s V_6 + IL_004c: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_0051: endfinally + IL_0052: endfinally + } + IL_0053: ldloc.s V_4 + IL_0055: pop + IL_0056: ldloca.s V_0 + IL_0058: call instance !0[] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Close() + IL_005d: ret + } + + .method public static int32[] f9(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1 V_0, + int32 V_1, + class [runtime]System.Collections.Generic.IEnumerator`1 V_2, + class [runtime]System.Collections.Generic.IEnumerable`1 V_3, + int32 V_4, + class [runtime]System.IDisposable V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.1 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.2 + .try + { + IL_0019: br.s IL_002f + + IL_001b: ldloc.2 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_4 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_4 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_002e: nop + IL_002f: ldloc.2 + IL_0030: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0035: brtrue.s IL_001b + + IL_0037: ldnull + IL_0038: stloc.3 + IL_0039: leave.s IL_0050 + + } + finally + { + IL_003b: ldloc.2 + IL_003c: isinst [runtime]System.IDisposable + IL_0041: stloc.s V_5 + IL_0043: ldloc.s V_5 + IL_0045: brfalse.s IL_004f + + IL_0047: ldloc.s V_5 + IL_0049: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004e: endfinally + IL_004f: endfinally + } + IL_0050: ldloc.3 + IL_0051: pop + IL_0052: ldloca.s V_0 + IL_0054: call instance !0[] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Close() + IL_0059: ret + } + + .method public static int32[] f10(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1 V_0, + class [runtime]System.Collections.Generic.IEnumerator`1 V_1, + class [runtime]System.Collections.Generic.IEnumerable`1 V_2, + int32 V_3, + class [runtime]System.IDisposable V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.1 + .try + { + IL_0019: br.s IL_002b + + IL_001b: ldloc.1 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.3 + IL_0022: ldloca.s V_0 + IL_0024: ldloc.3 + IL_0025: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_002a: nop + IL_002b: ldloc.1 + IL_002c: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0031: brtrue.s IL_001b + + IL_0033: ldnull + IL_0034: stloc.2 + IL_0035: leave.s IL_004c + + } + finally + { + IL_0037: ldloc.1 + IL_0038: isinst [runtime]System.IDisposable + IL_003d: stloc.s V_4 + IL_003f: ldloc.s V_4 + IL_0041: brfalse.s IL_004b + + IL_0043: ldloc.s V_4 + IL_0045: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004a: endfinally + IL_004b: endfinally + } + IL_004c: ldloc.2 + IL_004d: pop + IL_004e: ldloca.s V_0 + IL_0050: call instance !0[] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Close() + IL_0055: ret + } + + .method public static int32[] f11(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1 V_0, + int32 V_1, + class [runtime]System.Collections.Generic.IEnumerator`1 V_2, + class [runtime]System.Collections.Generic.IEnumerable`1 V_3, + int32 V_4, + class [runtime]System.IDisposable V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.1 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.2 + .try + { + IL_0019: br.s IL_002f + + IL_001b: ldloc.2 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_4 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_4 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_002e: nop + IL_002f: ldloc.2 + IL_0030: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0035: brtrue.s IL_001b + + IL_0037: ldnull + IL_0038: stloc.3 + IL_0039: leave.s IL_0050 + + } + finally + { + IL_003b: ldloc.2 + IL_003c: isinst [runtime]System.IDisposable + IL_0041: stloc.s V_5 + IL_0043: ldloc.s V_5 + IL_0045: brfalse.s IL_004f + + IL_0047: ldloc.s V_5 + IL_0049: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004e: endfinally + IL_004f: endfinally + } + IL_0050: ldloc.3 + IL_0051: pop + IL_0052: ldloca.s V_0 + IL_0054: call instance !0[] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Close() + IL_0059: ret + } + } .class private abstract auto ansi sealed ''.$assembly diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToList.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToList.fs index 5d9b73f6ef4..cfbb0fb567f 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToList.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToList.fs @@ -5,3 +5,8 @@ let f4 f g (list: int list) = [for x in list -> f (); g(); x] let f5 (list: int list) = [for x in list do yield x] let f6 f (list: int list) = [for x in list do f (); yield x] let f7 f g (list: int list) = [for x in list do f (); g (); yield x] + +let f8 f g (list: int list) = [let y = f () in let z = g () in for x in list -> x + y + z] +let f9 f g (list: int list) = [let y = f () in g (); for x in list -> x + y] +let f10 f g (list: int list) = [f (); g (); for x in list -> x] +let f11 f g (list: int list) = [f (); let y = g () in for x in list -> x + y] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToList.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToList.fs.il.bsl index 51145b138c7..81eaa9d474f 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToList.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInList_ToList.fs.il.bsl @@ -43,274 +43,40 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit f1@1 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field static assembly initonly class assembly/f1@1 @_instance - .method assembly specialname rtspecialname instance void .ctor() cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ret - } - - .method public strict virtual instance int32 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ret - } - - .method private specialname rtspecialname static void .cctor() cil managed - { - - .maxstack 10 - IL_0000: newobj instance void assembly/f1@1::.ctor() - IL_0005: stsfld class assembly/f1@1 assembly/f1@1::@_instance - IL_000a: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f2@2 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 class assembly/f2@2::f - IL_000d: ret - } - - .method public strict virtual instance !a Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 class assembly/f2@2::f - IL_0006: ldarg.1 - IL_0007: tail. - IL_0009: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000e: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f3@3 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f3@3::f - IL_000d: ret - } - - .method public strict virtual instance int32 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f3@3::f - IL_0006: ldnull - IL_0007: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000c: pop - IL_000d: ldarg.1 - IL_000e: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f4@4 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g - .method assembly specialname rtspecialname - instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f4@4::f - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f4@4::g - IL_0014: ret - } - - .method public strict virtual instance int32 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f4@4::f - IL_0006: ldnull - IL_0007: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000c: pop - IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f4@4::g - IL_0013: ldnull - IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0019: pop - IL_001a: ldarg.1 - IL_001b: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f5@5 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 - { - .field static assembly initonly class assembly/f5@5 @_instance - .method assembly specialname rtspecialname instance void .ctor() cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() - IL_0006: ret - } - - .method public strict virtual instance int32 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.1 - IL_0001: ret - } - - .method private specialname rtspecialname static void .cctor() cil managed - { - - .maxstack 10 - IL_0000: newobj instance void assembly/f5@5::.ctor() - IL_0005: stsfld class assembly/f5@5 assembly/f5@5::@_instance - IL_000a: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f6@6 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f6@6::f - IL_000d: ret - } - - .method public strict virtual instance class [runtime]System.Collections.Generic.IEnumerable`1 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f6@6::f - IL_0006: ldnull - IL_0007: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000c: pop - IL_000d: ldarg.1 - IL_000e: tail. - IL_0010: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) - IL_0015: ret - } - - } - - .class auto ansi serializable sealed nested assembly beforefieldinit f7@7 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> - { - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g - .method assembly specialname rtspecialname - instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed - { - .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f7@7::f - IL_000d: ldarg.0 - IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f7@7::g - IL_0014: ret - } - - .method public strict virtual instance class [runtime]System.Collections.Generic.IEnumerable`1 Invoke(int32 x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f7@7::f - IL_0006: ldnull - IL_0007: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_000c: pop - IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 assembly/f7@7::g - IL_0013: ldnull - IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0019: pop - IL_001a: ldarg.1 - IL_001b: tail. - IL_001d: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) - IL_0022: ret - } - - } - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f1(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed { - .maxstack 8 - IL_0000: ldsfld class assembly/f1@1 assembly/f1@1::@_instance - IL_0005: ldarg.0 - IL_0006: tail. - IL_0008: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_000d: ret + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: stloc.1 + IL_0003: ldloc.1 + IL_0004: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0009: stloc.2 + IL_000a: br.s IL_0025 + + IL_000c: ldloc.1 + IL_000d: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0012: stloc.3 + IL_0013: ldloca.s V_0 + IL_0015: ldloc.3 + IL_0016: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_001b: nop + IL_001c: ldloc.2 + IL_001d: stloc.1 + IL_001e: ldloc.1 + IL_001f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0024: stloc.2 + IL_0025: ldloc.2 + IL_0026: brtrue.s IL_000c + + IL_0028: ldloca.s V_0 + IL_002a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_002f: ret } .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 @@ -319,14 +85,39 @@ { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void class assembly/f2@2::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0006: ldarg.1 - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_000e: ret + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.1 + IL_0003: ldloc.1 + IL_0004: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0009: stloc.2 + IL_000a: br.s IL_002b + + IL_000c: ldloc.1 + IL_000d: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0012: stloc.3 + IL_0013: ldloca.s V_0 + IL_0015: ldarg.0 + IL_0016: ldloc.3 + IL_0017: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0021: nop + IL_0022: ldloc.2 + IL_0023: stloc.1 + IL_0024: ldloc.1 + IL_0025: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_002a: stloc.2 + IL_002b: ldloc.2 + IL_002c: brtrue.s IL_000c + + IL_002e: ldloca.s V_0 + IL_0030: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0035: ret } .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 @@ -335,14 +126,41 @@ { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void assembly/f3@3::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0006: ldarg.1 - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_000e: ret + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.1 + IL_0003: ldloc.1 + IL_0004: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0009: stloc.2 + IL_000a: br.s IL_002d + + IL_000c: ldloc.1 + IL_000d: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0012: stloc.3 + IL_0013: ldloca.s V_0 + IL_0015: ldarg.0 + IL_0016: ldnull + IL_0017: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001c: pop + IL_001d: ldloc.3 + IL_001e: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0023: nop + IL_0024: ldloc.2 + IL_0025: stloc.1 + IL_0026: ldloc.1 + IL_0027: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_002c: stloc.2 + IL_002d: ldloc.2 + IL_002e: brtrue.s IL_000c + + IL_0030: ldloca.s V_0 + IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0037: ret } .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 @@ -353,28 +171,81 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: newobj instance void assembly/f4@4::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0007: ldarg.2 - IL_0008: tail. - IL_000a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_000f: ret + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: stloc.1 + IL_0003: ldloc.1 + IL_0004: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0009: stloc.2 + IL_000a: br.s IL_0035 + + IL_000c: ldloc.1 + IL_000d: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0012: stloc.3 + IL_0013: ldloca.s V_0 + IL_0015: ldarg.0 + IL_0016: ldnull + IL_0017: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001c: pop + IL_001d: ldarg.1 + IL_001e: ldnull + IL_001f: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0024: pop + IL_0025: ldloc.3 + IL_0026: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002b: nop + IL_002c: ldloc.2 + IL_002d: stloc.1 + IL_002e: ldloc.1 + IL_002f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0034: stloc.2 + IL_0035: ldloc.2 + IL_0036: brtrue.s IL_000c + + IL_0038: ldloca.s V_0 + IL_003a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003f: ret } .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f5(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed { - .maxstack 8 - IL_0000: ldsfld class assembly/f5@5 assembly/f5@5::@_instance - IL_0005: ldarg.0 - IL_0006: tail. - IL_0008: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_000d: ret + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: stloc.1 + IL_0003: ldloc.1 + IL_0004: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0009: stloc.2 + IL_000a: br.s IL_0025 + + IL_000c: ldloc.1 + IL_000d: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0012: stloc.3 + IL_0013: ldloca.s V_0 + IL_0015: ldloc.3 + IL_0016: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_001b: nop + IL_001c: ldloc.2 + IL_001d: stloc.1 + IL_001e: ldloc.1 + IL_001f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0024: stloc.2 + IL_0025: ldloc.2 + IL_0026: brtrue.s IL_000c + + IL_0028: ldloca.s V_0 + IL_002a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_002f: ret } .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 @@ -383,14 +254,41 @@ { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void assembly/f6@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0006: ldarg.1 - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_000e: ret + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.1 + IL_0003: ldloc.1 + IL_0004: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0009: stloc.2 + IL_000a: br.s IL_002d + + IL_000c: ldloc.1 + IL_000d: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0012: stloc.3 + IL_0013: ldloca.s V_0 + IL_0015: ldarg.0 + IL_0016: ldnull + IL_0017: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001c: pop + IL_001d: ldloc.3 + IL_001e: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0023: nop + IL_0024: ldloc.2 + IL_0025: stloc.1 + IL_0026: ldloc.1 + IL_0027: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_002c: stloc.2 + IL_002d: ldloc.2 + IL_002e: brtrue.s IL_000c + + IL_0030: ldloca.s V_0 + IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0037: ret } .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 @@ -401,16 +299,257 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: newobj instance void assembly/f7@7::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0007: ldarg.2 - IL_0008: tail. - IL_000a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_000f: ret + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: stloc.1 + IL_0003: ldloc.1 + IL_0004: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0009: stloc.2 + IL_000a: br.s IL_0035 + + IL_000c: ldloc.1 + IL_000d: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0012: stloc.3 + IL_0013: ldloca.s V_0 + IL_0015: ldarg.0 + IL_0016: ldnull + IL_0017: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001c: pop + IL_001d: ldarg.1 + IL_001e: ldnull + IL_001f: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0024: pop + IL_0025: ldloc.3 + IL_0026: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002b: nop + IL_002c: ldloc.2 + IL_002d: stloc.1 + IL_002e: ldloc.1 + IL_002f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0034: stloc.2 + IL_0035: ldloc.2 + IL_0036: brtrue.s IL_000c + + IL_0038: ldloca.s V_0 + IL_003a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003f: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f8(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + int32 V_1, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_2, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_3, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.0 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.1 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: stloc.3 + IL_0014: ldloc.3 + IL_0015: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_001a: stloc.s V_4 + IL_001c: br.s IL_003f + + IL_001e: ldloc.3 + IL_001f: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0024: stloc.s V_5 + IL_0026: ldloca.s V_2 + IL_0028: ldloc.s V_5 + IL_002a: ldloc.0 + IL_002b: add + IL_002c: ldloc.1 + IL_002d: add + IL_002e: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0033: nop + IL_0034: ldloc.s V_4 + IL_0036: stloc.3 + IL_0037: ldloc.3 + IL_0038: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_003d: stloc.s V_4 + IL_003f: ldloc.s V_4 + IL_0041: brtrue.s IL_001e + + IL_0043: ldloca.s V_2 + IL_0045: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_004a: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f9(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.0 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: stloc.2 + IL_0014: ldloc.2 + IL_0015: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_001a: stloc.3 + IL_001b: br.s IL_003a + + IL_001d: ldloc.2 + IL_001e: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0023: stloc.s V_4 + IL_0025: ldloca.s V_1 + IL_0027: ldloc.s V_4 + IL_0029: ldloc.0 + IL_002a: add + IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0030: nop + IL_0031: ldloc.3 + IL_0032: stloc.2 + IL_0033: ldloc.2 + IL_0034: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0039: stloc.3 + IL_003a: ldloc.3 + IL_003b: brtrue.s IL_001d + + IL_003d: ldloca.s V_1 + IL_003f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0044: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f10(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: stloc.1 + IL_0014: ldloc.1 + IL_0015: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_001a: stloc.2 + IL_001b: br.s IL_0036 + + IL_001d: ldloc.1 + IL_001e: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0023: stloc.3 + IL_0024: ldloca.s V_0 + IL_0026: ldloc.3 + IL_0027: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002c: nop + IL_002d: ldloc.2 + IL_002e: stloc.1 + IL_002f: ldloc.1 + IL_0030: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0035: stloc.2 + IL_0036: ldloc.2 + IL_0037: brtrue.s IL_001d + + IL_0039: ldloca.s V_0 + IL_003b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0040: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f11(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.0 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: stloc.2 + IL_0014: ldloc.2 + IL_0015: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_001a: stloc.3 + IL_001b: br.s IL_003a + + IL_001d: ldloc.2 + IL_001e: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0023: stloc.s V_4 + IL_0025: ldloca.s V_1 + IL_0027: ldloc.s V_4 + IL_0029: ldloc.0 + IL_002a: add + IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0030: nop + IL_0031: ldloc.3 + IL_0032: stloc.2 + IL_0033: ldloc.2 + IL_0034: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0039: stloc.3 + IL_003a: ldloc.3 + IL_003b: brtrue.s IL_001d + + IL_003d: ldloca.s V_1 + IL_003f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0044: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToArray.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToArray.fs index b8656c8dbe6..f4a28b47626 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToArray.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToArray.fs @@ -5,3 +5,8 @@ let f4 f g (seq: int seq) = [|for x in seq -> f (); g(); x|] let f5 (seq: int seq) = [|for x in seq do yield x|] let f6 f (seq: int seq) = [|for x in seq do f (); yield x|] let f7 f g (seq: int seq) = [|for x in seq do f (); g (); yield x|] + +let f8 f g (seq: int seq) = [|let y = f () in let z = g () in for x in seq -> x + y + z|] +let f9 f g (seq: int seq) = [|let y = f () in g (); for x in seq -> x + y|] +let f10 f g (seq: int seq) = [|f (); g (); for x in seq -> x|] +let f11 f g (seq: int seq) = [|f (); let y = g () in for x in seq -> x + y|] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToArray.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToArray.fs.il.bsl index d94bd0b406b..446a17b4fd9 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToArray.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToArray.fs.il.bsl @@ -454,6 +454,282 @@ IL_0054: ret } + .method public static int32[] f8(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [runtime]System.Collections.Generic.IEnumerable`1 seq) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1 V_0, + int32 V_1, + int32 V_2, + class [runtime]System.Collections.Generic.IEnumerator`1 V_3, + class [runtime]System.Collections.Generic.IEnumerable`1 V_4, + int32 V_5, + class [runtime]System.IDisposable V_6) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.1 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.2 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.3 + .try + { + IL_0019: br.s IL_0031 + + IL_001b: ldloc.3 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_5 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_5 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: ldloc.2 + IL_002a: add + IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_0030: nop + IL_0031: ldloc.3 + IL_0032: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0037: brtrue.s IL_001b + + IL_0039: ldnull + IL_003a: stloc.s V_4 + IL_003c: leave.s IL_0053 + + } + finally + { + IL_003e: ldloc.3 + IL_003f: isinst [runtime]System.IDisposable + IL_0044: stloc.s V_6 + IL_0046: ldloc.s V_6 + IL_0048: brfalse.s IL_0052 + + IL_004a: ldloc.s V_6 + IL_004c: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_0051: endfinally + IL_0052: endfinally + } + IL_0053: ldloc.s V_4 + IL_0055: pop + IL_0056: ldloca.s V_0 + IL_0058: call instance !0[] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Close() + IL_005d: ret + } + + .method public static int32[] f9(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [runtime]System.Collections.Generic.IEnumerable`1 seq) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1 V_0, + int32 V_1, + class [runtime]System.Collections.Generic.IEnumerator`1 V_2, + class [runtime]System.Collections.Generic.IEnumerable`1 V_3, + int32 V_4, + class [runtime]System.IDisposable V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.1 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.2 + .try + { + IL_0019: br.s IL_002f + + IL_001b: ldloc.2 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_4 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_4 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_002e: nop + IL_002f: ldloc.2 + IL_0030: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0035: brtrue.s IL_001b + + IL_0037: ldnull + IL_0038: stloc.3 + IL_0039: leave.s IL_0050 + + } + finally + { + IL_003b: ldloc.2 + IL_003c: isinst [runtime]System.IDisposable + IL_0041: stloc.s V_5 + IL_0043: ldloc.s V_5 + IL_0045: brfalse.s IL_004f + + IL_0047: ldloc.s V_5 + IL_0049: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004e: endfinally + IL_004f: endfinally + } + IL_0050: ldloc.3 + IL_0051: pop + IL_0052: ldloca.s V_0 + IL_0054: call instance !0[] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Close() + IL_0059: ret + } + + .method public static int32[] f10(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [runtime]System.Collections.Generic.IEnumerable`1 seq) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1 V_0, + class [runtime]System.Collections.Generic.IEnumerator`1 V_1, + class [runtime]System.Collections.Generic.IEnumerable`1 V_2, + int32 V_3, + class [runtime]System.IDisposable V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.1 + .try + { + IL_0019: br.s IL_002b + + IL_001b: ldloc.1 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.3 + IL_0022: ldloca.s V_0 + IL_0024: ldloc.3 + IL_0025: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_002a: nop + IL_002b: ldloc.1 + IL_002c: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0031: brtrue.s IL_001b + + IL_0033: ldnull + IL_0034: stloc.2 + IL_0035: leave.s IL_004c + + } + finally + { + IL_0037: ldloc.1 + IL_0038: isinst [runtime]System.IDisposable + IL_003d: stloc.s V_4 + IL_003f: ldloc.s V_4 + IL_0041: brfalse.s IL_004b + + IL_0043: ldloc.s V_4 + IL_0045: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004a: endfinally + IL_004b: endfinally + } + IL_004c: ldloc.2 + IL_004d: pop + IL_004e: ldloca.s V_0 + IL_0050: call instance !0[] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Close() + IL_0055: ret + } + + .method public static int32[] f11(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [runtime]System.Collections.Generic.IEnumerable`1 seq) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1 V_0, + int32 V_1, + class [runtime]System.Collections.Generic.IEnumerator`1 V_2, + class [runtime]System.Collections.Generic.IEnumerable`1 V_3, + int32 V_4, + class [runtime]System.IDisposable V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.1 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.2 + .try + { + IL_0019: br.s IL_002f + + IL_001b: ldloc.2 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_4 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_4 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_002e: nop + IL_002f: ldloc.2 + IL_0030: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0035: brtrue.s IL_001b + + IL_0037: ldnull + IL_0038: stloc.3 + IL_0039: leave.s IL_0050 + + } + finally + { + IL_003b: ldloc.2 + IL_003c: isinst [runtime]System.IDisposable + IL_0041: stloc.s V_5 + IL_0043: ldloc.s V_5 + IL_0045: brfalse.s IL_004f + + IL_0047: ldloc.s V_5 + IL_0049: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004e: endfinally + IL_004f: endfinally + } + IL_0050: ldloc.3 + IL_0051: pop + IL_0052: ldloca.s V_0 + IL_0054: call instance !0[] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Close() + IL_0059: ret + } + } .class private abstract auto ansi sealed ''.$assembly diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToList.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToList.fs index 05be5e9f2d7..9c88ace26d3 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToList.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToList.fs @@ -5,3 +5,8 @@ let f4 f g (seq: int seq) = [for x in seq -> f (); g(); x] let f5 (seq: int seq) = [for x in seq do yield x] let f6 f (seq: int seq) = [for x in seq do f (); yield x] let f7 f g (seq: int seq) = [for x in seq do f (); g (); yield x] + +let f8 f g (seq: int seq) = [let y = f () in let z = g () in for x in seq -> x + y + z] +let f9 f g (seq: int seq) = [let y = f () in g (); for x in seq -> x + y] +let f10 f g (seq: int seq) = [f (); g (); for x in seq -> x] +let f11 f g (seq: int seq) = [f (); let y = g () in for x in seq -> x + y] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToList.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToList.fs.il.bsl index 6fe2894fc3a..bf3e4bf6eab 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToList.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInSeq_ToList.fs.il.bsl @@ -459,6 +459,286 @@ IL_0054: ret } + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f8(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [runtime]System.Collections.Generic.IEnumerable`1 seq) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + int32 V_1, + int32 V_2, + class [runtime]System.Collections.Generic.IEnumerator`1 V_3, + class [runtime]System.Collections.Generic.IEnumerable`1 V_4, + int32 V_5, + class [runtime]System.IDisposable V_6) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.1 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.2 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.3 + .try + { + IL_0019: br.s IL_0031 + + IL_001b: ldloc.3 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_5 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_5 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: ldloc.2 + IL_002a: add + IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0030: nop + IL_0031: ldloc.3 + IL_0032: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0037: brtrue.s IL_001b + + IL_0039: ldnull + IL_003a: stloc.s V_4 + IL_003c: leave.s IL_0053 + + } + finally + { + IL_003e: ldloc.3 + IL_003f: isinst [runtime]System.IDisposable + IL_0044: stloc.s V_6 + IL_0046: ldloc.s V_6 + IL_0048: brfalse.s IL_0052 + + IL_004a: ldloc.s V_6 + IL_004c: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_0051: endfinally + IL_0052: endfinally + } + IL_0053: ldloc.s V_4 + IL_0055: pop + IL_0056: ldloca.s V_0 + IL_0058: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_005d: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f9(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [runtime]System.Collections.Generic.IEnumerable`1 seq) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + int32 V_1, + class [runtime]System.Collections.Generic.IEnumerator`1 V_2, + class [runtime]System.Collections.Generic.IEnumerable`1 V_3, + int32 V_4, + class [runtime]System.IDisposable V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: stloc.1 + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.2 + .try + { + IL_0019: br.s IL_002f + + IL_001b: ldloc.2 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_4 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_4 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002e: nop + IL_002f: ldloc.2 + IL_0030: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0035: brtrue.s IL_001b + + IL_0037: ldnull + IL_0038: stloc.3 + IL_0039: leave.s IL_0050 + + } + finally + { + IL_003b: ldloc.2 + IL_003c: isinst [runtime]System.IDisposable + IL_0041: stloc.s V_5 + IL_0043: ldloc.s V_5 + IL_0045: brfalse.s IL_004f + + IL_0047: ldloc.s V_5 + IL_0049: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004e: endfinally + IL_004f: endfinally + } + IL_0050: ldloc.3 + IL_0051: pop + IL_0052: ldloca.s V_0 + IL_0054: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0059: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f10(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [runtime]System.Collections.Generic.IEnumerable`1 seq) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [runtime]System.Collections.Generic.IEnumerator`1 V_1, + class [runtime]System.Collections.Generic.IEnumerable`1 V_2, + int32 V_3, + class [runtime]System.IDisposable V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: pop + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.1 + .try + { + IL_0019: br.s IL_002b + + IL_001b: ldloc.1 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.3 + IL_0022: ldloca.s V_0 + IL_0024: ldloc.3 + IL_0025: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002a: nop + IL_002b: ldloc.1 + IL_002c: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0031: brtrue.s IL_001b + + IL_0033: ldnull + IL_0034: stloc.2 + IL_0035: leave.s IL_004c + + } + finally + { + IL_0037: ldloc.1 + IL_0038: isinst [runtime]System.IDisposable + IL_003d: stloc.s V_4 + IL_003f: ldloc.s V_4 + IL_0041: brfalse.s IL_004b + + IL_0043: ldloc.s V_4 + IL_0045: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004a: endfinally + IL_004b: endfinally + } + IL_004c: ldloc.2 + IL_004d: pop + IL_004e: ldloca.s V_0 + IL_0050: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0055: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f11(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [runtime]System.Collections.Generic.IEnumerable`1 seq) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + int32 V_1, + class [runtime]System.Collections.Generic.IEnumerator`1 V_2, + class [runtime]System.Collections.Generic.IEnumerable`1 V_3, + int32 V_4, + class [runtime]System.IDisposable V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0008: pop + IL_0009: ldarg.1 + IL_000a: ldnull + IL_000b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0010: stloc.1 + IL_0011: nop + IL_0012: ldarg.2 + IL_0013: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0018: stloc.2 + .try + { + IL_0019: br.s IL_002f + + IL_001b: ldloc.2 + IL_001c: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0021: stloc.s V_4 + IL_0023: ldloca.s V_0 + IL_0025: ldloc.s V_4 + IL_0027: ldloc.1 + IL_0028: add + IL_0029: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002e: nop + IL_002f: ldloc.2 + IL_0030: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0035: brtrue.s IL_001b + + IL_0037: ldnull + IL_0038: stloc.3 + IL_0039: leave.s IL_0050 + + } + finally + { + IL_003b: ldloc.2 + IL_003c: isinst [runtime]System.IDisposable + IL_0041: stloc.s V_5 + IL_0043: ldloc.s V_5 + IL_0045: brfalse.s IL_004f + + IL_0047: ldloc.s V_5 + IL_0049: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_004e: endfinally + IL_004f: endfinally + } + IL_0050: ldloc.3 + IL_0051: pop + IL_0052: ldloca.s V_0 + IL_0054: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0059: ret + } + } .class private abstract auto ansi sealed ''.$assembly diff --git a/tests/walkthroughs/DebugStepping/TheBigFileOfDebugStepping.fsx b/tests/walkthroughs/DebugStepping/TheBigFileOfDebugStepping.fsx new file mode 100644 index 00000000000..346761cc478 --- /dev/null +++ b/tests/walkthroughs/DebugStepping/TheBigFileOfDebugStepping.fsx @@ -0,0 +1,2273 @@ +// Instructions: +// artifacts\bin\fsc\Debug\net472\fsc.exe --debug+ --tailcalls- --optimize- --langversion:preview tests\walkthroughs\DebugStepping\TheBigFileOfDebugStepping.fsx +// devenv /debugexe TheBigFileOfDebugStepping.exe +// +// Repeat the above with +// - Just My Code on/off +// - 32-bit or 64-bit +// - .NET Core and .NET Framework +// - Linux and Windows +// - Different visual debuggers + +open System +open System.Threading +open System.Threading.Tasks + +type U2 = U2 of int * int + + +let (!) (r: 'T ref) = r.Value +let (:=) (r: 'T ref) (v: 'T) = r.Value <- v +let incr (r: int ref) = r.Value <- r.Value + 1 +let decr (r: int ref) = r.Value <- r.Value - 1 + +let InnerRecursiveFunction (str: string) = + let rec even n = if n = 0 then str else odd (n-1) + and odd n = even (n-1) + + even 6 + +let rec TailcallRecursionTest1 n = + if n = 0 then + 5 + else + TailcallRecursionTest1 (n-1) // check the 'n' updates correctly + +let rec TailcallRecursionTest2 (U2(a,b)) = + if a = 0 then + 5 + else + TailcallRecursionTest2 (U2(a-1,b-1)) // check the 'a' and 'b' update correctly + +let AsyncExpressionSteppingTest1 () = + async { Console.WriteLine "hello" + Console.WriteLine "stuck in the middle" + Console.WriteLine "goodbye"} + +let AsyncExpressionSteppingTest2 () = + let x = ref 0 + async { while !x < 4 do + incr x + Console.WriteLine "hello" } + + +let AsyncExpressionSteppingTest3 () = + async { let x = ref 0 + incr x + let y = ref 0 + incr y + let z = !x + !y + return z } + +let AsyncExpressionSteppingTest4 () = + async { let x = ref 0 + try + let y = ref 0 + incr y + let z = !x + !y + return z + finally + incr x + Console.WriteLine "done" } + + +let es = [3;4;5] +let AsyncExpressionSteppingTest5 () = + async { for x in es do + Console.WriteLine "hello" + Console.WriteLine "hello 2" + for x in es do + Console.WriteLine "goodbye" + Console.WriteLine "goodbye 2" } + + +let f2 () = + async { let x = ref 0 + incr x + let y = ref 0 + incr y + let z = !x + !y + return z } + +let AsyncExpressionSteppingTest6b () = + async { let! x1 = f2() + let! x2 = f2() + let! x3 = f2() + let y = ref 0 + incr y + let! x4 = f2() + let z = x1 + !y + x4 + return z } + +let AsyncBreakpoints1 () = + async { let! res1 = + f2() + let! res2 = + match 1 with + | 1 -> f2() + | _ -> f2() + let! res3 = + match 1 with + | 1 -> + let x = + match 4 with + | 2 -> f2() + | _ -> f2() + f2() + | _ -> + let x = + match 4 with + | 2 -> f2() + | _ -> f2() + f2() + return () } + + +let ListExpressionSteppingTest1 () = + [ yield 1 ] + +let ListExpressionSteppingTest2 () = + [ Console.WriteLine "hello" + yield 1 + Console.WriteLine "goodbye" + yield 2] + + +let ListExpressionSteppingTest3 () = + let x = ref 0 + [ while !x < 4 do + incr x + Console.WriteLine "hello" + yield x ] + + +let ListExpressionSteppingTest4 () = + [ let x = ref 0 + incr x + let y = ref 0 + incr y + yield !x + let z = !x + !y + yield z ] + + +let ListExpressionSteppingTest5 () = + [ let x = ref 0 + try + let y = ref 0 + incr y + yield !x + let z = !x + !y + yield z + finally + incr x + Console.WriteLine "done" ] + + +let ListExpressionSteppingTest6 () = + [ for x in es do + Console.WriteLine "hello" + yield x + for x in es do + Console.WriteLine "goodbye" + yield x ] + +let ListExpressionSteppingTest7 () = + [ for x in 1..4 do + printfn "hello" + yield x ] + +let ListExpressionSteppingTest8 () = + [ for x in 1..4 do + match x with + | 1 -> + printfn "hello" + yield x + | 2 -> + printfn "hello" + yield x + | _ -> + yield x + ] + +let SeqExpressionSteppingTest1 () = + seq { yield 1 } + + +let SeqExpressionSteppingTest2 () = + seq { Console.WriteLine "hello" + yield 1 + Console.WriteLine "goodbye" + yield 2 } + + + +let SeqExpressionSteppingTest3 () = + let x = ref 0 + seq { while !x < 4 do + incr x + Console.WriteLine "hello" + yield x } + + +let SeqExpressionSteppingTest4 () = + seq { let x = ref 0 + incr x + let y = ref 0 + incr y + yield !x + let z = !x + !y + yield z } + + + +let SeqExpressionSteppingTest5 () = + seq { let x = ref 0 + try + let y = ref 0 + incr y + yield !x + let z = !x + !y + yield z + finally + incr x + Console.WriteLine "done" } + + +let SeqExpressionSteppingTest6 () = + seq { for x in es do + Console.WriteLine "hello" + yield x + for x in es do + Console.WriteLine "goodbye" + yield x } + + + +let SeqExpressionSteppingTest7() = + // "Stepping into sequence expression pops up a dialog trying to located an unknown file" + let r = ref 0 + let f () = [ if (incr r; true) then yield! failwith "" ] + (try f () with Failure _ -> [!r]) + +let rec rwalk x = seq { yield x; yield! rwalk (x+1) } + +let SeqExpressionTailCalls01() = rwalk 3 |> Seq.truncate 3 |> Seq.length + +// Same as SeqExpressionTailCalls01.fs, but with MUTUALLY RECURSIVE PAIR OF SEQUENCES +let rec rwalk1 x = seq { yield x; yield! rwalk2 (x+1) } +and rwalk2 x = seq { yield x; yield! rwalk1 (x+1) } + +let SeqExpressionTailCalls02() = rwalk2 3 |> Seq.truncate 3 |> Seq.length + +SeqExpressionSteppingTest7() +SeqExpressionTailCalls01() +SeqExpressionTailCalls02() + +let SteppingMatch01 (n) = + match n with + | Choice2Of2 _ -> + Console.WriteLine("A") + | Choice1Of2 _ -> + Console.WriteLine("B") + +let SteppingMatch03 (n) = + match n with + | Choice1Of2 _ -> + Console.WriteLine("B") + | Choice2Of2 _ -> + Console.WriteLine("A") + +let SteppingMatch03b (n) = + match n with + | Choice1Of3 _ -> + Console.WriteLine("A") + | Choice2Of3 _ -> + Console.WriteLine("B") + | Choice3Of3 _ -> + Console.WriteLine("C") + + +let SteppingMatch04 (n) = + match n with + | Choice2Of3 _ -> + Console.WriteLine("B") + | Choice3Of3 _ -> + Console.WriteLine("C") + | Choice1Of3 _ -> + Console.WriteLine("A") + +let SteppingMatch05 (n) = + match n with + | Choice3Of3 _ -> + Console.WriteLine("C") + | Choice2Of3 _ -> + Console.WriteLine("B") + | Choice1Of3 _ -> + Console.WriteLine("A") + +type Discr = CaseA | CaseB +let SteppingMatch06 (n) = + match n with + | CaseB -> + Console.WriteLine("B") + | CaseA-> + Console.WriteLine("A") + +let SteppingMatch07 (n) = + match n with + | CaseA-> + Console.WriteLine("A") + | CaseB -> + Console.WriteLine("B") + +let SteppingMatch08 (x) = + let b = + match x with + | 0 -> 2 + | _ -> 0 + + System.Diagnostics.Debug.Write(b) + System.Diagnostics.Debug.Write(b) + +let SteppingMatch09 n = + match n with + | 1 -> + Some(10) // debug range should cover all of "Some(10)" + | 2 -> + None + | _ -> + Some( 22 ) // debug range should cover all of "Some( 22 )" + +// Test case from https://github.com/Microsoft/visualfsharp/issues/105 +let OuterWithGenericInner list = + let GenericInner (list: 'T list) = + match list with + | [] -> 1 + | _ -> 2 + + GenericInner list + +// Test case from https://github.com/Microsoft/visualfsharp/issues/105 +let OuterWithNonGenericInner list = + let NonGenericInner (list: int list) = + match list with + | [] -> 1 + | _ -> 2 + + NonGenericInner list + +// Test case from https://github.com/Microsoft/visualfsharp/issues/105 +let OuterWithNonGenericInnerWithCapture x list = + let NonGenericInnerWithCapture (list: int list) = + match list with + | [] -> 1 + | _ -> x + + NonGenericInnerWithCapture list + + +let TestFunction1() = + Console.WriteLine "Hello"; + Console.WriteLine "World"; + 3+4 + + +let TestFunction10(p) = + let (x,y) = p + x+y + + +let TestFunction11(p) = + [p; p + p; p + p + p ] + + +let TestFunction12(p) = + { contents = p+p } + + +let TestFunction13(x) = + [x;x+x], [] + + +let TestFunction14() = + List.map (fun f -> f 2) [(fun x -> x + 1)] + + +let TestFunction15(inp) = + let x = inp+1 + [1;2;3] |> List.map (fun x -> x + 1) + + +type U = U of int * int + +let TestFunction16(inp) = + let x = U(inp,inp) + x,x + + +type R = { x:int; y:int } + +let TestFunction17(inp) = + let x = {x=3;y=inp} + x,x + + +let TestFunction18(inp) = + System.Console.WriteLine("hello") + + +type C(x:int,y:int) = + member this.X = x + member this.Y = y + +let TestFunction19(inp) = + let c1 = C(inp,inp) + let c2 = C(inp,inp) + Console.WriteLine $"c1 = {c1}, c2 = {c2}" + +let TestFunction1_0() = + Console.WriteLine "Hello"; + Console.WriteLine "World"; + 3+4 + +let TestFunction2() = + let x = TestFunction1_0() + Console.WriteLine "Hello"; + Console.WriteLine "World" + + +type D(x:int,y:int) = + let z = x + y + let f a = x + a + let w = f z + z + member this.X = x + member this.Y = y + +let TestFunction20(inp) = + let d1 = D(inp,inp) + let d2 = D(inp,inp) + Console.WriteLine $"done d1 = {d1}, d2 = {d2}" + + +let TestFunction21(U2(a,b)) = + Console.WriteLine $"a = {a}, b = {b}" + +let TestFunction1_1() = + Console.WriteLine "Hello"; + Console.WriteLine "World"; + 3+4 + +let TestFunction3() = + try + let x = TestFunction1_1() + Console.WriteLine "Hello"; + with _ -> + Console.WriteLine "World" + +let TestFunction1_2() = + Console.WriteLine "Hello"; + Console.WriteLine "World"; + 3+4 + +let TestFunction3b() = + try + let x = TestFunction1_2() + failwith "hello" + with Failure _ -> + Console.WriteLine "World" + +let TestFunction1_3() = + Console.WriteLine "Hello"; + Console.WriteLine "World"; + 3+4 + +let TestFunction3c() = + try + let x = TestFunction1_3() + failwith "hello" + with Failure msg when msg = "hello" -> + Console.WriteLine "World" + + +let TestFunction1_4() = + Console.WriteLine "Hello"; + Console.WriteLine "World"; + 3+4 + +let TestFunction4() = + try + let x = TestFunction1_4() + Console.WriteLine "Hello"; + finally + Console.WriteLine "World" + +let TestFunction1_5() = + Console.WriteLine "Hello"; + Console.WriteLine "World"; + 3+4 + +let TestFunction5() = + let x = + let y = TestFunction1_5() + Console.WriteLine "Hello"; + y + y + x + x + + +let TestFunction1_6() = + Console.WriteLine "Hello"; + Console.WriteLine "World"; + 3+4 + +let TestFunction6() = + let f() = + let y = TestFunction1_6() + Console.WriteLine "Hello"; + y + y + f() + f() + + +let TestFunction7() = + let mutable r = 0 + while r < 3 do + r <- r + 1 + +let TestFunction8(x) = + if x > 3 then + x+4 + else x-4 + + +let TestFunction9(x) = + match x with + | 3 -> "three" + | 4 -> "four" + | _ -> "five" + +let TestFunction9b(x) = + match x with + | [1;2] -> "three" + | [3;4] -> "seven" + | [a;b] when a+b = 4 -> "four" + | _ -> "big" + +let TestFunction22() = + let x1 = if DateTime.Now.Day = 0 then DateTime.Now.Day else DateTime.MinValue.Day + let x2 = if DateTime.Now.Day = 1 then DateTime.Now.Day else DateTime.MinValue.Day + let x3 = if DateTime.Now.Day > 1 then DateTime.Now.Day else DateTime.MinValue.Day + (x1,x2,x3) + +let InnerFunctionDefinitionHadTwoBreakpoints (str: string) = + let isVowel (ch: char) = + let c = Char.ToUpper(ch) + c = 'A' || c = 'E' || c = 'I' || c = 'O' || c = 'U' + + let firstChar = str.[0] + + if isVowel firstChar then + str + "way" + else + str.[1..str.Length-1] + string(firstChar) + "ay" + +let InnerRecursiveFunctionDefinitionHadTwoBreakpoints (str: string) = + let firstChar = str.[0] + + let rec isVowel (ch: char) = + let c = Char.ToUpper(ch) + c = 'A' || c = 'E' || c = 'I' || c = 'O' || c = 'U' + + let firstChar = str.[0] + + if isVowel firstChar then + str + "way" + else + str.[1..str.Length-1] + string(firstChar) + "ay" + +let LocalValueShadowsArgument1 x = + let x = // quick watch 1 + if isNull(x) then + printf "value is null" // quick watch 2 + 2 + else + printf "value is not null" // breakpoint 1 + 3 + () + +let LocalValueShadowsArgument2 x = + let x = // quick watch 3 + if isNull(x) then + null // quick watch 4 + else + null // breakpoint 2 + () + +let TaskExpressionSteppingTest0 () = + task { Console.WriteLine "hello" + Console.WriteLine "stuck in the middle" + Console.WriteLine "goodbye"} + +let TaskExpressionSteppingTest1 () = + task { Console.WriteLine "hello" + Console.WriteLine "stuck in the middle" + do! Task.Delay 100 + Console.WriteLine "goodbye"} + +let TaskExpressionSteppingTest2 () = + let x = ref 0 + task { while !x < 4 do + incr x + Console.WriteLine "hello" } + +let TaskExpressionSteppingTest3 () = + task { let x = ref 0 + incr x + let y = ref 0 + incr y + let z = !x + !y + return z } + +let TaskExpressionSteppingTest4 () = + task { let x = ref 0 + try + let y = ref 0 + incr y + let z = !x + !y + return z + finally + incr x + Console.WriteLine "done" } + +let TaskExpressionSteppingTest5 () = + task { for x in es do + Console.WriteLine "hello" + Console.WriteLine "hello 2" + for x in es do + Console.WriteLine "goodbye" + Console.WriteLine "goodbye 2" } + +let tf2 () = + task { let x = ref 0 + incr x + let y = ref 0 + incr y + let z = !x + !y + return z } + +let TaskExpressionSteppingTest6b () = + task { let! x1 = tf2() + let! x2 = tf2() + let! x3 = tf2() + let y = ref 0 + incr y + let! x4 = tf2() + let z = x1 + !y + x4 + return z } + +let TaskExpressionSteppingTest7a () = + task { let x = ref 0 + try + let y = ref 0 + incr y + let z = !x + !y + return z + with exn -> + incr x + Console.WriteLine "done" + return 0 } + +let TaskExpressionSteppingTest7b () = + task { let x = ref 0 + try + let y = ref 0 + incr y + failwith "fail" + let z = !x + !y + return z + with exn -> + incr x + Console.WriteLine "done" + return 0 } + +let TaskBreakpoints1 () = + task { let! res1 = + tf2() + let! res2 = + match 1 with + | 1 -> tf2() + | _ -> tf2() + let! res3 = + match 1 with + | 1 -> + let x = + match 4 with + | 2 -> tf2() + | _ -> tf2() + tf2() + | _ -> + let x = + match 4 with + | 2 -> tf2() + | _ -> tf2() + tf2() + return () } + +module InlinedCode = + // NOTE: you can't place breakpoints in this method and hit them in either Debug and Release code + let inline bodyRunner z body = + let x = 1 + z + printfn "running" + body x + body x + + let test() = + let bodyWrapper = + let x = 1 + System.Random().Next() + bodyRunner 3 (fun n -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + printfn "line1, x = %d" x + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + printfn "line2, n = %d" n) + + let bodyWrapper2 = + // TEST: check you can place breakpoint here and hit it in both Debug and Release code + let x = 1 + System.Random().Next() + bodyRunner 3 <| (fun n -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + printfn "line1, x = %d" x + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + printfn "line2, n = %d" n) + () + +module Pipelined = + let testListPipeline() = + let data = [ 1 .. 5 ] + + // MANUAL TEST: check stepping through this looks ok + let newData = + data + |> List.filter (fun x -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + x > 3) + |> List.map (fun x -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + x * x) + + printfn "%A" newData + + let testArrayPipeline() = + let data = [| 1 .. 5 |] + + let newData = + data + |> Array.filter (fun x -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + x > 3) + |> Array.map (fun x -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug code + // TODO: surprisingly no breakpoint hit here in release code + x * x) + + printfn "%A" newData + +TailcallRecursionTest1 2 +TailcallRecursionTest2 (U2(2,3)) +SteppingMatch01 (Choice2Of2 3) +SteppingMatch01 (Choice1Of2 3) +SteppingMatch03 (Choice1Of2 3) +SteppingMatch03 (Choice2Of2 "3") +SteppingMatch03b (Choice1Of3 3) +SteppingMatch03b (Choice2Of3 "3") +SteppingMatch03b (Choice3Of3 5.0) +SteppingMatch04 (Choice2Of3 "3") +SteppingMatch04 (Choice3Of3 5.0) +SteppingMatch04 (Choice1Of3 3) +SteppingMatch05 (Choice3Of3 5.0) +SteppingMatch05 (Choice2Of3 "3") +SteppingMatch05 (Choice1Of3 3) +SteppingMatch06 CaseB +SteppingMatch06 CaseA +SteppingMatch07 CaseA +SteppingMatch07 CaseB +SteppingMatch08 0 +SteppingMatch08 1 +SteppingMatch09 1 +SteppingMatch09 2 +SteppingMatch09 3 + +OuterWithGenericInner [1;2;3;4;5;6] +OuterWithNonGenericInner [1;2;3;4;5;6] +OuterWithNonGenericInnerWithCapture 5 [1;2;3;4;5;6] +TestFunction1() +TestFunction2() +TestFunction3() +TestFunction4() +TestFunction5() +TestFunction6() +TestFunction7() +TestFunction8 3 +TestFunction8 4 +TestFunction9 3 +TestFunction9 4 +TestFunction9 5 +TestFunction10 (5,4) +TestFunction11 5 +TestFunction12 5 +TestFunction13 5 +TestFunction14 () +TestFunction15 3 +TestFunction16 3 +TestFunction17 3 +TestFunction18 3 +TestFunction19 3 +TestFunction21(U2(3,4)) +TestFunction22() +TestFunction9b [1;2] +TestFunction9b [3;4] +TestFunction9b [3;1] +TestFunction9b [3] + +AsyncExpressionSteppingTest1() |> Async.RunSynchronously +AsyncExpressionSteppingTest2() |> Async.RunSynchronously +AsyncExpressionSteppingTest3() |> Async.RunSynchronously +AsyncExpressionSteppingTest4() |> Async.RunSynchronously +AsyncExpressionSteppingTest5() |> Async.RunSynchronously +AsyncExpressionSteppingTest6b() |> Async.RunSynchronously +AsyncBreakpoints1() |> Async.RunSynchronously +ListExpressionSteppingTest1() +ListExpressionSteppingTest2() +ListExpressionSteppingTest3() +ListExpressionSteppingTest4() +ListExpressionSteppingTest5() +ListExpressionSteppingTest6() +ListExpressionSteppingTest7() +ListExpressionSteppingTest8() +SeqExpressionSteppingTest1()|> Seq.length +SeqExpressionSteppingTest2()|> Seq.length +SeqExpressionSteppingTest3()|> Seq.length +SeqExpressionSteppingTest4()|> Seq.length +SeqExpressionSteppingTest5()|> Seq.length +SeqExpressionSteppingTest6() |> Seq.length +InnerRecursiveFunction "cajcek" |> ignore +InnerFunctionDefinitionHadTwoBreakpoints "aaaa" |> ignore +InnerRecursiveFunctionDefinitionHadTwoBreakpoints "aaaa" |> ignore +LocalValueShadowsArgument1 "123" +LocalValueShadowsArgument2 "123" + +module Task = + let RunSynchronously (t: System.Threading.Tasks.Task<_>) = t.Wait(); t.Result + +TaskExpressionSteppingTest0() |> Task.RunSynchronously +TaskExpressionSteppingTest1() |> Task.RunSynchronously +TaskExpressionSteppingTest2() |> Task.RunSynchronously +TaskExpressionSteppingTest3() |> Task.RunSynchronously +TaskExpressionSteppingTest4() |> Task.RunSynchronously +TaskExpressionSteppingTest5() |> Task.RunSynchronously +TaskExpressionSteppingTest6b() |> Task.RunSynchronously +TaskExpressionSteppingTest7a() |> Task.RunSynchronously +TaskExpressionSteppingTest7b() |> Task.RunSynchronously +TaskBreakpoints1() |> Task.RunSynchronously +InlinedCode.test() +Pipelined.testListPipeline() +Pipelined.testArrayPipeline() + +module BooleanLogic = + + let testFunctionWithAnd x y = + x && y + + let testFunctionWithOr x y = + x || y + + let testFunctionWithMultipleAnd x y z = + x && y && z + + let testFunctionWithMultipleOr x y z = + x || y || z + + let testFunctionWithIfOfAnd x y = + if x && y then + 1 + else + 2 + + let testFunctionWithIfOfOr x y = + if x || y then + 1 + else + 2 + + testFunctionWithAnd true false + testFunctionWithMultipleAnd true true false + testFunctionWithMultipleOr false false true + testFunctionWithOr true false + testFunctionWithIfOfAnd true false + testFunctionWithIfOfOr false false + +// See https://github.com/dotnet/fsharp/issues/11977 +module FalseSteppingBug = + type U = + | A1 of int + | A2 of int + | A3 of int + | A4 of int + + let testFunc f u = + match u with + | A1 n -> f n + | A2 n when n > 4 -> f n // this was falsely hit + | A2 n -> f n + | A3 n -> f n + | A4 n -> f n + + testFunc id (A3 4) + + + +// https://github.com/dotnet/fsharp/pull/11981 +module MissingFirstTry = + let TestFunction3() = + try + let x = 1+1 + System.Console.WriteLine "Hello"; + with _ -> + System.Console.WriteLine "World" + + TestFunction3() + + +// https://github.com/dotnet/fsharp/issues/11979 +// +// Check debug points exist for 'when' +module DebuggingSteppingForMatchWithWhen1 = + + let TestMatchWithWhen x y = + match x with + | [_] when y > 4 -> 5 + | [_] when y < 4 -> -5 + | _ -> 2 + + + TestMatchWithWhen [1] 3 + TestMatchWithWhen [1] 4 + TestMatchWithWhen [1] 5 + TestMatchWithWhen [1] 6 + + +// https://github.com/dotnet/fsharp/issues/11979 +// +// Check debug points exist for 'when' +module DebuggingSteppingForMatchWithWhenWithVariableBinding = + + let TestMatchWithWhen x = + match x with + | [x] when x > 4 -> 5 + | [x] when x < 4 -> -5 + | _ -> 2 + + + TestMatchWithWhen [4] + TestMatchWithWhen [5] + TestMatchWithWhen [6] + +// https://github.com/dotnet/fsharp/issues/11979 +// +// Check debug points exist for 'when' +module DebuggingSteppingForMatchWithWhenWithUnionClauses= + + let TestMatchWithWhen x = + match x with + | [_;x] + | [x] when x < 4 -> -5 + | _ -> 2 + + + TestMatchWithWhen [4;5] + TestMatchWithWhen [5;4] + TestMatchWithWhen [6] + +module NestedScopesWithShadowing = + + let f2 (a, b) = + let v1 = 1 + if a then + let v2 = 1.4 + if b then + let v1 = "3" + let v2 = 5 + v1 + else + let v1 = "3" + let v2 = 5 + v1 + else + let v2 = 1.4 + if b then + let v1 = "3" + let v2 = 5 + v1 + else + let v1 = "3" + let v2 = 5 + v1 + + + f2 (true, true) + f2 (true, false) + f2 (false, true) + f2 (false, false) + +module ForLoopRegularCode = + let testSimpleForEachSeqLoopWithOneStatement inp = + for x in inp do + printfn $"hello, x = {x}" + + let testSimpleForEachSeqLoopWithTwoStatements inp = + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachArrayLoopWithOneStatement (inp:int array) = + for x in inp do + printfn $"hello, x = {x}" + + let testSimpleForEachArrayLoopWithTwoStatements (inp:int array) = + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachListLoopWithOneStatement (inp:int list) = + for x in inp do + printfn $"hello, x = {x}" + + let testSimpleForEachListLoopWithTwoStatements (inp:int list) = + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachStringLoopWithOneStatement (inp:string) = + for x in inp do + printfn $"hello, x = {x}" + + let testSimpleForEachStringLoopWithTwoStatements (inp:string) = + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachIntRangeLoopWithOneStatement (start, stop) = + for x in start .. stop do + printfn $"hello, x = {x}" + + let testSimpleForEachIntRangeLoopWithTwoStatements (start, stop) = + for x in start .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachIntRangeLoopDownWithOneStatement (start, stop) = + for x in stop .. -1 .. start do + printfn $"hello, x = {x}" + + let testSimpleForEachIntRangeLoopDownWithTwoStatements (start, stop) = + for x in stop .. -1 .. start do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachIntRangeStepLoopWithOneStatement (start, step, stop) = + for x in start .. step .. stop do + printfn $"hello, x = {x}" + + let testSimpleForEachIntRangeStepLoopWithTwoStatements (start, step, stop) = + for x in start .. step .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachInt64RangeLoopWithOneStatement (start: int64, stop) = + for x in start .. stop do + printfn $"hello, x = {x}" + + let testSimpleForEachInt64RangeLoopWithTwoStatements (start: int64, stop) = + for x in start .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachInt64RangeLoopDownWithOneStatement (start: int64, stop) = + for x in start .. -1L .. stop do + printfn $"hello, x = {x}" + + let testSimpleForEachInt64RangeLoopDownWithTwoStatements (start: int64, stop) = + for x in start .. -1L .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachInt64RangeStepLoopWithOneStatement (start: int64, step, stop) = + for x in start .. step .. stop do + printfn $"hello, x = {x}" + + let testSimpleForEachInt64RangeStepLoopWithTwoStatements (start: int64, step, stop) = + for x in start .. step .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachInt64RangeStepLoopWithConstCount () = + for x in 1L .. 3L .. 9L do + printfn $"hello, x = {x}" + + let testSimpleForEachIntLoopWithOneStatement (start, stop) = + for x = start to stop do + printfn $"hello, x = {x}" + + let testSimpleForEachIntLoopWithTwoStatements (start, stop) = + for x = start to stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + let testSimpleForEachIntLoopDownWithOneStatement (start, stop) = + for x = stop downto start do + printfn $"hello, x = {x}" + + let testSimpleForEachIntLoopDownWithTwoStatements (start, stop) = + for x = stop downto start do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + + testSimpleForEachSeqLoopWithOneStatement [1;2;3] + testSimpleForEachSeqLoopWithTwoStatements [1;2;3] + testSimpleForEachArrayLoopWithOneStatement [|1;2;3|] + testSimpleForEachArrayLoopWithTwoStatements [|1;2;3|] + testSimpleForEachListLoopWithOneStatement [1;2;3] + testSimpleForEachListLoopWithTwoStatements [1;2;3] + testSimpleForEachStringLoopWithOneStatement "123" + testSimpleForEachStringLoopWithTwoStatements "123" + testSimpleForEachIntRangeLoopWithOneStatement (1, 3) + testSimpleForEachIntRangeLoopWithTwoStatements (1, 3) + testSimpleForEachIntRangeLoopDownWithOneStatement (1, 3) + testSimpleForEachIntRangeLoopDownWithTwoStatements (1, 3) + + testSimpleForEachIntRangeStepLoopWithOneStatement (-1, 5, 10) + testSimpleForEachIntRangeStepLoopWithTwoStatements (-1, 5, 10) + testSimpleForEachInt64RangeLoopWithOneStatement (3L, 7L) + testSimpleForEachInt64RangeLoopWithTwoStatements (-4L, 0L) + testSimpleForEachInt64RangeLoopDownWithOneStatement (3L, -1L) + testSimpleForEachInt64RangeLoopDownWithTwoStatements (3L, -1L) + testSimpleForEachInt64RangeStepLoopWithOneStatement (0L, 2L, 5L) + testSimpleForEachInt64RangeStepLoopWithTwoStatements (0L, 2L, 5L) + testSimpleForEachInt64RangeStepLoopWithConstCount () + + testSimpleForEachIntLoopWithOneStatement (1, 3) + testSimpleForEachIntLoopWithTwoStatements (1, 3) + testSimpleForEachIntLoopDownWithOneStatement (1, 3) + testSimpleForEachIntLoopDownWithTwoStatements (1, 3) + +#if NETCOREAPP + let testSimpleForEachReadOnlySpanLoopWithOneStatement (inp: System.ReadOnlySpan) = + [ for x in inp do + printfn $"hello, x = {x}" ] + + let testSimpleForEachSpanLoopWithOneStatement (inp: System.Span) = + for x in inp do + printfn $"hello, x = {x}" + + testSimpleForEachReadOnlySpanLoopWithOneStatement ("abc".AsSpan()) + testSimpleForEachSpanLoopWithOneStatement ([|'a'..'c'|].AsSpan()) +#endif + +module ForLoopInGeneratedList = + let testSimpleListEachSeqLoopWithOneStatement inp = + [ for x in inp do + yield x+1 ] + + let testSimpleListEachSeqLoopWithTwoStatements inp = + [ for x in inp do + printfn $"hello, x = {x}" + yield x + 1 ] + + let testSimpleListEachArrayLoopWithOneStatement (inp:int array) = + [ for x in inp do + yield x + 1 ] + + let testSimpleListEachArrayLoopWithTwoStatements (inp:int array) = + [ for x in inp do + printfn $"hello, x = {x}" + yield x + 1 ] + + let testSimpleListEachListLoopWithOneStatement (inp:int list) = + [ for x in inp do + yield x + 1 ] + + let testSimpleListEachListLoopWithInitialLetBindings f g (inp:int list) = + [ let y = f () + let z = g () + for x in inp do + printfn $"hello, x = {x}" + yield x + y + z ] + + let testSimpleListEachListLoopWithInitialSequentialExpression f g (inp:int list) = + [ f () + g () + for x in inp do + printfn $"hello, x = {x}" + yield x + 1 ] + + let testSimpleListEachListLoopWithTwoStatements (inp:int list) = + [ for x in inp do + printfn $"hello, x = {x}" + yield x + 1 ] + + let testSimpleListEachStringLoopWithOneStatement (inp:string) = + [ for x in inp do + yield x ] + + let testSimpleListEachStringLoopWithTwoStatements (inp:string) = + [ for x in inp do + printfn $"hello, x = {x}" + yield x ] + + let testSimpleListEachIntRangeLoopWithOneStatement (start, stop) = + [ for x in start .. stop do + yield x + 1 ] + + let testSimpleListEachIntRangeLoopWithInitialLetBindings f g (start, stop) = + [ let y = f () + let z = g () + for x in start .. stop do + printfn $"hello, x = {x}" + yield x + y + z ] + + let testSimpleListEachIntRangeLoopWithInitialSequentialExpression f g (start, stop) = + [ f () + g () + for x in start .. stop do + yield x + 1 ] + + let testSimpleListEachIntRangeLoopWithTwoStatements (start, stop) = + [ for x in start .. stop do + printfn $"hello, x = {x}" + yield x + 1 ] + + let testSimpleListEachIntRangeLoopDownWithOneStatement (start, stop) = + [ for x in stop .. -1 .. start do + yield x + 1 ] + + let testSimpleListEachIntRangeLoopDownWithTwoStatements (start, stop) = + [ for x in stop .. -1 .. stop do + printfn $"hello, x = {x}" + yield x + 1 ] + + let testSimpleListEachIntLoopWithOneStatement (start, stop) = + [ for x = start to stop do + yield x + 1 ] + + let testSimpleListEachIntLoopWithTwoStatements (start, stop) = + [ for x = start to stop do + printfn $"hello, x = {x}" + yield x + 1 ] + + let testSimpleListEachIntLoopDownWithOneStatement (start, stop) = + [ for x = stop downto start do + yield x + 1 ] + + let testSimpleListEachIntLoopDownWithTwoStatements (start, stop) = + [ for x = stop downto start do + printfn $"hello, x = {x}" + yield x + 1 ] + + testSimpleListEachSeqLoopWithOneStatement [1;2;3] + testSimpleListEachSeqLoopWithTwoStatements [1;2;3] + testSimpleListEachArrayLoopWithOneStatement [|1;2;3|] + testSimpleListEachArrayLoopWithTwoStatements [|1;2;3|] + testSimpleListEachListLoopWithOneStatement [1;2;3] + testSimpleListEachListLoopWithInitialLetBindings (fun () -> 7) (fun () -> 8) [1;2;3] + testSimpleListEachListLoopWithInitialSequentialExpression (fun () -> printfn "7") (fun () -> printfn "8") [1;2;3] + testSimpleListEachListLoopWithTwoStatements [1;2;3] + testSimpleListEachStringLoopWithOneStatement "123" + testSimpleListEachStringLoopWithTwoStatements "123" + testSimpleListEachIntRangeLoopWithOneStatement (1, 3) + testSimpleListEachIntRangeLoopWithInitialLetBindings (fun () -> 7) (fun () -> 8) (1, 3) + testSimpleListEachIntRangeLoopWithInitialSequentialExpression (fun () -> printfn "7") (fun () -> printfn "8") (1, 3) + testSimpleListEachIntRangeLoopWithTwoStatements (1, 3) + testSimpleListEachIntRangeLoopDownWithOneStatement (1, 3) + testSimpleListEachIntRangeLoopDownWithTwoStatements (1, 3) + testSimpleListEachIntLoopWithOneStatement (1, 3) + testSimpleListEachIntLoopWithTwoStatements (1, 3) + testSimpleListEachIntLoopDownWithOneStatement (1, 3) + testSimpleListEachIntLoopDownWithTwoStatements (1, 3) + +module ForLoopInGeneratedArray = + let testSimpleArrayEachSeqLoopWithOneStatement inp = + [| for x in inp do + yield x+1 |] + + let testSimpleArrayEachSeqLoopWithTwoStatements inp = + [| for x in inp do + printfn $"hello, x = {x}" + yield x + 1 |] + + let testSimpleArrayEachArrayLoopWithOneStatement (inp:int array) = + [| for x in inp do + yield x + 1 |] + + let testSimpleArrayEachArrayLoopWithTwoStatements (inp:int array) = + [| for x in inp do + printfn $"hello, x = {x}" + yield x + 1 |] + + let testSimpleArrayEachListLoopWithOneStatement (inp:int list) = + [| for x in inp do + yield x + 1 |] + + let testSimpleArrayEachListLoopWithInitialLetBindings f g (inp:int array) = + [| let y = f () + let z = g () + for x in inp do + printfn $"hello, x = {x}" + yield x + y + z |] + + let testSimpleArrayEachListLoopWithInitialSequentialExpression f g (inp:int array) = + [| f () + g () + for x in inp do + printfn $"hello, x = {x}" + yield x + 1 |] + + let testSimpleArrayEachListLoopWithTwoStatements (inp:int list) = + [| for x in inp do + printfn $"hello, x = {x}" + yield x + 1 |] + + let testSimpleArrayEachStringLoopWithOneStatement (inp:string) = + [| for x in inp do + yield x |] + + let testSimpleArrayEachStringLoopWithTwoStatements (inp:string) = + [| for x in inp do + printfn $"hello, x = {x}" + yield x |] + + let testSimpleArrayEachIntRangeLoopWithOneStatement (start, stop) = + [| for x in start .. stop do + yield x + 1 |] + + let testSimpleArrayEachIntRangeLoopWithInitialLetBindings f g (start, stop) = + [| let y = f () + let z = g () + for x in start .. stop do + printfn $"hello, x = {x}" + yield x + y + z |] + + let testSimpleArrayEachIntRangeLoopWithInitialSequentialExpression f g (start, stop) = + [| f () + g () + for x in start .. stop do + yield x + 1 |] + + let testSimpleArrayEachIntRangeLoopWithTwoStatements (start, stop) = + [| for x in start .. stop do + printfn $"hello, x = {x}" + yield x + 1 |] + + let testSimpleArrayEachIntRangeLoopDownWithOneStatement (start, stop) = + [| for x in stop .. -1 .. start do + yield x + 1 |] + + let testSimpleArrayEachIntRangeLoopDownWithTwoStatements (start, stop) = + [| for x in stop .. -1 .. stop do + printfn $"hello, x = {x}" + yield x + 1 |] + + let testSimpleArrayEachIntLoopWithOneStatement (start, stop) = + [| for x = start to stop do + yield x + 1 |] + + let testSimpleArrayEachIntLoopWithTwoStatements (start, stop) = + [| for x = start to stop do + printfn $"hello, x = {x}" + yield x + 1 |] + + let testSimpleArrayEachIntLoopDownWithOneStatement (start, stop) = + [| for x = stop downto start do + yield x + 1 |] + + let testSimpleArrayEachIntLoopDownWithTwoStatements (start, stop) = + [| for x = stop downto start do + printfn $"hello, x = {x}" + yield x + 1 |] + + testSimpleArrayEachSeqLoopWithOneStatement [1;2;3] + testSimpleArrayEachSeqLoopWithTwoStatements [1;2;3] + testSimpleArrayEachArrayLoopWithOneStatement [|1;2;3|] + testSimpleArrayEachArrayLoopWithTwoStatements [|1;2;3|] + testSimpleArrayEachListLoopWithOneStatement [1;2;3] + testSimpleArrayEachListLoopWithInitialLetBindings (fun () -> 7) (fun () -> 8) [|1;2;3|] + testSimpleArrayEachListLoopWithInitialSequentialExpression (fun () -> printfn "7") (fun () -> printfn "8") [|1;2;3|] + testSimpleArrayEachListLoopWithTwoStatements [1;2;3] + testSimpleArrayEachStringLoopWithOneStatement "123" + testSimpleArrayEachStringLoopWithTwoStatements "123" + testSimpleArrayEachIntRangeLoopWithOneStatement (1, 3) + testSimpleArrayEachIntRangeLoopWithInitialLetBindings (fun () -> 7) (fun () -> 8) (1, 3) + testSimpleArrayEachIntRangeLoopWithInitialSequentialExpression (fun () -> printfn "7") (fun () -> printfn "8") (1, 3) + testSimpleArrayEachIntRangeLoopWithTwoStatements (1, 3) + testSimpleArrayEachIntRangeLoopDownWithOneStatement (1, 3) + testSimpleArrayEachIntRangeLoopDownWithTwoStatements (1, 3) + testSimpleArrayEachIntLoopWithOneStatement (1, 3) + testSimpleArrayEachIntLoopWithTwoStatements (1, 3) + testSimpleArrayEachIntLoopDownWithOneStatement (1, 3) + testSimpleArrayEachIntLoopDownWithTwoStatements (1, 3) + +#if NETCOREAPP + let testSimpleListEachReadOnlySpanLoopWithOneStatement (inp: System.ReadOnlySpan) = + [ for x in inp do + printfn $"hello, x = {x}" + yield x + 1 ] + + let testSimpleListEachSpanLoopWithOneStatement (inp: System.Span) = + [ for x in inp do + printfn $"hello, x = {x}" + yield x + 1 ] + + testSimpleListEachReadOnlySpanLoopWithOneStatement ("abc".AsSpan()) + testSimpleListEachSpanLoopWithOneStatement ([|'a'..'c'|].AsSpan()) +#endif + +module ForLoopTaskCode = + let testSimpleTaskEachSeqLoopWithOneStatement inp = + task { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachSeqLoopWithTwoStatements inp = + task { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + + let testSimpleTaskEachArrayLoopWithOneStatement (inp:int array) = + task { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachArrayLoopWithTwoStatements (inp:int array) = + task { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachListLoopWithOneStatement (inp:int list) = + task { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachListLoopWithTwoStatements (inp:int list) = + task { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachStringLoopWithOneStatement (inp:string) = + task { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachStringLoopWithTwoStatements (inp:string) = + task { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachIntRangeLoopWithOneStatement (start, stop) = + task { + for x in start .. stop do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachIntRangeLoopWithTwoStatements (start, stop) = + task { + for x in start .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachIntRangeLoopDownWithOneStatement (start, stop) = + task { + for x in stop .. -1 .. start do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachIntRangeLoopDownWithTwoStatements (start, stop) = + task { + for x in stop .. -1 .. start do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachIntLoopWithOneStatement (start, stop) = + task { + for x = start to stop do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachIntLoopWithTwoStatements (start, stop) = + task { + for x = start to stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachIntLoopDownWithOneStatement (start, stop) = + task { + for x = stop downto start do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachIntLoopDownWithTwoStatements (start, stop) = + task { + for x = stop downto start do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + testSimpleTaskEachSeqLoopWithOneStatement [1;2;3] |> fun t -> t.Result + testSimpleTaskEachSeqLoopWithTwoStatements [1;2;3] |> fun t -> t.Result + testSimpleTaskEachArrayLoopWithOneStatement [|1;2;3|] |> fun t -> t.Result + testSimpleTaskEachArrayLoopWithTwoStatements [|1;2;3|] |> fun t -> t.Result + testSimpleTaskEachListLoopWithOneStatement [1;2;3] |> fun t -> t.Result + testSimpleTaskEachListLoopWithTwoStatements [1;2;3] |> fun t -> t.Result + testSimpleTaskEachStringLoopWithOneStatement "123" |> fun t -> t.Result + testSimpleTaskEachStringLoopWithTwoStatements "123" |> fun t -> t.Result + testSimpleTaskEachIntRangeLoopWithOneStatement (1, 3) |> fun t -> t.Result + testSimpleTaskEachIntRangeLoopWithTwoStatements (1, 3) |> fun t -> t.Result + testSimpleTaskEachIntRangeLoopDownWithOneStatement (1, 3) |> fun t -> t.Result + testSimpleTaskEachIntRangeLoopDownWithTwoStatements (1, 3) |> fun t -> t.Result + testSimpleTaskEachIntLoopWithOneStatement (1, 3) |> fun t -> t.Result + testSimpleTaskEachIntLoopWithTwoStatements (1, 3) |> fun t -> t.Result + testSimpleTaskEachIntLoopDownWithOneStatement (1, 3) |> fun t -> t.Result + testSimpleTaskEachIntLoopDownWithTwoStatements (1, 3) |> fun t -> t.Result + +#if NETCOREAPP + let testSimpleTaskEachReadOnlySpanLoopWithOneStatement (inp: System.ReadOnlySpan) = + task { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleTaskEachSpanLoopWithOneStatement (inp: System.Span) = + task { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + testSimpleTaskEachReadOnlySpanLoopWithOneStatement ("abc".AsSpan()) |> fun t -> t.Result + testSimpleTaskEachSpanLoopWithOneStatement ([|'a'..'c'|].AsSpan()) |> fun t -> t.Result +#endif + + +module ForLoopSeqCode = + let testSimpleSeqEachSeqLoopWithOneStatement inp = + seq { + for x in inp do + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachSeqLoopWithTwoStatements inp = + seq { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachArrayLoopWithOneStatement (inp:int array) = + seq { + for x in inp do + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachArrayLoopWithTwoStatements (inp:int array) = + seq { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachListLoopWithOneStatement (inp:int list) = + seq { + for x in inp do + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachListLoopWithTwoStatements (inp:int list) = + seq { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachStringLoopWithOneStatement (inp:string) = + seq { + for x in inp do + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachStringLoopWithTwoStatements (inp:string) = + seq { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachIntRangeLoopWithOneStatement (start, stop) = + seq { + for x in start .. stop do + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachIntRangeLoopWithTwoStatements (start, stop) = + seq { + for x in start .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachIntRangeLoopDownWithOneStatement (start, stop) = + seq { + for x in stop .. -1 .. start do + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachIntRangeLoopDownWithTwoStatements (start, stop) = + seq { + for x in stop .. -1 .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachIntLoopWithOneStatement (start, stop) = + seq { + for x = start to stop do + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachIntLoopWithTwoStatements (start, stop) = + seq { + for x = start to stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachIntLoopDownWithOneStatement (start, stop) = + seq { + for x = stop downto start do + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachIntLoopDownWithTwoStatements (start, stop) = + seq { + for x = stop downto start do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + yield 1 + } + + testSimpleSeqEachSeqLoopWithOneStatement [1;2;3] |> Seq.toList + testSimpleSeqEachSeqLoopWithTwoStatements [1;2;3] |> Seq.toList + testSimpleSeqEachArrayLoopWithOneStatement [|1;2;3|] |> Seq.toList + testSimpleSeqEachArrayLoopWithTwoStatements [|1;2;3|] |> Seq.toList + testSimpleSeqEachListLoopWithOneStatement [1;2;3] |> Seq.toList + testSimpleSeqEachListLoopWithTwoStatements [1;2;3] |> Seq.toList + testSimpleSeqEachStringLoopWithOneStatement "123" |> Seq.toList + testSimpleSeqEachStringLoopWithTwoStatements "123" |> Seq.toList + testSimpleSeqEachIntRangeLoopWithOneStatement (1, 3) |> Seq.toList + testSimpleSeqEachIntRangeLoopWithTwoStatements (1, 3) |> Seq.toList + testSimpleSeqEachIntRangeLoopDownWithOneStatement (1, 3) |> Seq.toList + testSimpleSeqEachIntRangeLoopDownWithTwoStatements (1, 3) |> Seq.toList + testSimpleSeqEachIntLoopWithOneStatement (1, 3) |> Seq.toList + testSimpleSeqEachIntLoopWithTwoStatements (1, 3) |> Seq.toList + testSimpleSeqEachIntLoopDownWithOneStatement (1, 3) |> Seq.toList + testSimpleSeqEachIntLoopDownWithTwoStatements (1, 3) |> Seq.toList + +#if NETCOREAPP + let testSimpleSeqEachReadOnlySpanLoopWithOneStatement (inp: System.ReadOnlySpan) = + seq { + for x in inp do + printfn $"hello, x = {x}" + yield 1 + } + + let testSimpleSeqEachSpanLoopWithOneStatement (inp: System.Span) = + seq { + for x in inp do + printfn $"hello, x = {x}" + yield 1 + } + + testSimpleSeqEachReadOnlySpanLoopWithOneStatement ("abc".AsSpan()) + testSimpleSeqEachSpanLoopWithOneStatement ([|'a'..'c'|].AsSpan()) +#endif + +module ForLoopAsyncCode = + let testSimpleAsyncEachSeqLoopWithOneStatement inp = + async { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachSeqLoopWithTwoStatements inp = + async { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + + let testSimpleAsyncEachArrayLoopWithOneStatement (inp:int array) = + async { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachArrayLoopWithTwoStatements (inp:int array) = + async { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachListLoopWithOneStatement (inp:int list) = + async { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachListLoopWithTwoStatements (inp:int list) = + async { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachStringLoopWithOneStatement (inp:string) = + async { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachStringLoopWithTwoStatements (inp:string) = + async { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachIntRangeLoopWithOneStatement (start, stop) = + async { + for x in start .. stop do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachIntRangeLoopWithTwoStatements (start, stop) = + async { + for x in start .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachIntRangeLoopDownWithOneStatement (start, stop) = + async { + for x in stop .. -1 .. start do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachIntRangeLoopDownWithTwoStatements (start, stop) = + async { + for x in stop .. -1 .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachIntLoopWithOneStatement (start, stop) = + async { + for x = start to stop do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachIntLoopWithTwoStatements (start, stop) = + async { + for x = start to stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachIntLoopDownWithOneStatement (start, stop) = + async { + for x = stop downto start do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachIntLoopDownWithTwoStatements (start, stop) = + async { + for x = stop downto start do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + testSimpleAsyncEachSeqLoopWithOneStatement [1;2;3] |> Async.RunSynchronously + testSimpleAsyncEachSeqLoopWithTwoStatements [1;2;3] |> Async.RunSynchronously + testSimpleAsyncEachArrayLoopWithOneStatement [|1;2;3|] |> Async.RunSynchronously + testSimpleAsyncEachArrayLoopWithTwoStatements [|1;2;3|] |> Async.RunSynchronously + testSimpleAsyncEachListLoopWithOneStatement [1;2;3] |> Async.RunSynchronously + testSimpleAsyncEachListLoopWithTwoStatements [1;2;3] |> Async.RunSynchronously + testSimpleAsyncEachStringLoopWithOneStatement "123" |> Async.RunSynchronously + testSimpleAsyncEachStringLoopWithTwoStatements "123" |> Async.RunSynchronously + testSimpleAsyncEachIntRangeLoopWithOneStatement (1, 3) |> Async.RunSynchronously + testSimpleAsyncEachIntRangeLoopWithTwoStatements (1, 3) |> Async.RunSynchronously + testSimpleAsyncEachIntRangeLoopDownWithOneStatement (1, 3) |> Async.RunSynchronously + testSimpleAsyncEachIntRangeLoopDownWithTwoStatements (1, 3) |> Async.RunSynchronously + testSimpleAsyncEachIntLoopWithOneStatement (1, 3) |> Async.RunSynchronously + testSimpleAsyncEachIntLoopWithTwoStatements (1, 3) |> Async.RunSynchronously + testSimpleAsyncEachIntLoopDownWithOneStatement (1, 3) |> Async.RunSynchronously + testSimpleAsyncEachIntLoopDownWithTwoStatements (1, 3) |> Async.RunSynchronously + +#if NETCOREAPP + let testSimpleAsyncEachReadOnlySpanLoopWithOneStatement (inp: System.ReadOnlySpan) = + async { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleAsyncEachSpanLoopWithOneStatement (inp: System.Span) = + async { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + testSimpleAsyncEachReadOnlySpanLoopWithOneStatement ("abc".AsSpan()) |> Async.RunSynchronously + testSimpleAsyncEachSpanLoopWithOneStatement ([|'a'..'c'|].AsSpan()) |> Async.RunSynchronously +#endif + +//------------------------------------------------------------- + + +[] +type ValueOrCancelled<'TResult> = + | Value of result: 'TResult + | Cancelled of ``exception``: OperationCanceledException + +/// Represents a cancellable computation with explicit representation of a cancelled result. +/// +/// A cancellable computation is passed may be cancelled via a CancellationToken, which is propagated implicitly. +/// If cancellation occurs, it is propagated as data rather than by raising an OperationCanceledException. +//[] +type Cancellable<'TResult> = (*Cancellable of*) (CancellationToken -> ValueOrCancelled<'TResult>) + +module Cancellable = + + /// Run a cancellable computation using the given cancellation token + let run (ct: CancellationToken) (comp : Cancellable<_>) = + if ct.IsCancellationRequested then + ValueOrCancelled.Cancelled (OperationCanceledException ct) + else + comp ct + +(* + /// Bind the result of a cancellable computation + let inline bind f comp1 : Cancellable<_> = + (fun ct -> + match run ct comp1 with + | ValueOrCancelled.Value v1 -> run ct (f v1) + | ValueOrCancelled.Cancelled err1 -> ValueOrCancelled.Cancelled err1) +*) + + /// Return a simple value as the result of a cancellable computation + let inline ret x : Cancellable<_> = (fun _ -> ValueOrCancelled.Value x) + + let one = ret 1 + + /// Run the computation in a mode where it may not be cancelled. The computation never results in a + /// ValueOrCancelled.Cancelled. + let runWithoutCancellation comp = + let res = run CancellationToken.None comp + match res with + | ValueOrCancelled.Cancelled _ -> failwith "unexpected cancellation" + | ValueOrCancelled.Value r -> r + + /// Bind the cancellation token associated with the computation + let token () : Cancellable<_> = (fun ct -> ValueOrCancelled.Value ct) + + /// Represents a canceled computation + let canceled() : Cancellable<_> = (fun ct -> ValueOrCancelled.Cancelled (OperationCanceledException ct)) + +(* + /// Catch exceptions in a computation + let inline catch e : Cancellable<_> = + (fun ct -> + try + match e ct with + | ValueOrCancelled.Value r -> ValueOrCancelled.Value (Choice1Of2 r) + | ValueOrCancelled.Cancelled e -> ValueOrCancelled.Cancelled e + with err -> + ValueOrCancelled.Value (Choice2Of2 err)) + + /// Implement try/finally for a cancellable computation + let inline tryFinally e compensation : Cancellable<_> = + catch e |> bind (fun res -> + compensation() + match res with Choice1Of2 r -> ret r | Choice2Of2 err -> raise err) + + /// Implement try/with for a cancellable computation + let inline tryWith e handler : Cancellable<_> = + catch e |> bind (fun res -> + match res with Choice1Of2 r -> ret r | Choice2Of2 err -> handler err) +*) + +let inline invoke ([] f: Cancellable<'T>) ct = f ct + +type CancellableBuilder() = + + member inline _.Delay ([] f: unit -> Cancellable<'T>) : Cancellable<'T> = + (fun ct -> + let g = f() + invoke g ct) + + member inline _.BindReturn([] comp: Cancellable<'T>, [] f: ('T -> 'U)) : Cancellable<'U> = + (fun ct -> + if ct.IsCancellationRequested then + ValueOrCancelled.Cancelled (OperationCanceledException ct) + else + match comp ct with + | ValueOrCancelled.Value res -> ValueOrCancelled.Value (f res) + | ValueOrCancelled.Cancelled err -> ValueOrCancelled.Cancelled err) + + member inline _.Bind([] comp: Cancellable<'T>, [] f: ('T -> Cancellable<'U>)) : Cancellable<'U> = + (fun ct -> + if ct.IsCancellationRequested then + ValueOrCancelled.Cancelled (OperationCanceledException ct) + else + match comp ct with + | ValueOrCancelled.Value res -> + let comp2 = f res + invoke comp2 ct + | ValueOrCancelled.Cancelled err -> ValueOrCancelled.Cancelled err) + + member inline _.Return v = + (fun _ -> ValueOrCancelled.Value v) + + member inline _.ReturnFrom ([] v: Cancellable<'T>) : Cancellable<'T> = + (fun ct -> v ct) + + member inline _.Combine([] comp1: Cancellable, [] comp2: Cancellable<'T>) : Cancellable<'T> = + (fun ct -> + if ct.IsCancellationRequested then + ValueOrCancelled.Cancelled (OperationCanceledException ct) + else + match comp1 ct with + | ValueOrCancelled.Value () -> comp2 ct + | ValueOrCancelled.Cancelled err -> ValueOrCancelled.Cancelled err) + + member inline _.For(sequence: seq<'T>, [] (f: 'T -> Cancellable<_>)) : Cancellable = + (fun ct -> + use ie = sequence.GetEnumerator() + let mutable fin = false + let mutable res = Unchecked.defaultof<_> + while not fin do + if ie.MoveNext() then + let step = f ie.Current + match invoke step ct with + | ValueOrCancelled.Value () -> () + | ValueOrCancelled.Cancelled err -> + fin <- true + res <- ValueOrCancelled.Cancelled err + else + fin <- true + res <- ValueOrCancelled.Value () + res) + +(* + member (* inline *) _.TryWith(e, handler) = Cancellable.tryWith e handler + + member (* inline *) _.Using(resource, e) = Cancellable.tryFinally (e resource) (fun () -> (resource :> IDisposable).Dispose()) + + member (* inline *) _.TryFinally(e, compensation) = Cancellable.tryFinally e compensation + +*) + member inline _.Zero() : Cancellable = + (fun _ -> ValueOrCancelled.Value ()) + +[] +module CancellableAutoOpens = + let cancellable = CancellableBuilder() + +// 1. Internal delayed type must be a function to flatten the code with InlineIfLambda +// 1. Bind and BindReturn methods must be inlined to flatten the code + +module CancellableBasicTests = + let test0() = + cancellable.Delay (fun () -> + cancellable.Return(0xABBA)) + + test0() |> Cancellable.runWithoutCancellation + + let test1() = + cancellable { + return 12345 + } + + test1() |> Cancellable.runWithoutCancellation + + let test2() = + cancellable { + printfn "hello" + return 12345 + } + + test2() |> Cancellable.runWithoutCancellation + + let testLetBinding() = + cancellable { + let x = 1 + return 12345 + x + } + + testLetBinding() |> Cancellable.runWithoutCancellation + + let testLetFunctionBinding() = + cancellable { + let f () = 1 + return 12345 + f() + } + + testLetFunctionBinding() |> Cancellable.runWithoutCancellation + + let testBindReturn1() = + cancellable { + let! one = Cancellable.one + return 12345 + one + } + + testBindReturn1() |> Cancellable.runWithoutCancellation + + let testBindReturn2() = + cancellable { + System.Console.WriteLine() + let! one = Cancellable.one + return 12345 + one + } + + testBindReturn2() |> Cancellable.runWithoutCancellation + + let testBindReturn3() = + cancellable { + let! one = Cancellable.one + System.Console.WriteLine() + return 12345 + one + } + + testBindReturn3() |> Cancellable.runWithoutCancellation + + let testBind1() = + cancellable { + let! one = Cancellable.one + let! one = Cancellable.one + System.Console.WriteLine() + return 12345 + one + one + } + + testBind1() |> Cancellable.runWithoutCancellation + + +module ForLoopCancellableCode = + let testSimpleCancellableEachSeqLoopWithOneStatement inp = + cancellable { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachSeqLoopWithTwoStatements inp = + cancellable { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + + let testSimpleCancellableEachArrayLoopWithOneStatement (inp:int array) = + cancellable { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachArrayLoopWithTwoStatements (inp:int array) = + cancellable { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachListLoopWithOneStatement (inp:int list) = + cancellable { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachListLoopWithTwoStatements (inp:int list) = + cancellable { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachStringLoopWithOneStatement (inp:string) = + cancellable { + for x in inp do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachStringLoopWithTwoStatements (inp:string) = + cancellable { + for x in inp do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachIntRangeLoopWithOneStatement (start, stop) = + cancellable { + for x in start .. stop do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachIntRangeLoopWithTwoStatements (start, stop) = + cancellable { + for x in start .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachIntRangeLoopDownWithOneStatement (start, stop) = + cancellable { + for x in stop .. -1 .. start do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachIntRangeLoopDownWithTwoStatements (start, stop) = + cancellable { + for x in stop .. -1 .. stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachIntLoopWithOneStatement (start, stop) = + cancellable { + for x = start to stop do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachIntLoopWithTwoStatements (start, stop) = + cancellable { + for x = start to stop do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachIntLoopDownWithOneStatement (start, stop) = + cancellable { + for x = stop downto start do + printfn $"hello, x = {x}" + return 1 + } + + let testSimpleCancellableEachIntLoopDownWithTwoStatements (start, stop) = + cancellable { + for x = stop downto start do + printfn $"hello, x = {x}" + printfn $"hello, x = {x}" + return 1 + } + + testSimpleCancellableEachSeqLoopWithOneStatement [1;2;3] |> Cancellable.runWithoutCancellation + testSimpleCancellableEachSeqLoopWithTwoStatements [1;2;3] |> Cancellable.runWithoutCancellation + testSimpleCancellableEachArrayLoopWithOneStatement [|1;2;3|] |> Cancellable.runWithoutCancellation + testSimpleCancellableEachArrayLoopWithTwoStatements [|1;2;3|] |> Cancellable.runWithoutCancellation + testSimpleCancellableEachListLoopWithOneStatement [1;2;3] |> Cancellable.runWithoutCancellation + testSimpleCancellableEachListLoopWithTwoStatements [1;2;3] |> Cancellable.runWithoutCancellation + testSimpleCancellableEachStringLoopWithOneStatement "123" |> Cancellable.runWithoutCancellation + testSimpleCancellableEachStringLoopWithTwoStatements "123" |> Cancellable.runWithoutCancellation + testSimpleCancellableEachIntRangeLoopWithOneStatement (1, 3) |> Cancellable.runWithoutCancellation + testSimpleCancellableEachIntRangeLoopWithTwoStatements (1, 3) |> Cancellable.runWithoutCancellation + testSimpleCancellableEachIntRangeLoopDownWithOneStatement (1, 3) |> Cancellable.runWithoutCancellation + testSimpleCancellableEachIntRangeLoopDownWithTwoStatements (1, 3) |> Cancellable.runWithoutCancellation + testSimpleCancellableEachIntLoopWithOneStatement (1, 3) |> Cancellable.runWithoutCancellation + testSimpleCancellableEachIntLoopWithTwoStatements (1, 3) |> Cancellable.runWithoutCancellation + testSimpleCancellableEachIntLoopDownWithOneStatement (1, 3) |> Cancellable.runWithoutCancellation + testSimpleCancellableEachIntLoopDownWithTwoStatements (1, 3) |> Cancellable.runWithoutCancellation +