dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.92k stars 785 forks source link

Stack overflow typechecking large CEs on macOS #13084

Open samritchie opened 2 years ago

samritchie commented 2 years ago

Upgrading from FSAC v0.51.0 to v0.52.0 (Ionide 6.0.0) triggers a stack overflow in FSharp.Compiler.CheckComputationExpressions on macOS when attempting to typecheck a file containing large CEs.

I saw similar issues a couple of years ago with early versions of the netcore FSAC. Tracing through the versions, it looks like there may have been a performance regression between FCS 41.0.1 and 41.0.3?

Repro steps

Open the following file on macOS

#r "nuget: Chiron"

open Chiron

type LargeRecord =
    {
        Property1: string
        Property2: string
        Property3: string
        Property4: string
        Property5: string
        Property6: string
        Property7: string
        Property8: string
        Property9: string
        Property10: string
        Property11: string
        Property12: string
        Property13: string
        Property14: string
        Property15: string
        Property16: string
        Property17: string
        Property18: string
        Property19: string
        Property20: string
        Property21: string
        Property22: string
        Property23: string
        Property24: string
        Property25: string
        Property26: string
        Property27: string
        Property28: string
        Property29: string
        Property30: string
        Property31: string
        Property32: string
        Property33: string
        Property34: string
        Property35: string
        Property36: string
        Property37: string
    }
    with
    static member ToJson(x: LargeRecord) = json {
        do! Json.write "property1" x.Property1
        do! Json.write "property2" x.Property2
        do! Json.write "property3" x.Property3
        do! Json.write "property4" x.Property4
        do! Json.write "property5" x.Property5
        do! Json.write "property6" x.Property6
        do! Json.write "property7" x.Property7
        do! Json.write "property8" x.Property8
        do! Json.write "property9" x.Property9
        do! Json.write "property10" x.Property10
        do! Json.write "property11" x.Property11
        do! Json.write "property12" x.Property12
        do! Json.write "property13" x.Property13
        do! Json.write "property14" x.Property14
        do! Json.write "property15" x.Property15
        do! Json.write "property16" x.Property16
        do! Json.write "property17" x.Property17
        do! Json.write "property18" x.Property18
        do! Json.write "property19" x.Property19
        do! Json.write "property20" x.Property20
        do! Json.write "property21" x.Property21
        do! Json.write "property22" x.Property22
        do! Json.write "property23" x.Property23
        do! Json.write "property24" x.Property24
        do! Json.write "property25" x.Property25
        do! Json.write "property26" x.Property26
        do! Json.write "property27" x.Property27
        do! Json.write "property28" x.Property28
        do! Json.write "property29" x.Property29
        do! Json.write "property30" x.Property30
        do! Json.write "property31" x.Property31
        do! Json.write "property32" x.Property32
        do! Json.write "property33" x.Property33
        do! Json.write "property34" x.Property34
        do! Json.write "property35" x.Property35
        do! Json.write "property36" x.Property36
        do! Json.write "property37" x.Property37
    }

Expected behavior

File typechecks successfully

Actual behavior

Language server crashes and reports a stack overflow starting with:

