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.94k stars 788 forks source link

FSI fails to find references from loaded libraries #6662

Closed KillyMXI closed 5 years ago

KillyMXI commented 5 years ago

If a library loaded into FSI session has it's own references - it fails at any attempt to call them.

Demo project with various actions I've taken trying to isolate the issue: https://github.com/KillyMXI/FsiOddityDemo

Repro steps

(This is an essence of it, demo project with more details above)

  1. Add a library project to solution (let's say library A)

  2. Add another project to solution (let's say library B)

  3. Make library B referencing to library A (either by project reference or dll reference)

  4. Make a function in B that will call some function from A

  5. Make an fsx script file, reference B.dll from it, call the function in B from the previous step.

Expected behavior

Since all references of library B are copied over to the same folder as B.dll - there should be no issues to find them. The function call from the script should produce the expected output, as if it were called from compiled code.

Actual behavior

FSI fails at the call from B to A - having issues to locate the library A.

PS > dotnet fsi .\script.fsx
System.IO.FileNotFoundException: Could not load file or assembly 'A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
File name: 'A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
   at B.Worker.doWork(Int32 x)
   at <StartupCode$FSI_0002>.$FSI_0002.main@()

Stopped due to error

Known workarounds

#load all the code files from all libraries into script manually. This is not a feasible way in case of bigger projects with many files. This will require manual tracking of code structure changes.

Related information

zpodlovics commented 5 years ago

Just checked on linux in release mode with the following changes, it works to me. Could you check the the library loading with the sysinternals procmon tool [1] ?

The B/bin/Release/netcoreapp2.2 have the following contant:

A.dll  A.pdb  B.deps.json  B.dll  B.pdb
diff --git a/B.DllTests/B.DllTests.fsproj b/B.DllTests/B.DllTests.fsproj
index 324f7bd..3103dcb 100644
--- a/B.DllTests/B.DllTests.fsproj
+++ b/B.DllTests/B.DllTests.fsproj
@@ -15,7 +15,7 @@
     </ItemGroup>
     <ItemGroup>
         <Reference Include="B">
-            <HintPath>..\B\bin\Debug\netcoreapp2.2\B.dll</HintPath>
+            <HintPath>../B/bin/Release/netcoreapp2.2/B.dll</HintPath>
         </Reference>
     </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/C/C.fsproj b/C/C.fsproj
index f76d368..5993b8b 100644
--- a/C/C.fsproj
+++ b/C/C.fsproj
@@ -7,7 +7,7 @@
   </ItemGroup>
   <ItemGroup>
     <Reference Include="A">
-      <HintPath>..\A\bin\Debug\netcoreapp2.2\A.dll</HintPath>
+      <HintPath>../A/bin/Release/netcoreapp2.2/A.dll</HintPath>
     </Reference>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/script.fsx b/script.fsx
index fdc8a15..3b7308e 100644
--- a/script.fsx
+++ b/script.fsx
@@ -1,4 +1,4 @@
-#I "B\\bin\\Debug\\netcoreapp2.2";;
+#I "B/bin/Release/netcoreapp2.2";;
 #r "B.dll";;

 B.Worker.doWork 5
dotnet /usr/share/dotnet/sdk/2.2.203/FSharp/fsi.exe script.fsx
5 ^2 *2 = 50
/usr/local/stow/netcore3.0/dotnet /usr/local/stow/netcore3.0/sdk/3.0.100-preview4-011223/FSharp/fsi.exe script.fsx 
5 ^2 *2 = 50

[1] https://docs.microsoft.com/en-us/sysinternals/downloads/procmon

cartermp commented 5 years ago

@KillyMXI Have you also tried this with the latest .NET Core 3.0 preview? Some changes in this area have gone in an addressed a lot of problems with finding assemblies, but they aren't in the latest release quality .NET Core.

KillyMXI commented 5 years ago

@zpodlovics some good points there

I updated back slashes to forward slashes. It doesn't affect the issue but it makes it easier to cross-check on different platforms.

Another change you did is that you have built a Release build. I checked it myself and turns out it works in the Release build when the reference to A is made by project. I updated my repo. script.release.fsx (B->A project) is working, while script3.release.fsx (C->A dll) is not. I'm not really concerned about script3 so this is a sensible workaround for core 2.2. (Can't see how to make release builds with commands available in vscode - probably have to open another issue in DCE repo...)

As for procmon, I don't know what to look for there. I couldn't capture any mention of A.dll even on working example, I can only see B.dll opened.

@cartermp I had no intent to get it before release, but oh well. I got the preview4 now.

> dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   3.0.100-preview4-011223
 Commit:    118dd862c8
...

Looks like just installing it was enough. Libraries are loaded fine now, even if they were built for 2.2 target, and I also haven't changed the path to fsi...

KillyMXI commented 5 years ago

I guess nothing left to be done about this issue. Probably too much for a backport and fix for 2.2.

We plan to ship .NET Core 3.0 in the second half of 2019. We will announce the ship date at the Build 2019 conference.

Got +1 reason to impatience.

KevinRansom commented 5 years ago

2.2 will be updated in a future release as will 2.1.

KillyMXI commented 5 years ago

@KevinRansom What kind of updates will be made to 2.2? From @cartermp 's words I got it might've been some involving changes in 3.0.

I only know that PowerShell team not backporting anything but security fixes probably. So I have to wait until they ship PowerShell 7 to Windows to get the patch I care about...

cartermp commented 5 years ago

@KillyMXI Since Core 2.2 is considered Current, it will get any and all F# compiler and FSI improvements until it is no longer Current. Eventually, .NET Core 3.0 will be the Current release, at which point any further issues will be met with, "use .NET Core 3.0".

KevinRansom commented 5 years ago

@KillyMXI, obviously nothing I say represents a commitment. But for now, dotnet cli 2.1, 2.2 and 3.0 will ship the same version of the F# compiler.

There may be changes in language and feature support dependent upon capabilities of the runtime hosting it. For example, fsi on coreclr 3.0, supports pinvoke. On 2.1 and 2.2 that does not work.

The fix for this is showing up in previews of 2.1.X and 2.2.X

c:\kevinransom\FsiOddityDemo>dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   2.1.700-preview-009618
 Commit:    4c068328cc

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18362
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.1.700-preview-009618\

Host (useful for support):
  Version: 3.0.0-preview4-27610-12
  Commit:  d5a76cb8c0

.NET Core SDKs installed:
  2.1.504 [C:\Program Files\dotnet\sdk]
  2.1.505 [C:\Program Files\dotnet\sdk]
  2.1.600 [C:\Program Files\dotnet\sdk]
  2.1.601 [C:\Program Files\dotnet\sdk]
  2.1.602 [C:\Program Files\dotnet\sdk]
  2.1.700-preview-009597 [C:\Program Files\dotnet\sdk]
  2.1.700-preview-009601 [C:\Program Files\dotnet\sdk]
  2.1.700-preview-009618 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0-preview4-19210-17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0-preview3-27512-04 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0-preview4-27610-12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.0.0-preview4-27611-18 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

c:\kevinransom\FsiOddityDemo>dotnet fsi .\script.fsx
5 ^2 *2 = 50
c:\kevinransom\FsiOddityDemo>
KillyMXI commented 5 years ago

@KevinRansom oh, cool!

Makes sense to keep this issue open until it gets released then.

KevinRansom commented 5 years ago

@KillyMXI, you can download previews from here: https://github.com/dotnet/core-sdk to verify the behavior.

KillyMXI commented 5 years ago

Thank you, I was wondering where to find the previews for 2.2.x.

> dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   2.2.204-preview-010112
 Commit:    52308a9ad4
...

-- the issue is still present (no surprises if that's the security fixes branch)

> dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   2.2.300-preview-010067
 Commit:    803425478a
...

-- all works, the fix seems to be in place.

So, waiting for 2.2.300 release.

cartermp commented 5 years ago

@KillyMXI There are no previews for this. @KevinRansom is referring to .NET Core 3.0 preview.

KillyMXI commented 5 years ago

I followed the link he provided, founds the following note:

Note: Be aware that the following installers are the latest bits. ...

And the links:

It says "preview" in the badges and in version info. That's what we were referring to. I would rather call it "nightly" though.

cartermp commented 5 years ago

Closing this as the official released-and-supported fix is to be in .NET Core 3.0, which is later this year. The latest preview of .NET Core 3.0 has the updated FSI that fixes this.

KillyMXI commented 5 years ago

.NET Core SDK 2.2.300 did come out and it includes the fix for this issue. Now the issue is fully resolved with the fix available in a public version. Thanks @KevinRansom for useful answers.

PS > dotnet fsi .\script.fsx
5 ^2 *2 = 50
PS > dotnet fsi .\script3.fsx
5 *2 = 10
PS > dotnet fsi .\script3.release.fsx
5 *2 = 10
PS > dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   2.2.300
 Commit:    73efd5bd87

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.17763
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.2.300\

Host (useful for support):
  Version: 2.2.5
  Commit:  0a3c9209c0
...