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.87k stars 779 forks source link

IDE crashing (StackOverflow in FCS) #13806

Closed vsfeedback closed 2 years ago

vsfeedback commented 2 years ago

This issue has been moved from a ticket on Developer Community.


Reporting this on request of David Kean (see https://twitter.com/davkean/status/1561539959236210688)


Original Comments

Feedback Bot on 8/22/2022, 07:10 AM:

(private comment, text removed)

David Kean [MSFT] on 8/22/2022, 07:20 AM:

(private comment, text removed)

Kent Boogaart on 8/23/2022, 06:11 AM:

(private comment, text removed)

David Kean [MSFT] on 8/23/2022, 06:13 AM:

(private comment, text removed)

Kent Boogaart on 8/23/2022, 06:29 AM:

(private comment, text removed)

David Kean [MSFT] on 8/23/2022, 09:09 AM:

(private comment, text removed)


Original Solutions

(no solutions)

vzarytovskii commented 2 years ago

More info: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1597537

vzarytovskii commented 2 years ago

cc @davkean

kentcb commented 2 years ago

@vzarytovskii Thanks for moving this to GH. This issue is really slaughtering my productivity with the one solution that it appears to affect (which is unfortunately the main solution I'm working with day-to-day). No trying to rush things, but is there any chance this will be looked at soon? Just want to figure out whether I need to pivot somehow, although I've already tried Rider and it exhibits the same issue since it's in the FCS.

My only real recourse right now seems to be using Code with Ionide disabled and editing without any IDE assistance. That has been a rather unproductive experience as well.

dsyme commented 2 years ago

Odd stack, need to look at this code, don't really expect 30+ deep module hierarchies and wouldn't really expect this to use so much stack anyway even if we did

mscorlib.dll!System.Lazy<FSharp.Compiler.TypedTree.ModuleOrNamespaceType>.LazyInitValue() Line 388 C#
  FSharp.Compiler.Service.dll!FSharp.Compiler.TypedTree.Entity.DemangledModuleOrNamespaceName.get() Line 819 Unknown
> FSharp.Compiler.Service.dll!FSharp.Compiler.TypedTreeOps.CombineEntities@9644-2.Invoke(Microsoft.FSharp.Core.Unit unitVar) Line 9644 Unknown
  mscorlib.dll!System.Lazy<FSharp.Compiler.TypedTree.ModuleOrNamespaceType>.CreateValue() Line 437 C#
  [The 4 frame(s) above this were repeated 29 times]
dsyme commented 2 years ago

Looks like unusually deeply nested module/namespace/type, would be good to confirm that @kentcb . Possibly from type provider or other codegen, maybe from imported assembly.

kentcb commented 2 years ago

@dsyme I wrote a little script (below for reference) to load all app assemblies and determine namespace depth. The deepest is 6, which I'm assuming is completely reasonable. It feels like I must be missing something...

open System.IO
open System.Reflection
open System.Runtime.InteropServices

let runtimeAssemblyPaths =
    Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll")
    |> List.ofArray

let applicationAssemblyPaths =
    Directory.GetFiles(@"<redacted>\bin\Fable\net6.0\", "*.dll")
    |> List.ofArray

let resolver =  PathAssemblyResolver(applicationAssemblyPaths @ runtimeAssemblyPaths)
let metadataLoadContext = new MetadataLoadContext(resolver)

let namespacesByDepth =
    applicationAssemblyPaths
    |> List.map metadataLoadContext.LoadFromAssemblyPath
    |> List.collect (fun assembly -> assembly.GetTypes() |> List.ofArray)
    |> List.map (fun t -> t.Namespace)
    |> List.where (fun ns -> ns <> null)
    |> List.distinct
    |> List.map (fun ns -> ns, ns.Split(".") |> Array.length)
    |> List.sortByDescending snd
kentcb commented 2 years ago

@dsyme Interestingly, the crashes have stopped for me, and I believe I know the exact change that alleviated the problem, though I will admit I haven't confirmed (due to time constraints). That said, it's the only change that I would foresee having any bearing on this situation and intuitively it might explain things.

Here's an explanation. We've got a Fable React app that we're transitioning from one way of defining components to another. The details don't matter too much, but suffice to say that our new way of doing things benefits from defining a component hierarchy up-front. Something like this:

namespace MyApp.Components

type Components = class end

module Route =
    type User = class end
    type System = class end
    type Debug = class end

We then extend those various types elsewhere in our code base, such as:

type MyApp.Components.Route.User with
    [<ReactComponent>]
    static member Profile() =
        // the user profile component

We were able to build and run this in Fable just fine. But here's the problem: the MyApp.Components.Route module was already defined by our old component mechanism. Fable handles this just fine, so we didn't immediately notice the problem. It was a .NET build that made it clear, and after I moved the new components to a distinct namespace (MyApp.Components.New.Route, for example) then the .NET build works, but also the compiler crashes have disappeared (touch wood)

dsyme commented 2 years ago

OK. Since the crashes have stopped we can close this for now, please don't hesitate to reopen if they start again, thanks