Stack overflow.
   at FSharp.Compiler.Syntax.DebugPointAtLeafExpr.NewYes(FSharp.Compiler.Text.Range)
   at FSharp.Compiler.CheckComputationExpressions.convertSimpleReturnToExpr@1668(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Syntax.SynExpr)
   at FSharp.Compiler.CheckComputationExpressions.transBind@1630(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>, System.String, Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.SynExpr>, FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions+tryTrans@776-1.Invoke(Microsoft.FSharp.Core.Unit)
   at FSharp.Compiler.ErrorLogger+StackGuard.Guard[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.__Canon>)
   at FSharp.Compiler.CheckComputationExpressions.tryTrans@774(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CompExprTranslationPass, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions.trans@1589-2(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CompExprTranslationPass, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions.transBind@1630(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>, System.String, Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.SynExpr>, FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions+tryTrans@776-1.Invoke(Microsoft.FSharp.Core.Unit)
   at FSharp.Compiler.ErrorLogger+StackGuard.Guard[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.__Canon>)
   at FSharp.Compiler.CheckComputationExpressions.tryTrans@774(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CompExprTranslationPass, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions.trans@1589-2(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CompExprTranslationPass, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions+tryTrans@776-1.Invoke(Microsoft.FSharp.Core.Unit)
   at FSharp.Compiler.ErrorLogger+StackGuard.Guard[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.__Canon>)
   at FSharp.Compiler.CheckComputationExpressions.tryTrans@774(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CompExprTranslationPass, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions.trans@1589-2(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CompExprTranslationPass, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions.transBind@1630(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>, System.String, Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.SynExpr>, FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions+tryTrans@776-1.Invoke(Microsoft.FSharp.Core.Unit)
   at FSharp.Compiler.ErrorLogger+StackGuard.Guard[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.__Canon>)
   at FSharp.Compiler.CheckComputationExpressions.tryTrans@774(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CompExprTranslationPass, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions.trans@1589-2(TcFileState, UnscopedTyparEnv, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, TType, AccessorDomain, System.String, Boolean, Microsoft.FSharp.Collections.FSharpList`1<MethInfo>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, System.Collections.Generic.IDictionary`2<System.String,Microsoft.FSharp.Collections.FSharpList`1<System.Tuple`8<System.String,Boolean,Boolean,Boolean,Boolean,Boolean,Boolean,System.Tuple`2<Microsoft.FSharp.Core.FSharpOption`1<System.String>,MethInfo>>>>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.Ident,Boolean>, TcEnv, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, Boolean, CompExprTranslationPass, CustomOperationsMode, Internal.Utilities.Library.LazyWithContext`2<System.Tuple`2<Microsoft.FSharp.Collections.FSharpList`1<Val>,TcEnv>,FSharp.Compiler.Text.Range>, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Syntax.SynExpr>)
   at FSharp.Compiler.CheckComputationExpressions+tryTrans@776-1.Invoke(Microsoft.FSharp.Core.Unit)

Known workarounds

Setting the environment variable COMPlus_DefaultStackSize=180000 allows typecheck to complete successfully

Related information

.NET SDK (reflecting any global.json):
 Version:   6.0.201
 Commit:    ef40e6aa06

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  12.3
 OS Platform: Darwin
 RID:         osx.12-arm64
 Base Path:   /usr/local/share/dotnet/sdk/6.0.201/

Host (useful for support):
  Version: 6.0.3
  Commit:  c24d9a9c91

.NET SDKs installed:
  6.0.201 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
vzarytovskii commented 2 years ago

This may have been fixed in https://github.com/dotnet/fsharp/pull/12420 I will test it in latest dev17.3, everything from 17.2 should be there. Although, I'm not sure whether we've released FCS since the fix, @KevinRansom?

CC @dsyme FYI

samritchie commented 2 years ago

I'm not sure how to tell which PRs are in which release, but the performance appears to have regressed between 41.0.1 (released 6 months ago) and 41.0.3 (released 2 months ago)

dsyme commented 2 years ago

I'm not sure how to tell which PRs are in which release, but the performance appears to have regressed between 41.0.1 (released 6 months ago) and 41.0.3 (released 2 months ago)

It would be good to have separate issues for the stackoverflow and any perf regression, thanks. Is the perf regression specifically with the kind of large-input code above?

samritchie commented 2 years ago

Sorry, 'performance' was the wrong word - I meant the previous version (41.0.1) was okay with this code, the stack overflow was introduced some time after then.

I've been describing it a regression as I'm pretty sure it is the same issue I had with this same code a couple of years ago - it prevented me switching from mono FSAC to netcore FSAC for a good year or so.

dsyme commented 2 years ago

@samritchie Could you set the environment variable FSHARP_TcStackGuardDepth=50 in your command prompt prior to building and see if you continue to repro this? Thanks

It might be we just have to reduce this stack guard, either on all or on MacOS:

#if DEBUG
let TcStackGuardDepth = GetEnvInteger "FSHARP_TcStackGuardDepth" 40
#else
let TcStackGuardDepth = GetEnvInteger "FSHARP_TcStackGuardDepth" 80
#endif
samritchie commented 2 years ago

@dsyme FSHARP_TcStackGuardDepth=50 prevents the crash, at least on Ionide 6.0/FSAC 0.54. Sorry, it’s been difficult to confirm, there appears to be a fresh issue in Ionide 7.0/FSAC 0.56 where typecheck looks like it is looping endlessly. I'll see if I can block out some time next week to do a repro.

dsyme commented 2 years ago

Thanks for confirming.

I'll see if I can block out some time next week to do a repro.

Please do, if there's been a regression we'd like to know about it ASAP, thanks

samritchie commented 2 years ago

I've upgraded to Ionide 7.1.0/FSAC 0.56.2 and intellisense is not instant but is at least usable - possibly it was related to this: https://github.com/fsharp/FsAutoComplete/pull/977. This version still crashes with an SO opening the repro file without the FSHARP_TcStackGuardDepth workaround.