diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index c188b548073..74d633b9f9c 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -245,6 +245,12 @@ type cenv = /// Used to apply forced inlining optimizations to witnesses generated late during codegen mutable optimizeDuringCodeGen: (Expr -> Expr) + + /// What depth are we at when generating an expression? + mutable exprRecursionDepth: int + + /// Delayed Method Generation - prevents stack overflows when we need to generate methods that are split into many methods by the optimizer. + delayedGenMethods: Queue unit> } @@ -2130,20 +2136,53 @@ let DoesGenExprStartWithSequencePoint g sp expr = FirstEmittedCodeWillBeSequencePoint g sp expr || EmitSequencePointForWholeExpr g sp expr +let ProcessSequencePointForExpr (cenv: cenv) (cgbuf: CodeGenBuffer) sp expr = + let g = cenv.g + if not (FirstEmittedCodeWillBeSequencePoint g sp expr) then + if EmitSequencePointForWholeExpr g sp expr then + CG.EmitSeqPoint cgbuf (RangeOfSequencePointForWholeExpr g expr) + elif EmitHiddenCodeMarkerForWholeExpr g sp expr then + cgbuf.EmitStartOfHiddenCode() + //------------------------------------------------------------------------- // Generate expressions //------------------------------------------------------------------------- -let rec GenExpr (cenv: cenv) (cgbuf: CodeGenBuffer) eenv sp expr sequel = +let rec GenExpr cenv cgbuf eenv sp (expr: Expr) sequel = + cenv.exprRecursionDepth <- cenv.exprRecursionDepth + 1 + + if cenv.exprRecursionDepth > 1 then + StackGuard.EnsureSufficientExecutionStack cenv.exprRecursionDepth + GenExprAux cenv cgbuf eenv sp expr sequel + else + GenExprWithStackGuard cenv cgbuf eenv sp expr sequel + + cenv.exprRecursionDepth <- cenv.exprRecursionDepth - 1 + + if cenv.exprRecursionDepth = 0 then + ProcessDelayedGenMethods cenv + +and ProcessDelayedGenMethods cenv = + while cenv.delayedGenMethods.Count > 0 do + let gen = cenv.delayedGenMethods.Dequeue () + gen cenv + +and GenExprWithStackGuard cenv cgbuf eenv sp expr sequel = + assert (cenv.exprRecursionDepth = 1) + try + GenExprAux cenv cgbuf eenv sp expr sequel + assert (cenv.exprRecursionDepth = 1) + with + | :? System.InsufficientExecutionStackException -> + error(InternalError("Expression is too large and/or complex to emit.", expr.Range)) + +and GenExprAux (cenv: cenv) (cgbuf: CodeGenBuffer) eenv sp expr sequel = let g = cenv.g let expr = stripExpr expr - if not (FirstEmittedCodeWillBeSequencePoint g sp expr) then - if EmitSequencePointForWholeExpr g sp expr then - CG.EmitSeqPoint cgbuf (RangeOfSequencePointForWholeExpr g expr) - elif EmitHiddenCodeMarkerForWholeExpr g sp expr then - cgbuf.EmitStartOfHiddenCode() + ProcessSequencePointForExpr cenv cgbuf sp expr + // A sequence expression will always match Expr.App. match (if compileSequenceExpressions then LowerCallsAndSeqs.LowerSeqExpr g cenv.amap expr else None) with | Some info -> GenSequenceExpr cenv cgbuf eenv info sequel @@ -2154,32 +2193,8 @@ let rec GenExpr (cenv: cenv) (cgbuf: CodeGenBuffer) eenv sp expr sequel = GenConstant cenv cgbuf eenv (c, m, ty) sequel | Expr.Match (spBind, exprm, tree, targets, m, ty) -> GenMatch cenv cgbuf eenv (spBind, exprm, tree, targets, m, ty) sequel - | Expr.Sequential (e1, e2, dir, spSeq, m) -> - GenSequential cenv cgbuf eenv sp (e1, e2, dir, spSeq, m) sequel | Expr.LetRec (binds, body, m, _) -> GenLetRec cenv cgbuf eenv (binds, body, m) sequel - | Expr.Let (bind, body, _, _) -> - // This case implemented here to get a guaranteed tailcall - // Make sure we generate the sequence point outside the scope of the variable - let startScope, endScope as scopeMarks = StartDelayedLocalScope "let" cgbuf - let eenv = AllocStorageForBind cenv cgbuf scopeMarks eenv bind - let spBind = GenSequencePointForBind cenv cgbuf bind - GenBindingAfterSequencePoint cenv cgbuf eenv spBind bind (Some startScope) - - // Work out if we need a sequence point for the body. For any "user" binding then the body gets SPAlways. - // For invisible compiler-generated bindings we just use "sp", unless its body is another invisible binding - // For sticky bindings arising from inlining we suppress any immediate sequence point in the body - let spBody = - match bind.SequencePointInfo with - | SequencePointAtBinding _ - | NoSequencePointAtLetBinding - | NoSequencePointAtDoBinding -> SPAlways - | NoSequencePointAtInvisibleBinding -> sp - | NoSequencePointAtStickyBinding -> SPSuppress - - // Generate the body - GenExpr cenv cgbuf eenv spBody body (EndLocalScope(sequel, endScope)) - | Expr.Lambda _ | Expr.TyLambda _ -> GenLambda cenv cgbuf eenv false None expr sequel | Expr.App (Expr.Val (vref, _, m) as v, _, tyargs, [], _) when @@ -2200,8 +2215,10 @@ let rec GenExpr (cenv: cenv) (cgbuf: CodeGenBuffer) eenv sp expr sequel = // Most generation of linear expressions is implemented routinely using tailcalls and the correct sequels. // This is because the element of expansion happens to be the final thing generated in most cases. However // for large lists we have to process the linearity separately + | Expr.Sequential _ + | Expr.Let _ | LinearOpExpr _ -> - GenLinearExpr cenv cgbuf eenv expr sequel id |> ignore + GenLinearExpr cenv cgbuf eenv sp expr sequel (* canProcessSequencePoint *) false id |> ignore | Expr.Op (op, tyargs, args, m) -> match op, args, tyargs with @@ -2515,16 +2532,63 @@ and GenAllocUnionCase cenv cgbuf eenv (c,tyargs,args,m) sequel = GenAllocUnionCaseCore cenv cgbuf eenv (c,tyargs,args.Length,m) GenSequel cenv eenv.cloc cgbuf sequel -and GenLinearExpr cenv cgbuf eenv expr sequel (contf: FakeUnit -> FakeUnit) = - match expr with - | LinearOpExpr (TOp.UnionCase c, tyargs, argsFront, argLast, m) -> +and GenLinearExpr cenv cgbuf eenv sp expr sequel canProcessSequencePoint (contf: FakeUnit -> FakeUnit) = + match stripExpr expr with + | LinearOpExpr (TOp.UnionCase c, tyargs, argsFront, argLast, m) -> GenExprs cenv cgbuf eenv argsFront - GenLinearExpr cenv cgbuf eenv argLast Continue (contf << (fun Fake -> + GenLinearExpr cenv cgbuf eenv SPSuppress argLast Continue (* canProcessSequencePoint *) true (contf << (fun Fake -> GenAllocUnionCaseCore cenv cgbuf eenv (c, tyargs, argsFront.Length + 1, m) GenSequel cenv eenv.cloc cgbuf sequel Fake)) + + | Expr.Sequential (e1, e2, specialSeqFlag, spSeq, _) -> + if canProcessSequencePoint then + ProcessSequencePointForExpr cenv cgbuf sp expr + + // Compiler generated sequential executions result in suppressions of sequence points on both + // left and right of the sequence + let spAction, spExpr = + (match spSeq with + | SequencePointsAtSeq -> SPAlways, SPAlways + | SuppressSequencePointOnExprOfSequential -> SPSuppress, sp + | SuppressSequencePointOnStmtOfSequential -> sp, SPSuppress) + match specialSeqFlag with + | NormalSeq -> + GenExpr cenv cgbuf eenv spAction e1 discard + GenLinearExpr cenv cgbuf eenv spExpr e2 sequel (* canProcessSequencePoint *) true contf + | ThenDoSeq -> + GenExpr cenv cgbuf eenv spExpr e1 Continue + GenExpr cenv cgbuf eenv spAction e2 discard + GenSequel cenv eenv.cloc cgbuf sequel + contf Fake + + | Expr.Let (bind, body, _, _) -> + if canProcessSequencePoint then + ProcessSequencePointForExpr cenv cgbuf sp expr + + // This case implemented here to get a guaranteed tailcall + // Make sure we generate the sequence point outside the scope of the variable + let startScope, endScope as scopeMarks = StartDelayedLocalScope "let" cgbuf + let eenv = AllocStorageForBind cenv cgbuf scopeMarks eenv bind + let spBind = GenSequencePointForBind cenv cgbuf bind + GenBindingAfterSequencePoint cenv cgbuf eenv spBind bind (Some startScope) + + // Work out if we need a sequence point for the body. For any "user" binding then the body gets SPAlways. + // For invisible compiler-generated bindings we just use "sp", unless its body is another invisible binding + // For sticky bindings arising from inlining we suppress any immediate sequence point in the body + let spBody = + match bind.SequencePointInfo with + | SequencePointAtBinding _ + | NoSequencePointAtLetBinding + | NoSequencePointAtDoBinding -> SPAlways + | NoSequencePointAtInvisibleBinding -> sp + | NoSequencePointAtStickyBinding -> SPSuppress + + // Generate the body + GenLinearExpr cenv cgbuf eenv spBody body (EndLocalScope(sequel, endScope)) (* canProcessSequencePoint *) true contf + | _ -> - GenExpr cenv cgbuf eenv SPSuppress expr sequel + GenExpr cenv cgbuf eenv sp expr sequel contf Fake and GenAllocRecd cenv cgbuf eenv ctorInfo (tcref,argtys,args,m) sequel = @@ -3475,28 +3539,6 @@ and GenWhileLoop cenv cgbuf eenv (spWhile, e1, e2, m) sequel = // SEQUENCE POINTS: Emit a sequence point to cover 'done' if present GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel -//-------------------------------------------------------------------------- -// Generate seq -//-------------------------------------------------------------------------- - -and GenSequential cenv cgbuf eenv spIn (e1, e2, specialSeqFlag, spSeq, _m) sequel = - - // Compiler generated sequential executions result in suppressions of sequence points on both - // left and right of the sequence - let spAction, spExpr = - (match spSeq with - | SequencePointsAtSeq -> SPAlways, SPAlways - | SuppressSequencePointOnExprOfSequential -> SPSuppress, spIn - | SuppressSequencePointOnStmtOfSequential -> spIn, SPSuppress) - match specialSeqFlag with - | NormalSeq -> - GenExpr cenv cgbuf eenv spAction e1 discard - GenExpr cenv cgbuf eenv spExpr e2 sequel - | ThenDoSeq -> - GenExpr cenv cgbuf eenv spExpr e1 Continue - GenExpr cenv cgbuf eenv spAction e2 discard - GenSequel cenv eenv.cloc cgbuf sequel - //-------------------------------------------------------------------------- // Generate IL assembly code. // Polymorphic IL/ILX instructions may be instantiated when polymorphic code is inlined. @@ -5210,7 +5252,14 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) s let tps, ctorThisValOpt, baseValOpt, vsl, body', bodyty = IteratedAdjustArityOfLambda g cenv.amap topValInfo rhsExpr let methodVars = List.concat vsl CommitStartScope cgbuf startScopeMarkOpt - GenMethodForBinding cenv cgbuf eenv (vspec, mspec, access, paramInfos, retInfo) (topValInfo, ctorThisValOpt, baseValOpt, tps, methodVars, methodArgTys, body', bodyty) + + let ilxMethInfoArgs = + (vspec, mspec, access, paramInfos, retInfo, topValInfo, ctorThisValOpt, baseValOpt, tps, methodVars, methodArgTys, body', bodyty) + // if we have any expression recursion depth, we should delay the generation of a method to prevent stack overflows + if cenv.exprRecursionDepth > 0 then + DelayGenMethodForBinding cenv cgbuf.mgbuf eenv ilxMethInfoArgs + else + GenMethodForBinding cenv cgbuf.mgbuf eenv ilxMethInfoArgs | StaticProperty (ilGetterMethSpec, optShadowLocal) -> @@ -5649,11 +5698,10 @@ and ComputeMethodImplAttribs cenv (_v: Val) attrs = let hasAggressiveInliningImplFlag = (implflags &&& 0x0100) <> 0x0 hasPreserveSigImplFlag, hasSynchronizedImplFlag, hasNoInliningImplFlag, hasAggressiveInliningImplFlag, attrs -and GenMethodForBinding - cenv cgbuf eenv - (v: Val, mspec, access, paramInfos, retInfo) - (topValInfo, ctorThisValOpt, baseValOpt, tps, methodVars, methodArgTys, body, returnTy) = +and DelayGenMethodForBinding cenv mgbuf eenv ilxMethInfoArgs = + cenv.delayedGenMethods.Enqueue (fun cenv -> GenMethodForBinding cenv mgbuf eenv ilxMethInfoArgs) +and GenMethodForBinding cenv mgbuf eenv (v, mspec, access, paramInfos, retInfo, topValInfo, ctorThisValOpt, baseValOpt, tps, methodVars, methodArgTys, body, returnTy) = let g = cenv.g let m = v.Range let selfMethodVars, nonSelfMethodVars, compileAsInstance = @@ -5714,7 +5762,7 @@ and GenMethodForBinding else body - let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, tailCallInfo, mspec.Name, eenvForMeth, 0, bodyExpr, sequel) + let ilCode = CodeGenMethodForExpr cenv mgbuf (SPAlways, tailCallInfo, mspec.Name, eenvForMeth, 0, bodyExpr, sequel) // This is the main code generation for most methods false, MethodBody.IL ilCode, false @@ -5780,7 +5828,7 @@ and GenMethodForBinding else mdef CountMethodDef() - cgbuf.mgbuf.AddMethodDef(tref, mdef) + mgbuf.AddMethodDef(tref, mdef) match v.MemberInfo with @@ -5817,7 +5865,7 @@ and GenMethodForBinding let mdef = List.fold (fun mdef f -> f mdef) mdef flagFixups // fixup can potentially change name of reflected definition that was already recorded - patch it if necessary - cgbuf.mgbuf.ReplaceNameOfReflectedDefinition(v, mdef.Name) + mgbuf.ReplaceNameOfReflectedDefinition(v, mdef.Name) mdef else mkILGenericNonVirtualMethod (v.CompiledName g.CompilerGlobalState, access, ilMethTypars, ilParams, ilReturn, ilMethodBody) @@ -5844,7 +5892,7 @@ and GenMethodForBinding // Emit the pseudo-property as an event, but not if its a private method impl if mdef.Access <> ILMemberAccess.Private then let edef = GenEventForProperty cenv eenvForMeth mspec v ilAttrsThatGoOnPrimaryItem m returnTy - cgbuf.mgbuf.AddEventDef(tref, edef) + mgbuf.AddEventDef(tref, edef) // The method def is dropped on the floor here else @@ -5854,7 +5902,7 @@ and GenMethodForBinding let ilPropTy = GenType cenv.amap m eenvUnderMethTypeTypars.tyenv vtyp let ilArgTys = v |> ArgInfosOfPropertyVal g |> List.map fst |> GenTypes cenv.amap m eenvUnderMethTypeTypars.tyenv let ilPropDef = GenPropertyForMethodDef compileAsInstance tref mdef v memberInfo ilArgTys ilPropTy (mkILCustomAttrs ilAttrsThatGoOnPrimaryItem) compiledName - cgbuf.mgbuf.AddOrMergePropertyDef(tref, ilPropDef, m) + mgbuf.AddOrMergePropertyDef(tref, ilPropDef, m) // Add the special name flag for all properties let mdef = mdef.WithSpecialName.With(customAttrs= mkILCustomAttrs ((GenAttrs cenv eenv attrsAppliedToGetterOrSetter) @ sourceNameAttribs @ ilAttrsCompilerGenerated)) @@ -7668,7 +7716,9 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: Constrai casApplied = casApplied intraAssemblyInfo = intraAssemblyInfo opts = codeGenOpts - optimizeDuringCodeGen = (fun x -> x) } + optimizeDuringCodeGen = (fun x -> x) + exprRecursionDepth = 0 + delayedGenMethods = Queue () } GenerateCode (cenv, anonTypeTable, ilxGenEnv, typedAssembly, assemAttribs, moduleAttribs) /// Invert the compilation of the given value and clear the storage of the value diff --git a/src/fsharp/lib.fs b/src/fsharp/lib.fs index e7eaf9543fd..dfcbddc2da3 100755 --- a/src/fsharp/lib.fs +++ b/src/fsharp/lib.fs @@ -536,3 +536,14 @@ module UnmanagedProcessExecutionOptions = "HeapSetInformation() returned FALSE; LastError = 0x" + GetLastError().ToString("X").PadLeft(8, '0') + ".")) +[] +module StackGuard = + + open System.Runtime.CompilerServices + + [] + let private MaxUncheckedRecursionDepth = 20 + + let EnsureSufficientExecutionStack recursionDepth = + if recursionDepth > MaxUncheckedRecursionDepth then + RuntimeHelpers.EnsureSufficientExecutionStack () \ No newline at end of file diff --git a/tests/fsharp/Compiler/CompilerAssert.fs b/tests/fsharp/Compiler/CompilerAssert.fs index 37946c40872..90298870f4b 100644 --- a/tests/fsharp/Compiler/CompilerAssert.fs +++ b/tests/fsharp/Compiler/CompilerAssert.fs @@ -11,6 +11,19 @@ open FSharp.Compiler.SourceCodeServices open FSharp.Compiler.Interactive.Shell open NUnit.Framework +open System.Reflection.Emit + +[] +type ILVerifier (dllFilePath: string) = + + member this.VerifyIL (qualifiedItemName: string, expectedIL: string) = + ILChecker.checkILItem qualifiedItemName dllFilePath [ expectedIL ] + + member this.VerifyIL (expectedIL: string list) = + ILChecker.checkIL dllFilePath expectedIL + + member this.VerifyILWithLineNumbers (qualifiedItemName: string, expectedIL: string) = + ILChecker.checkILItemWithLineNumbers qualifiedItemName dllFilePath [ expectedIL ] [] module CompilerAssert = @@ -48,10 +61,45 @@ module CompilerAssert = Stamp = None } - let lockObj = obj () + let private gate = obj () + + let private compile isExe source f = + lock gate <| fun () -> + let inputFilePath = Path.ChangeExtension(Path.GetTempFileName(), ".fs") + let outputFilePath = Path.ChangeExtension (Path.GetTempFileName(), if isExe then ".exe" else ".dll") + let runtimeConfigFilePath = Path.ChangeExtension (outputFilePath, ".runtimeconfig.json") + let fsCoreDllPath = config.FSCOREDLLPATH + let tmpFsCoreFilePath = Path.Combine (Path.GetDirectoryName(outputFilePath), Path.GetFileName(fsCoreDllPath)) + try + File.Copy (fsCoreDllPath , tmpFsCoreFilePath, true) + File.WriteAllText (inputFilePath, source) + File.WriteAllText (runtimeConfigFilePath, """ +{ + "runtimeOptions": { + "tfm": "netcoreapp2.1", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "2.1.0" + } + } +} + """) + + let args = + defaultProjectOptions.OtherOptions + |> Array.append [| "fsc.exe"; inputFilePath; "-o:" + outputFilePath; (if isExe then "--target:exe" else "--target:library"); "--nowin32manifest" |] + let errors, _ = checker.Compile args |> Async.RunSynchronously + + f (errors, outputFilePath) + + finally + try File.Delete inputFilePath with | _ -> () + try File.Delete outputFilePath with | _ -> () + try File.Delete runtimeConfigFilePath with | _ -> () + try File.Delete tmpFsCoreFilePath with | _ -> () let Pass (source: string) = - lock lockObj <| fun () -> + lock gate <| fun () -> let parseResults, fileAnswer = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, defaultProjectOptions) |> Async.RunSynchronously Assert.True(parseResults.Errors.Length = 0, sprintf "Parse errors: %A" parseResults.Errors) @@ -63,7 +111,7 @@ module CompilerAssert = Assert.True(typeCheckResults.Errors.Length = 0, sprintf "Type Check errors: %A" typeCheckResults.Errors) let TypeCheckSingleError (source: string) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) = - lock lockObj <| fun () -> + lock gate <| fun () -> let parseResults, fileAnswer = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, defaultProjectOptions) |> Async.RunSynchronously Assert.True(parseResults.Errors.Length = 0, sprintf "Parse errors: %A" parseResults.Errors) @@ -81,8 +129,46 @@ module CompilerAssert = Assert.AreEqual(expectedErrorMsg, info.Message, "expectedErrorMsg") ) + let CompileExe (source: string) = + compile true source (fun (errors, _) -> + if errors.Length > 0 then + Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors)) + + let CompileExeAndRun (source: string) = + compile true source (fun (errors, outputExe) -> + + if errors.Length > 0 then + Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors) + + let pInfo = ProcessStartInfo () +#if NETCOREAPP + pInfo.FileName <- config.DotNetExe + pInfo.Arguments <- outputExe +#else + pInfo.FileName <- outputExe +#endif + + pInfo.RedirectStandardError <- true + pInfo.UseShellExecute <- false + + let p = Process.Start(pInfo) + + p.WaitForExit() + let errors = p.StandardError.ReadToEnd () + if not (String.IsNullOrWhiteSpace errors) then + Assert.Fail errors + ) + + let CompileLibraryAndVerifyIL (source: string) (f: ILVerifier -> unit) = + compile false source (fun (errors, outputFilePath) -> + if errors.Length > 0 then + Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors) + + f (ILVerifier outputFilePath) + ) + let RunScript (source: string) (expectedErrorMessages: string list) = - lock lockObj <| fun () -> + lock gate <| fun () -> // Intialize output and input streams use inStream = new StringReader("") use outStream = new StringWriter() diff --git a/tests/fsharp/Compiler/ILChecker.fs b/tests/fsharp/Compiler/ILChecker.fs new file mode 100644 index 00000000000..200206f861f --- /dev/null +++ b/tests/fsharp/Compiler/ILChecker.fs @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open System +open System.IO +open System.Diagnostics + +open NUnit.Framework +open TestFramework + +[] +module ILChecker = + + let config = initializeSuite () + + let private exec exe args = + let startInfo = ProcessStartInfo(exe, String.concat " " args) + startInfo.RedirectStandardError <- true + startInfo.UseShellExecute <- false + use p = Process.Start(startInfo) + p.WaitForExit() + p.StandardError.ReadToEnd(), p.ExitCode + + /// Filters i.e ['The system type \'System.ReadOnlySpan`1\' was required but no referenced system DLL contained this type'] + let private filterSpecialComment (text: string) = + let pattern = @"(\[\'(.*?)\'\])" + System.Text.RegularExpressions.Regex.Replace(text, pattern, + (fun me -> String.Empty) + ) + + let private checkILAux ildasmArgs dllFilePath expectedIL = + let ilFilePath = Path.ChangeExtension(dllFilePath, ".il") + + let mutable errorMsgOpt = None + try + let ildasmPath = config.ILDASM + + exec ildasmPath (ildasmArgs @ [ sprintf "%s /out=%s" dllFilePath ilFilePath ]) |> ignore + + let text = File.ReadAllText(ilFilePath) + let blockComments = @"/\*(.*?)\*/" + let lineComments = @"//(.*?)\r?\n" + let strings = @"""((\\[^\n]|[^""\n])*)""" + let verbatimStrings = @"@(""[^""]*"")+" + let textNoComments = + System.Text.RegularExpressions.Regex.Replace(text, + blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings, + (fun me -> + if (me.Value.StartsWith("/*") || me.Value.StartsWith("//")) then + if me.Value.StartsWith("//") then Environment.NewLine else String.Empty + else + me.Value), System.Text.RegularExpressions.RegexOptions.Singleline) + |> filterSpecialComment + + expectedIL + |> List.iter (fun (ilCode: string) -> + let expectedLines = ilCode.Split('\n') + let startIndex = textNoComments.IndexOf(expectedLines.[0]) + if startIndex = -1 || textNoComments.Length < startIndex + ilCode.Length then + errorMsgOpt <- Some("==EXPECTED CONTAINS==\n" + ilCode + "\n") + else + let errors = ResizeArray() + let actualLines = textNoComments.Substring(startIndex, textNoComments.Length - startIndex).Split('\n') + for i = 0 to expectedLines.Length - 1 do + let expected = expectedLines.[i].Trim() + let actual = actualLines.[i].Trim() + if expected <> actual then + errors.Add(sprintf "\n==\nName: %s\n\nExpected:\t %s\nActual:\t\t %s\n==" actualLines.[0] expected actual) + + if errors.Count > 0 then + let msg = String.concat "\n" errors + "\n\n\n==EXPECTED==\n" + ilCode + "\n" + errorMsgOpt <- Some(msg + "\n\n\n==ACTUAL==\n" + String.Join("\n", actualLines, 0, expectedLines.Length)) + ) + + if expectedIL.Length = 0 then + errorMsgOpt <- Some ("No Expected IL") + + match errorMsgOpt with + | Some(msg) -> errorMsgOpt <- Some(msg + "\n\n\n==ENTIRE ACTUAL==\n" + textNoComments) + | _ -> () + finally + try File.Delete(ilFilePath) with | _ -> () + + match errorMsgOpt with + | Some(errorMsg) -> + Assert.Fail(errorMsg) + | _ -> () + + let checkILItem item dllFilePath expectedIL = + checkILAux [ sprintf "/item:%s" item ] dllFilePath expectedIL + + let checkILItemWithLineNumbers item dllFilePath expectedIL = + checkILAux [ sprintf "/item:\"%s\"" item; "/linenum" ] dllFilePath expectedIL + + let checkIL dllFilePath expectedIL = + checkILAux [] dllFilePath expectedIL diff --git a/tests/fsharp/Compiler/ILHelpers.fs b/tests/fsharp/Compiler/ILHelpers.fs deleted file mode 100644 index f31c4fdbbdf..00000000000 --- a/tests/fsharp/Compiler/ILHelpers.fs +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open System -open System.IO -open System.Diagnostics - -open NUnit.Framework - -open FSharp.Compiler.SourceCodeServices - -open TestFramework - -[] -module ILChecker = - - let checker = CompilerAssert.checker - - let config = initializeSuite () - - let private exec exe args = - let startInfo = ProcessStartInfo(exe, String.concat " " args) - startInfo.RedirectStandardError <- true - startInfo.UseShellExecute <- false - use p = Process.Start(startInfo) - p.WaitForExit() - p.StandardError.ReadToEnd(), p.ExitCode - - /// Filters i.e ['The system type \'System.ReadOnlySpan`1\' was required but no referenced system DLL contained this type'] - let private filterSpecialComment (text: string) = - let pattern = @"(\[\'(.*?)\'\])" - System.Text.RegularExpressions.Regex.Replace(text, pattern, - (fun me -> String.Empty) - ) - - let private checkAux extraDlls source expectedIL = - let tmp = Path.GetTempFileName() - let tmpFs = Path.ChangeExtension(tmp, ".fs") - let tmpDll = Path.ChangeExtension(tmp, ".dll") - let tmpIL = Path.ChangeExtension(tmp, ".il") - - let mutable errorMsgOpt = None - try - let ildasmPath = config.ILDASM - - File.WriteAllText(tmpFs, source) - - let extraReferences = extraDlls |> Array.ofList |> Array.map (fun reference -> "-r:" + reference) - -#if NETCOREAPP - // Hack: Currently a hack to get the runtime assemblies for netcore in order to compile. - let runtimeAssemblies = - typeof.Assembly.Location - |> Path.GetDirectoryName - |> Directory.EnumerateFiles - |> Seq.toArray - |> Array.filter (fun x -> x.ToLowerInvariant().Contains("system.")) - |> Array.map (fun x -> sprintf "-r:%s" x) - - let extraReferences = Array.append runtimeAssemblies extraReferences - - let errors, exitCode = checker.Compile(Array.append [| "fsc.exe"; "--optimize+"; "-o"; tmpDll; "-a"; tmpFs; "--targetprofile:netcore"; "--noframework" |] extraReferences) |> Async.RunSynchronously -#else - let errors, exitCode = checker.Compile(Array.append [| "fsc.exe"; "--optimize+"; "-o"; tmpDll; "-a"; tmpFs |] extraReferences) |> Async.RunSynchronously -#endif - let errors = - String.concat "\n" (errors |> Array.map (fun x -> x.Message)) - - if exitCode = 0 then - exec ildasmPath [ sprintf "%s /out=%s" tmpDll tmpIL ] |> ignore - - let text = File.ReadAllText(tmpIL) - let blockComments = @"/\*(.*?)\*/" - let lineComments = @"//(.*?)\r?\n" - let strings = @"""((\\[^\n]|[^""\n])*)""" - let verbatimStrings = @"@(""[^""]*"")+" - let textNoComments = - System.Text.RegularExpressions.Regex.Replace(text, - blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings, - (fun me -> - if (me.Value.StartsWith("/*") || me.Value.StartsWith("//")) then - if me.Value.StartsWith("//") then Environment.NewLine else String.Empty - else - me.Value), System.Text.RegularExpressions.RegexOptions.Singleline) - |> filterSpecialComment - - expectedIL - |> List.iter (fun (ilCode: string) -> - let expectedLines = ilCode.Split('\n') - let startIndex = textNoComments.IndexOf(expectedLines.[0]) - if startIndex = -1 || textNoComments.Length < startIndex + ilCode.Length then - errorMsgOpt <- Some("==EXPECTED CONTAINS==\n" + ilCode + "\n") - else - let errors = ResizeArray() - let actualLines = textNoComments.Substring(startIndex, textNoComments.Length - startIndex).Split('\n') - for i = 0 to expectedLines.Length - 1 do - let expected = expectedLines.[i].Trim() - let actual = actualLines.[i].Trim() - if expected <> actual then - errors.Add(sprintf "\n==\nName: %s\n\nExpected:\t %s\nActual:\t\t %s\n==" actualLines.[0] expected actual) - - if errors.Count > 0 then - let msg = String.concat "\n" errors + "\n\n\n==EXPECTED==\n" + ilCode + "\n" - errorMsgOpt <- Some(msg + "\n\n\n==ACTUAL==\n" + String.Join("\n", actualLines, 0, expectedLines.Length)) - ) - - if expectedIL.Length = 0 then - errorMsgOpt <- Some ("No Expected IL") - - match errorMsgOpt with - | Some(msg) -> errorMsgOpt <- Some(msg + "\n\n\n==ENTIRE ACTUAL==\n" + textNoComments) - | _ -> () - else - errorMsgOpt <- Some(errors) - finally - try File.Delete(tmp) with | _ -> () - try File.Delete(tmpFs) with | _ -> () - try File.Delete(tmpDll) with | _ -> () - try File.Delete(tmpIL) with | _ -> () - - match errorMsgOpt with - | Some(errorMsg) -> - Assert.Fail(errorMsg) - | _ -> () - - let getPackageDlls name version framework dllNames = - dllNames - |> List.map (fun dllName -> - requireFile (packagesDir ++ name ++ version ++ "lib" ++ framework ++ dllName) - ) - - /// Compile the source and check to see if the expected IL exists. - /// The first line of each expected IL string is found first. - let check source expectedIL = - checkAux [] source expectedIL - - let checkWithDlls extraDlls source expectedIL = - checkAux extraDlls source expectedIL - diff --git a/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs b/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs index b6f5ce9d952..efcea68afd3 100644 --- a/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs +++ b/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs @@ -4,7 +4,7 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -#if !NETCOREAPP +#if NETCOREAPP [] module SpanOptimizationTests = @@ -22,24 +22,24 @@ let test () = Console.WriteLine(item) """ - ILChecker.checkWithDlls - (ILChecker.getPackageDlls "System.Memory" "4.5.2" "netstandard2.0" [ "System.Memory.dll" ]) - source - [ - """.method public static void test() cil managed + CompilerAssert.CompileLibraryAndVerifyIL source + (fun verifier -> + verifier.VerifyIL + [ + """.method public static void test() cil managed { .maxstack 5 - .locals init (valuetype [System.Memory]System.Span`1 V_0, + .locals init (valuetype [System.Private.CoreLib]System.Span`1 V_0, int32 V_1, - int32 V_2, - object& V_3) - IL_0000: call valuetype [System.Memory]System.Span`1 valuetype [System.Memory]System.Span`1::get_Empty() + valuetype [System.Private.CoreLib]System.Int32 V_2, + class [System.Private.CoreLib]System.Object& V_3) + IL_0000: call valuetype [System.Private.CoreLib]System.Span`1 valuetype [System.Private.CoreLib]System.Span`1::get_Empty() IL_0005: stloc.0 IL_0006: ldc.i4.0 IL_0007: stloc.2 IL_0008: ldloca.s V_0 - IL_000a: call instance int32 valuetype [System.Memory]System.Span`1::get_Length() + IL_000a: call instance int32 valuetype [System.Private.CoreLib]System.Span`1::get_Length() IL_000f: ldc.i4.1 IL_0010: sub IL_0011: stloc.1 @@ -49,11 +49,11 @@ let test () = IL_0016: ldloca.s V_0 IL_0018: ldloc.2 - IL_0019: call instance !0& valuetype [System.Memory]System.Span`1::get_Item(int32) + IL_0019: call instance !0& valuetype [System.Private.CoreLib]System.Span`1::get_Item(int32) IL_001e: stloc.3 IL_001f: ldloc.3 - IL_0020: ldobj [mscorlib]System.Object - IL_0025: call void [mscorlib]System.Console::WriteLine(object) + IL_0020: ldobj [System.Private.CoreLib]System.Object + IL_0025: call void [System.Console]System.Console::WriteLine(object) IL_002a: ldloc.2 IL_002b: ldc.i4.1 IL_002c: add @@ -66,7 +66,7 @@ let test () = IL_0034: ret } """ - ] + ]) [] let ReadOnlySpanForInDo() = @@ -82,24 +82,24 @@ let test () = Console.WriteLine(item) """ - ILChecker.checkWithDlls - (ILChecker.getPackageDlls "System.Memory" "4.5.2" "netstandard2.0" [ "System.Memory.dll" ]) - source - [ - """.method public static void test() cil managed + CompilerAssert.CompileLibraryAndVerifyIL source + (fun verifier -> + verifier.VerifyIL + [ + """.method public static void test() cil managed { .maxstack 5 - .locals init (valuetype [System.Memory]System.ReadOnlySpan`1 V_0, + .locals init (valuetype [System.Private.CoreLib]System.ReadOnlySpan`1 V_0, int32 V_1, - int32 V_2, - object& V_3) - IL_0000: call valuetype [System.Memory]System.ReadOnlySpan`1 valuetype [System.Memory]System.ReadOnlySpan`1::get_Empty() + valuetype [System.Private.CoreLib]System.Int32 V_2, + class [System.Private.CoreLib]System.Object& V_3) + IL_0000: call valuetype [System.Private.CoreLib]System.ReadOnlySpan`1 valuetype [System.Private.CoreLib]System.ReadOnlySpan`1::get_Empty() IL_0005: stloc.0 IL_0006: ldc.i4.0 IL_0007: stloc.2 IL_0008: ldloca.s V_0 - IL_000a: call instance int32 valuetype [System.Memory]System.ReadOnlySpan`1::get_Length() + IL_000a: call instance int32 valuetype [System.Private.CoreLib]System.ReadOnlySpan`1::get_Length() IL_000f: ldc.i4.1 IL_0010: sub IL_0011: stloc.1 @@ -109,11 +109,11 @@ let test () = IL_0016: ldloca.s V_0 IL_0018: ldloc.2 - IL_0019: call instance !0& modreq([netstandard]System.Runtime.InteropServices.InAttribute) valuetype [System.Memory]System.ReadOnlySpan`1::get_Item(int32) + IL_0019: call instance !0& modreq([System.Private.CoreLib]System.Runtime.InteropServices.InAttribute) valuetype [System.Private.CoreLib]System.ReadOnlySpan`1::get_Item(int32) IL_001e: stloc.3 IL_001f: ldloc.3 - IL_0020: ldobj [mscorlib]System.Object - IL_0025: call void [mscorlib]System.Console::WriteLine(object) + IL_0020: ldobj [System.Private.CoreLib]System.Object + IL_0025: call void [System.Console]System.Console::WriteLine(object) IL_002a: ldloc.2 IL_002b: ldc.i4.1 IL_002c: add @@ -126,7 +126,7 @@ let test () = IL_0034: ret }""" - ] + ]) [] let ExplicitSpanTypeForInDo() = @@ -150,7 +150,7 @@ open System.Runtime.CompilerServices type Span<'T>(arr: 'T []) = member __.Item - with get (i: int) = &arr.[0] + with get (i: int) = &arr.[i] member __.Length with get () = 0 @@ -170,36 +170,36 @@ module Test = """ // The current behavior doesn't optimize, but it could in the future. Making a test to catch if it ever does. - ILChecker.checkWithDlls - (ILChecker.getPackageDlls "System.Memory" "4.5.2" "netstandard2.0" [ "System.Memory.dll" ]) - source - [ - """.method public static void test() cil managed + CompilerAssert.CompileLibraryAndVerifyIL source + (fun verifier -> + verifier.VerifyIL + [ + """.method public static void test() cil managed { .maxstack 3 - .locals init (valuetype System.Span`1 V_0, - class [mscorlib]System.Collections.IEnumerator V_1, + .locals init (valuetype System.Span`1 V_0, + class [System.Private.CoreLib]System.Collections.IEnumerator V_1, class [FSharp.Core]Microsoft.FSharp.Core.Unit V_2, - class [mscorlib]System.IDisposable V_3) + class [System.Private.CoreLib]System.IDisposable V_3) IL_0000: ldc.i4.0 - IL_0001: newarr [mscorlib]System.Object - IL_0006: newobj instance void valuetype System.Span`1::.ctor(!0[]) + IL_0001: newarr [System.Private.CoreLib]System.Object + IL_0006: newobj instance void valuetype System.Span`1::.ctor(!0[]) IL_000b: stloc.0 IL_000c: ldloc.0 - IL_000d: box valuetype System.Span`1 - IL_0012: unbox.any [mscorlib]System.Collections.IEnumerable - IL_0017: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator() + IL_000d: box valuetype System.Span`1 + IL_0012: unbox.any [System.Private.CoreLib]System.Collections.IEnumerable + IL_0017: callvirt instance class [System.Private.CoreLib]System.Collections.IEnumerator [System.Private.CoreLib]System.Collections.IEnumerable::GetEnumerator() IL_001c: stloc.1 .try { IL_001d: ldloc.1 - IL_001e: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_001e: callvirt instance bool [System.Private.CoreLib]System.Collections.IEnumerator::MoveNext() IL_0023: brfalse.s IL_0032 IL_0025: ldloc.1 - IL_0026: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current() - IL_002b: call void [mscorlib]System.Console::WriteLine(object) + IL_0026: callvirt instance object [System.Private.CoreLib]System.Collections.IEnumerator::get_Current() + IL_002b: call void [System.Console]System.Console::WriteLine(object) IL_0030: br.s IL_001d IL_0032: ldnull @@ -210,13 +210,13 @@ module Test = finally { IL_0036: ldloc.1 - IL_0037: isinst [mscorlib]System.IDisposable + IL_0037: isinst [System.Private.CoreLib]System.IDisposable IL_003c: stloc.3 IL_003d: ldloc.3 IL_003e: brfalse.s IL_0049 IL_0040: ldloc.3 - IL_0041: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0041: callvirt instance void [System.Private.CoreLib]System.IDisposable::Dispose() IL_0046: ldnull IL_0047: pop IL_0048: endfinally @@ -228,5 +228,5 @@ module Test = IL_004d: pop IL_004e: ret }""" - ] + ]) #endif diff --git a/tests/fsharp/Compiler/Language/StringConcatOptimizationTests.fs b/tests/fsharp/Compiler/Language/StringConcatOptimizationTests.fs index 494b4f1fe69..37f3ce3c410 100644 --- a/tests/fsharp/Compiler/Language/StringConcatOptimizationTests.fs +++ b/tests/fsharp/Compiler/Language/StringConcatOptimizationTests.fs @@ -833,16 +833,19 @@ let test9 () = test9Source ] let source = String.Join("", sources) - ILChecker.check source - [ - test1IL - test2IL - test3IL - test4IL - test5IL - test6IL - test7IL - test8IL - test9IL - ] + CompilerAssert.CompileLibraryAndVerifyIL source + (fun verifier -> + verifier.VerifyIL + [ + test1IL + test2IL + test3IL + test4IL + test5IL + test6IL + test7IL + test8IL + test9IL + ] + ) #endif \ No newline at end of file diff --git a/tests/fsharp/Compiler/Stress/LargeExprTests.fs b/tests/fsharp/Compiler/Stress/LargeExprTests.fs new file mode 100644 index 00000000000..572c0e53550 --- /dev/null +++ b/tests/fsharp/Compiler/Stress/LargeExprTests.fs @@ -0,0 +1,3550 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module LargeExprTests = + + [] + let LargeRecordDoesNotStackOverflow() = + CompilerAssert.CompileExe + """ +type TestRecord = + { + test1: int + test2: int + test3: int + test4: int + test5: int + test6: int + test7: int + test8: int + test9: int + test10: int + test11: int + test12: int + test13: int + test14: int + test15: int + test16: int + test17: int + test18: int + test19: int + test20: int + test21: int + test22: int + test23: int + test24: int + test25: int + test26: int + test27: int + test28: int + test29: int + test30: int + test31: int + test32: int + test33: int + test34: int + test35: int + test36: int + test37: int + test38: int + test39: int + test40: int + test41: int + test42: int + test43: int + test44: int + test45: int + test46: int + test47: int + test48: int + test49: int + test50: int + test51: int + test52: int + test53: int + test54: int + test55: int + test56: int + test57: int + test58: int + test59: int + test60: int + test61: int + test62: int + test63: int + test64: int + test65: int + test66: int + test67: int + test68: int + test69: int + test70: int + test71: int + test72: int + test73: int + test74: int + test75: int + test76: int + test77: int + test78: int + test79: int + test80: int + test81: int + test82: int + test83: int + test84: int + test85: int + test86: int + test87: int + test88: int + test89: int + test90: int + test91: int + test92: int + test93: int + test94: int + test95: int + test96: int + test97: int + test98: int + test99: int + test100: int + test101: int + test102: int + test103: int + test104: int + test105: int + test106: int + test107: int + test108: int + test109: int + test110: int + test111: int + test112: int + test113: int + test114: int + test115: int + test116: int + test117: int + test118: int + test119: int + test120: int + test121: int + test122: int + test123: int + test124: int + test125: int + test126: int + test127: int + test128: int + test129: int + test130: int + test131: int + test132: int + test133: int + test134: int + test135: int + test136: int + test137: int + test138: int + test139: int + test140: int + test141: int + test142: int + test143: int + test144: int + test145: int + test146: int + test147: int + test148: int + test149: int + test150: int + test151: int + test152: int + test153: int + test154: int + test155: int + test156: int + test157: int + test158: int + test159: int + test160: int + test161: int + test162: int + test163: int + test164: int + test165: int + test166: int + test167: int + test168: int + test169: int + test170: int + test171: int + test172: int + test173: int + test174: int + test175: int + test176: int + test177: int + test178: int + test179: int + test180: int + test181: int + test182: int + test183: int + test184: int + test185: int + test186: int + test187: int + test188: int + test189: int + test190: int + test191: int + test192: int + test193: int + test194: int + test195: int + test196: int + test197: int + test198: int + test199: int + test200: int + test201: int + test202: int + test203: int + test204: int + test205: int + test206: int + test207: int + test208: int + test209: int + test210: int + test211: int + test212: int + test213: int + test214: int + test215: int + test216: int + test217: int + test218: int + test219: int + test220: int + test221: int + test222: int + test223: int + test224: int + test225: int + test226: int + test227: int + test228: int + test229: int + test230: int + test231: int + test232: int + test233: int + test234: int + test235: int + test236: int + test237: int + test238: int + test239: int + test240: int + test241: int + test242: int + test243: int + test244: int + test245: int + test246: int + test247: int + test248: int + test249: int + test250: int + test251: int + test252: int + test253: int + test254: int + test255: int + test256: int + test257: int + test258: int + test259: int + test260: int + test261: int + test262: int + test263: int + test264: int + test265: int + test266: int + test267: int + test268: int + test269: int + test270: int + test271: int + test272: int + test273: int + test274: int + test275: int + test276: int + test277: int + test278: int + test279: int + test280: int + test281: int + test282: int + test283: int + test284: int + test285: int + test286: int + test287: int + test288: int + test289: int + test290: int + test291: int + test292: int + test293: int + test294: int + test295: int + test296: int + test297: int + test298: int + test299: int + test300: int + test301: int + test302: int + test303: int + test304: int + test305: int + test306: int + test307: int + test308: int + test309: int + test310: int + test311: int + test312: int + test313: int + test314: int + test315: int + test316: int + test317: int + test318: int + test319: int + test320: int + test321: int + test322: int + test323: int + test324: int + test325: int + test326: int + test327: int + test328: int + test329: int + test330: int + test331: int + test332: int + test333: int + test334: int + test335: int + test336: int + test337: int + test338: int + test339: int + test340: int + test341: int + test342: int + test343: int + test344: int + test345: int + test346: int + test347: int + test348: int + test349: int + test350: int + test351: int + test352: int + test353: int + test354: int + test355: int + test356: int + test357: int + test358: int + test359: int + test360: int + test361: int + test362: int + test363: int + test364: int + test365: int + test366: int + test367: int + test368: int + test369: int + test370: int + test371: int + test372: int + test373: int + test374: int + test375: int + test376: int + test377: int + test378: int + test379: int + test380: int + test381: int + test382: int + test383: int + test384: int + test385: int + test386: int + test387: int + test388: int + test389: int + test390: int + test391: int + test392: int + test393: int + test394: int + test395: int + test396: int + test397: int + test398: int + test399: int + test400: int + test401: int + test402: int + test403: int + test404: int + test405: int + test406: int + test407: int + test408: int + test409: int + test410: int + test411: int + test412: int + test413: int + test414: int + test415: int + test416: int + test417: int + test418: int + test419: int + test420: int + test421: int + test422: int + test423: int + test424: int + test425: int + test426: int + test427: int + test428: int + test429: int + test430: int + test431: int + test432: int + test433: int + test434: int + test435: int + test436: int + test437: int + test438: int + test439: int + test440: int + test441: int + test442: int + test443: int + test444: int + test445: int + test446: int + test447: int + test448: int + test449: int + test450: int + test451: int + test452: int + test453: int + test454: int + test455: int + test456: int + test457: int + test458: int + test459: int + test460: int + test461: int + test462: int + test463: int + test464: int + test465: int + test466: int + test467: int + test468: int + test469: int + test470: int + test471: int + test472: int + test473: int + test474: int + test475: int + test476: int + test477: int + test478: int + test479: int + test480: int + test481: int + test482: int + test483: int + test484: int + test485: int + test486: int + test487: int + test488: int + test489: int + test490: int + test491: int + test492: int + test493: int + test494: int + test495: int + test496: int + test497: int + test498: int + test499: int + test500: int + test501: int + test502: int + test503: int + test504: int + test505: int + test506: int + test507: int + test508: int + test509: int + test510: int + test511: int + test512: int + test513: int + test514: int + test515: int + test516: int + test517: int + test518: int + test519: int + test520: int + test521: int + test522: int + test523: int + test524: int + test525: int + test526: int + test527: int + test528: int + test529: int + test530: int + test531: int + test532: int + test533: int + test534: int + test535: int + test536: int + test537: int + test538: int + test539: int + test540: int + test541: int + test542: int + test543: int + test544: int + test545: int + test546: int + test547: int + test548: int + test549: int + test550: int + test551: int + test552: int + test553: int + test554: int + test555: int + test556: int + test557: int + test558: int + test559: int + test560: int + test561: int + test562: int + test563: int + test564: int + test565: int + test566: int + test567: int + test568: int + test569: int + test570: int + test571: int + test572: int + test573: int + test574: int + test575: int + test576: int + test577: int + test578: int + test579: int + test580: int + test581: int + test582: int + test583: int + test584: int + test585: int + test586: int + test587: int + test588: int + test589: int + test590: int + test591: int + test592: int + test593: int + test594: int + test595: int + test596: int + test597: int + test598: int + test599: int + test600: int + test601: int + test602: int + test603: int + test604: int + test605: int + test606: int + test607: int + test608: int + test609: int + test610: int + test611: int + test612: int + test613: int + test614: int + test615: int + test616: int + test617: int + test618: int + test619: int + test620: int + test621: int + test622: int + test623: int + test624: int + test625: int + test626: int + test627: int + test628: int + test629: int + test630: int + test631: int + test632: int + test633: int + test634: int + test635: int + test636: int + test637: int + test638: int + test639: int + test640: int + test641: int + test642: int + test643: int + test644: int + test645: int + test646: int + test647: int + test648: int + test649: int + test650: int + test651: int + test652: int + test653: int + test654: int + test655: int + test656: int + test657: int + test658: int + test659: int + test660: int + test661: int + test662: int + test663: int + test664: int + test665: int + test666: int + test667: int + test668: int + test669: int + test670: int + test671: int + test672: int + test673: int + test674: int + test675: int + test676: int + test677: int + test678: int + test679: int + test680: int + test681: int + test682: int + test683: int + test684: int + test685: int + test686: int + test687: int + test688: int + test689: int + test690: int + test691: int + test692: int + test693: int + test694: int + test695: int + test696: int + test697: int + test698: int + test699: int + test700: int + test701: int + test702: int + test703: int + test704: int + test705: int + test706: int + test707: int + test708: int + test709: int + test710: int + test711: int + test712: int + test713: int + test714: int + test715: int + test716: int + test717: int + test718: int + test719: int + test720: int + test721: int + test722: int + test723: int + test724: int + test725: int + test726: int + test727: int + test728: int + test729: int + test730: int + test731: int + test732: int + test733: int + test734: int + test735: int + test736: int + test737: int + test738: int + test739: int + test740: int + test741: int + test742: int + test743: int + test744: int + test745: int + test746: int + test747: int + test748: int + test749: int + test750: int + test751: int + test752: int + test753: int + test754: int + test755: int + test756: int + test757: int + test758: int + test759: int + test760: int + test761: int + test762: int + test763: int + test764: int + test765: int + test766: int + test767: int + test768: int + test769: int + test770: int + test771: int + test772: int + test773: int + test774: int + test775: int + test776: int + test777: int + test778: int + test779: int + test780: int + test781: int + test782: int + test783: int + test784: int + test785: int + test786: int + test787: int + test788: int + test789: int + test790: int + test791: int + test792: int + test793: int + test794: int + test795: int + test796: int + test797: int + test798: int + test799: int + test800: int + test801: int + test802: int + test803: int + test804: int + test805: int + test806: int + test807: int + test808: int + test809: int + test810: int + test811: int + test812: int + test813: int + test814: int + test815: int + test816: int + test817: int + test818: int + test819: int + test820: int + test821: int + test822: int + test823: int + test824: int + test825: int + test826: int + test827: int + test828: int + test829: int + test830: int + test831: int + test832: int + test833: int + test834: int + test835: int + test836: int + test837: int + test838: int + test839: int + test840: int + test841: int + test842: int + test843: int + test844: int + test845: int + test846: int + test847: int + test848: int + test849: int + test850: int + test851: int + test852: int + test853: int + test854: int + test855: int + test856: int + test857: int + test858: int + test859: int + test860: int + test861: int + test862: int + test863: int + test864: int + test865: int + test866: int + test867: int + test868: int + test869: int + test870: int + test871: int + test872: int + test873: int + test874: int + test875: int + test876: int + test877: int + test878: int + test879: int + test880: int + test881: int + test882: int + test883: int + test884: int + test885: int + test886: int + test887: int + test888: int + test889: int + test890: int + test891: int + test892: int + test893: int + test894: int + test895: int + test896: int + test897: int + test898: int + test899: int + test900: int + test901: int + test902: int + test903: int + test904: int + test905: int + test906: int + test907: int + test908: int + test909: int + test910: int + test911: int + test912: int + test913: int + test914: int + test915: int + test916: int + test917: int + test918: int + test919: int + test920: int + test921: int + test922: int + test923: int + test924: int + test925: int + test926: int + test927: int + test928: int + test929: int + test930: int + test931: int + test932: int + test933: int + test934: int + test935: int + test936: int + test937: int + test938: int + test939: int + test940: int + test941: int + test942: int + test943: int + test944: int + test945: int + test946: int + test947: int + test948: int + test949: int + test950: int + test951: int + test952: int + test953: int + test954: int + test955: int + test956: int + test957: int + test958: int + test959: int + test960: int + test961: int + test962: int + test963: int + test964: int + test965: int + test966: int + test967: int + test968: int + test969: int + test970: int + test971: int + test972: int + test973: int + test974: int + test975: int + test976: int + test977: int + test978: int + test979: int + test980: int + test981: int + test982: int + test983: int + test984: int + test985: int + test986: int + test987: int + test988: int + test989: int + test990: int + test991: int + test992: int + test993: int + test994: int + test995: int + test996: int + test997: int + test998: int + test999: int + test1000: int + } + +[] +let main _ = 0 + """ + + [] + let LargeExprDoesNotStackOverflow() = + CompilerAssert.CompileExe + """ +module Test = + let test () = + let test1 = obj () + let test2 = obj () + let test3 = obj () + let test4 = obj () + let test5 = obj () + let test6 = obj () + let test7 = obj () + let test8 = obj () + let test9 = obj () + let test10 = obj () + let test11 = obj () + let test12 = obj () + let test13 = obj () + let test14 = obj () + let test15 = obj () + let test16 = obj () + let test17 = obj () + let test18 = obj () + let test19 = obj () + let test20 = obj () + let test21 = obj () + let test22 = obj () + let test23 = obj () + let test24 = obj () + let test25 = obj () + let test26 = obj () + let test27 = obj () + let test28 = obj () + let test29 = obj () + let test30 = obj () + let test31 = obj () + let test32 = obj () + let test33 = obj () + let test34 = obj () + let test35 = obj () + let test36 = obj () + let test37 = obj () + let test38 = obj () + let test39 = obj () + let test40 = obj () + let test41 = obj () + let test42 = obj () + let test43 = obj () + let test44 = obj () + let test45 = obj () + let test46 = obj () + let test47 = obj () + let test48 = obj () + let test49 = obj () + let test50 = obj () + let test51 = obj () + let test52 = obj () + let test53 = obj () + let test54 = obj () + let test55 = obj () + let test56 = obj () + let test57 = obj () + let test58 = obj () + let test59 = obj () + let test60 = obj () + let test61 = obj () + let test62 = obj () + let test63 = obj () + let test64 = obj () + let test65 = obj () + let test66 = obj () + let test67 = obj () + let test68 = obj () + let test69 = obj () + let test70 = obj () + let test71 = obj () + let test72 = obj () + let test73 = obj () + let test74 = obj () + let test75 = obj () + let test76 = obj () + let test77 = obj () + let test78 = obj () + let test79 = obj () + let test80 = obj () + let test81 = obj () + let test82 = obj () + let test83 = obj () + let test84 = obj () + let test85 = obj () + let test86 = obj () + let test87 = obj () + let test88 = obj () + let test89 = obj () + let test90 = obj () + let test91 = obj () + let test92 = obj () + let test93 = obj () + let test94 = obj () + let test95 = obj () + let test96 = obj () + let test97 = obj () + let test98 = obj () + let test99 = obj () + let test100 = obj () + let test101 = obj () + let test102 = obj () + let test103 = obj () + let test104 = obj () + let test105 = obj () + let test106 = obj () + let test107 = obj () + let test108 = obj () + let test109 = obj () + let test110 = obj () + let test111 = obj () + let test112 = obj () + let test113 = obj () + let test114 = obj () + let test115 = obj () + let test116 = obj () + let test117 = obj () + let test118 = obj () + let test119 = obj () + let test120 = obj () + let test121 = obj () + let test122 = obj () + let test123 = obj () + let test124 = obj () + let test125 = obj () + let test126 = obj () + let test127 = obj () + let test128 = obj () + let test129 = obj () + let test130 = obj () + let test131 = obj () + let test132 = obj () + let test133 = obj () + let test134 = obj () + let test135 = obj () + let test136 = obj () + let test137 = obj () + let test138 = obj () + let test139 = obj () + let test140 = obj () + let test141 = obj () + let test142 = obj () + let test143 = obj () + let test144 = obj () + let test145 = obj () + let test146 = obj () + let test147 = obj () + let test148 = obj () + let test149 = obj () + let test150 = obj () + let test151 = obj () + let test152 = obj () + let test153 = obj () + let test154 = obj () + let test155 = obj () + let test156 = obj () + let test157 = obj () + let test158 = obj () + let test159 = obj () + let test160 = obj () + let test161 = obj () + let test162 = obj () + let test163 = obj () + let test164 = obj () + let test165 = obj () + let test166 = obj () + let test167 = obj () + let test168 = obj () + let test169 = obj () + let test170 = obj () + let test171 = obj () + let test172 = obj () + let test173 = obj () + let test174 = obj () + let test175 = obj () + let test176 = obj () + let test177 = obj () + let test178 = obj () + let test179 = obj () + let test180 = obj () + let test181 = obj () + let test182 = obj () + let test183 = obj () + let test184 = obj () + let test185 = obj () + let test186 = obj () + let test187 = obj () + let test188 = obj () + let test189 = obj () + let test190 = obj () + let test191 = obj () + let test192 = obj () + let test193 = obj () + let test194 = obj () + let test195 = obj () + let test196 = obj () + let test197 = obj () + let test198 = obj () + let test199 = obj () + let test200 = obj () + let test201 = obj () + let test202 = obj () + let test203 = obj () + let test204 = obj () + let test205 = obj () + let test206 = obj () + let test207 = obj () + let test208 = obj () + let test209 = obj () + let test210 = obj () + let test211 = obj () + let test212 = obj () + let test213 = obj () + let test214 = obj () + let test215 = obj () + let test216 = obj () + let test217 = obj () + let test218 = obj () + let test219 = obj () + let test220 = obj () + let test221 = obj () + let test222 = obj () + let test223 = obj () + let test224 = obj () + let test225 = obj () + let test226 = obj () + let test227 = obj () + let test228 = obj () + let test229 = obj () + let test230 = obj () + let test231 = obj () + let test232 = obj () + let test233 = obj () + let test234 = obj () + let test235 = obj () + let test236 = obj () + let test237 = obj () + let test238 = obj () + let test239 = obj () + let test240 = obj () + let test241 = obj () + let test242 = obj () + let test243 = obj () + let test244 = obj () + let test245 = obj () + let test246 = obj () + let test247 = obj () + let test248 = obj () + let test249 = obj () + let test250 = obj () + let test251 = obj () + let test252 = obj () + let test253 = obj () + let test254 = obj () + let test255 = obj () + let test256 = obj () + let test257 = obj () + let test258 = obj () + let test259 = obj () + let test260 = obj () + let test261 = obj () + let test262 = obj () + let test263 = obj () + let test264 = obj () + let test265 = obj () + let test266 = obj () + let test267 = obj () + let test268 = obj () + let test269 = obj () + let test270 = obj () + let test271 = obj () + let test272 = obj () + let test273 = obj () + let test274 = obj () + let test275 = obj () + let test276 = obj () + let test277 = obj () + let test278 = obj () + let test279 = obj () + let test280 = obj () + let test281 = obj () + let test282 = obj () + let test283 = obj () + let test284 = obj () + let test285 = obj () + let test286 = obj () + let test287 = obj () + let test288 = obj () + let test289 = obj () + let test290 = obj () + let test291 = obj () + let test292 = obj () + let test293 = obj () + let test294 = obj () + let test295 = obj () + let test296 = obj () + let test297 = obj () + let test298 = obj () + let test299 = obj () + let test300 = obj () + let test301 = obj () + let test302 = obj () + let test303 = obj () + let test304 = obj () + let test305 = obj () + let test306 = obj () + let test307 = obj () + let test308 = obj () + let test309 = obj () + let test310 = obj () + let test311 = obj () + let test312 = obj () + let test313 = obj () + let test314 = obj () + let test315 = obj () + let test316 = obj () + let test317 = obj () + let test318 = obj () + let test319 = obj () + let test320 = obj () + let test321 = obj () + let test322 = obj () + let test323 = obj () + let test324 = obj () + let test325 = obj () + let test326 = obj () + let test327 = obj () + let test328 = obj () + let test329 = obj () + let test330 = obj () + let test331 = obj () + let test332 = obj () + let test333 = obj () + let test334 = obj () + let test335 = obj () + let test336 = obj () + let test337 = obj () + let test338 = obj () + let test339 = obj () + let test340 = obj () + let test341 = obj () + let test342 = obj () + let test343 = obj () + let test344 = obj () + let test345 = obj () + let test346 = obj () + let test347 = obj () + let test348 = obj () + let test349 = obj () + let test350 = obj () + let test351 = obj () + let test352 = obj () + let test353 = obj () + let test354 = obj () + let test355 = obj () + let test356 = obj () + let test357 = obj () + let test358 = obj () + let test359 = obj () + let test360 = obj () + let test361 = obj () + let test362 = obj () + let test363 = obj () + let test364 = obj () + let test365 = obj () + let test366 = obj () + let test367 = obj () + let test368 = obj () + let test369 = obj () + let test370 = obj () + let test371 = obj () + let test372 = obj () + let test373 = obj () + let test374 = obj () + let test375 = obj () + let test376 = obj () + let test377 = obj () + let test378 = obj () + let test379 = obj () + let test380 = obj () + let test381 = obj () + let test382 = obj () + let test383 = obj () + let test384 = obj () + let test385 = obj () + let test386 = obj () + let test387 = obj () + let test388 = obj () + let test389 = obj () + let test390 = obj () + let test391 = obj () + let test392 = obj () + let test393 = obj () + let test394 = obj () + let test395 = obj () + let test396 = obj () + let test397 = obj () + let test398 = obj () + let test399 = obj () + let test400 = obj () + let test401 = obj () + let test402 = obj () + let test403 = obj () + let test404 = obj () + let test405 = obj () + let test406 = obj () + let test407 = obj () + let test408 = obj () + let test409 = obj () + let test410 = obj () + let test411 = obj () + let test412 = obj () + let test413 = obj () + let test414 = obj () + let test415 = obj () + let test416 = obj () + let test417 = obj () + let test418 = obj () + let test419 = obj () + let test420 = obj () + let test421 = obj () + let test422 = obj () + let test423 = obj () + let test424 = obj () + let test425 = obj () + let test426 = obj () + let test427 = obj () + let test428 = obj () + let test429 = obj () + let test430 = obj () + let test431 = obj () + let test432 = obj () + let test433 = obj () + let test434 = obj () + let test435 = obj () + let test436 = obj () + let test437 = obj () + let test438 = obj () + let test439 = obj () + let test440 = obj () + let test441 = obj () + let test442 = obj () + let test443 = obj () + let test444 = obj () + let test445 = obj () + let test446 = obj () + let test447 = obj () + let test448 = obj () + let test449 = obj () + let test450 = obj () + let test451 = obj () + let test452 = obj () + let test453 = obj () + let test454 = obj () + let test455 = obj () + let test456 = obj () + let test457 = obj () + let test458 = obj () + let test459 = obj () + let test460 = obj () + let test461 = obj () + let test462 = obj () + let test463 = obj () + let test464 = obj () + let test465 = obj () + let test466 = obj () + let test467 = obj () + let test468 = obj () + let test469 = obj () + let test470 = obj () + let test471 = obj () + let test472 = obj () + let test473 = obj () + let test474 = obj () + let test475 = obj () + let test476 = obj () + let test477 = obj () + let test478 = obj () + let test479 = obj () + let test480 = obj () + let test481 = obj () + let test482 = obj () + let test483 = obj () + let test484 = obj () + let test485 = obj () + let test486 = obj () + let test487 = obj () + let test488 = obj () + let test489 = obj () + let test490 = obj () + let test491 = obj () + let test492 = obj () + let test493 = obj () + let test494 = obj () + let test495 = obj () + let test496 = obj () + let test497 = obj () + let test498 = obj () + let test499 = obj () + let test500 = obj () + let test501 = obj () + let test502 = obj () + let test503 = obj () + let test504 = obj () + let test505 = obj () + let test506 = obj () + let test507 = obj () + let test508 = obj () + let test509 = obj () + let test510 = obj () + let test511 = obj () + let test512 = obj () + let test513 = obj () + let test514 = obj () + let test515 = obj () + let test516 = obj () + let test517 = obj () + let test518 = obj () + let test519 = obj () + let test520 = obj () + let test521 = obj () + let test522 = obj () + let test523 = obj () + let test524 = obj () + let test525 = obj () + let test526 = obj () + let test527 = obj () + let test528 = obj () + let test529 = obj () + let test530 = obj () + let test531 = obj () + let test532 = obj () + let test533 = obj () + let test534 = obj () + let test535 = obj () + let test536 = obj () + let test537 = obj () + let test538 = obj () + let test539 = obj () + let test540 = obj () + let test541 = obj () + let test542 = obj () + let test543 = obj () + let test544 = obj () + let test545 = obj () + let test546 = obj () + let test547 = obj () + let test548 = obj () + let test549 = obj () + let test550 = obj () + let test551 = obj () + let test552 = obj () + let test553 = obj () + let test554 = obj () + let test555 = obj () + let test556 = obj () + let test557 = obj () + let test558 = obj () + let test559 = obj () + let test560 = obj () + let test561 = obj () + let test562 = obj () + let test563 = obj () + let test564 = obj () + let test565 = obj () + let test566 = obj () + let test567 = obj () + let test568 = obj () + let test569 = obj () + let test570 = obj () + let test571 = obj () + let test572 = obj () + let test573 = obj () + let test574 = obj () + let test575 = obj () + let test576 = obj () + let test577 = obj () + let test578 = obj () + let test579 = obj () + let test580 = obj () + let test581 = obj () + let test582 = obj () + let test583 = obj () + let test584 = obj () + let test585 = obj () + let test586 = obj () + let test587 = obj () + let test588 = obj () + let test589 = obj () + let test590 = obj () + let test591 = obj () + let test592 = obj () + let test593 = obj () + let test594 = obj () + let test595 = obj () + let test596 = obj () + let test597 = obj () + let test598 = obj () + let test599 = obj () + let test600 = obj () + let test601 = obj () + let test602 = obj () + let test603 = obj () + let test604 = obj () + let test605 = obj () + let test606 = obj () + let test607 = obj () + let test608 = obj () + let test609 = obj () + let test610 = obj () + let test611 = obj () + let test612 = obj () + let test613 = obj () + let test614 = obj () + let test615 = obj () + let test616 = obj () + let test617 = obj () + let test618 = obj () + let test619 = obj () + let test620 = obj () + let test621 = obj () + let test622 = obj () + let test623 = obj () + let test624 = obj () + let test625 = obj () + let test626 = obj () + let test627 = obj () + let test628 = obj () + let test629 = obj () + let test630 = obj () + let test631 = obj () + let test632 = obj () + let test633 = obj () + let test634 = obj () + let test635 = obj () + let test636 = obj () + let test637 = obj () + let test638 = obj () + let test639 = obj () + let test640 = obj () + let test641 = obj () + let test642 = obj () + let test643 = obj () + let test644 = obj () + let test645 = obj () + let test646 = obj () + let test647 = obj () + let test648 = obj () + let test649 = obj () + let test650 = obj () + let test651 = obj () + let test652 = obj () + let test653 = obj () + let test654 = obj () + let test655 = obj () + let test656 = obj () + let test657 = obj () + let test658 = obj () + let test659 = obj () + let test660 = obj () + let test661 = obj () + let test662 = obj () + let test663 = obj () + let test664 = obj () + let test665 = obj () + let test666 = obj () + let test667 = obj () + let test668 = obj () + let test669 = obj () + let test670 = obj () + let test671 = obj () + let test672 = obj () + let test673 = obj () + let test674 = obj () + let test675 = obj () + let test676 = obj () + let test677 = obj () + let test678 = obj () + let test679 = obj () + let test680 = obj () + let test681 = obj () + let test682 = obj () + let test683 = obj () + let test684 = obj () + let test685 = obj () + let test686 = obj () + let test687 = obj () + let test688 = obj () + let test689 = obj () + let test690 = obj () + let test691 = obj () + let test692 = obj () + let test693 = obj () + let test694 = obj () + let test695 = obj () + let test696 = obj () + let test697 = obj () + let test698 = obj () + let test699 = obj () + let test700 = obj () + let test701 = obj () + let test702 = obj () + let test703 = obj () + let test704 = obj () + let test705 = obj () + let test706 = obj () + let test707 = obj () + let test708 = obj () + let test709 = obj () + let test710 = obj () + let test711 = obj () + let test712 = obj () + let test713 = obj () + let test714 = obj () + let test715 = obj () + let test716 = obj () + let test717 = obj () + let test718 = obj () + let test719 = obj () + let test720 = obj () + let test721 = obj () + let test722 = obj () + let test723 = obj () + let test724 = obj () + let test725 = obj () + let test726 = obj () + let test727 = obj () + let test728 = obj () + let test729 = obj () + let test730 = obj () + let test731 = obj () + let test732 = obj () + let test733 = obj () + let test734 = obj () + let test735 = obj () + let test736 = obj () + let test737 = obj () + let test738 = obj () + let test739 = obj () + let test740 = obj () + let test741 = obj () + let test742 = obj () + let test743 = obj () + let test744 = obj () + let test745 = obj () + let test746 = obj () + let test747 = obj () + let test748 = obj () + let test749 = obj () + let test750 = obj () + let test751 = obj () + let test752 = obj () + let test753 = obj () + let test754 = obj () + let test755 = obj () + let test756 = obj () + let test757 = obj () + let test758 = obj () + let test759 = obj () + let test760 = obj () + let test761 = obj () + let test762 = obj () + let test763 = obj () + let test764 = obj () + let test765 = obj () + let test766 = obj () + let test767 = obj () + let test768 = obj () + let test769 = obj () + let test770 = obj () + let test771 = obj () + let test772 = obj () + let test773 = obj () + let test774 = obj () + let test775 = obj () + let test776 = obj () + let test777 = obj () + let test778 = obj () + let test779 = obj () + let test780 = obj () + let test781 = obj () + let test782 = obj () + let test783 = obj () + let test784 = obj () + let test785 = obj () + let test786 = obj () + let test787 = obj () + let test788 = obj () + let test789 = obj () + let test790 = obj () + let test791 = obj () + let test792 = obj () + let test793 = obj () + let test794 = obj () + let test795 = obj () + let test796 = obj () + let test797 = obj () + let test798 = obj () + let test799 = obj () + let test800 = obj () + let test801 = obj () + let test802 = obj () + let test803 = obj () + let test804 = obj () + let test805 = obj () + let test806 = obj () + let test807 = obj () + let test808 = obj () + let test809 = obj () + let test810 = obj () + let test811 = obj () + let test812 = obj () + let test813 = obj () + let test814 = obj () + let test815 = obj () + let test816 = obj () + let test817 = obj () + let test818 = obj () + let test819 = obj () + let test820 = obj () + let test821 = obj () + let test822 = obj () + let test823 = obj () + let test824 = obj () + let test825 = obj () + let test826 = obj () + let test827 = obj () + let test828 = obj () + let test829 = obj () + let test830 = obj () + let test831 = obj () + let test832 = obj () + let test833 = obj () + let test834 = obj () + let test835 = obj () + let test836 = obj () + let test837 = obj () + let test838 = obj () + let test839 = obj () + let test840 = obj () + let test841 = obj () + let test842 = obj () + let test843 = obj () + let test844 = obj () + let test845 = obj () + let test846 = obj () + let test847 = obj () + let test848 = obj () + let test849 = obj () + let test850 = obj () + let test851 = obj () + let test852 = obj () + let test853 = obj () + let test854 = obj () + let test855 = obj () + let test856 = obj () + let test857 = obj () + let test858 = obj () + let test859 = obj () + let test860 = obj () + let test861 = obj () + let test862 = obj () + let test863 = obj () + let test864 = obj () + let test865 = obj () + let test866 = obj () + let test867 = obj () + let test868 = obj () + let test869 = obj () + let test870 = obj () + let test871 = obj () + let test872 = obj () + let test873 = obj () + let test874 = obj () + let test875 = obj () + let test876 = obj () + let test877 = obj () + let test878 = obj () + let test879 = obj () + let test880 = obj () + let test881 = obj () + let test882 = obj () + let test883 = obj () + let test884 = obj () + let test885 = obj () + let test886 = obj () + let test887 = obj () + let test888 = obj () + let test889 = obj () + let test890 = obj () + let test891 = obj () + let test892 = obj () + let test893 = obj () + let test894 = obj () + let test895 = obj () + let test896 = obj () + let test897 = obj () + let test898 = obj () + let test899 = obj () + let test900 = obj () + let test901 = obj () + let test902 = obj () + let test903 = obj () + let test904 = obj () + let test905 = obj () + let test906 = obj () + let test907 = obj () + let test908 = obj () + let test909 = obj () + let test910 = obj () + let test911 = obj () + let test912 = obj () + let test913 = obj () + let test914 = obj () + let test915 = obj () + let test916 = obj () + let test917 = obj () + let test918 = obj () + let test919 = obj () + let test920 = obj () + let test921 = obj () + let test922 = obj () + let test923 = obj () + let test924 = obj () + let test925 = obj () + let test926 = obj () + let test927 = obj () + let test928 = obj () + let test929 = obj () + let test930 = obj () + let test931 = obj () + let test932 = obj () + let test933 = obj () + let test934 = obj () + let test935 = obj () + let test936 = obj () + let test937 = obj () + let test938 = obj () + let test939 = obj () + let test940 = obj () + let test941 = obj () + let test942 = obj () + let test943 = obj () + let test944 = obj () + let test945 = obj () + let test946 = obj () + let test947 = obj () + let test948 = obj () + let test949 = obj () + let test950 = obj () + let test951 = obj () + let test952 = obj () + let test953 = obj () + let test954 = obj () + let test955 = obj () + let test956 = obj () + let test957 = obj () + let test958 = obj () + let test959 = obj () + let test960 = obj () + let test961 = obj () + let test962 = obj () + let test963 = obj () + let test964 = obj () + let test965 = obj () + let test966 = obj () + let test967 = obj () + let test968 = obj () + let test969 = obj () + let test970 = obj () + let test971 = obj () + let test972 = obj () + let test973 = obj () + let test974 = obj () + let test975 = obj () + let test976 = obj () + let test977 = obj () + let test978 = obj () + let test979 = obj () + let test980 = obj () + let test981 = obj () + let test982 = obj () + let test983 = obj () + let test984 = obj () + let test985 = obj () + let test986 = obj () + let test987 = obj () + let test988 = obj () + let test989 = obj () + let test990 = obj () + let test991 = obj () + let test992 = obj () + let test993 = obj () + let test994 = obj () + let test995 = obj () + let test996 = obj () + let test997 = obj () + let test998 = obj () + let test999 = obj () + let test1000 = obj () + + printfn "%A" test1 + printfn "%A" test2 + printfn "%A" test3 + printfn "%A" test4 + printfn "%A" test5 + printfn "%A" test6 + printfn "%A" test7 + printfn "%A" test8 + printfn "%A" test9 + printfn "%A" test10 + printfn "%A" test11 + printfn "%A" test12 + printfn "%A" test13 + printfn "%A" test14 + printfn "%A" test15 + printfn "%A" test16 + printfn "%A" test17 + printfn "%A" test18 + printfn "%A" test19 + printfn "%A" test20 + printfn "%A" test21 + printfn "%A" test22 + printfn "%A" test23 + printfn "%A" test24 + printfn "%A" test25 + printfn "%A" test26 + printfn "%A" test27 + printfn "%A" test28 + printfn "%A" test29 + printfn "%A" test30 + printfn "%A" test31 + printfn "%A" test32 + printfn "%A" test33 + printfn "%A" test34 + printfn "%A" test35 + printfn "%A" test36 + printfn "%A" test37 + printfn "%A" test38 + printfn "%A" test39 + printfn "%A" test40 + printfn "%A" test41 + printfn "%A" test42 + printfn "%A" test43 + printfn "%A" test44 + printfn "%A" test45 + printfn "%A" test46 + printfn "%A" test47 + printfn "%A" test48 + printfn "%A" test49 + printfn "%A" test50 + printfn "%A" test51 + printfn "%A" test52 + printfn "%A" test53 + printfn "%A" test54 + printfn "%A" test55 + printfn "%A" test56 + printfn "%A" test57 + printfn "%A" test58 + printfn "%A" test59 + printfn "%A" test60 + printfn "%A" test61 + printfn "%A" test62 + printfn "%A" test63 + printfn "%A" test64 + printfn "%A" test65 + printfn "%A" test66 + printfn "%A" test67 + printfn "%A" test68 + printfn "%A" test69 + printfn "%A" test70 + printfn "%A" test71 + printfn "%A" test72 + printfn "%A" test73 + printfn "%A" test74 + printfn "%A" test75 + printfn "%A" test76 + printfn "%A" test77 + printfn "%A" test78 + printfn "%A" test79 + printfn "%A" test80 + printfn "%A" test81 + printfn "%A" test82 + printfn "%A" test83 + printfn "%A" test84 + printfn "%A" test85 + printfn "%A" test86 + printfn "%A" test87 + printfn "%A" test88 + printfn "%A" test89 + printfn "%A" test90 + printfn "%A" test91 + printfn "%A" test92 + printfn "%A" test93 + printfn "%A" test94 + printfn "%A" test95 + printfn "%A" test96 + printfn "%A" test97 + printfn "%A" test98 + printfn "%A" test99 + printfn "%A" test100 + printfn "%A" test101 + printfn "%A" test102 + printfn "%A" test103 + printfn "%A" test104 + printfn "%A" test105 + printfn "%A" test106 + printfn "%A" test107 + printfn "%A" test108 + printfn "%A" test109 + printfn "%A" test110 + printfn "%A" test111 + printfn "%A" test112 + printfn "%A" test113 + printfn "%A" test114 + printfn "%A" test115 + printfn "%A" test116 + printfn "%A" test117 + printfn "%A" test118 + printfn "%A" test119 + printfn "%A" test120 + printfn "%A" test121 + printfn "%A" test122 + printfn "%A" test123 + printfn "%A" test124 + printfn "%A" test125 + printfn "%A" test126 + printfn "%A" test127 + printfn "%A" test128 + printfn "%A" test129 + printfn "%A" test130 + printfn "%A" test131 + printfn "%A" test132 + printfn "%A" test133 + printfn "%A" test134 + printfn "%A" test135 + printfn "%A" test136 + printfn "%A" test137 + printfn "%A" test138 + printfn "%A" test139 + printfn "%A" test140 + printfn "%A" test141 + printfn "%A" test142 + printfn "%A" test143 + printfn "%A" test144 + printfn "%A" test145 + printfn "%A" test146 + printfn "%A" test147 + printfn "%A" test148 + printfn "%A" test149 + printfn "%A" test150 + printfn "%A" test151 + printfn "%A" test152 + printfn "%A" test153 + printfn "%A" test154 + printfn "%A" test155 + printfn "%A" test156 + printfn "%A" test157 + printfn "%A" test158 + printfn "%A" test159 + printfn "%A" test160 + printfn "%A" test161 + printfn "%A" test162 + printfn "%A" test163 + printfn "%A" test164 + printfn "%A" test165 + printfn "%A" test166 + printfn "%A" test167 + printfn "%A" test168 + printfn "%A" test169 + printfn "%A" test170 + printfn "%A" test171 + printfn "%A" test172 + printfn "%A" test173 + printfn "%A" test174 + printfn "%A" test175 + printfn "%A" test176 + printfn "%A" test177 + printfn "%A" test178 + printfn "%A" test179 + printfn "%A" test180 + printfn "%A" test181 + printfn "%A" test182 + printfn "%A" test183 + printfn "%A" test184 + printfn "%A" test185 + printfn "%A" test186 + printfn "%A" test187 + printfn "%A" test188 + printfn "%A" test189 + printfn "%A" test190 + printfn "%A" test191 + printfn "%A" test192 + printfn "%A" test193 + printfn "%A" test194 + printfn "%A" test195 + printfn "%A" test196 + printfn "%A" test197 + printfn "%A" test198 + printfn "%A" test199 + printfn "%A" test200 + printfn "%A" test201 + printfn "%A" test202 + printfn "%A" test203 + printfn "%A" test204 + printfn "%A" test205 + printfn "%A" test206 + printfn "%A" test207 + printfn "%A" test208 + printfn "%A" test209 + printfn "%A" test210 + printfn "%A" test211 + printfn "%A" test212 + printfn "%A" test213 + printfn "%A" test214 + printfn "%A" test215 + printfn "%A" test216 + printfn "%A" test217 + printfn "%A" test218 + printfn "%A" test219 + printfn "%A" test220 + printfn "%A" test221 + printfn "%A" test222 + printfn "%A" test223 + printfn "%A" test224 + printfn "%A" test225 + printfn "%A" test226 + printfn "%A" test227 + printfn "%A" test228 + printfn "%A" test229 + printfn "%A" test230 + printfn "%A" test231 + printfn "%A" test232 + printfn "%A" test233 + printfn "%A" test234 + printfn "%A" test235 + printfn "%A" test236 + printfn "%A" test237 + printfn "%A" test238 + printfn "%A" test239 + printfn "%A" test240 + printfn "%A" test241 + printfn "%A" test242 + printfn "%A" test243 + printfn "%A" test244 + printfn "%A" test245 + printfn "%A" test246 + printfn "%A" test247 + printfn "%A" test248 + printfn "%A" test249 + printfn "%A" test250 + printfn "%A" test251 + printfn "%A" test252 + printfn "%A" test253 + printfn "%A" test254 + printfn "%A" test255 + printfn "%A" test256 + printfn "%A" test257 + printfn "%A" test258 + printfn "%A" test259 + printfn "%A" test260 + printfn "%A" test261 + printfn "%A" test262 + printfn "%A" test263 + printfn "%A" test264 + printfn "%A" test265 + printfn "%A" test266 + printfn "%A" test267 + printfn "%A" test268 + printfn "%A" test269 + printfn "%A" test270 + printfn "%A" test271 + printfn "%A" test272 + printfn "%A" test273 + printfn "%A" test274 + printfn "%A" test275 + printfn "%A" test276 + printfn "%A" test277 + printfn "%A" test278 + printfn "%A" test279 + printfn "%A" test280 + printfn "%A" test281 + printfn "%A" test282 + printfn "%A" test283 + printfn "%A" test284 + printfn "%A" test285 + printfn "%A" test286 + printfn "%A" test287 + printfn "%A" test288 + printfn "%A" test289 + printfn "%A" test290 + printfn "%A" test291 + printfn "%A" test292 + printfn "%A" test293 + printfn "%A" test294 + printfn "%A" test295 + printfn "%A" test296 + printfn "%A" test297 + printfn "%A" test298 + printfn "%A" test299 + printfn "%A" test300 + printfn "%A" test301 + printfn "%A" test302 + printfn "%A" test303 + printfn "%A" test304 + printfn "%A" test305 + printfn "%A" test306 + printfn "%A" test307 + printfn "%A" test308 + printfn "%A" test309 + printfn "%A" test310 + printfn "%A" test311 + printfn "%A" test312 + printfn "%A" test313 + printfn "%A" test314 + printfn "%A" test315 + printfn "%A" test316 + printfn "%A" test317 + printfn "%A" test318 + printfn "%A" test319 + printfn "%A" test320 + printfn "%A" test321 + printfn "%A" test322 + printfn "%A" test323 + printfn "%A" test324 + printfn "%A" test325 + printfn "%A" test326 + printfn "%A" test327 + printfn "%A" test328 + printfn "%A" test329 + printfn "%A" test330 + printfn "%A" test331 + printfn "%A" test332 + printfn "%A" test333 + printfn "%A" test334 + printfn "%A" test335 + printfn "%A" test336 + printfn "%A" test337 + printfn "%A" test338 + printfn "%A" test339 + printfn "%A" test340 + printfn "%A" test341 + printfn "%A" test342 + printfn "%A" test343 + printfn "%A" test344 + printfn "%A" test345 + printfn "%A" test346 + printfn "%A" test347 + printfn "%A" test348 + printfn "%A" test349 + printfn "%A" test350 + printfn "%A" test351 + printfn "%A" test352 + printfn "%A" test353 + printfn "%A" test354 + printfn "%A" test355 + printfn "%A" test356 + printfn "%A" test357 + printfn "%A" test358 + printfn "%A" test359 + printfn "%A" test360 + printfn "%A" test361 + printfn "%A" test362 + printfn "%A" test363 + printfn "%A" test364 + printfn "%A" test365 + printfn "%A" test366 + printfn "%A" test367 + printfn "%A" test368 + printfn "%A" test369 + printfn "%A" test370 + printfn "%A" test371 + printfn "%A" test372 + printfn "%A" test373 + printfn "%A" test374 + printfn "%A" test375 + printfn "%A" test376 + printfn "%A" test377 + printfn "%A" test378 + printfn "%A" test379 + printfn "%A" test380 + printfn "%A" test381 + printfn "%A" test382 + printfn "%A" test383 + printfn "%A" test384 + printfn "%A" test385 + printfn "%A" test386 + printfn "%A" test387 + printfn "%A" test388 + printfn "%A" test389 + printfn "%A" test390 + printfn "%A" test391 + printfn "%A" test392 + printfn "%A" test393 + printfn "%A" test394 + printfn "%A" test395 + printfn "%A" test396 + printfn "%A" test397 + printfn "%A" test398 + printfn "%A" test399 + printfn "%A" test400 + printfn "%A" test401 + printfn "%A" test402 + printfn "%A" test403 + printfn "%A" test404 + printfn "%A" test405 + printfn "%A" test406 + printfn "%A" test407 + printfn "%A" test408 + printfn "%A" test409 + printfn "%A" test410 + printfn "%A" test411 + printfn "%A" test412 + printfn "%A" test413 + printfn "%A" test414 + printfn "%A" test415 + printfn "%A" test416 + printfn "%A" test417 + printfn "%A" test418 + printfn "%A" test419 + printfn "%A" test420 + printfn "%A" test421 + printfn "%A" test422 + printfn "%A" test423 + printfn "%A" test424 + printfn "%A" test425 + printfn "%A" test426 + printfn "%A" test427 + printfn "%A" test428 + printfn "%A" test429 + printfn "%A" test430 + printfn "%A" test431 + printfn "%A" test432 + printfn "%A" test433 + printfn "%A" test434 + printfn "%A" test435 + printfn "%A" test436 + printfn "%A" test437 + printfn "%A" test438 + printfn "%A" test439 + printfn "%A" test440 + printfn "%A" test441 + printfn "%A" test442 + printfn "%A" test443 + printfn "%A" test444 + printfn "%A" test445 + printfn "%A" test446 + printfn "%A" test447 + printfn "%A" test448 + printfn "%A" test449 + printfn "%A" test450 + printfn "%A" test451 + printfn "%A" test452 + printfn "%A" test453 + printfn "%A" test454 + printfn "%A" test455 + printfn "%A" test456 + printfn "%A" test457 + printfn "%A" test458 + printfn "%A" test459 + printfn "%A" test460 + printfn "%A" test461 + printfn "%A" test462 + printfn "%A" test463 + printfn "%A" test464 + printfn "%A" test465 + printfn "%A" test466 + printfn "%A" test467 + printfn "%A" test468 + printfn "%A" test469 + printfn "%A" test470 + printfn "%A" test471 + printfn "%A" test472 + printfn "%A" test473 + printfn "%A" test474 + printfn "%A" test475 + printfn "%A" test476 + printfn "%A" test477 + printfn "%A" test478 + printfn "%A" test479 + printfn "%A" test480 + printfn "%A" test481 + printfn "%A" test482 + printfn "%A" test483 + printfn "%A" test484 + printfn "%A" test485 + printfn "%A" test486 + printfn "%A" test487 + printfn "%A" test488 + printfn "%A" test489 + printfn "%A" test490 + printfn "%A" test491 + printfn "%A" test492 + printfn "%A" test493 + printfn "%A" test494 + printfn "%A" test495 + printfn "%A" test496 + printfn "%A" test497 + printfn "%A" test498 + printfn "%A" test499 + printfn "%A" test500 + printfn "%A" test501 + printfn "%A" test502 + printfn "%A" test503 + printfn "%A" test504 + printfn "%A" test505 + printfn "%A" test506 + printfn "%A" test507 + printfn "%A" test508 + printfn "%A" test509 + printfn "%A" test510 + printfn "%A" test511 + printfn "%A" test512 + printfn "%A" test513 + printfn "%A" test514 + printfn "%A" test515 + printfn "%A" test516 + printfn "%A" test517 + printfn "%A" test518 + printfn "%A" test519 + printfn "%A" test520 + printfn "%A" test521 + printfn "%A" test522 + printfn "%A" test523 + printfn "%A" test524 + printfn "%A" test525 + printfn "%A" test526 + printfn "%A" test527 + printfn "%A" test528 + printfn "%A" test529 + printfn "%A" test530 + printfn "%A" test531 + printfn "%A" test532 + printfn "%A" test533 + printfn "%A" test534 + printfn "%A" test535 + printfn "%A" test536 + printfn "%A" test537 + printfn "%A" test538 + printfn "%A" test539 + printfn "%A" test540 + printfn "%A" test541 + printfn "%A" test542 + printfn "%A" test543 + printfn "%A" test544 + printfn "%A" test545 + printfn "%A" test546 + printfn "%A" test547 + printfn "%A" test548 + printfn "%A" test549 + printfn "%A" test550 + printfn "%A" test551 + printfn "%A" test552 + printfn "%A" test553 + printfn "%A" test554 + printfn "%A" test555 + printfn "%A" test556 + printfn "%A" test557 + printfn "%A" test558 + printfn "%A" test559 + printfn "%A" test560 + printfn "%A" test561 + printfn "%A" test562 + printfn "%A" test563 + printfn "%A" test564 + printfn "%A" test565 + printfn "%A" test566 + printfn "%A" test567 + printfn "%A" test568 + printfn "%A" test569 + printfn "%A" test570 + printfn "%A" test571 + printfn "%A" test572 + printfn "%A" test573 + printfn "%A" test574 + printfn "%A" test575 + printfn "%A" test576 + printfn "%A" test577 + printfn "%A" test578 + printfn "%A" test579 + printfn "%A" test580 + printfn "%A" test581 + printfn "%A" test582 + printfn "%A" test583 + printfn "%A" test584 + printfn "%A" test585 + printfn "%A" test586 + printfn "%A" test587 + printfn "%A" test588 + printfn "%A" test589 + printfn "%A" test590 + printfn "%A" test591 + printfn "%A" test592 + printfn "%A" test593 + printfn "%A" test594 + printfn "%A" test595 + printfn "%A" test596 + printfn "%A" test597 + printfn "%A" test598 + printfn "%A" test599 + printfn "%A" test600 + printfn "%A" test601 + printfn "%A" test602 + printfn "%A" test603 + printfn "%A" test604 + printfn "%A" test605 + printfn "%A" test606 + printfn "%A" test607 + printfn "%A" test608 + printfn "%A" test609 + printfn "%A" test610 + printfn "%A" test611 + printfn "%A" test612 + printfn "%A" test613 + printfn "%A" test614 + printfn "%A" test615 + printfn "%A" test616 + printfn "%A" test617 + printfn "%A" test618 + printfn "%A" test619 + printfn "%A" test620 + printfn "%A" test621 + printfn "%A" test622 + printfn "%A" test623 + printfn "%A" test624 + printfn "%A" test625 + printfn "%A" test626 + printfn "%A" test627 + printfn "%A" test628 + printfn "%A" test629 + printfn "%A" test630 + printfn "%A" test631 + printfn "%A" test632 + printfn "%A" test633 + printfn "%A" test634 + printfn "%A" test635 + printfn "%A" test636 + printfn "%A" test637 + printfn "%A" test638 + printfn "%A" test639 + printfn "%A" test640 + printfn "%A" test641 + printfn "%A" test642 + printfn "%A" test643 + printfn "%A" test644 + printfn "%A" test645 + printfn "%A" test646 + printfn "%A" test647 + printfn "%A" test648 + printfn "%A" test649 + printfn "%A" test650 + printfn "%A" test651 + printfn "%A" test652 + printfn "%A" test653 + printfn "%A" test654 + printfn "%A" test655 + printfn "%A" test656 + printfn "%A" test657 + printfn "%A" test658 + printfn "%A" test659 + printfn "%A" test660 + printfn "%A" test661 + printfn "%A" test662 + printfn "%A" test663 + printfn "%A" test664 + printfn "%A" test665 + printfn "%A" test666 + printfn "%A" test667 + printfn "%A" test668 + printfn "%A" test669 + printfn "%A" test670 + printfn "%A" test671 + printfn "%A" test672 + printfn "%A" test673 + printfn "%A" test674 + printfn "%A" test675 + printfn "%A" test676 + printfn "%A" test677 + printfn "%A" test678 + printfn "%A" test679 + printfn "%A" test680 + printfn "%A" test681 + printfn "%A" test682 + printfn "%A" test683 + printfn "%A" test684 + printfn "%A" test685 + printfn "%A" test686 + printfn "%A" test687 + printfn "%A" test688 + printfn "%A" test689 + printfn "%A" test690 + printfn "%A" test691 + printfn "%A" test692 + printfn "%A" test693 + printfn "%A" test694 + printfn "%A" test695 + printfn "%A" test696 + printfn "%A" test697 + printfn "%A" test698 + printfn "%A" test699 + printfn "%A" test700 + printfn "%A" test701 + printfn "%A" test702 + printfn "%A" test703 + printfn "%A" test704 + printfn "%A" test705 + printfn "%A" test706 + printfn "%A" test707 + printfn "%A" test708 + printfn "%A" test709 + printfn "%A" test710 + printfn "%A" test711 + printfn "%A" test712 + printfn "%A" test713 + printfn "%A" test714 + printfn "%A" test715 + printfn "%A" test716 + printfn "%A" test717 + printfn "%A" test718 + printfn "%A" test719 + printfn "%A" test720 + printfn "%A" test721 + printfn "%A" test722 + printfn "%A" test723 + printfn "%A" test724 + printfn "%A" test725 + printfn "%A" test726 + printfn "%A" test727 + printfn "%A" test728 + printfn "%A" test729 + printfn "%A" test730 + printfn "%A" test731 + printfn "%A" test732 + printfn "%A" test733 + printfn "%A" test734 + printfn "%A" test735 + printfn "%A" test736 + printfn "%A" test737 + printfn "%A" test738 + printfn "%A" test739 + printfn "%A" test740 + printfn "%A" test741 + printfn "%A" test742 + printfn "%A" test743 + printfn "%A" test744 + printfn "%A" test745 + printfn "%A" test746 + printfn "%A" test747 + printfn "%A" test748 + printfn "%A" test749 + printfn "%A" test750 + printfn "%A" test751 + printfn "%A" test752 + printfn "%A" test753 + printfn "%A" test754 + printfn "%A" test755 + printfn "%A" test756 + printfn "%A" test757 + printfn "%A" test758 + printfn "%A" test759 + printfn "%A" test760 + printfn "%A" test761 + printfn "%A" test762 + printfn "%A" test763 + printfn "%A" test764 + printfn "%A" test765 + printfn "%A" test766 + printfn "%A" test767 + printfn "%A" test768 + printfn "%A" test769 + printfn "%A" test770 + printfn "%A" test771 + printfn "%A" test772 + printfn "%A" test773 + printfn "%A" test774 + printfn "%A" test775 + printfn "%A" test776 + printfn "%A" test777 + printfn "%A" test778 + printfn "%A" test779 + printfn "%A" test780 + printfn "%A" test781 + printfn "%A" test782 + printfn "%A" test783 + printfn "%A" test784 + printfn "%A" test785 + printfn "%A" test786 + printfn "%A" test787 + printfn "%A" test788 + printfn "%A" test789 + printfn "%A" test790 + printfn "%A" test791 + printfn "%A" test792 + printfn "%A" test793 + printfn "%A" test794 + printfn "%A" test795 + printfn "%A" test796 + printfn "%A" test797 + printfn "%A" test798 + printfn "%A" test799 + printfn "%A" test800 + printfn "%A" test801 + printfn "%A" test802 + printfn "%A" test803 + printfn "%A" test804 + printfn "%A" test805 + printfn "%A" test806 + printfn "%A" test807 + printfn "%A" test808 + printfn "%A" test809 + printfn "%A" test810 + printfn "%A" test811 + printfn "%A" test812 + printfn "%A" test813 + printfn "%A" test814 + printfn "%A" test815 + printfn "%A" test816 + printfn "%A" test817 + printfn "%A" test818 + printfn "%A" test819 + printfn "%A" test820 + printfn "%A" test821 + printfn "%A" test822 + printfn "%A" test823 + printfn "%A" test824 + printfn "%A" test825 + printfn "%A" test826 + printfn "%A" test827 + printfn "%A" test828 + printfn "%A" test829 + printfn "%A" test830 + printfn "%A" test831 + printfn "%A" test832 + printfn "%A" test833 + printfn "%A" test834 + printfn "%A" test835 + printfn "%A" test836 + printfn "%A" test837 + printfn "%A" test838 + printfn "%A" test839 + printfn "%A" test840 + printfn "%A" test841 + printfn "%A" test842 + printfn "%A" test843 + printfn "%A" test844 + printfn "%A" test845 + printfn "%A" test846 + printfn "%A" test847 + printfn "%A" test848 + printfn "%A" test849 + printfn "%A" test850 + printfn "%A" test851 + printfn "%A" test852 + printfn "%A" test853 + printfn "%A" test854 + printfn "%A" test855 + printfn "%A" test856 + printfn "%A" test857 + printfn "%A" test858 + printfn "%A" test859 + printfn "%A" test860 + printfn "%A" test861 + printfn "%A" test862 + printfn "%A" test863 + printfn "%A" test864 + printfn "%A" test865 + printfn "%A" test866 + printfn "%A" test867 + printfn "%A" test868 + printfn "%A" test869 + printfn "%A" test870 + printfn "%A" test871 + printfn "%A" test872 + printfn "%A" test873 + printfn "%A" test874 + printfn "%A" test875 + printfn "%A" test876 + printfn "%A" test877 + printfn "%A" test878 + printfn "%A" test879 + printfn "%A" test880 + printfn "%A" test881 + printfn "%A" test882 + printfn "%A" test883 + printfn "%A" test884 + printfn "%A" test885 + printfn "%A" test886 + printfn "%A" test887 + printfn "%A" test888 + printfn "%A" test889 + printfn "%A" test890 + printfn "%A" test891 + printfn "%A" test892 + printfn "%A" test893 + printfn "%A" test894 + printfn "%A" test895 + printfn "%A" test896 + printfn "%A" test897 + printfn "%A" test898 + printfn "%A" test899 + printfn "%A" test900 + printfn "%A" test901 + printfn "%A" test902 + printfn "%A" test903 + printfn "%A" test904 + printfn "%A" test905 + printfn "%A" test906 + printfn "%A" test907 + printfn "%A" test908 + printfn "%A" test909 + printfn "%A" test910 + printfn "%A" test911 + printfn "%A" test912 + printfn "%A" test913 + printfn "%A" test914 + printfn "%A" test915 + printfn "%A" test916 + printfn "%A" test917 + printfn "%A" test918 + printfn "%A" test919 + printfn "%A" test920 + printfn "%A" test921 + printfn "%A" test922 + printfn "%A" test923 + printfn "%A" test924 + printfn "%A" test925 + printfn "%A" test926 + printfn "%A" test927 + printfn "%A" test928 + printfn "%A" test929 + printfn "%A" test930 + printfn "%A" test931 + printfn "%A" test932 + printfn "%A" test933 + printfn "%A" test934 + printfn "%A" test935 + printfn "%A" test936 + printfn "%A" test937 + printfn "%A" test938 + printfn "%A" test939 + printfn "%A" test940 + printfn "%A" test941 + printfn "%A" test942 + printfn "%A" test943 + printfn "%A" test944 + printfn "%A" test945 + printfn "%A" test946 + printfn "%A" test947 + printfn "%A" test948 + printfn "%A" test949 + printfn "%A" test950 + printfn "%A" test951 + printfn "%A" test952 + printfn "%A" test953 + printfn "%A" test954 + printfn "%A" test955 + printfn "%A" test956 + printfn "%A" test957 + printfn "%A" test958 + printfn "%A" test959 + printfn "%A" test960 + printfn "%A" test961 + printfn "%A" test962 + printfn "%A" test963 + printfn "%A" test964 + printfn "%A" test965 + printfn "%A" test966 + printfn "%A" test967 + printfn "%A" test968 + printfn "%A" test969 + printfn "%A" test970 + printfn "%A" test971 + printfn "%A" test972 + printfn "%A" test973 + printfn "%A" test974 + printfn "%A" test975 + printfn "%A" test976 + printfn "%A" test977 + printfn "%A" test978 + printfn "%A" test979 + printfn "%A" test980 + printfn "%A" test981 + printfn "%A" test982 + printfn "%A" test983 + printfn "%A" test984 + printfn "%A" test985 + printfn "%A" test986 + printfn "%A" test987 + printfn "%A" test988 + printfn "%A" test989 + printfn "%A" test990 + printfn "%A" test991 + printfn "%A" test992 + printfn "%A" test993 + printfn "%A" test994 + printfn "%A" test995 + printfn "%A" test996 + printfn "%A" test997 + printfn "%A" test998 + printfn "%A" test999 + printfn "%A" test1000 + +[] +let main _ = 0 + """ + + [] + let LargeListExprDoesNotStackOverflow() = + let source = """ +let test () : unit = + let largeList = + [ + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 + 111 + 112 + 113 + 114 + 115 + 116 + 117 + 118 + 119 + 120 + 121 + 122 + 123 + 124 + 125 + 126 + 127 + 128 + 129 + 130 + 131 + 132 + 133 + 134 + 135 + 136 + 137 + 138 + 139 + 140 + 141 + 142 + 143 + 144 + 145 + 146 + 147 + 148 + 149 + 150 + 151 + 152 + 153 + 154 + 155 + 156 + 157 + 158 + 159 + 160 + 161 + 162 + 163 + 164 + 165 + 166 + 167 + 168 + 169 + 170 + 171 + 172 + 173 + 174 + 175 + 176 + 177 + 178 + 179 + 180 + 181 + 182 + 183 + 184 + 185 + 186 + 187 + 188 + 189 + 190 + 191 + 192 + 193 + 194 + 195 + 196 + 197 + 198 + 199 + 200 + 201 + 202 + 203 + 204 + 205 + 206 + 207 + 208 + 209 + 210 + 211 + 212 + 213 + 214 + 215 + 216 + 217 + 218 + 219 + 220 + 221 + 222 + 223 + 224 + 225 + 226 + 227 + 228 + 229 + 230 + 231 + 232 + 233 + 234 + 235 + 236 + 237 + 238 + 239 + 240 + 241 + 242 + 243 + 244 + 245 + 246 + 247 + 248 + 249 + 250 + 251 + 252 + 253 + 254 + 255 + 256 + 257 + 258 + 259 + 260 + 261 + 262 + 263 + 264 + 265 + 266 + 267 + 268 + 269 + 270 + 271 + 272 + 273 + 274 + 275 + 276 + 277 + 278 + 279 + 280 + 281 + 282 + 283 + 284 + 285 + 286 + 287 + 288 + 289 + 290 + 291 + 292 + 293 + 294 + 295 + 296 + 297 + 298 + 299 + 300 + 301 + 302 + 303 + 304 + 305 + 306 + 307 + 308 + 309 + 310 + 311 + 312 + 313 + 314 + 315 + 316 + 317 + 318 + 319 + 320 + 321 + 322 + 323 + 324 + 325 + 326 + 327 + 328 + 329 + 330 + 331 + 332 + 333 + 334 + 335 + 336 + 337 + 338 + 339 + 340 + 341 + 342 + 343 + 344 + 345 + 346 + 347 + 348 + 349 + 350 + 351 + 352 + 353 + 354 + 355 + 356 + 357 + 358 + 359 + 360 + 361 + 362 + 363 + 364 + 365 + 366 + 367 + 368 + 369 + 370 + 371 + 372 + 373 + 374 + 375 + 376 + 377 + 378 + 379 + 380 + 381 + 382 + 383 + 384 + 385 + 386 + 387 + 388 + 389 + 390 + 391 + 392 + 393 + 394 + 395 + 396 + 397 + 398 + 399 + 400 + 401 + 402 + 403 + 404 + 405 + 406 + 407 + 408 + 409 + 410 + 411 + 412 + 413 + 414 + 415 + 416 + 417 + 418 + 419 + 420 + 421 + 422 + 423 + 424 + 425 + 426 + 427 + 428 + 429 + 430 + 431 + 432 + 433 + 434 + 435 + 436 + 437 + 438 + 439 + 440 + 441 + 442 + 443 + 444 + 445 + 446 + 447 + 448 + 449 + 450 + 451 + 452 + 453 + 454 + 455 + 456 + 457 + 458 + 459 + 460 + 461 + 462 + 463 + 464 + 465 + 466 + 467 + 468 + 469 + 470 + 471 + 472 + 473 + 474 + 475 + 476 + 477 + 478 + 479 + 480 + 481 + 482 + 483 + 484 + 485 + 486 + 487 + 488 + 489 + 490 + 491 + 492 + 493 + 494 + 495 + 496 + 497 + 498 + 499 + 500 + ] + if largeList.Length <> 500 then + failwith "Length is not 500" + + for i = 1 to 500 do + if largeList.[i - 1] <> i then + failwithf "Element was %i. Expecting %i." largeList.[i - 1] i + +test () +""" + CompilerAssert.RunScript source [] \ No newline at end of file diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index 56240b466b4..10e1f4733ac 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -30,13 +30,14 @@ + - +