Fsharp: Internal error when using #load in fsi

Created on 18 Apr 2017  路  4Comments  路  Source: dotnet/fsharp

In the sample below, F# Interactive reports:

error FS0193: internal error: Could not load type 'MyType' from assembly 'FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.

Repro steps

Create some.fs with:

module MyModule
type MyType = A of string

And app.fsx with:

#load "some.fs"
open MyModule

let foo () : MyType =
  let cache = new System.Collections.Generic.Dictionary<_, _>()    
  let remove = [ for (KeyValue(k, _)) in cache -> k ]
  cache.[""]

Now, run: fsiAnyCpu.exe --load:app.fsx

Expected behavior

No error.

Actual behavior

error FS0193: internal error: Could not load type 'MyType' from assembly 'FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.

Known workarounds

Would love to know how to workaround this!

Related information

  • Operating system: Windows 10
  • Branch: fsiAnyCpu from Fsharp.Compiler.Tools 4.1.5
  • .NET Runtime: Whatever comes with Windows 10 + VS 2015 without VS 2017
  • Editing Tools: notepad!
Area-FSI Severity-Medium bug

All 4 comments

Interesting here it reproduces from command line, but neither in VS2015/17 when evaluating app.fsx.

Whoa, I haven't seen such a simple type loading bug in fsi in ages.

It's odd, because the code is totally normal - there's just nothing unusual about it. Traditionally the System.Reflect.Emit implementation has had some trouble creating types that were mutually recursive, especially where nested types referred to their containing type in some way - but we haven't seen those problems for a while.

Here's a workaround (though entirely unintuitive)

  let remove = cache |> Seq.map (fun kvp -> kvp.Key) |> Seq.toList

Note to self: Removing the capture of cache by the generated state machine enumerator allows the code to load

let foo () : MyType =
  let cache = new System.Collections.Generic.Dictionary<_, _>()    
  let remove = [ for k in (new System.Collections.Generic.Dictionary<_, _>())     -> k.Key ]
  cache.[""]

@tpetricek Putting the type in some.fs in a namespace instead of a module is a workaround

BTW here is a single-file repro:

namespace global

module MyModule =
    type MyType = A of string

module OtherModule = 
  open MyModule

  open System.Collections.Generic

  let foo () = [ for (k: KeyValuePair<string,MyType>) in []    -> () ]
Was this page helpful?
0 / 5 - 0 ratings