Fable compilation error: The type referenced through 'XXXX' is defined in an assembly that is not referenced. You must add a reference to assembly 'XXXX'

Created on 2 Apr 2021  路  6Comments  路  Source: fable-compiler/Fable

Description

Fable doesn't compile my project while dotnet build does.

Repro code

  1. Clone the repo: https://github.com/MangelMaxime/FableAssemblyNotReferencedError
  2. dotnet tool restore
  3. dotnet fable src --outDir fableBuild
  4. See that Fable compilation is errored with:
C:/Users/mamangel/Documents/Workspace/Github/ReproBugFable/src/Main.fs(15,13): 
(15,27) error FSHARP: The type referenced through 'Glutinum.RangeParser.RangeParser.Options' is defined in 
an assembly that is not referenced. You must add a reference to assembly 'Glutinum.RangeParser'. (code 74)

Note: dotnet build src works with or without referencing the package Glutinum.RangeParser in the Server.fsproj.

Expected and actual results

It should compile the project as dotnet build src does.

Related information

  • Fable version: 3.1.12
  • Operating system: Windows
bug

All 6 comments

It seems like the error goes away if I remove the line let x = req.body.Value.

Hi @MangelMaxime! Thanks a lot for creating the repro and sorry for the late reply. I think this happens because of a conflict between "pure" bindings (which don't include the .fs sources in the package) and Fable packages containing code. This is what happens when Fable parses an .fproj for compilation:

  1. First Fable calls MsBuild (through Dotnet.Projinfo) which returns the .fs files in the project, the project references and the .dll references corresponding to Nuget packages. The project references are resolved until we only have .fs files and .dll references.
  2. Then Fable scans the path of the .dll references to see if the nuget package contains a fable folder with the sources. In that case, it replaces the .dll reference with the .fs sources as if it were a project reference.

The problem here seems to be that Glutinum.ExpressServeStaticCore is a "pure" binding (doesn't include a fable folder) so it will be kept as a .dll reference. But it has a dependency on Glutinum.RangeParser which does include the .fs sources, so Fable removes the Glutinum.RangeParser.dll reference. Because .dll libraries cannot reference a type in an .fs file the Fable compilation fails (dotnet build succeeds because the .dll references are not being replaced).

Looking at the source Glutinum.RangeParser, it seems the only actual code included is for the active pattern |UnkownError|ResultInvalid|ResultUnsatisfiable|Range| so I can think of two solutions:

  • Remove that code and publish Glutinum.RangeParser without the fable folder (if necessary, publish a different package like Glutinum.RangeParser.Extensions).
  • Publish Glutinum.ExpressServeStaticCore also with the fable folder. But then you need to remember to include the sources for all dependent packages. So if you choose this path probably the easiest thing is to just include the sources for all Glutinum packages.

Sorry I can only offer an "all or nothing" solution for Glutinum, but unfortunately this is they way it works now :/

Hello @alfonsogarciacaro ,

thank you for the explanations. I think I will go with the solution of publishing all the related packages with the fable folder because I don't think people will think of adding two packages for a single "binding".

I suppose this will have an impact on the performance of Fable. I am right to suppose this will only impact the first compilation as Fable will have to compile the *.fs files from the packages but then as they will never change it will not impact or not much the rest?

That should be correct. Only thing is the F# compiler will keep hold of the AST of all the Glutinum libraries, so the memory consumption will increase. I believe compilation speed shouldn't be affected though.

If one I day I can retake my idea of serializing the AST for inlined functions we can just precompile the libraries once and then free the memory (and the results can also be cached for the next watch compilation too even after stopping the compiler).

Thank you for the confirmation, I will make the changes.

Memory consumption should be ok

Closing for now as I understand the issue is fixed (or at least there's a workaround). Please reopen if that's not the case.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

et1975 picture et1975  路  3Comments

ncave picture ncave  路  3Comments

alfonsogarciacaro picture alfonsogarciacaro  路  3Comments

krauthaufen picture krauthaufen  路  3Comments

theprash picture theprash  路  3Comments